【勉強会】NoOps Meetup Tokyo #6
2019-06-04_NoOpsMeetupTokyo#6
GCPのObservebility - Stackdriverの紹介
Observabilityを支えるStackdriver(Google 山口さん)
SREとは
システム信頼性のために方針を持ってDevOpsを実践すること
信頼向上のためには、
- 意思決定は主観でなく、データに基づく
- 運用の課題をソフトウェアエンジニアリングで解決する
SLI/SLO/SLA
- Indicatorは単なる指標、Objectiveが許容できる限界値、Agreementは規約
- SLOを100%にするのは意味がない
- システムの入れ替えが不安定なことは回避できない
- 不安定をどの程度許容できるかを定義するべき
エラーバジェット
- 許容可能なエラー率
オブザーバビリティ(可観測性)
GCP向けのオブザーバビリティソリューション=Stackdriver
通常運用時の取得情報
- メトリクス
- 「統計的に」全体が問題なく動いているか、外形監視など
- アラート
- SLO違反が発生した場合の見地
- カスタムメトリクス
- アプリケーション固有で取得したい指標、ある処理の処理時間やファイルサイズなど、ユーザビリティに繋がりそうな指標
高負荷・調査のための情報
- プロファイラ、
- 分散トレース、MicroServiceで複数サービスをまたがったトレース
障害調査のための情報
- エラーレポート
- IRM:Incident Response and Management:インシデント管理
2000台オンプレのコンテナ化 - Necoプロジェクト
物理データセンターでも NoOps(サイボウズ 山本さん)
Necoプロジェクト
- 国内数カ所のDC、サーバ数十台のアーキのまま現在の数千台へ
- Kuberantesを採用
- 物理サーバに依存させない
- 自作からの脱却
- 拡張性に優れた設計になっている
典型的なToil - プログラムの更新作業
- 手順書を書き起こす
- 手順書をレビューする
- アドホックに自動化
- 開発環境でリハーサル
- 本番環境で、ペアで手動適用
こうありたい
- 撃ちっぱなし可能な宣言的オペレーション
- 継続的デリバリー
Necoの設計原則
- Be Declarative
- Kubernetes以外もすべて宣言的に操作可能にする
- Define by Software
- サーバ・NWは目的に依存しない、ソフトウェアで制御する
- Test Everything
- DCで動作するすべての機能を自動試験する
SREの実践例とプラクティス
NoOpsを実現するSREの存在意義と役割(Studist かつひささん)
NoOpsとは
DevOps focus Collaboration, NoOps focus Automation
SREとNoOpsの関係
"No Comfortable Ops"の思想は、SRE本でいう"Eliminating Toil"と似ている
Toilとは、何回やってもサービス成長に寄与しない繰り返し作業
Toilの撲滅の実践例
撲滅するためには、まず対象を計測する必要がある
Toilの計測
業務を分類した
- Software engineering/設計・製造 =OKR達成に関連するタスク(と定義)
- Systems engineering/システム構成変更 =Issueベースで取り組むタスク(と定義)
- Toil/反復的な手動作業
- Overhead/チームや組織のMTG
週単位で集計
- カンバンのレーンを分けてタスク管理
- 作業にはすべてポイント付与
- ToilとOverheadはバックログにはなく、発生都度ポイント付与しカンバンに追加
- ベロシティよりも作業時間割合の計測をより重視、チームの時間の使い方を重視する
計測ができれば、目標値が設定できる →今年は5〜10%が目標
どうやってToilをここまで減らしたのか
Toil Management Strategies(SRE WorkBook)を参考にする
SRE wookbookから3つ抜粋
Engineer Toil Out of the System
Toilを減らす前にシステムを変えられないか、Toilを増やさないことを考える
- Toilを増やさないために、Design Documentを書く
- 初めの設計の段階で、(ゼロにはできないが)できるだけ減らす
- 不可逆性の高い部分
- 性能面で詰まる可能性の高い部分
- なぜその設計だとダメなのか
- DesignDocumentは必ず書く、障害を収束させた人より障害を産まなかった人を評価
Use SLOs to Reduce Toil
(SLAは規約だが、)SLOではダウンタイムを許容する
- 許容できない、ではなく、許容できるとしたらどれくらいかを真剣に考える
- 必要以上に性能目標を高くしすぎないことで、Toilの膨張を防ぐ
Provide Self-Service Methods
開発者から依頼を受けて仕事をするのではなく、開発者自身がやってくれるようにする
- チケット駆動の依頼方式は、組織の経済的な無駄を生む
- 依頼仕事は減らして、セルフサービスにしよう
- 開発者がOpsを実行できるように、適切な権限を与える
- Define/Execute/Govern(定義/実行/ガバナンス)
- AWS Organizationを活用して、権限制御することでガバナンスを聞かせる
- デプロイの責務を開発者に移管する
- GitHubへのPullからリハ環境(PRD同等環境)までは自動でデプロイ実行
- 承認ボタン押下でPRD環境へデプロイ実行
- 開発者の改善を促進するための情報を可視化する
- レイテンシの計測
- 非同期処理のジョブキューの滞留状況を計測
- NewRelicのApdex(ユーザの使用性の満足度的な)
- エラーレート
- ログの分析はElasticsearch/kibana
Recap
- NoOpsの実践に、SRE本は最高の教材
- DevOps 3つの道に忠実に
- フロー改善、フィードバック、継続的な学習と経験
【技術メモ】MacにDockerでknowledgeを立てて繋ぐ
【技術メモ】MacにDockerでknowledgeを立てて繋ぐ
概要
Qiitaっぽいナレッジツールknowledgeをローカルに立てる+バックアップを復元させる
詳細
既にdocker-composeを用意していただいているので、cloneしてくる
設定変更
### ポートを変更 $ vi docker-compose.yml ### knowledgeのポートを変更 "8080:8080" -> "28080:8080" ### postgresにアクセスできるようにポートを追加 port: - "25432:5432"
起動
### 起動 $ docker-compose up -d ### 停止 $ docker-compose down
データ復元
### 事前に繋がるか試してからの方がいい $ psql -U postgres -h localhost -p 25432 knowledge_production < バックアップファイル
http://localhost:28080/knowledgeに繋いで、ログイン、管理者メニューからインデックスの再作成をする
参考リンク
【技術メモ】Micrometerで取得してCloudWatchに送る
Micrometerで取得してCloudWatchに送る
概要
SpringBootで、Micrometerで取得したメトリクスをCloudWatchに送るメモ。なにしろ、Prometheus連携の記事は大量にあるがCloudWatchはほぼない(需要がないのか?)
公式を見ると、なんとCloudWatchだけドキュメントがない。。。
英語はよくわからないが、作ってくださろうとしているそうなので、公開されたらそちらを参照で。
詳細
前提として、
- Actuatorが入ったSpringBootアプリがあること(過去記事参照)
- AWSアカウントはとっていること(CloudWatchが見れること)
- 検証環境は、Mac Sierra 13.10.6 + Eclipse Oxygen
- SpringBoot 2.1.2
流れ
- CloudWatchにメトリクスを送る用のロールをつくる
- SpringBootにCloudWatch連携ライブラリを追加する
- CloudWatch連携を実装
- CloudWatch連携実行
- ダッシュボードを作る
メトリクスを送る用のロール作成
AWSコンソールのIAMからロールの作成。
- ユーザ名:cloudWatchSubscriber(任意でOK)
- アクセスの種類:プログラムによるアクセス(コンソールは不要)
- アクセス許可の設定:ユーザーをグループに追加
- グループ :cloudWatchAccessGroup(任意でOK)
- アタッチされたポリシー:CloudWatchFullAccess(もっと絞った方がいいかも)
- タグの追加 (オプション):いったんなし
成功したら、アクセスキー ID、シークレットアクセスキーがあとで必要になるので、.csv のダウンロードをしておく。
CloudWatch連携ライブラリの追加
pom.xmlに以下を追加。(Actuatorはすでに入ってる前提。)
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-cloudwatch</artifactId> <version>1.1.2</version> </dependency>
CloudWatch連携を実装
定期実行をどうしようかと思ったけど、とりあえずSpringBootのメインクラスで起動時に呼ぶのがいいか。 (@Scheduledで定期実行させたら、非同期のスレッドが大量にあがってしまった)
private static void monitoringByMicrometer() throws Exception { CloudWatchMeterRegistry registry = new CloudWatchMeterRegistry(config, clock, cloudWatch); // io.micrometer.core.instrument.binder.* に定義されているBinderをBindする new ClassLoaderMetrics().bindTo(registry); new JvmGcMetrics().bindTo(registry); new JvmMemoryMetrics().bindTo(registry); new JvmThreadMetrics().bindTo(registry); IntStream.range(1, 20).forEach(n -> new Thread(sleep).run()); Thread.sleep(60000); }
CloudWatch連携実行
SpringBootアプリ実行時に環境変数を設定
プロジェクト名右クリック > [Run As] > [Run Configurations...] > [Environment]
ダッシュボード作成
AWSコンソールからCloudWatchを選択、右メニューのメトリクスを見ると値が届いている(はず)
メトリクスでアドホックにグラフを作ってみてもいいし
右メニューのダッシュボードからグラフを並べることもできる
ホストが違うのをどうやって出し分けるんだろう・・・
参考リンク
【技術メモ】MacにDockerでMySQLを立てて繋ぐ
MacにDockerでMySQLを立てて繋ぐ
概要
とりあえずDB接続系の検証用に、サクッとローカルMacにMySQLを立てたい時。
ポイント - バージョンを5.7にする(8以上だとパスワード認証方式が変わっていて繋ぐのが面倒) - 接続時はlocalhostでなくループバックIPを使う
詳細
### DockerHubのイメージでコンテナ立てる $ docker run -d --name mysql-container -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql:5.7 ### 繋ぐ $ mysql -h127.0.0.1 -uroot -p
### とりあえずデータベースとテーブルを作ってデータを入れる時のメモ。 create database database1; use database1; create table table1 ( id int auto_increment not null primary key, name varchar(20) ); insert into table1 values ( default, 'tom' ); insert into table1 values ( default, 'joji' ); insert into table1 values ( default, 'andy' ); insert into table1 values ( default, 'bob' ); insert into table1 values ( default, 'sam' );
以上。
参考リンク
【技術メモ】MacにDockerでPostgresを立てて繋ぐ
MacにDockerでPostgresを立てて繋ぐ
概要
とりあえずDB接続系の検証用に、サクッとローカルMacにPostgresを立てたい時。
詳細
### DockerHubのイメージでコンテナ立てる $ docker run -d --name postgres-container -e POSTGRES_PASSWORD=password -p 5432:5432 postgres ### 繋ぐ $ psql -h localhost -p 5432 -U postgres
### 何かSELECTしたいのでDBを作るメモ create table table1 ( id serial not null, name varchar(20), primary key (id) ); insert into table1 values ( default, 'tom' ); insert into table1 values ( default, 'joji' ); insert into table1 values ( default, 'andy' ); insert into table1 values ( default, 'bob' ); insert into table1 values ( default, 'sam' );
以上。
参考リンク
【技術メモ】SpringBootからPostgresに繋ぐ
SpringBootからPostgresに繋ぐ
概要
詳細
postgres
postgres=> create database testdb; postgres=>\c testdb; postgres=> create schema testschema; postgres=> set search_path to testschema; postgres=> create table test_data ( id serial, data varchar(200), primary key (id) ); postgres=> insert into test_data values ( default, 'data1'); postgres=> insert into test_data values ( default, 'data2'); postgres=> insert into test_data values ( default, 'data3');
設定ファイル
pom.xml
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
application.properties
spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5432/testdb spring.datasource.username=postgres spring.datasource.password=password spring.jpa.properties.hibernate.default_schema=testschema
hibernate.properties
「PostgresにCLOBが見つかりません」の起動時エラーを防ぐ
hibernate.jdbc.lob.non_contextual_creation=true
Java
Entityクラス
@Entity @Table(name = "test_data") @Data public class TestData { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; @Column(name="data") private String data; }
Repositoryインタフェース
@Repository public interface TestDataRepository extends JpaRepository<TestData,Integer> { }
Serviceクラス
@Service @Transactional public class TestDataCrudService { @Autowired TestDataRepository repository; public List<String> getTestData() { List<String> ret = new ArrayList<>(); repository.findAll().forEach(data -> ret.add(data.getData())); return ret; } }
参考リンク
【Docker】基本のキ
概要
dockerコマンドのオプションがたくさんあるのはいいとして、まずは最初に使うものを覚える
詳細
### リポジトリからイメージ取得 docker pull imagename ### もしくは、Dockerfileからイメージの作成 $ docker build . -t imagename:version ### イメージからコンテナの起動。 $ docker run --name containername -v ./:/usr/local/app -p 80:8080 -e envname:envvalue -itd imagename:version /bin/bash ### コンテナの確認 $ docker ps ### コンテナにログイン $ docker attach containername ### ログアウト(Ctrlを押しながら、q押してp押す) Ctrl + q -> Ctrl + p ### コンテナ停止 $ docker stop containername ### コンテナ破棄 $
参考リンク
- link Dockerの基本操作メモ
- link docker コマンド チートシート