Tocyukiのブログ

ギターと柔術とプログラミングが好き!

「AWSクラウドネイティブデザインパターン」を読んだ ⛅

というわけで読了したので気づきや感想やらなんやらをつらつらと📝

目次

  • 第1部:運用を効率化する
    • 第1章:責任共有モデルを意識してアーキテクチャを選択する
      • 責任共有モデルとは
      • 責任範囲を最小化するようクラウドサービスを選択する
      • 利用者の責任範囲をサポートするサービスに習熟する
      • 責任共有モデルを意識したアーキテクチャパターン
    • 第2章:テスト容易性を高める
      • ユニットテストを阻害する複雑な依存関係
      • 開発者に夜信頼性の高いテスト
      • 独立した組織によるテスト
      • テストピラミッドとCI/CD
      • テスト容易性をたかめるためのアーキテクチャパターン
    • 第3章:小規模かつ可逆的な変更を頻繁に行う
      • 継続的インテグレーション
      • トランクベース開発
      • 継続的インテグレーションに必要なプラクティス
      • 継続的デリバリー
      • 進化的なアーキテクチャ
      • 小規模かつ可逆的な変更を頻繁に行うためのアーキテクチャパターン
    • 第4章:セキュリティを作り込む
      • 責任共有モデルとクラウドのセキュリティ
      • 疎結合なアプリケーションセキュリティ
      • 脅威モデリング
      • DFD (Data Flow Diagram) によるモデリング
      • STRIDEフレームワークによる脅威のリストアップ
      • 脅威への対策
      • セキュリティを高めるためのアーキテクチャパターン
    • 第5章:DevOpsとプラットフォームエンジニアリング
      • 運用と開発のコラボレーション
      • クラウドネイティブなチームモデル
      • プラットフォームエンジニアリング
      • アーキテクチャパターン
  • 第2部:回復力を高める
    • 第6章:スケーラブルなアーキテクチャを実装する
      • オートスケーリングを前提としたアプリケーションの構造
      • 非同期アーキテクチャによるスケーラビリティ
      • 制限をコントロールする
      • アーキテクチャパターン
    • 第7章:障害からの自動的な復旧を実現する
      • リカバリ目標を定義する
      • フェイルオーバーを実装する
      • タイムアウト、リトライを実装する
      • 安全なデプロイメント
      • アーキテクチャパターン
    • 第8章:回復力をテストする
      • スケーラビリティをテストする
      • 障害復旧のテストを行う
      • Game Day を実施する
      • アーキテクチャパターン
  • 第3部:可観測性を高める
    • 第9章:可観測性を実装し運用する
      • 可観測性の3本柱
      • SLI、SLO、SLAとエラーバジェット
      • トリアージ
      • ビジネスの観点でメトリクスを収集する
      • FinOps
      • アーキテクチャパターン
    • 第10章:AWSのサービスを活用してテレメトリを収集する
      • OpenTelemetryとADOT
      • AWS X-Rayによる分散トレーシング
      • 抽象化レイヤのメトリクスを収集する
      • ログ出力先を抽象化する
      • アーキテクチャパターン
      • OSS、3rd Party製品の活用

関連リンク

gihyo.jp

余談だが、公式ページに記載されている目次とだいぶ違いがあったので報告したらすぐに修正してくれた。

著者

※敬称略

  • 林政利(はやしまさとし)
    • https://twitter.com/literalice
    • アマゾン ウェブ サービス ジャパン合同会社
      • サービススペシャリスト統括本部
        • アプリケーション開発技術本部
          • コンテナスペシャリスト
  • 根本裕規(ねもとゆうき)
    • https://twitter.com/rr250r_smr
    • アマゾン ウェブ サービス ジャパン合同会社
      • 技術統括本部
        • フィナンシャルサービスインダストリ技術本部
          • シニアソリューションアーキテクト
  • 吉澤稔(よしざわみのる)
    • アマゾン ウェブ サービス ジャパン合同会社
      • 技術統括本部
        • フィナンシャルサービスインダストリ技術本部
          • シニアソリューションアーキテクト

気づきと感想

  • ECSのローリングアップデート機能、AWS AppConfigでベイクタイムを設定しCloudWatchアラームをロールバックする仕組みが設けられているというのは知らなかった
  • AppConfigをあまり使ったことがなかったので機能フラグを実装する際に便利なマネージドサービスということを認識できた
  • STOP(Standby Takes Over Primary)というパターンも知らなかった
  • 継続的インテグレーション、トランクベース開発について、なかなか実現するのは難しそうな手法、プラクティスだなと感じたが、実現できる仕組みを整理できたらデリバリープロセスの劇的な向上を実現できそう

まとめ

「AWSクラウドネイティブデザインパターン」を読んだ ⛅

クラウドネイティブな開発、運用を実現するためのアイディアやプラクティスが様々な観点で記載されていてとても参考になった!

DevOpsやPlatform Engineeringに関連してチームトポロジーについての言及もあり、クラウドネイティブな開発を行うためのチームモデルについても説明されていた。

AWSのサービスでここまでできるようになったのかという気付きも多くあり、AWSでクラウドネイティブなソフトウェア開発を行っているエンジニアにはとても参考になる一冊になると思うのでオススメです!

筋トレへの取り組み内容を整理してみた

育休中に筋トレを本格的にはじめていて、日々様々な筋トレ動画を見漁ったり、取り組みの改善を行っている。

来週から育休も終わるので習慣が途切れないよう、改めて取り組んでいる内容とトレーニングメニューの整理をしてみる。

取り組み内容

現在は以下の内容をベースに取り組んでいる。

  • 各種サプリメントとタンパク質の摂取
    • マルチビタミン、エビオス錠、EAA、プロテイン
  • 腸内環境を整える
    • スーパー大麦、ビオフェルミン
  • 除脂肪食
    • アプリでレコーディング、PFC管理
  • トレーニング(週2〜3目安)
    • 自宅トレ週2(ダンベルベンチ)、ジムトレ週1

利用器具

以下をメルカリで仕入れた

利用アプリ

これらを以下のアプリで管理している(もちろん(?)すべて課金している

レコーディングアプリ www.myfitnesspal.com

習慣化アプリ www.habitify.me

筋トレアプリ myworkout.hateblo.jp

摂取しているもの

マルチビタミン

EAA

プロテイン

スーパー大麦

ビオフェルミン

エビオス錠

分割法について

以下の部位に分けてトレーニングをする方法

  • 背中

腹はとても小さい筋肉なので毎日のトレーニングにクランチを2〜3セット取り入れるぐらいか、なんならやらないぐらいの感じで主に腹以外の5分割として見ると良い。

しかし週5トレーニングするのは無理ゲーなので、現在週3を目安に一回のトレーニングは60分以内で以下の3分割に取り組んでいる(週3もかなりキツいが

  • 胸と二頭
  • 肩と三頭
  • 背中と脚

ちなみにトレーニングしないときは出来る限り以下の腹筋メドレーをやるようにしている。

youtu.be

各部位のトレーニングメニュー

現在以下のメニューを中心に取り組んでいる。

ギリギリ10回できる重さでそれぞれ3〜4セット

  • バーベルベンチプレス
  • ダンベルベンチプレス
  • ダンベルフライ
  • インクラインダンベルベンチプレス
  • デクラインダンベルベンチプレス

背中

12〜15回を丁寧に引き切れるぐらいの重さをそれぞれ3〜4セット

  • ラットプルダウン
  • シーテッドロー
  • ベントオーバーダンベルロー

フロント、サイド、リアの三箇所があるので最低3種目8〜12回を3〜4セット

  • フロントレイズ
  • サイドレイズ
  • アーノルドプレス
  • ダンベルフレンチプレス

腕(二頭筋)

12〜15回を3〜4セット

  • ダンベルカール
  • ハンマーカール

腕(三頭筋)

8〜10回より重たい重量で3〜4セット

  • ダンベルフレンチプレス

  • バーベルスクワット
  • バーベルワイドスクワット
  • ブルガリアンスクワット

参考動画

PivotのBODY SKILL SETがとても面白くて参考になるのでめちゃくちゃオススメです。

www.youtube.com

おわりに

以前もゴールドジムに通ったことがあるが、通い初めて一ヶ月でコロナ禍が訪れてしまい思ったような効果が出なかったが、今回は習慣化に今のところ成功していて良い結果も出ているのでこのまま継続出来るように頑張っていきたい!

SQLパフォーマンス改善手法について

mattnさんがめちゃくちゃ良い感じの回答をしてくれていたが、詳細については触れていなかったのでほんの少しだけ回答を深掘ってみる。

mond.how

以下、引用

SQL でパフォーマンス改善するには幾らか手法がありますが、おおよそは以下の数個に絞られます。

  • フルスキャンを避ける事
  • インデックスを適切に張る事
  • 集約関数や分析関数の利用
  • 速い演算子や副問合せへの書き換え

なぜ速い演算子に書き換えるべきなのか、なぜ分析関数が必要のか、なぜフルスキャンを避けるべきなのか、なぜインデックスを張るとパフォーマンスが改善するのか、そして適切にインデックスを貼らないどうなるのか、といった内容は読み物として調べ、実際に試されるのが良いと思います。

一例を上げますとインデックスは張るだけで表引きについてはすぐにパフォーマンスが改善できるのですが、それはつまりデータ挿入時にインデックスを登録する事になるので、INSERT が遅くなったりデータ容量が増えたりします。

その辺りを経験して知見として持ちつつ要件にマッチするよううまく改善できるかがデータベースエンジニアとしての成長になると思います。残念ながら僕はウェブのサービスでこれらを体系的に学べる物を知りません(あるかもしれません)が、チュートリアルサイトは幾らかある様に思います。インデックスやフルスキャンといったキーワードを使って検索頂き、チュートリアルサイトを確認頂くのが良いと思います。

なぜフルスキャンを避けるべきなのか

フルスキャンとは

フルスキャン(テーブルスキャン)とは、データベースがテーブル内のすべての行を順番に読み込んで、条件に一致するデータを探す操作です。

なぜ避けるべきか

  • パフォーマンスの低下: テーブルが大きい場合、フルスキャンは非常に時間がかかります。
    • 大量のデータを読み込むため、I/O操作が増え、処理時間が長くなります。
  • リソースの消費: フルスキャンは、CPUやメモリ、ディスクI/Oを大量に消費します。
    • これにより、他のクエリやトランザクションが遅くなる可能性があります。

対策

  • インデックスの利用: インデックスを使うことで、データの検索を効率化できます。
    • インデックスは、特定の列に対して高速な検索を可能にするデータ構造です。
  • 適切なフィルタリング: クエリで必要なデータだけを取得するようにし、不要なデータのスキャンを避けます。

なぜインデックスを張るとパフォーマンスが改善するのか

インデックスとは

  • インデックスは、データベーステーブル内の特定の列に対して作成されるデータ構造で、検索を迅速にするための手法です。
  • B-treeやハッシュなどの構造が一般的です。

なぜパフォーマンスが改善するのか

  • 検索の高速化: インデックスを使用すると、特定の列に対して高速な検索が可能になります。
    • インデックスは、テーブル内のすべての行を読み込むのではなく、インデックス構造を参照するだけで済むため、検索が大幅に高速化します。
  • クエリの最適化: インデックスを使うことで、データベースのクエリオプティマイザが効率的なクエリプランを選択できるようになります。

適切にインデックスを貼らないとどうなるか

  • パフォーマンスの低下: インデックスがないと、フルスキャンが必要になるため、クエリのパフォーマンスが低下します。
  • クエリの複雑化: 適切なインデックスがないと、データの検索や結合が効率的に行えず、クエリが複雑になり、実行速度が遅くなります。

なぜ速い演算子に書き換えるべきなのか

速い演算子

演算子の選択は、クエリのパフォーマンスに大きな影響を与えます。

例えば、= 演算子は比較演算子の中で最も効率的ですが、LIKE 演算子はパターンマッチングのため、場合によってはパフォーマンスが低下することがあります。

副問合せ(サブクエリ)

副問合せは、主クエリ内で別のクエリを実行する手法です。

ただし、非効率なサブクエリは、パフォーマンスの低下を招く可能性があります。

なぜ書き換えが必要なのか

  • 効率的な演算子の使用: 適切な演算子を使用することで、クエリの実行速度が向上します。
    • 例えば、IN 演算子よりも EXISTS を使うことで、パフォーマンスが向上する場合があります。
  • サブクエリの最適化: サブクエリを使う場合は、クエリプランによってパフォーマンスが大きく変わります。
    • 必要な場合には、JOIN句に書き換えたり、サブクエリの結果を一時テーブルに保存してから利用することで、パフォーマンスを改善できます。

なぜ集約関数や分析関数が必要のか

集約関数とは

集約関数は、複数の行から1つの値を計算する関数です。

例として、SUM(), AVG(), COUNT() などがあります。

分析関数とは

分析関数(ウィンドウ関数)は、特定のウィンドウ(行のサブセット)に対して集計を行う関数です。

例として、ROW_NUMBER(), RANK(), LEAD(), LAG() などがあります。

なぜ必要なのか

  • 効率的なデータ処理: 集約関数を使うことで、大量のデータを効率的に処理し、必要な統計情報や集計結果を迅速に取得できます。
  • 複雑な計算の簡素化: 分析関数を使用することで、複雑な計算やデータ分析をSQLクエリ内で簡潔に表現できます。
    • これにより、アプリケーションコードの複雑さを減少させ、パフォーマンスを改善できます。

まとめ

  • フルスキャンを避ける: 大量のデータを無駄にスキャンせず、効率的な検索を実現します。
  • インデックスを適切に張る: データの検索を高速化し、クエリのパフォーマンスを向上させます。
  • 集約関数や分析関数の利用: 大量のデータから効率的に情報を取得し、複雑な計算を簡素化します。
  • 速い演算子や副問合せへの書き換え: クエリの効率を高め、パフォーマンスを最適化します。

これらの手法を理解し、適切に実施することで、SQLクエリのパフォーマンスを大幅に改善することができます。

このあたりの過去記事も参考になるかも

blog.tocyuki.com

blog.tocyuki.com

GitHub CLIでリポジトリ作成して手元にクローンするまで

TL;DR

  • ghgh-qを使ってやってます

gh repo createでリポジトリ作成

GUIでリポジトリを作成することはほぼなくなった

cli.github.com

gh repo create scrwr --add-readme -g Go -l mit --public -d "Check if SupportsCertificateRotationWithoutRestart is enabled in Amazon RDS"

gh qでリポジトリをクローン

GitHub Extentionであるgh qを使ってクローンする

github.com

使い方はシンプルで自分のリポジトリをクローンする場合はgh qするだけで、他の人やOrganizationのリポジトリをクローンするにはgh q {USER_NAME}とするだけです

参考

cli.github.com

zenn.dev

RDS証明書更新の際に再起動が発生するかどうかの確認方法

無慈悲に訪れるRDS証明書更新の影響(再起動するかどうかの部分)を確認する方法メモ

DBエンジンバージョン確認

aws rds describe-db-instances | jq '.DBInstances[] | select(.DBInstanceIdentifier | startswith("app-")) | {"Name": .DBInstanceIdentifier, "Engine": .Engine, "EngineVersion": .EngineVersion}'
{
  "Name": "app-prod",
  "Engine": "postgres",
  "EngineVersion": "15.5"
}
{
  "Name": "app-stg",
  "Engine": "postgres",
  "EngineVersion": "15.5"
}

SupportsCertificateRotationWithoutRestartの確認

  • trueだとSupportsCertificateRotationWithoutRestartがサポートされており再起動は発生しない
aws rds describe-db-engine-versions --engine postgres --engine-version 15.5 --profile mobilico |jq '.DBEngineVersions[].SupportsCertificateRotationWithoutRestart'
true

参考

www.k-friendly.com

docs.aws.amazon.com

SupportsCertificateRotationWithoutRestart Indicates whether the engine version supports rotating the server certificate without rebooting the DB instance.

Type: Boolean

Required: No

リレーショナルデータベース技術関連で読むと良さそうな技術書

読んだもの、積読、これから買うもの、色々あるが備忘のため記録しておく

基本

↓2024/8/26発売予定

設計

SQLアンチパターン

SQLアンチパターン

Amazon

↓2024/8/28発売予定

SQLの書き方やパフォーマンスなど

初めてのSQL 第3版

初めてのSQL 第3版

Amazon

↓2024/9/14発売予定

運用

関連記事

こちらもSQL&DB力アップさせるのに参考になれば幸いです。

blog.tocyuki.com

blog.tocyuki.com

「つくって、壊して、直して学ぶ Kubernetes入門」を読んだ🐳

というわけで読了したので気づきや感想やらなんやらをつらつらと📝

目次

  • Part 1:つくってみようKubernetes
    • Chapter 1 Dockerコンテナをつくってみる
    • Chapter 2 Kubernetesクラスタをつくってみる
    • Chapter 3 全体像の説明
    • Chapter 4 アプリケーションをKubernetesクラスタ上につくる
  • Part 2:アプリケーションを壊して学ぶKubernetes
    • Chapter 5 トラブルシューティングガイドとkubectlコマンドの使い方
    • Chapter 6 Kubernetes リソースをつくって壊そう
    • Chapter 7 安全なステートレス・アプリケーションをつくるために
    • Chapter 8 総復習:アプリケーションを直そう
  • Part 3:壊れても動くKubernetes
    • Chapter 9 Kubernetesの仕組み、アーキテクチャーを理解しよう
    • Chapter 10 Kubernetesの開発ワークフローを理解しよう
    • Chapter 11 オブザーバビリティとモニタリングに触れてみよう
    • Chapter 12 この先の歩み方

関連リンク

著者のブログ blux.hatenablog.com

サンプルコードリポジトリ github.com

「Chapter 3 全体像の説明」と「Chapter 4 アプリケーションをKubernetesクラスタ上につくる」から一部を抜粋した記事 codezine.jp

speakerdeck.com

speakerdeck.com

www.youtube.com

気づきと感想

  • 全体を通してハンズオンが豊富でとても楽しく読み進めることができた
  • kindでのローカル環境も体験が良く、もうkindでええじゃん!となった
  • kubectl debug便利そう
  • 周辺エコシステムやPluginの紹介、各種Tipsも参考になる
  • Prometheus & GrafanaのデプロイとTraceの確認もハンズオンでカバーしてて良き
  • ユーザー管理と認証・権限確認周りについては特に言及なかったけど漫画で書いてくれたらめちゃくちゃわかりやすそう
  • Chapter11にはお掃除コマンドがないのでお掃除を忘れないように

誤植

※2024/06/05時点で正誤表に記載のないもので気付いたもののみ記載 www.shoeisha.co.jp

  • P.039 (2つ目の実行結果)Hello, world! Let's learn Kubernetes!Hello, world!
  • P.093 -stdin(-i)--stdin(-i)
  • P.171 ユーザー名などを変更する可能性があるすべての設定情報に使えます。ユーザー名など変更する可能性があるすべての設定情報に使えます。
  • P.254 今回は簡単のためにDeploymentの今回は簡単にするためDeploymentの

まとめ

「つくって、壊して、直して学ぶ Kubernetes入門」を読んだ🐳

ハンズオンが豊富で色々な気づきもあり、これからKubernetesを始めるという方の最初に読む本としてとても良いのでは??となる書籍でした!

会員特典データとして「ArgoCDでGitOps体験してみよう」のPDFがもらえるのでこちらも是非!

HelmでPrometheus Stackをインストールする

自宅のラズパイk8sクラスターにPrometheus Stackを生やしていく

Helm Chart Repositoryを追加

github.com

$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update

Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "prometheus-community" chart repository
Update Complete. ⎈Happy Helming!⎈

namespaceの作成

$ k create namespace monitoring

namespace/monitoring created

helm installの実行

$ helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack

NAME: kube-prometheus-stack
LAST DEPLOYED: Mon Jun  3 21:26:28 2024
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl --namespace monitoring get pods -l "release=kube-prometheus-stack"

Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.

起動確認

Pod

$ k get po

NAME                                                        READY   STATUS    RESTARTS   AGE
alertmanager-kube-prometheus-stack-alertmanager-0           2/2     Running   0          49m
kube-prometheus-stack-grafana-67997d8bd4-wnh9f              3/3     Running   0          49m
kube-prometheus-stack-kube-state-metrics-657ddb7877-jcj26   1/1     Running   0          49m
kube-prometheus-stack-operator-5975686646-bhk6m             1/1     Running   0          49m
kube-prometheus-stack-prometheus-node-exporter-jc6qx        1/1     Running   0          49m
kube-prometheus-stack-prometheus-node-exporter-n5hwh        1/1     Running   0          49m
kube-prometheus-stack-prometheus-node-exporter-x6kz6        1/1     Running   0          49m
prometheus-kube-prometheus-stack-prometheus-0               2/2     Running   0          49m

Grafanaへアクセス

自動生成されたServiceを使ってport-forwardする

$ k port-forward service/kube-prometheus-stack-grafana 8080:80

Forwarding from 127.0.0.1:8080 -> 3000
Forwarding from [::1]:8080 -> 3000
Handling connection for 8080
Handling connection for 8080

http://localhost:8080/login へアクセスしてログイン画面が出ることを確認

Grafanaログイン画面

デフォルトで以下のログイン情報となっているのでログインしてみる

username password
admin prom-operator

ログイン後の画面

なんて簡単にできるんだ...(感動

HPAを利用するためにインストールしたmetrics-serverが起動しなかったのでトラブルシュートした

自宅のラズパイk8sクラスターでHPAを利用できるようにしようと思い立ち、metrics-serverをインストールしてみたものの、metrics-serverが起動しなかったのでトラブルシュートしてみた

環境

  • Kubernetes v1.30.0
  • metrics-server v0.7.1

インストール

手順に従いインストールコマンドを実行

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

github.com

起動確認

Deployment

READYが0/1のまま...

k get deployment metrics-server -n kube-system

NAME             READY   UP-TO-DATE   AVAILABLE   AGE
metrics-server   0/1     1            0           10h

Pod

metrics-serverだけREADYにならない

k get po -n kube-system

NAME                                   READY   STATUS    RESTARTS   AGE
coredns-7db6d8ff4d-67gfj               1/1     Running   0          8d
coredns-7db6d8ff4d-xlznj               1/1     Running   0          8d
etcd-k8s-master01                      1/1     Running   0          8d
kube-apiserver-k8s-master01            1/1     Running   0          8d
kube-controller-manager-k8s-master01   1/1     Running   0          8d
kube-proxy-dww28                       1/1     Running   0          8d
kube-proxy-lb9h2                       1/1     Running   0          8d
kube-proxy-t9lsn                       1/1     Running   0          8d
kube-scheduler-k8s-master01            1/1     Running   0          8d
metrics-server-7ffbc6d68-pqtdt         0/1     Running   0          10h

Describe Pods

kubelet Readiness probe failed: HTTP probe failed with statuscode: 500

Readiness probeが失敗してしまっているようだ

k describe po metrics-server-7ffbc6d68-pqtdt -n kube-system

Name:                 metrics-server-7ffbc6d68-pqtdt
Namespace:            kube-system
Priority:             2000000000
Priority Class Name:  system-cluster-critical
Service Account:      metrics-server
Node:                 k8s-worker01/192.168.1.111
Start Time:           Wed, 29 May 2024 23:51:51 +0900
Labels:               k8s-app=metrics-server
                      pod-template-hash=7ffbc6d68
Annotations:          <none>
Status:               Running
IP:                   10.244.1.73
IPs:
  IP:           10.244.1.73
Controlled By:  ReplicaSet/metrics-server-7ffbc6d68
Containers:
  metrics-server:
    Container ID:  containerd://603b5f91968f0afb410fa3a49786c563bd26f87de59c11ce1d4822e743a7fa29
    Image:         registry.k8s.io/metrics-server/metrics-server:v0.7.1
    Image ID:      registry.k8s.io/metrics-server/metrics-server@sha256:db3800085a0957083930c3932b17580eec652cfb6156a05c0f79c7543e80d17a
    Port:          10250/TCP
    Host Port:     0/TCP
    Args:
      --cert-dir=/tmp
      --secure-port=10250
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
      --kubelet-use-node-status-port
      --metric-resolution=15s
    State:          Running
      Started:      Wed, 29 May 2024 23:52:00 +0900
    Ready:          False
    Restart Count:  0
    Requests:
      cpu:        100m
      memory:     200Mi
    Liveness:     http-get https://:https/livez delay=0s timeout=1s period=10s #success=1 #failure=3
    Readiness:    http-get https://:https/readyz delay=20s timeout=1s period=10s #success=1 #failure=3
    Environment:  <none>
    Mounts:
      /tmp from tmp-dir (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-6szcf (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       False
  ContainersReady             False
  PodScheduled                True
Volumes:
  tmp-dir:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  kube-api-access-6szcf:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Burstable
Node-Selectors:              kubernetes.io/os=linux
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason     Age                     From     Message
  ----     ------     ----                    ----     -------
  Warning  Unhealthy  4m41s (x4114 over 10h)  kubelet  Readiness probe failed: HTTP probe failed with statuscode: 500

Logs

k logs metrics-server-7ffbc6d68-6srfk -n kube-system

I0530 03:08:07.651554       1 serving.go:374] Generated self-signed cert (/tmp/apiserver.crt, /tmp/apiserver.key)
I0530 03:08:08.554701       1 handler.go:275] Adding GroupVersion metrics.k8s.io v1beta1 to ResourceManager
I0530 03:08:08.686371       1 requestheader_controller.go:169] Starting RequestHeaderAuthRequestController
I0530 03:08:08.686459       1 shared_informer.go:311] Waiting for caches to sync for RequestHeaderAuthRequestController
I0530 03:08:08.686466       1 configmap_cafile_content.go:202] "Starting controller" name="client-ca::kube-system::extension-apiserver-authentication::client-ca-file"
I0530 03:08:08.686518       1 shared_informer.go:311] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I0530 03:08:08.686517       1 configmap_cafile_content.go:202] "Starting controller" name="client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file"
I0530 03:08:08.687032       1 shared_informer.go:311] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
I0530 03:08:08.689211       1 dynamic_serving_content.go:132] "Starting controller" name="serving-cert::/tmp/apiserver.crt::/tmp/apiserver.key"
E0530 03:08:08.689974       1 scraper.go:149] "Failed to scrape node" err="Get \"https://192.168.1.101:10250/metrics/resource\": tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.101 because it doesn't contain any IP SANs" node="k8s-master01"
I0530 03:08:08.690832       1 secure_serving.go:213] Serving securely on [::]:10250
I0530 03:08:08.691791       1 tlsconfig.go:240] "Starting DynamicServingCertificateController"
E0530 03:08:08.692009       1 scraper.go:149] "Failed to scrape node" err="Get \"https://192.168.1.112:10250/metrics/resource\": tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.112 because it doesn't contain any IP SANs" node="k8s-worker02"
E0530 03:08:08.701807       1 scraper.go:149] "Failed to scrape node" err="Get \"https://192.168.1.111:10250/metrics/resource\": tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.111 because it doesn't contain any IP SANs" node="k8s-worker01"
I0530 03:08:08.786953       1 shared_informer.go:318] Caches are synced for RequestHeaderAuthRequestController
I0530 03:08:08.787115       1 shared_informer.go:318] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I0530 03:08:08.788043       1 shared_informer.go:318] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
E0530 03:08:23.685957       1 scraper.go:149] "Failed to scrape node" err="Get \"https://192.168.1.112:10250/metrics/resource\": tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.112 because it doesn't contain any IP SANs" node="k8s-worker02"
E0530 03:08:23.692988       1 scraper.go:149] "Failed to scrape node" err="Get \"https://192.168.1.111:10250/metrics/resource\": tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.111 because it doesn't contain any IP SANs" node="k8s-worker01"
E0530 03:08:23.695203       1 scraper.go:149] "Failed to scrape node" err="Get \"https://192.168.1.101:10250/metrics/resource\": tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.101 because it doesn't contain any IP SANs" node="k8s-master01"
I0530 03:08:36.493054       1 server.go:191] "Failed probe" probe="metric-storage-ready" err="no metrics to serve"

ログからmetrics Serverが起動しない原因は、Kubeletの証明書がIP SAN(Subject Alternative Name)を含んでいないため、TLS検証が失敗していることっぽいことがわかったのでTLS検証を無効化していく

TLS検証の無効化

というわけで現状自宅のラズパイk8sクラスターはkubelet証明書がクラスター認証局に署名されていないのでargs--kubelet-insecure-tlsを渡して証明書の検証を無効化していく

k edit deploy metrics-server -n kube-system
  template:
    metadata:
      creationTimestamp: null
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=10250
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        - --kubelet-insecure-tls # ←こいつを追加

再度動作確認

Pods

k get po -n kube-system

NAME                                   READY   STATUS    RESTARTS   AGE
coredns-7db6d8ff4d-67gfj               1/1     Running   0          12d
coredns-7db6d8ff4d-xlznj               1/1     Running   0          12d
etcd-k8s-master01                      1/1     Running   0          12d
kube-apiserver-k8s-master01            1/1     Running   0          12d
kube-controller-manager-k8s-master01   1/1     Running   0          12d
kube-proxy-dww28                       1/1     Running   0          12d
kube-proxy-lb9h2                       1/1     Running   0          12d
kube-proxy-t9lsn                       1/1     Running   0          12d
kube-scheduler-k8s-master01            1/1     Running   0          12d
metrics-server-d994c478f-8f7hh         1/1     Running   0          23m

Deployments

k get deploy -n kube-system

NAME             READY   UP-TO-DATE   AVAILABLE   AGE
coredns          2/2     2            2           12d
metrics-server   1/1     1            1           3d10h

というわけで無事起動させることができた!

DockerのCI改善に寄与しそうなリンク・Tips・ツールたち

リンク

NIST SP 800-190 Application Container Security Guide

コンテナセキュリティの国際的なガイダンス

コンテナに関するセキュリティ上の考慮ポイントが網羅されている csrc.nist.gov

CIS Docker Benchmark

www.cisecurity.org

ツール

Trivy

Aqua Security Software社が提供する脆弱性ツール

コンテナOSパッケージやプログラムの各言語に関連した依存関係などをスキャンしてくれる github.com

aquasecurity.github.io

Hadolint

DockerfileのLintツール

DockerのベストプラクティスやShellCheckによる静的解析ツールのチェック項目が組み込まれている

github.com

github.com

www.shellcheck.net

Dockle

ビルドされたイメージに対して、DockerのベストプラクティスやCIS Docker Benchmarksで求められる項目をチェックしてくれる

github.com

containers.goodwith.tech

Kritis Sgner

Kritis Signer はオープンソースのコマンドライン ツールで、構成したポリシーに基づいて Binary Authorization 証明書を作成できるツール

github.com

cloud.google.com

kaniko

Googleが中心となって開発したOSS

特定のコンテナランタイムに依存しないコンテナイメージビルドが可能

kanikoを利用してビルドするとDockerfileの各コマンドごとにそれぞれスナップショットを作成&レイヤーとして保存してイメージを作成してレジストリにプッシュする

レイヤーごとに作成されたイメージ情報は次回ビルド時にキャッシュとして利用できるのでレイヤの変更がなければビルド時間の短縮ができる

github.com

cloud.google.com

Tips

公式配布のベースイメージかどうかのチェック

現状、公式配布のベースイメージかどうかのチェックができるツールはないので、以下をCIに組み込むことで対応できる

docker search --filter is-official=true <IMAGE_NAME>

Hadolintでも関連IssueがあるのでHadolintで対応される日が来るかも?

github.com

Kubernetes運用のTips

Kubernetes運用関連で自身が遭遇した事象への対処の備忘録としてTips集的にエントリを育てていく

Kubernetesで消えないPodを強制的に削除する

まれにkubectl delete podsしてもPodが消えてくれないことがあり、その時は--grace-period=0, --forceオプションを付けることで強制的に削除することができる。

kubectl delete pods {$pod_name} --grace-period=0 --force

この方法はkubeletからの確認を待たずに強制的に削除するので、Podのプロセスが完全になくならなかったりほかのリソースとの競合などが起こりえる。 この方法を常に行うような状況の場合は原因を追究する必要がある。

Option Description
--grace-period=0 正常に終了するためにリソースに与えられる秒単位の時間。負の場合は無視されます。即時シャットダウンするには 1 に設定します。 --force が true (強制削除) の場合にのみ 0 に設定できます。
--force true の場合、API からリソースを直ちに削除し、正常な削除をバイパスします。一部のリソースをすぐに削除すると、不整合やデータ損失が発生する可能性があるため、確認が必要であることに注意してください。

kubernetes.io

TLS証明書のエラー

kubectlコマンド実行時に以下の様なエラーで接続できない場合、証明書の不一致が原因である可能性が高い

Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")

kubeconfigを確認して実行元で持っている情報と差分がないかを確認する

kubernetes.io

「世界一流エンジニアの思考法」を読んだ

というわけで世界一流エンジニアの思考法を読了したので今更ながら備忘録的な書評を書いてみる📕

この書籍は米マクロソフトシニアエンジニアでAzure Functionsの開発者である牛尾剛さんが執筆した書籍

牛尾剛さんのnoteやブログがきっかけに発足した執筆プロジェクトとのことでnoteの記事もちょこちょこ見てみたがとてもおもしろいので興味があればこちらも是非!

note.com

目次

  • 第1章 世界一流エンジニアは何が違うのだろう? - 生産性の高さの秘密
    • 「生産性の高さ」の違い
    • トップエンジニアの衝撃的な解決方法
    • 試行錯誤は「悪」である
    • 頭が良くても「理解」には時間がかかる
    • 「理解に時間をかける」を実践する
    • 複雑な技術をコントロールできている感覚を得る
    • 「感覚」で批判せずファクトを積み重ねる
    • 小さなドキュメントをコードの前に書く
    • 頭の中に「メンタルモデル」をつくる
    • まずエキスパートに頼る
    • 「偉大な習慣を身につけたプログラマ」になる
  • 第2章 アメリカで見つけたマインドセット - 日本にいるときにはきづかなかったこと
    • 「Be Lazy」というマインドセット
    • いかにやることを減らすか?
      1. 一つだけピックアップする
      2. 時間を固定して、できることを最大化する
      3. 「準備」「持ち帰り」をやめてその場で解決する
      4. 物理的にやることを減らす
    • リスクや間違いを快く受け入れる
    • 失敗を受け入れる具体的な実践法
      1. 「フィードバック」を歓迎するムードをつくる
      2. 「検討」をやめて「検証」する
      3. 「早く失敗」できるように考える
    • 不確実性を受け入れよう
    • バリューストリームマッピングで「見える化」する
    • 「思考回路」を形作る実践
      1. 「楽に達成できる」計画で仕事をする
      2. 「無理・断る」練習をする
      3. 他の文化の視点を学んでみる
    • 「結果を出す」から「バリューを出す」へ
  • 第3章 脳に余裕を生む情報整理・記憶術 - ガチで才能のある同僚たちの極意
    • コードリーディングのコツは極力コードを読まないこと
    • いかに脳みその負荷を減らすか
    • 仕事の難易度別で考える
    • 「アウトカム」至上主義が上達を阻害する
    • マルチタスクは生産性が最低なのでやらない
    • 1日4時間は自分だけの時間を確保する
    • なぜ同僚たちは「記憶力」がいいのだろう
    • 「書く」すすめ
    • 頭の中のみで整理する
    • 理解・記憶・反復という黄金則
  • 第4章 コミュニケーションの極意- 伝え方・聞き方・ディスカッション
    • 「情報量を減らす」大切さ
    • 準備は効く ---伝え方のコツ
    • 相手が求めている情報への感度を研ぎ澄ます
    • コードを「読み物」として扱う
    • ミスコミュニケーションのサイン
    • クイックコールのすすめ
    • クイックコールされる側もよいことがある
    • 気軽に聞ける空気の大切さ
    • ディスカッションで鍛えられること
    • 意見が対立しても「否定しない」
    • 「会話力」を育てよう
  • 第5章 生産性を高めるチームビルディング - 「サーバントリーダーシップ」「自己組織型チーム」へ
    • 「サーバントリーダーシップ」とは何か
    • 自己組織チーム/フィーチャーチーム
    • 開発者それぞれが責任を持って設計し実装する
    • 「仕事を楽しんでいるか?」を確認する文化
    • ボスの役割はサポートすること
    • 納期がなく、マネージャも急かさない
    • 自己組織チームをいかに導入するか
    • チームの上下関係をなくす
    • 失敗に寛容な職場がチャレンジ精神を生む
    • 「Be Lazy」を推奨し、休暇を尊重する
    • チームにパワーを持たせることの価値
  • 第6章 仕事と人生の質を高める生活習慣術 - 「タイムボックス」制から身体づくりまで
    • 同僚たちのワークライフバランス
    • 生産性を上げたければ定時上がりが効率が良い
    • 「タイムボックス」制で、学習の時間を確保する
    • 「脳の酷使をやめる」三つの工夫
    • 違うことをするのがリフレッシュに
    • 掃除で「人生をコントロールする感覚」を取り戻す
    • 整理の技術
    • 物理的なエネルギー不足をどう解消するか
    • テストステロンを意識的に増やす
  • 第7章 AI時代をどう生き残るか? - 変化に即応する力と脱「批判文化」のすすめ
    • AIと過去のテクノロジーの違い
    • どんな職業ならAIに食われないだろう?
    • ChatGPTがやってきたときアメリカで起こっていたこと
    • AI時代には「専門性」こそが強みとなる
    • 日米のエンジニアを取り巻く文化の違い
    • 「批判」の文化がすべてをぶち壊しにする
    • コントリビュートと感謝のループ
    • 日本再生への道すじ
    • 自分の人生は自分でコントロールする

読書メモ

自分が読んでいて学びになったことをつらつらと

  • 「基礎」練習は「誰でもできる」ことだが、習得には「時間がかかる」ものなので遠回りせず習得すべし
  • 手を動かす前にDesignDocを書いて整理してから作業に取り掛かり、それをナレッジとしてシェアする
  • 頭の中にメンタルモデルを意識的に構築する癖をつける
  • 会議では「準備」、「持ち帰り」をやめてその場で解決させる
  • 不確実性を受け入れられるような文化の醸成に努める
  • KPIは定時で無理なく楽に達成できる程度のものであるべき
  • コードリーディングの際は実装はちゃんと動いていると信じて極力見ずにインターフェイスと構造を理解するようにする
  • 仕事の難易度別で考え、Level1を増やしていく
    • Level1: 何もググらず即座に実装できるもの
    • Level2: 問題をどう解決するかはすぐに思いつくが、具体的な方法は忘れているのでググる必要があるもの
    • Level3: 解法を知らないが、スパイクソリューションをしたらできそうなもの
    • Level4: 自分では解決が難しい、もしくはものすごく時間がかかるもの
  • エンジニア、プログラマは積み重ねが大事なのでアウトカム勝負だけではない
  • マルチタスクは絶対やめる
  • 「作業内容を人にそらで説明できるかどうか」を記憶できたかのチェックポイントにする
  • 「エビングハウスの忘却曲線」を意識した振り返りで記憶を定着させる
  • チーム全体が強くなるためには、気軽に互いのち県を交換できるコミュニケーション文化が大切
  • サーバントリーダーシップ型のマネジメント手法においてリーダーはビジョンとKPIは示すが、実際にどのように達成するかはチームが考え意思決定する
  • メンバーが楽しんでいるかを重視する

まとめ

「世界一流エンジニアの思考法」を読んだ!

全体的にとても学びと共感が多かったが、「第3章 脳に余裕を生む情報整理・記憶術」では昨年読了した書籍「プログラマ脳」にも通ずる話も多く合わせて読むとより理解が深まりそうだと思った。

この書籍の売れゆきがとても好調で牛尾さんのメディアへの露出が激増していたのだが、その中でもけんすうさんとの対談が個人的に面白かった。

bunshun.jp

また248ページという量でサクッと読めるのでとてもおすすめです!

エンジニアリングにおけるさまざまな成熟度モデル

オペレーション成熟度

support.pagerduty.com

Service Reliability Hierarchy

sre.google

Service Reliability Hierarchy

SRE成熟度評価シート

MoneyforwardのSRE成熟度評価シート

moneyforward-dev.jp

Observerbillity成熟度

Observability Maturity with New Relic

docs.newrelic.com

おわりに

ここに全部書いてあった... zenn.dev

マイクロサービスの課題感を感じるためのリンク集

前提となる概要

aws.amazon.com

WEB

blog.vte.cx

qiita.com

codezine.jp

codezine.jp

www.infoq.com

www.infoq.com

www.infoq.com

type.jp

tech.timee.co.jp

www.techscore.com

zenn.dev

active.nikkeibp.co.jp

appmaster.io

スライド資料系

speakerdeck.com

speakerdeck.com

speakerdeck.com

speakerdeck.com

speakerdeck.com

www.docswell.com

www.slideshare.net

speakerdeck.com

speakerdeck.com

speakerdeck.com

動画

www.youtube.com