【SRE】SRE業務1ヶ月で考えたことをまとめてみた


# SRE業務についたよ
転職して、SREエンジニアとして働いています。
転職後、全く何をやっていいのかわからず、先輩に色々聞きながら進めていく中で、概要だけ記載するところが欲しかったので、記載していきます。
またこの記事は随時アップデートしていく予定です。

## システムを構築する上で常に意識すること
システムを考える上で、重要なことは以下3点だと考えています。

### スケーラビリティ
負荷が増大したとしても、パフォーマンスを保つことができる機能のことを言います。
大量のトラフィックが来たときに、サーバーは過負荷状態になります。
この際に、サーバー自体が自動でサーバーを増やしてくれれば、トラフィックによるシステムの障害を防ぐことができます。

この設定を容易にしてくれるのが、**Kubernetes**です。
例えばKubernetesがスケールする方法には、スケールアウト(水平スケール)、スケールアップ(垂直スケール)の2種類あります。
対象としては、Pod、Nodeのスケール2つがあります。下記の記事が参考になります。
[KubernetesのPodとNodeのAuto Scalingについて](https://qiita.com/sheepland/items/37ea0b77df9a4b4c9d80)
[[超簡単！]kubernetesでオートスケール](https://daichan.club/container/78690)

### 冗長性
これはシステムの信頼性を担保するための性質です。
ここでは、主にデータベースの話になります。

#### データベースの配置
例えば、AWS Auroraの場合、Read Repliaを**いくつ、どのように設置するか**というのははじめに考えることだと思います。よくあるのは、Read Replicaを異なるリージョンごとに設定(MZで設定)することだと思います。
**TODO: またS3とかにもこの冗長性は適応できるので、そこも考える必要がある**

#### バックアップ
毎日バックアップされてれば基本的に問題ないと思っています。
例えば、AWS Auroraだと、自動的にバックアップを行ってくれます。
AWS Auroraは毎日スナップショットが保存され、そこから復元を行うことができます。


#### その他冗長性を考えるときに重要となった質問
- サーバー1台死ぬ可能性はあるか
- マルチリージョンにしてて、一つのリージョンが死ぬ可能性はあるか
　以前のAWSの障害の場合どうするか？⇛年間0.1%が発生可能性
- Masterが詰まって機能しなくなるケースはどうする
- データが失われて、バックアップを使用しなくてはいけない可能性はどのくらいあるか
- どのくらい過去にさかのぼってデータ復旧をしなければいけないか


### メンテナンス性
ここには2つ意味が含まれています。

#### 単純性
**1. 新しい開発メンバーに対して優しい情報の残し方**
ドキュメントなどを定期的に残しており、キャッチアップするのに図やドキュメントをみるだけで実施することができるのがベストだと思ってます。

**2. 学習コストの低下**
新しいエンジニアが見てもわかりやすく、学習コストが低いインフラ構成を指します。

#### 運用性
他のメンバーが運用しやすいようにしましょう！！


## コンテナ基盤構築
Kubernetesベースで書きたいと思います。

### Kubernetes 参考記事
コンテナ基盤構築に関しては、**Kubernetes**をいかに理解するかが重要になると思っています。ここではKubernetesで重要となる記事を紹介させていただきます。
**TODO: 参考記事アップデートする**
[Kubernetes: スケジューラの動作](https://qiita.com/tkusumi/items/58fdadbe4053812cb44e)

### クラスタの構成
主に2種類あると考えています。

#### ゾーンクラスタ
##### ゾーンクラスタ
デフォルトの設定で作成すると、一つのリージョン、ゾーン内にクラスタが作成されます。

##### マルチゾーン クラスタ
1 つのリージョンに単一のクラスタマスターを作成し、複数のゾーンにノードを作成する方法です。
ゾーンをそれぞれ分けるだけなので、簡単に構築することができます。

#### リージョナル クラスタ
3 つのゾーンに 3 つのクラスタマスターを作成する方法です。
デフォルトで3 つのゾーンにノードを作成します。
小さいサービスだと、少しノードの数が多すぎるかもしれません。

[GKE multi-cluster Ingress](https://www.slideshare.net/kiyo0123/gke-multicluster-ingress)
[本番環境での Google Kubernetes Engine の準備](https://cloud.google.com/solutions/prep-kubernetes-engine-for-prod?hl=ja)
[リージョン クラスタ](https://cloud.google.com/kubernetes-engine/docs/concepts/regional-clusters?hl=ja)
[GKEのRegional Clusters(Beta)を試してみた](https://nokok.hatenablog.com/entry/2017/12/20/000043)

### Nodeをいくつに設定するべきか
はじめにぶつかるところだと思います。
etcdのRaftアルゴリズムの性質上、3, 5, 7の奇数のnode数が推奨されています。
詳しくは、下記を確認してみてください。

#### なぜnodeが3個以上必要か
下記が参考になりました。
https://qiita.com/ntoreg/items/ec6f1eca87ba5c5c0399
https://www.techscore.com/blog/2019/03/28/raft-consensus-algorithm/

### ReplicaSet数をいくつに設定すべきか
Podの数を随時いくつに保つべきか決定するとことです。
下記の式で数を算出するこができますが、これは実際にサービスを運用もしくは負荷試験をしてから決定する方法です。

`必要なレプリカ数 = ceil(sum(Podの現在のCPU使用率) / targetAvrageUtilazation)`

参考本：
[Kubernetes完全ガイド](https://amzn.to/2PFR84b)

## CI/CDパイプライン構築

### 観点
- 自動化
   - 人の手を介入させない
- 高速化
   - デプロイは速いほうがよい。ビルドとか時間かかるのは嫌
- 属人性の排除
   - 誰でもデプロイできる

最初のデプロイ自動化に関しては、高度なデプロイ方法(グリーンデプロイなど)は考えませんでした。
理由は、あとで差し替えることが可能で、高度なデプロイ方法には学習コストがかかると考えたからです。
ただ後々取り入れることを前提にしておけばよいと思います。

### Kubernetesでのデプロイ方法
今回は、Kubernetesを使ったデプロイ方法に焦点を絞っていきたいと思います。

#### CirrcleCIでのデプロイ
使用している企業さんが一番多い気がします。
CI回して、そこからデプロイもしてしまえば良いですね。

#### Spinnaker
[Spinnaker](https://www.spinnaker.io/)

NetFlixが開発しており、高度なデプロイに適しているしています。
高度なデプロイとは、**マルチクラウドへのデプロイ**、**カナリアデプロイ**、**Blue-Greenデプロイ**のようなデプロイ方法を指します。
ただデメリットとして、学習コストがかかることはよく挙げられます。

[PLAID Engineer BlogHOMEPLAIDエンジニア募集中！PLOG SRE Netflix発のOSS"Spinnaker"でマルチクラウドにデプロイしている話 #builderscon](https://tech.plaid.co.jp/builderscon-2018/)
[近年のデプロイ手法について](https://clonos.jp/knowledge/detail14/)
[デプロイ / リリース 手法 まとめ](https://garafu.blogspot.com/2018/11/release-strategy.html)

#### Skaffold
[Skaffold](https://skaffold.dev/)

**Pros**
・Googleが作っているので、信用できる
・イメージのタグを自動で付与する機能がある..らしい

**Cons**
・buildが遅いらしい....
・ローカルにkubernetesの設定が必要になる
・kubernetesの知識が必要になる

[Kubernetesの開発環境で困っているならskaffoldを使え](https://qiita.com/tomoyamachi/items/660bd7bb3afff8340307)
[Google、開発者のためのKubernetes用コマンドラインツール「Skaffold」オープンソースで公開](https://www.publickey1.jp/blog/18/googlekubernetesskaffoldkubernetesminikube.html)


#### GitOps
Githubのソースコードを正とし、Githubを中心にCI/CDを回していきましょうという考え方です。

**Pros**
・導入が容易そう
・なんか流行ってる

**Cons**
・Githubが落ちたらなんにもできなくなる

##### 何を用いるか
GitOpsを実現するツールは非常に増えつつあります。
ArgoCD, Fluxなどが有名です。

[Cloud Build を使用した GitOps スタイルの継続的デリバリー](https://cloud.google.com/kubernetes-engine/docs/tutorials/gitops-cloud-build?hl=ja)
[【ArgoCD/GKE】GitOpsを実現させる](https://qiita.com/sanoyo/items/d9125ab2586455c29a8d)
[Argo CDによってGKEでGitOpsをする](https://www.1915keke.com/entry/2018/12/15/034843)

### デプロイに関して考慮したこと
- masterにマージする前に、デプロイしたい場合があること
- PRをマージすることでデプロイすることが正解ではない
- Circle CIを使うのが正解ではない
- Githubが落ちた時にきちんとワークするか、デプロイできるか
- 手動をあえて残す方法を検討すべきか
- マージはしたいけど、deployしたくない場合どうするか
- ブランチ単位のdeployしたいときどうする


## 監視
### 監視で重要なこと
1. どのくらいの粒度でアラートを出すべきか
アラート疲れを起こさせないために、適切な粒度でアラートを管理する必要がある
Kubernetesの監視となるとよく上がるのがこの2つだった
2. どこを監視するのか
3. アラートを出してからどのような手順で原因までたどり着くか

### どこで何を監視するか
#### 何を
HTTPレスポンスコード、リクエスト時間(レイテンシ)が有効らしい(入門監視より)

#### どこで
ユーザーに一番近いところ。CloudFrontとかが該当する(入門監視より)

### データ収集
なんのデータを集めて、監視をするのかという話です。
主に2つあります。

#### メトリクス
メトリクスの取得頻度は60秒に一回が推奨されています(入門監視より)

#### ログ
例えば、GCPだとStack Driverにログがはかれており、AWSだとS3かCloudWatchです。

### slack通知
重要なエラーが起きた時はslackで通知されるようにします。
まずは検知することが大事。
そして追加で重要なことが、**アラートの粒度**になります。
アラートが多すぎると、段々見なくなってくるし、かといってアラートが少なすぎて重要なことを通知してくれないのも困ります。つまり**メンバーがいつまでも関心を保ってくれるチャンネル設計をしましょう**ということになります。
ココらへんは現在試行錯誤中です。

### ダウンタイム
システムがダウンしてもよい時間を探ります。
ただ最初のサービスだと、最初の小さいチームだと、ダウンの気づかなくて、決めた時間をすぎる可能性のほうが高いのではないでしょうか。そのため、最初は**ダウンタイム**の時間を設定するよりも**「どのようにアラートを出すか」を設計する**ほうが重要だと考えました。

許容できるダウンタイムを決める記事は下記が参考になります。
[ちょっと待って！Auroraを使う時にMulti-AZが本当に必要ですか？](https://dev.classmethod.jp/cloud/aws/decision-method-for-aurora-multiaz/)

この記事では、最初に「(サービスなどが停止・中断している時間)が10分を許容できるか？」という質問をしていき、冗長性をどう設計するか決めていきます。
※今回は、「アラートの設計」が重視されると思ったので、監視の項目に記載しています。

ただ、実際ダウンタイムの時間が10分というのはかなり短く、
この問いかけは、**深夜体制のチーム体制ができている、もしくはそのチーム体制を築くことができる会社**だと思っています。

### 監視ツール
Kubernetesの監視ツールについて見ていきます。

#### Push型とPull型
Push型、Pull型の監視システムについて⇛時代の流れは、Pull 型から Push 型？

#### Datadog
Datadogについてよくまとまってる
[モニタリングシステムの Push 型 Pull 型アプローチと Prometheus についての考察](https://www.datadoghq.com/ja/blog/monitoring-kubernetes-datadog/)

**Pros**
・Cloud WatchとGKEの統合が容易
　AWS CloudWatchの情報や、NewRelicなどの他のMonitoring Toolの情報などを簡単な設定でDatadogに取り込む事ができる。この機能を用いることでDashboardの情報をDatadogに一元化することが可能になる。
・設定(インストールなど)が容易⇛GUIで可能
・時代の流れに関してPush型なので、こっち使いたい...
・UIが綺麗.....

**Cons**
・お金かかる⇛ミニマム月1万円くらい
・監視対象が増えた時に監視サーバに負荷が集中しがち
　⇛現状サーバーの台数が多いというわけではないので、Consとしては弱い
・今後APM(Application Performance Monitoring)の監視をしていくとなると料金が倍になる

#### Prometheus
**Pros**
・無料

**Cons**
・設定(インストールなど)がDatadogよりも面倒
・Cloud WatchとGKEの統合の方法が現状わからない
・AutoScaling 等で監視対象の数が変わった場合、監視対象リストをアップデートする必要がある
。これ面倒

[モニタリングシステムの Push 型 Pull 型アプローチと Prometheus についての考察](http://yasuharu519.hatenablog.com/entry/2017/12/16/215855)
[クラウド時代の監視ツールDatadogをあらためて紹介します](https://techblog.zozo.com/entry/monitoring-kubernetes-using-datadog)
[【運用監視ツール比較】ZABBIXからPrometheusへの移行を開始しました](https://tech.willgate.co.jp/entry/2019/03/26/120553)


## 可搬性の高いコンテナの設計
開発環境で `docker-compose`コマンド1発で環境構築ができ、migration、seedの管理もできており、ステージング環境やプロダクション環境のimageがほしければすぐに持ってくることができる状態がベストだと思っています。
難しい言葉でいうと、**「immutableかつdisposable」　⇛　不変でかつ使い捨てできる**

[Immutable Infrastructureはアプリケーションのアーキテクチャを変えていく](https://www.publickey1.jp/blog/14/immutable_infrastructure_1.html)

## インフラのコード化
### なぜIaCとCaCを区別したほうがよいか
運用する面でこの考え方のほうが便利で、
同じにしてし考えてしまうと、インフラ構築用のコードをからコードを実行することになるため。

### なぜIaS(インフラのコード化)なのか
そもそもの考え方として以下2つがある。
・クラウドのインフラをどのように作ったかをコードベースで残すため
・同じ環境terraformのコマンドを実行すればすぐに作成できる状況を作るため

### IaC(Infrastructure As Code)
サーバーの構築

#### 主に使用されるツール
- Terraform
- Cloud Formation

### CaC(Configuration As Code)
各種のツールやライブラリをインストールする
①terraformでフォルダを分けて管理
　terraformで管理すると、間違って構築のフォルダを実行してしまう可能性がある？
②別のツールで実行
　Puppet、Chef、Salt、Ansible
　⇛学習コストを考慮するとAnsible

[Infrastructure as Code 再考](https://mizzy.org/blog/2016/04/22/1/)
[私は Infrastructure as Code をわかっていなかった](http://simplearchitect.hatenablog.com/entry/2016/02/18/165917)
[Puppet、Chef、Salt、Ansible を使用した Compute Engine の管理 - 付録](https://cloud.google.com/solutions/google-compute-engine-management-puppet-chef-salt-ansible-appendix?hl=ja)


### 権限設定
当たり前ですが、権限設定をしないと、**人為的ミス**が起きやすくなってしまいます。
この事故が一番恐ろしく、そして確率的に一番起きやすです。
これをそもそも発生しにくくするために、適切な人に適切な権限を付与しましょう、というのが第一歩だと思います。

随時更新していきます！！！