Emissary-Ingressで疑似的にIPを条件にルーティングを行う
こちらの記事はcloud.config tech blogにもマルチポストします。
はじめに
Emissary-IngressはKubernetesで動作するオープンソースのAPI Gatewayの仕組みの実装です。
CNCFのプロジェクトとしても登録されていて、2021年には成熟度としてIncubatingの認定を受けたみたいですね。
これを用いると様々な条件でリクエストのルーティングが行えるのですが、API Gatewayで行いたいこととしてIP制限があると思います。
特に、特定のパスにのみIP制限を設けたい、でもそれを行えるレイヤーがAPI Gatewayの前にも後にもない・・・なんてことありませんか?
なければいいのですが。可能であればWAFなどのAPI Gatewayより手前のレイヤーで行うに越したことはありません。
ただ、不幸にもそのようなパターンにぶち当たった場合には条件さえ合えばこのような手段が取れるよという解決パターンを紹介します。
概要
Emissary-Ingressには様々な条件でリクエストのルーティングができるのですが、リクエスト元IPを条件にしてルーティングを行うことは直接行うことはできません。
しかし、インターネットからのアクセスに対してKubernetesより手前にロードバランサーなどのレイヤーが挟まっていて、そこでアクセス元IPをリクエストヘッダーに追記してくれている場合、Emissary-Ingressでヘッダーを条件にルーティングすることで疑似的にIP制限を行うことができます。
Emissary-Ingressはヘッダーを条件にルーティングを行う機能があるので、こちらを利用します。
https://www.getambassador.io/docs/emissary/latest/topics/using/headers/headers
前提
- Emissary-IngressがKubernetes上で動作している
- インターネットからKubernetesクラスターまでの通信経路上にヘッダーにアクセス元IPを付与するハードウェアがあること
実装方法
例として、X-Forwarded-Forヘッダーにリクエスト元IPが追加されている場合、以下のようなMappingリソースを作成することで同じパスへのリクエストに対するリクエストが特定IPからのものの場合はsvc-route-1サービスにルーティングされます。
precedenceパラメータは判断の優先順位を示しています。値が大きいほど先に判断され、最初に合致した条件でルーティングされます。
regex_headersパラメータではルーティングの条件にリクエストのヘッダーを指定します。
例えば、X-Forwarded-Forヘッダーにアクセス元のクライアントIP、通信経路上のロードバランサー等のIPが追加されていく場合X-Forwarded-Forの一番最初のIPはクライアントIPになります。
これを正規表現で最初のIPだけ条件とすることでリクエスト元のIPでルーティングできます。
実際に使用する場合は***の部分を適切なIPに書き換えてご利用ください。
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: sample-mapping-1
spec:
precedence: 100
hostname: "*"
service: svc-route-1
prefix: /sample/
regex_headers:
X-Forwarded-For: '^(***\.***\.***\.***|***\.***\.***\.***).*$'
---
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: sample-mapping-2
spec:
precedence: 50 # 特定IP以外の場合、アクセス禁止のページなどを表示する用
hostname: "*"
service: svc-sample-2
prefix: /sample/
おわりに
Emissary-Ingressは既存の機能としてはIPを条件にリクエストのルーティングを行うことができないのですが、周辺のハードウェアの条件によってはヘッダーを条件にルーティングする機能を用いて疑似的にIPを条件にルーティングできます。
お手元のアーキテクチャと相談して、可能そうであればご利用ください。
参考
KubernetesでCNIにFlannelを使うときに気を付けること

初めに結論
kubeadmでkubernetesクラスターを立ち上げてCNIプラグインにFlannelをインストールしようとすると以下のようなエラーが出ることがあります。
Error registering network: failed to acquire lease: subnet "10.244.0.0/16" specified in the flannel net config doesn't contain "<kubeadmの起動時に設定したpodCIDR>" PodCIDR of the "<自分のnode名>>" node
これは、Flannelが通信を行う際に使用するCIDRである10.244.0.0とクラスター内でPodが使用するCIDRが異なるために発生します。
そのため、Kubernetesを立ち上げる時に設定したPodのCIDRが10.244.0.0/16でない場合は、Flannel導入時に使うマニフェストを変更する必要があります。
net-conf.json: |
{
"Network": "10.244.0.0/16", #←この行を変更します
"Backend": {
"Type": "vxlan"
}
}
もう少し詳しい解説
Flannelをインストールするとき、おそらくFlannelの公式サイトにある以下のコマンドでインストールしているかと思います。
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
つまるところFlannelのパブリックのリポジトリ上のマニフェストファイルを適用して必要な機能をDaemonSetとしてそれぞれのNodeのPodで実行する形ですね。
ただ、この方法でインストールするとエラーを起こす場合があります。
そのエラーが以下のようなものです。
Error registering network: failed to acquire lease: subnet "10.244.0.0/16" specified in the flannel net config doesn't contain "<kubeadmの起動時に設定したpodCIDR>" PodCIDR of the "<自分のnode名>>" node
これは、Flannelが通信を行う際に使用するCIDRである10.244.0.0とクラスター内でPodが使用するCIDRが異なっていることが原因です。
通信時に使用するCIDRが食い違ってしまっているということのようです。
公式サイトにも以下のような説明があります。
If you use custom podCIDR (not 10.244.0.0/16) you first need to download the above manifest and modify the network to match your one.
podCIDRについて、カスタムのものを使用している場合は使用するマニフェストの中身を適宜書き換えてください、ということですね。
おそらく、このようなことが起きるときはKubernetesの立ち上げ時に以下のようなコマンドを実行したのではないでしょうか。
kubeadm init --pod-network-cidr=<希望のCIDR>
おそらく、マシン外部のネットワークのサブネットの制約やら何やらでこのような設定をしているかと思います。
Flannelを導入してやる際は、Flannelが使用するCIDRとKubernetesが使用するCIDRを一致させてやる必要があります。
Kubernetesクラスターを再起動させて上記のオプションを変更する手もありますが大変なので、Flannelのマニフェストを変更しましょう。
https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml からマニフェストをダウンロードして、以下の部分を --pod-network-cidrで設定したCIDRに書き換えます。
net-conf.json: |
{
"Network": "10.244.0.0/16", #←この行を変更します
"Backend": {
"Type": "vxlan"
}
}
このマニフェストを適用すれば、CIDRが異なるエラーは発生しなくなります。
おわりに
今回はKubernetesクラスターにFlannelを導入しようとした際に発生しうるエラーとその解消法について解説しました。
同じエラーで詰まっている方の助けになれば幸いです。
参考
コンテナランタイムcontainerdでKubernetesを立ち上げるには
こちらの記事はcloud.config tech blogにもマルチポストします。
はじめに
前回の記事では、kubeadmを用いてKubernetesクラスターを立ち上げる方法を確立できたのでそれを記事にしました。
今回はその中で大の一つであった、コンテナランタイムとしてcontainerdを使用してKubernetesを立ち上げる方法が確立できたので記事として残しておきます。
環境
今回使用している環境はAWSのEC2としています。
主な設定は以下の通りです。
- name: kubernetestest-dev-app-controlplane
image: Canonical, Ubuntu, 24.04 LTS, amd64 noble image build on 2024-04-23
instanceType: t3.small
パブリックIPの自動割り当て: 有効化
手順
- containerdをインストール
sudo apt-get update sudo apt-get install -y containerd sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml sudo systemctl restart containerd sudo systemctl enable containerd
- IPv4フォワーディングを有効化し、iptablesからブリッジされたトラフィックを見えるようにする
こちらでかいせつされているとおり、設定の変更を行います。
この設定を行わないとkubeadmの起動時にpreflightチェックでエラーを起こすので注意です。
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sudo sysctl --system
- kubeadmのインストール、軌道
# Kubernetesのインストール curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl # Kubernetesの起動 sudo kubeadm init --pod-network-cidr=10.0.0.0/16
動作確認
kubectl get nodes -o wideコマンドを実行すると、以下のようにコンテナランタイムの名前付きでノードの情報が表示されます。
コンテナランタイムがcontainerdになっています、やったね!(この環境ではCNIも仕込んだためNodeの状態がReadyになっています、コンテナランタイムを仕込んでKubernetesを立ち上げただけの状態だとNot Readyとなります)

おわりに
今回の記事では、コンテナランタイムとしてcontainerdを使用してKubernetesを立ち上げる方法を解説しました。
これと前回の記事と合わせて、最新のパッケージを用いてマシンにKubernetesを仕込む方法が確立できたかと思います。
マシンにkubeadmでKubernetesを仕込む方法が確立できていれば、Kubernetesの新しいバージョンが発表されてもEKSやAKSが対応するのを待つことなく新しいバージョンの機能に触れることができるので、個人的にできるようになりたかったことの一つです。
同じようなことがやりたい方がこの記事を読んでいるのかなと思います、そんな方の助けになれば幸いです。
参考
AWS EC2でkubeadmを用いたKubernetesクラスターを作ってみたのでメモ
こちらの記事はcloud.config tech blogにもマルチポストします。
はじめに
Kubernetesって動かすと楽しいじゃないですか。
でも、Kubernetesで遊ぼうと思ったら普段はローカルでRancher Desktopからシングルノードのクラスターをワンボタンで作ったりEKSやAKSでマネージドなクラスターを作ったりするのですが、それではちょっと物足りないこともあります。
例えば最新のバージョンのKubernetesを使ってみようとしたら、前述の方法だとどれもすぐには対応していなくて、最新バージョンに対応するのを待つ必要があります。
そのためいつでも最新のバージョンのKubernetesを試せるように、ついでにマルチノードの構成で立ち上げるようにするためにAWS EC2の中にkubeadmでKubernetesを立ち上げ、クラスターを構成する方法を確立しておこうと試みたので今のところ確立できている方法をメモしておきます。
そのうちもっといい方法が確立できるかもしれないのでその時はその時で別途記事にしようと思います。
今回の構成
今回作成した構成は以下のような形です。
Control Plane Nodeが1台、Worker Nodeの数は2台にしましたが実際はお好みで。
コンテナランタイム: runc
CNI: Cilium

作成したリソース
EC2
- name: kubernetestest-dev-app-controlplane
image: Canonical, Ubuntu, 24.04 LTS, amd64 noble image build on 2024-04-23
instanceType: t3.small
keyPair: 新規作成
VPC: kubernetestest-dev-pvc
サブネット: kubernetes-dev-subnet
NSG: kubernetestest-dev-nsg
パブリックIPの自動割り当て: 有効化
- name: kubernetestest-dev-app-worker
image: Canonical, Ubuntu, 24.04 LTS, amd64 noble image build on 2024-04-23
instanceType: t3.micro
keyPair: 新規作成
VPC: kubernetestest-dev-pvc
サブネット: kubernetes-dev-subnet
NSG: kubernetestest-dev-nsg
パブリックIPの自動割り当て: 有効化
インスタンスサイズは、Control Plane用のインスタンスではメモリとCPUがそれぞれ2GiBと2v必要なためt3.smallとしています。
Worker Node用では最低限で構わないのでt3.microにしています。
また、今回は学習用リソースとして作成しているため、インスタンスにローカルから直接sshするためにパブリックIPの自動割り当てを有効にいています。
VPC
- name: kubernetestest-dev-vpc
IPv4 CIDR: 10.0.0.0/16
Subnet
- name:
VPC: kubernetestest-dev-vpc
IPv4 Subnet CIDR: 10.0.0.0/16
Route Table
- name: kubernetes-dev-rtb
VPC: kubernetestest-dev-vpc
routes:
- to: 10.0.0.0/16
target: local
- to: 0.0.0.0/16
target: kubernetestest-dev-igw
IGW
- name: kubernetestest-dev-igw
VPC: kubernetestest-dev-vpc
NSG
- type: ssh
source: 0.0.0.0/0
- type: customTCP
source: 0.0.0.0/0
port: 6443
- type: customTCP
source: 10.0.0.0/16
port: 10250
NSGではこちらを参考に許可する通信を規定しています。
本当はControl PlaneとWorker Nodeで要件は異なりますが、今回はひとまとめにしています。
ssh用の22番、API Serverへのアクセス用の6443番、Kubernetes Nodeのkubelet間のやりとりのための10250番ポートを開放してあります。
特に10250番はクラスター内部の通信であるため、通信元は同じVPC内部に限定しています。
実行したコマンド
リソースが一通り作成できれば、EC2 Instance Connect等を用いてインスタンスにssh接続します。
Control Plane NodeとなるEC2インスタンスでは起動後に以下のコマンドを実行してコンテナランタイム、Kubernetes、CNIをインストールしています。
実行時は先にControl Plane Nodeのコマンドから実行してください。
# Dockerのインストール
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo apt-get update
sudo apt-get install -y docker.io
# Dockerの開始
sudo systemctl start docker
sudo systemctl enable docker
# Kubernetesのインストール
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
# Kubernetesの起動
sudo kubeadm init --pod-network-cidr=10.0.0.0/16
# kubeconfigのコピー
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# CNIのインストール
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
cilium install
Worker NodeとなるEC2インスタンスでは以下のコマンドを実行しています。KubernetesのインストールコマンドまではControl Plane Nodeと同様です。
クラスターに加入するコマンドは、Control Plane Nodeの立ち上げ時に最後のほうでkubeadm join ~~~といった形で表示されるのでそれをそのままWorker Nodeで打ち込んでください。
# Dockerのインストール sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl sudo apt-get update sudo apt-get install -y docker.io # Dockerの開始 sudo systemctl start docker sudo systemctl enable docker # Kubernetesのインストール curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl # Kubernetesクラスターに加入 sudo kubeadm join <Control PlaneノードのプライベートIP>:6443 --token <トークン> --discovery-token-ca-cert-hash sha256:<hash値>
動作確認
各ノードでコマンドを実行し、成功していれば以下のような出力が得られるかと思います。
Control Plane Nodeでkubectl get nodeを実行

どこのノードでもsudo docker infoコマンドを実行すると現在使用しているDockerのバージョンやコンテナランタイムが表示されるかと思います。

Todo
このクラスターではまだメトリクスサーバーがインストールされていません。
そのためkubectl topコマンドやHPAが使えません。
スケーリングの動きを確かめようと思ったらこのあたりの機能が使える必要があるので、また今度インストールも試してみます。
今回動作確認が取れたコンテナランタイムはruncで、しかもそのためにインストールしたパッケージは少し古めのdocker.ioでした。
推奨されるコンテナランタイムはcotainerdかcri-oなのですが、今回は動作確認が取れなかったので今度動作することを確認したいと思います。
また、今回はEC2やネットワーク系のリソース、Kubernetesのインストール等を手動で行っていますが、1コマンドでできたほうが楽なので今度Terraform化を試してみます。
おわりに
今回は勉強がてらEC2でKubernetesクラスターをkubeadmベースで作成してみました。
この方法が確立できていれば後でいろいろ検証するのに役立ちそうに思います。
ただ、今回はそれなりに苦労した割に妥協した点も多くあるので、これからもっと構成を洗練させていければと考えています。
自分と同様にKubernetesクラスターをkubeadmベースで作ってみたいという方の助けになれば幸いです。
Ambassador で Mapping の apply 時にエラーが起きる時は
こちらの記事はcloud.config tech blogにもマルチポストします。
シンプルな答え
apply 時に出力されるエラーが以下のようなパターンであれば内部の証明書の期限が切れているので、いくつかコマンドを実行して証明書を更新してください。
Error from server: error when creating "<リソース名orマニフェスト名>": conversion webhook for getambassador.io/v3alpha1, Kind=Mapping failed: Post "https://emissary-apiext.emissary-system.svc:443/webhooks/crd-convert?timeout=30s": tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time yyyy-mm-ddThh:mm:ssZ is after yyyy-mm-ddThh:mm:ssZ
証明書更新には以下のコマンドを順に実行します。
大抵の場合コマンドは決め打ちで大丈夫ですが、環境に応じて namespace 等変更してください。
# 既存の有効期限が切れた証明書を削除します kubectl delete secret emissary-ingress-webhook-ca -n emissary-system # emissary-apiextを再起動します。再起動のタイミングで証明書が自動生成されます。 kubectl rollout restart deploy/emissary-apiext -n emissary-system
原因
Ambassador(現Emissary)のCRDのリクエストを処理するWebhook APIがKubernetes内に作られるのですが、このエンドポイントはサーバー証明書を自動的に作成して使用します。
ただ、Ambassadorの古いバージョンでは証明書の更新を自動で更新を行わないた、め起動して1年が経つと証明書の有効期限が切れてしまい、上記のエラーが発生します。
この問題は過去全てのバージョンで発生しますが、現在修正PRがマージされているのでおそらく次のバージョン辺りで修正されるかと思われます。
https://github.com/emissary-ingress/emissary/pull/5494
解決策
有効期限が切れた証明書を削除してWebhook APIのDeploymentをrestartします。Podの起動時に証明書が自動生成されます。
# 既存の有効期限が切れた証明書を削除します kubectl delete secret emissary-ingress-webhook-ca -n emissary-system # emissary-apiextを再起動します。再起動のタイミングで証明書が自動生成されます。 kubectl rollout restart deploy/emissary-apiext -n emissary-system
おわりに
今回は最近遭遇したエラー対応時に得た知見を共有しました。
一致期間ごとにこのコマンドを実行するCronJobを実行する解決する方法もありますが、根本解決には次のバージョンのEmissaryが公開されたタイミングでアップグレードするべきかと考えています。
同様の問題に直面した方の助けになると幸いです。
参考
cert-manager について簡潔にまとめておきますね
この記事は cloud.config tech blog にもマルチポストします
はじめに
最近触った環境で cert-manager というソフトウェアを使用していて、その概要について把握するのにまあまあ時間がかかったため、あとで忘れたときの備忘録として、そして同様にソフトウェアについて把握したい方向けに簡潔にまとめておきます。
cert-manager とは
Kubernetes や OpenShift 上で動作する TLS 証明書の管理ソフトウェアです。
Kubernetes 上で Pod として常駐し、証明書が期限切れになる前に定期的に証明書の更新を自動的に行ってくれます。
作成した証明書は Kubernetes の Secret として自動生成されます。
Helm またはマニフェストで直接インストール可能です。
インストール方法
※前提条件として Helm のインストールが必要ですが未インストールであれば別途インストールしてください
マニフェストでインストールする
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.5/cert-manager.yaml
これで、cert-manager ネームスペースに cert-manager がインストールされます
Helm でインストールする
helm repo add jetstack https://charts.jetstack.io --force-update helm repo update helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.14.5 \ --set installCRDs=true
インストールされるカスタムリソース例
cert-manager をインストールすると、cert-manager で使用するいくつかのカスタムリソースが Kubernetes 上にインストールされます。
cert-manager を使用しているクラスターには以下のリソースが存在するため、探してみてください。
インストールされるものの中で代表的なものは以下です。
Issuer
証明書を取得する認証局の設定を行います。
取得する元の認証局によって設定値が異なります。
https://cert-manager.io/docs/concepts/issuer/
パターンによる実装例はこちらから
https://cert-manager.io/docs/configuration/issuers/
ClusterIssuer
Issuer を全ての Namespace で使いまわす場合に使用します。
設定値は Issuer とほぼ同じです。Namespace の指定がないのが大きな差異です。
Certificate
作成する証明書の詳細設定を行うリソースです。
証明書の有効期限や期限の何時間前に更新処理を行うか、作成した証明書を保存する Secret リソースの名前、証明書の CommonName 等を設定します。
https://cert-manager.io/docs/usage/certificate/#creating-certificate-resources
何か問題が起きたときは
証明書発行に何か問題が起きた場合は、まず cert-manager の Pod のログを確認することをお勧めします。
デフォルトでは cert-manager ネームスペースに証明書更新を実行する Pod がいるはずなので、 kubectl logsコマンドで Pod のログを確認してください。
また、cert-manager は起動時の設定次第では Prometheus 用フォーマットでメトリクスを出力できるので、そのメトリクスを監視することで証明書の更新失敗を検知できそうです。
具体的にどんな値が取得できるかは未検証&ドキュメントが見つかりません・・・
https://cert-manager.io/docs/devops-tips/prometheus-metrics/
おわりに
以前作業を行った環境で、名前だけは聞いていた cert-manager について実際に操作する段階でいろいろと調べる羽目になったため、同様に調べるときに欲しそうな情報だけまとめておきました。
同様の場面に遭遇した誰かの役に立つと幸いです。
参考
まずは 106 ページまで読んでみよう まだ読んでいる途中だけど SRE 本についてまとめてみる
こちらの記事は cloud.config tech blog にもマルチポストします。
ハイライト
- SRE 本は分厚く見えますが「SREとは何か」については 106 ページまでにまとまっているのでまずは 106 ページまで読んでみるといいですよ!
はじめに
「SRE サイトリライアビリティエンジニアリング Google の信頼性を支えるエンジニアリングチーム」は、全 550 ページにもわたってサイトリライアビリティエンジニアリング(以下 SRE)というエンジニアリング手法とは何か、どのように行うのかについて書かれた本です。
通称 SRE 本とも呼ばれており、SRE というものについて知るための最初の一冊なのですが、何と言っても分厚いです。
自分でも気になって読み始めて、私物としても買って読み進めているのですが読み切るのにはかなり時間がかかりそうです。
ただ、全体で Ⅴ 部まであるうちの第 Ⅱ 部まで読み終わり、ここがキリがよさそうに見えたので今の段階で一度、この本がどのようなことが書いてあって、どのように読むのがよさそうかについて現状の自分なりにまとめられればと思います。
「なぜ全部読み切る前から書評を書くの?」というのはあるのですが、理由としては二つあります。
- 職場に最近この本がやってきて、周りのメンバーが興味を持っていそうなので。できれば一度読んでほしいので。鉄は熱いうちに打つ意味で
- おもに自分のため、現状での自分の認識を整理する意味で。この先読み進めて印象が変わればそれはそれで書籍を読んで成長したということです
ということで、この記事の第一目的は職場の同じ部屋にいる周りのメンバーが SRE 本を手にして読み始め、何かを得るところまで読み進めさせることになります。そうなるといいな。
他にも、これから SRE 本を読もうと考えている人にとって実際に読み始めるきっかけになったり、すでに読んでいる方にとってこの本が読みやすくなったりすると幸いです。
全容
この本は全体で 5 部構成になっています。その中に各章があります。
それぞれの部で書かれていることをざっくり紹介します。
第 Ⅰ 部 イントロダクション(1-24 ページ)
SRE とは何か、どのようなことをするのかについて、それが生まれた当時の Google の背景を交えながら説明しています。
ソフトウェアエンジニアの背景を持ったエンジニアで運用を行うことでソフトウェアエンジニアリングのアプローチで運用を考えること、それを通してサイトの信頼性を上げていくことが SRE であるというのが結論になるかと思います。
第 Ⅱ 部 原則(25-106 ページ)
SRE の仕事の原則について説明しています。
ここで言う原則とは、SRE ではどのような要素に関心を持つか、どのように仕事を進めるかに関する諸々のトピックになります。
そのため、この書籍を「サイトリライアビリティエンジニアがどのような仕事をするのかについて知りたい」というモチベーションで読むなら一番重点的に読むべきかと考えています。
自分が読んでいるのは現状ここまでです。
第 Ⅲ 部 実践(107-408 ページ)
この章は SRE で扱うトピックについて細かく、各論を述べています。
全体で 300 ページもありますが、一つ一つのトピックの粒度が細かいのでここではディテールを詰めていくために読むことになりそうです。
第 Ⅳ 部 管理(409-478 ページ)
この章では、実際に SRE チームを運用していくときの方法論について書かれています。
新人 SRE がやってきたときにどのように学習経験を積ませて一人前の SRE に成長させるかが主なトピックになります。
逆に、自分が新人 SRE であったときにどのように業務を学んでいくべきかについて書かれていると見ることもできます。
第 Ⅴ 部 まとめ(479-496 ページ)
本当にその通りで、まとめの一言(一言ではない)が書かれています。
まずは 106 ページまで読んでみよう
この書籍は全体で 550 ページもあります、一息では読み切れないのもごもっともです。
ただ、この書籍を読む最初の一番の目的は「SRE とは何か」であるかと思います。
その場合は、最初の 106 ページまで読むと大体ほしいものが見つかるかと思うので、まずはそこまで読んでみるのがおすすめです。
というのも、全容で書いた通り、第 Ⅱ 部では SRE の仕事の原則について説明しています。
ここを読めば、SRE の基本的な考え方やそのための概念を理解することができます。
SRE の話題でよく言われるトイルとは何か、SLI、SLO、SLA とは何か、エラーバジェットとは何か、エラーバジェットを使ってどのように仕事をするのかがわかります。
そしてそれらのためにどのように監視や自動化を進めていくのか、アプリのリリースはどのように行うかの具体的な方針が書かれています。
その前の第 Ⅰ 部では SRE とは何かの概要がつかめるので、第 Ⅰ 部と第 Ⅱ 部までで SRE についての概要と基本的な考え方が身に付けられてしまいます。
逆に、第 Ⅲ 部は 300 ページもあるものの中身としてはアラートや障害対応、ロードバランシングといった各論に入っていくのであとで時間を作って読むか、最低限気になったトピックだけ拾い読みする読み方でも良さそうです。
ということで、SRE 本を読むならまずは最初の 106 ページまでをそれなりに集中して読んで、それから他の部を読むのが SRE とは何かについて知る上では良さそうです。
次に読むなら?
第 Ⅳ 部が良さそうです。
というのも、第 Ⅳ 部では SRE の主に育成方法が解説されているのですが、逆に見ると自分が SRE らしいスキルを身に付けたいときにどのように動くべきか、学ぶべきかが書かれているともいえるためです。
第 Ⅰ 部、第 Ⅱ 部と読んできて SRE というエンジニアリング手法に興味が出てきたら次はそれを身に着けるための方法が知りたくなるかと思います。
- プロジェクトの目的を理解しながら作業を行う
- ポストモーテムを読む/書く
- 他のメンバーが行っている障害対応を横で見る(シャドウイングする)
など、目次を見ただけでもやるべきことが見つかりそうです。
自分も、次に読むならここかなと考えています。
「SRE とは?」今答えるなら
今の理解を試すため、あとでもっと SRE について知ったあとで読み返して恥ずかしくなるために今の SRE についての理解を書いておきます。
サイトリライアビリティエンジニアリングとは、文字通りサイトの信頼性を高めることを目的としたエンジニアリング手法です。
業務としては主にインフラの運用を行うのですが、ここにソフトウェアエンジニアリングのアプローチを組み込むことでより良い運用を目指します。
例えば、サイトの許容できるレベルの信頼性について SLO をプロダクトオーナーと合意し、それを満たすことを目標にインフラの運用を行います。
SRE チーム内では許容できる SLO と現状の余裕分をエラーバジェットとして管理し、SLO を下回らないように(国内では「SLO を割る」という言い方もあるようです)プロダクト開発チームと折り合いをつけながらサイトの信頼性とプロダクト開発のスピードを両立します。
運用における繰り返しの仕事、オーバーヘッドをトイルと呼び、これについてはできる限りうまく自動化したり仕組みを改善(エンジニアリング)することで減らそうとします。
まとめると、特に運用をエンジニアリングで改善するという考え方をすることがソフトウェアエンジニアリングのアプローチをとるということで、サイトリライアビリティエンジニアリングそれがなのかな・・・と今は考えています。
そうするとサイトリライアビリティエンジニアリングという文字通りの意味「サイトの信頼性」からは少し離れている気もするのですが、そこは「はじめに」で著者も認めているとおり、その内容をはっきりと表現出来ていないということなのかなと思います。
最初に名前を付けた時と実際に運用していく中で振る舞いやコアにあるものが変わってくることはよくあることなので、これもそういうものなのかな・・・・・という理解です。
おわりに
今回の記事では「SRE サイトリライアビリティエンジニアリング」という書籍について、途中まで読んだ状態で内容をまとめてどのように読むと読みやすいかを考えて説明してみました。
全体ではかなり分厚い書籍ですが、まずは特に最初の 106 ページを読もうと考えて読むとそれなりにハードルが下がるかと思うのでおすすめです。
周りのメンバーや他の人がこの書籍から何かを得る助けになっていると幸いです。
また、自分でも 3 章から先も引き続き読み進めるつもりです。
全体を読んでから何か考えが変わったりしたらまたブログを書くと思います~