Tocyukiのブログ

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

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

他社SREチームのミッションについて調べてみる

現職のSREチームのMVVを検討し始めてるので他社のMVVについて調べてみる

NewsPicks

note.com

NewsPicks SREチームのミッション

SmartShopping

tech.smartshopping.co.jp

  • ミッション
    • 日常を革新するプロダクトが走り続けるために、整備された道とガードレールを作り改善していく
  • ビジョン
    • 自律して信頼性の高いプロダクトを作り続けられるスマートな開発組織の実現
  • バリュー
    • Bold and Flexible
    • Automation
    • One for All
    • Data Driven
    • Proactive

dely

tech.dely.jp

delyが持つ熱量と幸せをできるだけ多くの人に届けられるように、プロダクトの価値最大化をシステム運用において実現する。 その過程において最善の選択が何であるかを考え、システムの設計と運用を改善し続ける。

『スタディサプリENGLISH』 SREグループ

blog.recruit.co.jp

  • ミッション
    • 自分たちの持つ専門性を活かし、開発者が開発に集中して最大限の力を発揮できる状態を目指す
  • ビジョン
    • 品質も効率もあきらめない!イケてる環境を作る

『スタディサプリ小中高』 SREグループ

blog.studysapuri.jp

  • Mission
    • 自己完結チームがプロダクトを素早く安全に届け続けるためのプラットフォームと文化を作る
  • Vision
    • 最高の学習プロダクトを作り続けられる開発組織の実現
  • Values
    • Fail smart
    • Learning
    • Borderless
    • Metrics-driven

STORES

product.st.inc

ユーザーにたくさんの価値を素早く提供できるようにしながら、事業の成長を阻害する要因を取り除く

レバレジーズ

tech.leverages.jp

SRE化を通して、Developer Experienceの改善、事業の拡大への対応、お客様に信頼されるサービスの提供を実現する

Sansan BillOne

speakerdeck.com

Mission/Vision

eureka

medium.com

  • Mission
    • SREプラクティスを開発組織にインストールしていく
  • Vision
    • 自律的にリライアビリティとアジリティを両立するプロダクト開発組織の実現
  • Values
    • Metrics First
      • 主観ではなく、計測した定量的な指標に基づいて意思決定する
    • Draw a Blueprint
      • 物事のAsIs — ToBeを自ら描いて自ら実現していく
    • No Blame
      • 非難をしない、問題を回避したり最小化したり隠蔽するのではなく問題を明らかにしていく
    • Learning Animal
      • 現状に甘んじず、ToBeを描くために貪欲にインプットし続けていく
    • Change Agent
      • 組織に忖度せず、必要なことについて議論を恐れず、やるべきことは自らが主導となって働きかける

mercari Microservice SREチーム

engineering.mercari.com

  • マイクロサービスチーム特有の事情に合わせた信頼性向上のサポートを行うEmbedded SREs
  • 組織全体にSREプラクティスを広めていく
  • Platformチームが開発するマイクロサービス基盤の新しい機能の導入を支援する

M3

www.m3tech.blog

  • エムスリーが提供するサービスのシステム基盤について、現在から将来に渡って高い信頼性やセキュリティを保った管理・運用を行うことで、顧客が安心して快適にサービスを利用できるようにする。
  • ビジネス要求や環境の変化に素早く柔軟に対応できるようなシステム基盤を実現し、スケール可能なチームづくりとその維持を行う。

カヤック

明確なミッションが書かれているわけではないが参考になるので貼っておく

techblog.kayac.com

色々な会社のCTO室設立の背景やミッションについて調べてみる

今所属している会社にもCTO室があるが、他の会社がどのような背景・目的・役割でCTO室を設けているのか気になったので調べてみる。 インターネットで雑に検索して出て来たものをいくつかピックアップし、設立の背景・目的、ミッションなどで共通項があるかなどを見てみる。

ZOZO

qiita.com

設立の背景・目的

VPoEが2018年度に担っていた動きをチームとして対応できるようにするためにCTO室が設立されました。

ミッション

ZOZO CTO室ミッション

MIXI

mixil.mixi.co.jp

設立の背景・目的

詳細は不明

CTO室は2019年5月にできました。前身はモンストの開発・運用をしていた事業本部内にて、複数のサービスに関わるエンジニアを集めてできた開発本部の下部組織でした。現在は事業部を横断した開発者支援や、事業部内のサービス、プロジェクトに入って個別支援を行っています。

ミッション

CTO室は主に以下の4つのミッションがあります。 1つ目の「サービス技術の設計、開発、保守の研究および開発」というミッションでは、最新の技術動向を追跡し、それを調査・検証しています。これにより、サービスの価値向上をリードする役割を果たしています。 次に、「ものづくり人材の育成」というミッションは、社内エンジニアの育成に重点を置いていますが、同時に渋谷区などの高等専修学校への教育サポート活動も行っています。 「QAの改善活動」は、サービス品質の向上だけでなく、各事業部に継続的な改善プロセスや手順を提供し、その実践を支援することをミッションとしています。 最後に、「データのKPI設計や分析の支援」では、データ活用に関する考え方やアプローチを企業全体に展開しています。KPI設計やデータ分析を通じて、サービスのパフォーマンスを評価し、事業部や経営層の意思決定をサポートしています。

KAONAVI

vivivi.kaonavi.jp

設立の背景・目的

事業会社ですから、個々の機能のリリースや突発的なパフォーマンスの改善などのほうが、どうしても優先されます。その都度いろいろなチームにヘルプとして呼ばれる、というような状況でした。正直、それだと横軸の改善作業は全然進まない状態だったんですね。ですから、いわゆる全社的な改善作業をするチームを切り分けようというのが、CTOの松下さんが、これまでのプロダクト本部とは別にCTO室という組織を立ち上げた意図だと思います。

ミッション

CTO室の役割は、課題を自分たちで見つけてきて、それを改善することです。課題はたくさんあるので、できることから手をつけていくしかありません。その際に意識しているのは、「カオナビ」の開発効率が上がって、より顧客に対する価値提供をスムーズに行えるようになることです。逆に言えば、そこさえブレなければ手法は何でもいい。

YOUTRUST

tech.youtrust.co.jp

設立の背景・目的

不明

ミッション

CTO室では、インフラやセキュリティなどのいわゆる共通基盤や事業部のミッション外ではあるが会社として必要な技術領域の取り組みを行なっています。

DMM

inside.dmm.com

設立の背景・目的

CTO就任とともに発足?

ミッション

簡単に言えば、CTOの想いを実現させる部署です。CTOが就任した後、弊社ではDMM Tech Visionを発表しています。私たちがやるべきことは、その実現です。そのために、現在は3つのチームに分かれて活動をしています。 まずは、制度設計やブランディングを担当するエバンジェリストチーム。技術のスペシャリストで結成されたチームで、人事と接点を持ちながらエンジニアのスキルアップを支援したり、技術広報をしたりと、対外的な活動も行います。 そのほかに、事業支援チームと技術支援チームがあります。事業支援チームは、読んで字のごとく事業部に対して技術的な側面から事業支援を行う組織です。コードを書くなど実務的なサポートもしますが、事業成長に貢献することをミッションに置いており、組織開発からシステム開発までなんでもこなします。 技術支援チームの役割は、社内エンジニア向けの共有ツールを開発したり、自社運用していたシステムのクラウド化を推進したり、全社単位での技術支援を行うことです。基本的にはこの3チームが力を合わせ、DMM.comのテックカンパニー化を推進しています。

レバテック

tech.leverages.jp

設立の背景・目的

レバテックにおけるシステム・データの課題を解決をリードしていくため

ミッション

レバテックCTO室のミッション

ベルフェイス

bs.bell-face.com

設立の背景・目的

ちなみに、CTO室設立の背景として、ベルフェイスの開発環境がお世辞にも整ったものではなかったということが挙げられます。上記の3点に取り組み、CTOや開発メンバーがやりたいと思ったことを実現するための環境づくりを行うことで、プロダクト作りを推進しています。

ミッション

端的に言うと以下の3つに取り組んでいる組織です。  1.システムの安定稼働  2.開発プロセスの健全化  3.無理無駄の撲滅  総じてリーンでアジャイルな開発体制を確立し、QCDFを向上させることに注力しています。

Hey

people.st.inc

設立の背景・目的

僕がCTOになって仕事を抱えすぎて辛そうにしているのを見て、社長の佐藤が、heyの中にいるCTO経験者を集めてチームにしてみてはどうかと提案してくれました。どの会社にも、会社を横断した課題を解決する箱があるものです。heyの場合はプロダクトごとに組織がわかれていますが、目指していることはひとつ。横断だからできることや、個別のチームだけでは解決できないことをCTO室の裁量で解決するためにこのチームができました。

ミッション

事業的に目指すところがある程度わかっていて、未来の目標も共有できているメンバーが集まって、さまざまなことを解決しています。例えば、組織マネジメントの課題として、今の組織の形をどうしたらもっと良くできるか、などです。他にも、採用基準、評価、査定、異動など。組織を運営している上で起こる、事務的でもあり、難しい判断が必要なことを解決しています。 また、技術的に横断でやったほうがいい仕事もここで話し合っています。モバイルアプリや、インフラなどのテクノロジーをどう考えるか、などです。

マネーフォワード

moneyforward-dev.jp

設立の背景・目的

DB分割のためのチームを作ったことがきっかけでCTO室という組織を作りました。

ミッション

全社的な、あるいは複数のサービスにまたがるような技術的負債の返済を主なミッションとした組織です。各サービスチームの意思決定はどうしても個別最適な意思決定になりがちなので、時には全体最適で意思決定して取り組む必要がある課題も出てきます。 私はCTO室を作って以来、全体最適の取り組みにアサインするべきリソースをCTO室で確保するようにしていて、タイミングによって増減はありますが、おおむね10-15%ぐらいのエンジニアにCTO室で働いてもらってます。 各サービスの開発チームにアサインされているエンジニアの人事権は私にはありませんが、CTO室のリソースは全社的な課題にアサインしたり、その時に最もフォローが必要なサービス開発チームを支援したり等の調整弁になっていて、リソース調整のスピードと柔軟性を高めることに役立っています。

各社のCTO室設立の背景・目的まとめ

  • VPoE, CTOの負担軽減
  • 全社横断な課題解決組織として発足

各社のCTO室ミッションまとめ

  • ZOZO
    • 全社における技術的な戦略策定および、エンジニア組織強化のための施策の推進
  • MIXI
    • サービス技術の設計、開発、保守の研究および開発
    • ものづくり人材の育成
    • QAの改善活動
    • データのKPI設計や分析の支援
  • KAONAVI
    • 開発効率が上がって、より顧客に対する価値提供をスムーズに行えるようになること
  • YOUTRUST
    • インフラやセキュリティなどのいわゆる共通基盤や事業部のミッション外ではあるが会社として必要な技術領域の取り組み
  • DMM
    • CTOの想いを実現させる、DMM.comのテックカンパニー化を推進
  • レバテック
    • 事業拡大に伴い、既存の複数サービスとこれから立ち上がるサービス含めて総合的にアーキテクチャや設計を考え、開発や事業をリードしていくための組織
  • ベルフェイス
    • システムの安定稼働
    • 開発プロセスの健全化
    • 無理無駄の撲滅
    • 総じてリーンでアジャイルな開発体制を確立し、QCDFを向上させることに注力
  • Hey
    • 事業的に目指すところがある程度わかっていて、未来の目標も共有できているメンバーが集まって、さまざまなことを解決
    • 採用基準、評価、査定、異動など組織を運営している上で起こる、事務的でもあり、難しい判断が必要なことを解決
    • 技術的に横断でやったほうがいい仕事もここで話し合っています。モバイルアプリや、インフラなどのテクノロジーをどう考えるか
  • マネーフォワード
    • 全社的な、あるいは複数のサービスにまたがるような技術的負債の返済を主なミッションとした組織

まとめ

各社のCTO室について設立の背景やミッションについて調べてみた。 当たり前に各社様々な目的や背景、ミッションを持っているが大枠では「全社横断で解決すべき課題を解決するための組織」という部分が共通しているのかなと思った。

これらの調べてた内容を元に自組織の運営に活かしていきたい。