Taste of Tech Topics

Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

社内技術イベントLTxRT紹介 ~うちのアジャイル、実際どうやってるの?~

こんにちは。QAエンジニアの@です。
何度かこのブログでも紹介しましたが、Acroではほぼ毎週木曜日に社内勉強会「LTxRT」を行っています。

今週のテーマは「アジャイル」。先日アジャイルの勉強会に参加してきた若手リーダーからのフィードバックと、社内でスクラム開発を行っている各プロジェクトからの事例の共有がありました。
f:id:acro-engineer:20180524190250j:plain:w300
内容は、

  • ふりかえり会どうやってる?
  • レビューどうやってる?
  • ユーザーストーリー描いてメンバに共有したけど、実際どうだった?

などなど。
参加者からも、「うちのプロジェクトではこうやってるよー」や「スクラムに忠実にやりすぎなくてもいいんじゃない?」など色々な意見が飛び出し、活発な会になりました。
このような場があると、自分のプロジェクトにも使えるかもしれない発見があって楽しいですね!

それでは~。

Acroquest Technologyでは、キャリア採用を行っています。


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
【エンジニア全般(どのリンクをはるか迷った時)】
モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

Angular4アプリをAngular6にバージョンアップする際の嵌りどころ

こんにちは、阪本です。

f:id:acro-engineer:20180509102654p:plain:w200

最近、画面系を触ることが多くて、Angularを使ったシステムを3つほど作ったのですが、
LTSであるAngular6がつい最近リリースされたので、
作った中でシンプルなAngular4アプリケーションをAngular6にバージョンアップさせてみました。

前提

バージョンアップ前のAngularのバージョンは4.4.6でした。
Angular Material 2.0.0-beta.12を使っています。

ちなみに対象のアプリケーションは2KL強(クライアントサイド)の申請管理システムで、申請→承認のフローを実行するものです。

バージョンアップ開始

いざ、出陣!(何

バージョン変更

まずは、ncuを使って、package.jsonに書かれた各パッケージのバージョンを上げます。

C:\App> ncu
Using C:\App\package.json
[..................] | :
 @angular/animations                         4.4.6  →   6.0.0
 @angular/cdk                        2.0.0-beta.12  →   6.0.0
 @angular/common                             4.4.6  →   6.0.0
 @angular/compiler                           4.4.6  →   6.0.0
 @angular/compiler-cli                       4.3.6  →   6.0.0
 @angular/core                               4.4.6  →   6.0.0
 @angular/forms                              4.4.6  →   6.0.0
 @angular/http                               4.4.6  →   6.0.0
 @angular/material                   2.0.0-beta.12  →   6.0.0
 @angular/platform-browser                   4.4.6  →   6.0.0
 @angular/platform-browser-dynamic           4.4.6  →   6.0.0
 @angular/platform-server                    4.4.6  →   6.0.0
 @angular/router                             4.4.6  →   6.0.0
 core-js                                     2.4.1  →   2.5.6
 rxjs                                        5.4.3  →   6.1.0
 ts-helpers                                  1.1.1  →   1.1.2
 typescript                                  2.0.3  →   2.8.3
 zone.js                                    0.8.17  →  0.8.26
 @angular/cli                                1.3.2  →   6.0.0
 @types/node                                6.0.42  →  10.0.4
 codelyzer                                   3.1.2  →   4.3.0
 jasmine-core                                2.4.1  →   3.1.0
 jasmine-spec-reporter                       2.5.0  →   4.2.1
 karma                                       1.2.0  →   2.0.2
 karma-chrome-launcher                       2.0.0  →   2.2.0
 karma-jasmine                               1.0.2  →   1.1.2
 karma-remap-istanbul                        0.2.1  →   0.6.0
 protractor                                  4.0.9  →   5.3.1
 ts-node                                     1.2.1  →   6.0.3
 tslint                                      5.6.0  →  5.10.0
 webdriver-manager                          10.2.5  →  12.0.6

The following dependency is satisfied by its declared version range, but the installed version is behind. You can install the latest version without modifying your package file by using npm update. If you want to update the dependency in your package file anyway, run ncu -a.

 moment   2.19.2  →   2.22.1

Run ncu with -u to upgrade package.json


C:\App>

何やらたくさんバージョンアップされます。恐ろしや。。
思い切って、 ncu -u でバージョンを反映させます。

C:\App> ncu -u
Using C:\App\package.json
[..................] - :
 @angular/animations                         4.4.6  →   6.0.0
(中略)
 moment   2.19.2  →   2.22.1
Upgraded C:\App>

package.jsonが書き換わりました。
なお、TypeScriptは2.8.3にバージョンアップしていますが、
Angular6ではTypeScriptは2.7.xまでしか対応していないため、2.7.2に手で変更する必要があります

package.jsonのTypeScriptのバージョンを変更したら、新しいバージョンのパッケージをインストールします。

C:\App> npm update
npm WARN deprecated nodemailer@2.7.2: All versions below 4.0.1 of Nodemailer are deprecated. See https://nodemailer.com/status/
(中略)
================================================================================
The Angular CLI configuration format has been changed, and your existing configuration can
be updated automatically by running the following command:

  ng update @angular/cli
================================================================================
(中略)
C:\App>

途中、メッセージが出てくる通り、
Angular6では、設定ファイルの記述の仕方が変わっているため、
ng update @angular/cli で設定ファイルの更新が必要です。

C:\App> ng update @angular/cli
            Updating karma configuration
            Updating configuration
            Removing old config file (angular-cli.json)
            Writing config file (angular.json)
            Some configuration options have been changed, please make sure to update any npm scripts which you may have modified.
DELETE angular-cli.json
CREATE angular.json (3523 bytes)
UPDATE karma.conf.js (1074 bytes)
UPDATE src/tsconfig.spec.json (324 bytes)
UPDATE package.json (1466 bytes)
UPDATE tslint.json (2971 bytes)
(中略)
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\karma\node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

angular-cli.jsonが削除され、代わりにangular.jsonになりました。
package.jsonには@angular-devkit/build-angularが追加されています。
追加されたパッケージは自動でインストールされます。

とりあえず、パッケージ自体のバージョンアップは完了です。

RxJSの破壊的変更対応

今回のバージョンアップの一番面倒なところが、これです。(Angular本体とちゃうんかい!)
Angularのバージョンアップに伴い、RxJSも5.4から6にバージョンアップ。
importを軒並み書き換え&コードも書き換えが必要です😖

ちなみに、rxjs-compatパッケージをインストールすれば、書き換えずに動作するらしいですが、
ここでは頑張って最新の書き方にしていきます💪

Observable

Angularとは切っても切れないObservable。
Angular4で使われていたRxJS 5.4では

import { Observable } from 'rxjs/Observable';

だったのが、RxJS 6では

import { Observable } from 'rxjs';

に。
rxjsから直接importするように変更されています。

Observable以外にも、BehaviorSubject等がrxjsからのimportに変わっています。

of / merge / throw

Observable.of のように、Observableのstaticメソッドで呼び出していたのが、RxJS 6では独立しました。

■RxJS 5.4

import 'rxjs/add/observable/of';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/throw';

Observable.of(o);
Observable.merge(o1, o2);
Observable.throw(e);

■RxJS 6

import { of, merge, throwError } from 'rxjs';

of(o);
merge(o1, o2);
throwError(e);

例外発生は、throwErrorに名称変更されています。

map / catch

RxJS 5.4では observable.map().catch().subscribe() のような書き方をしていたのが、
RxJS 6では observable.pipe(map(), catch()).subscribe() のように、 pipe で挟むようになりました。
convertprocess はオリジナル関数。

■RxJS 5.4

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

this.http.get('url')
    .map(response => convert(response))
    .catch(error => Observable.of(error))
    .subscribe(response => process(response));

■RxJS 6

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

this.http.get('url')
    .pipe(
      map(response => convert(response)),
      catchError(error => of(error)))
    .subscribe(response => process(response));

pipe の中に、 mapcathError を複数書けるようになっています。

tap

余談ですが、RxJS 5.4では、戻り値のない関数も map で実行できましたが、
RxJS 6では tap が用意されており、こちらを使用するようになっています。

HTTPレスポンスの内容をログ出力する例を示します。

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, tap, catchError } from 'rxjs/operators';

this.http.get('url')
    .pipe(
      tap(response => console.log(response)),
      map(response => convert(response)),
      catchError(error => of(error)))
    .subscribe(response => process(response));

combineLatest

RxJS 5.4では、最初のObservableの combineLatest を呼んでいましたが、
RxJS 6では独立しました。こちらの方が自然ですね。
ただ、結合した結果はObservableの配列になるので、 map で変換します。
combine はオリジナル関数。

■RxJS 5.4

import 'rxjs/add/operator/combineLatest';

observable1.combineLatest(observable2, (o1, o2) => combine(o1, o2));

■RxJS 6

import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';

combineLatest(observable1, observable2)
  .pipe(map(values => combine(values[0], values[1]));

Angular

RxJSの対応が一通り完了したら、あとは大したことはありません。

今回のバージョンアップでは、Angularの内容は全く修正が要りませんでした。
Deprecatedなものを使っていた場合は、削除されている可能性があるため、直す必要があります。

Angular Material

こちらも、今回は何も変更せずに動作しました。
使っているのは matInputmat-selectmat-table くらいですが。

まとめ

RxJSの変更はつらいものがありましたが、それさえ乗り越えれば、最新のAngularを適用するのは楽チンです👍
Angular6はLTSでサポートも2019年10月まで続くので、
古いAngularを使っている場合は、アップデートを検討してみてください。

Acroquest Technologyでは、キャリア採用を行っています。


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、Angular)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

www.wantedly.com

Elasticsearchの圧縮方式の比較

こんにちは。
2年目エンジニアのノムラです。
普段はElasticStackを用いた分析基盤の開発等を行っています。

Elasticsearchを使っているとストレージの使用量を節約したいと思う方は多いのではないでしょうか。

Elasticsearchはデータを格納するときにデフォルトでLZ4という圧縮方式でデータ圧縮を行っていますが、
実はLZ4よりも圧縮率の高いbest_compressionという圧縮方式を利用することもできます。

このbest_compressionは圧縮率が高い分、検索時にはLZ4よりも遅くなると言われるのですが、
実際にどれくらいデータサイズに違いがあるのか、検索速度の違いはどれくらいになるのかが
実はよく分かりません。

ということで今回はこの2つの圧縮方式のデータサイズと検索速度への影響を比較してみました。


目次は以下になります

環境情報

OS: Amazon Linux release 2.0 (2017.12) LTS Release Candidate
インスタンスタイプ: t2.2xlarge
ディスクサイズ: 30gb

バージョン情報

elasticsearch 6.2.2
kibana 6.2.2
logstash 6.2.2

準備

今回はapacheログを用いて比較を実施します。
比較のためのデータは apache-loggenを使って1000万件のデータ(2.2gb)を作成しました。
appache-loggenのURLは以下
github.com


データは以下のような形式です。

160.87.30.197 - - [05/Jan/2018:15:01:07 +0900] "GET /category/music HTTP/1.1" 200 113 "/item/finance/777" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"

検証のための準備は以下となります。

1.インデックステンプレートの適用

今回は1ノードでの検証になるため、シャード数を1にレプリカ数を0に設定します

curl -XPUT -u user:pass 'localhost:9200/_template/tmpl_00_shard?pretty' -H 'Content-Type: application/json' -d'
{
  "index_patterns": "*",
  "settings": {
    "index": {
      "number_of_shards": "1",
      "number_of_replicas": "0"
    }
  }
}
'
2.LZ4形式のデータ投入

lz4_sampleインデックスにLZ4形式(デフォルト形式)でデータを投入します

$cat apache_logs | bin/logstash -f apache_lz4.conf

apache_lz4.confの設定は以下です。

input{
  stdin{}
}
filter{
  grok { 
    match => [ "message", "%{COMBINEDAPACHELOG}" ] 
  }
}
output{
  stdout{
    codec => dots
  }
  elasticsearch{
    hosts => localhost
    index => "lz4_sample"
    user => "user"
    password => "pass"
  }
}
3. best_compression形式のデータ投入

APIを用いてbest_compression_sampleインデックスの圧縮方式をbest_compressionに設定します

curl -XPUT -u user:pass 'localhost:9200/best_compression_example?pretty' -H 'Content-Type: application/json' -d'
{
  "settings": {
    "index.codec": "best_compression"
  }
}
'

best_compression_sampleインデックスにbest_compression形式でデータを投入します

$cat apache_logs | bin/logstash -f apache_best_compression.conf

apache_best_compression.confの設定は以下

input{
  stdin{}
}
filter{
  grok { 
    match => [ "message", "%{COMBINEDAPACHELOG}" ] 
  }
}
output{
  stdout{
    codec => dots
  }
  elasticsearch{
    hosts => localhost
    index => "best_compression_sample"
    user => "user"
    password => "pass"
  }
}
4.投入されたデータの確認
curl -XGET ‘localhost:9200/lz4_sample/_search

以下の様なデータが投入されていることが確認できます。(best_compression_sampleでも同様です)

{
  "took" : 23,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 10310974,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "lz4_sample",
        "_type" : "doc",
        "_id" : "PsXqDmEBl8mqXpdfS3ci",
        "_score" : 1.0,
        "_source" : {
          "request" : "/category/software",
          "agent" : "\"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\"",
          "auth" : "-",
          "ident" : "-",
          "verb" : "GET",
          "message" : "104.129.152.199 - - [05/Jan/2018:14:56:46 +0900] \"GET /category/software HTTP/1.1\" 200 63 \"/search/?c=Sports+Computers\" \"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\"\r",
          "referrer" : "\"/search/?c=Sports+Computers\"",
          "@timestamp" : "2018-01-19T14:54:46.064Z",
          "response" : "200",
          "bytes" : "63",
          "clientip" : "104.129.152.199",
          "@version" : "1",
          "host" : "HOGE",
          "httpversion" : "1.1",
          "timestamp" : "05/Jan/2018:14:56:46 +0900"
        }
      },
      (略)
    ]
  }
}

データサイズの比較

KibanaのDevToolsからCAT APIを用いてデータサイズを計測します。
f:id:acro-engineer:20180409003727p:plain

best_compression形式で圧縮されたデータの方が、LZ4形式で圧縮されたデータと比較してデータサイズが16%程小さくなっています。

検索速度の比較

KibanaのDevToolsを用いて、検索速度を計測します。
計測はlz4_sampleインデックス、best_compression_sampleインデックスそれぞれ10回ずつ実施しました。

検索クエリは以下

# lz4
GET lz4_sample/_search
{
  "size": 10000,
  "query": {
    "match_all": {}
  }
}
# best_compression
GET best_compression_sample/_search
{
  "size": 10000,
  "query": {
    "match_all": {}
  }
}

結果は以下

圧縮方式 平均 最大 最小
LZ4 1.14s 1.53s 0.87s
best_compression 1.86s 2.11s 1.61s

best_compression形式で圧縮されたデータに対する検索速度は、LZ4形式と比較すると163%と遅くなりました。
データの解凍が遅い分検索処理にも時間がかかっているようです。

LZ4とbest_compressionのデータが両方存在する場合

ここで、実際の利用シーンではLZ4形式とbest_compression形式、両方の形式で圧縮されたデータに跨って、検索するシーンが考えられます。
単純に考えれば、検索対象のドキュメント数が同じ場合、検索速度はLZ4形式のみの検索速度と、best_compression形式のデータのみの検索速度の間になりそうです。
そちらも検証してみました。

そこで、先ほどのデータとは別に、ドキュメント数は同じで、LZ4形式とbest_compression形式が半分ずつになるようにデータを投入しました。(データサイズ:計4.2gb)
投入処理については割愛します。
f:id:acro-engineer:20180409012135p:plain

同様にKibanaのDevToolsを用いて、検索速度を計測します。
検索クエリは以下

# 混合
GET apache_*/_search
{
  "size": 10000,
  "query": {
    "match_all": {}
  }
}

結果は以下のようになりました。

圧縮方式 平均 最大 最小
LZ4 1.14s 1.53s 0.87s
混合 1.38s 1.49s 1.28s
best_compression 1.86s 2.11s 1.61s

予想通り、混合したデータに対する検索速度はLZ4形式とbest_compression形式、それぞれの形式の間の値になりました。

まとめ

LZ4とbest_compressionのデータサイズと検索速度への影響の違いは以下のようになります。

圧縮方式 元データ LZ4 混合 best_compression
データサイズ 2.2 gb 4.6gb 4.2gb 3.9gb
検索速度 - 1.14s 1.38s 1.86s

今回はapacheログを用いて圧縮形式の比較を行いました。
他のデータの場合にはまた状況が違ってくると思いますが、一つの例として参考になれば嬉しいです。

それでは!

Acroquest Technologyでは、キャリア採用を行っています。


  • データ分析(Elasticsearch、Python関連)、ビッグデータHadoop/Spark、NoSQL)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 

社内技術イベントLTxRT紹介 ~「エンジニアリング組織論への招待 ☓ カイゼン・ジャーニー」のイベントを視聴しました~ #eotkaizenj

こんにちは。@です。
気がついたら4月になり、しばらくしたら突然暑くなって、うっかりスタバで購入した
抹茶フラペチーノがおいしかったです。

本題ですが、先日、LTxRTを開催し、
「エンジニアリング組織論への招待 ☓ カイゼン・ジャーニー」のイベントを会社の寮で視聴していました。

devlove.doorkeeper.jp

※前回のLTxRTはこちら

社内でもこの2冊はエンジニアの組織やチームを改善していく本で
良い本だとよくおすすめされていました。
そこで、今回のこのイベントを皆で見たいといった呼びかけがあり、Zoom越しですが、見たい人で集まりました!

f:id:acro-engineer:20180426202450j:plain:w500

イベントの最初はそれぞれの本について、どんな本か、そして、何が良かったか読者から紹介がありました。
そして、次に著者陣によるパネルディスカッションが行われました。

2つの本の共通点、違うこと、本の使い方など、著者ご自身が
どんなことを考えているのかを説明されており、面白いと思いました。

Zoomで視聴していて、聞き取りづらいなどハプニングがありました。
しかし、視聴が終わった後に本を既に読んだ人から補足をしてもらいつつ、
より細かい感想を共有してもらいながら、ディスカッションをしました。
話してみると実践できていること、まだまだ足りていないことが出てきたので非常に面白かったです。

ちなみに、LTxRTをきっかけにイベントの本をAmazonでポチった参加者も多かったです。
ちょうどGW前なのでGW中に読んで習得してきそうです。

今回も議論が活発で、面白い会になりました!
社内の勉強会も昨年度より多く増え、非常に知的刺激が多くなってきます!

また、次回お会いしましょう!

※今回のイベントの本

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

Acroquest Technologyでは、キャリア採用を行っています。


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

Kibanaのマルチテナント運用について考えてみた(後編)

こんにちは。
@です😊

この記事は
Kibanaのマルチテナント運用について考えてみた(前編) - Taste of Tech Topics
の後編となります。事前にそちらをご一読ください。

さて、前回の記事では
データが入っているindexに対してアクセス制限をかけることで、見せたくないデータを隠すことができました。
しかし、ダッシュボードが編集できてしまうなどの問題がありました。

ここでは、その対策としてkibana_dashboard_only_userを使ってみます。

ダッシュボードの閲覧専用ユーザー

バージョン5.xまでは自分で.kibanaへのアクセスを制限したroleを作る必要がありましたが、バージョン6からは予めkibana_dashboard_only_userというroleが定義されています。
これをkibana_userの代わりに付与してみます。
f:id:acro-engineer:20180121233236p:plain:w700

使える機能がダッシュボードだけに制限された上、編集などもできなくなっています。
良い感じです。
f:id:acro-engineer:20180121234155p:plain:w700

ダッシュボードの存在を隠す

しかし、dashboard_only_userを使うだけでは「B社のダッシュボードが存在すること」がA社の人間にもわかってしまします。
.kibana indexに対する制御をカスタマイズして、この問題を解決してみましょう。

何をするかと言うと、kibana_userの代わりに、roleA_kibanaといったようなロールを作ります。
(roleA_kibanaを作らず、roleA_adminなどにまとめて設定することも可能です)
f:id:acro-engineer:20180204230710p:plain:w700

設定内容としては、「DashboardとVisualizationは"[A社]"がタイトルに含まれる場合しかアクセスできない」というものになっています。
また、Kibanaの設定(config)や、company_aというindex-patternを読む権限もつけています。

※match_phrase_prefixではqueryがanalyzeされるので、予期せぬ名前がヒットしないよう、注意が必要です。
※本気で運用を考えるなら、saved searchやreportingについてもアクセス制御を考える必要がありますが、それに関しては本記事では考慮しません。

f:id:acro-engineer:20180207012532p:plain:w700

これでuserA_adminからはA社のダッシュボードのみが見えるようになりました。

一応、当初想定していた下記の要件を満たすことができました。

  • 「一部のダッシュボードだけを見せたい」
  • 「編集できないようにしたい」
  • ダッシュボードの存在を知られたくない」

...しかし、少しもやもやが残ります。
この方法では、ダッシュボードなどの作成時に命名の制約が生じるし、ロール定義が煩雑になる可能性が高く、スマートな方法とは言えません。

結局どうするのが良いのか?

さて、回りくどく色々と書きましたが、おそらくelasticsearch + kIbanaのマルチテナント運用をおこなう上で最も現実的な解は「Kibanaをテナントごとに用意する」というところに落ち着くのではないかと思います。(異論は認めます)


先ほど、

Kibanaのダッシュボード自体の情報は、.kibanaというindexに保存されている

と言いましたが、kibanaは設定を変更することで、.kibana以外のindex名でダッシュボードなどの情報を保存することができます。


つまり、A社のユーザーが利用するkibanaの情報は.kibana_aに、B社のユーザーが利用するkibanaの情報は.kibana_bに保存するという運用が可能になります。
そうすれば、kibana用のindexに対して細かく制限をかける必要がありません。


設定に必要な手順は、kibana.ymlを編集しkibana.indexの値を書き換えてKibanaを起動するだけです。

# kibana.index: ".kibana"
kibana.index: ".kibana_a"


こうすることで、elasticsearchのクラスタは単一でも、安全にマルチテナント運用が可能です。
この通り、A社のユーザーは、A社の情報だけが見られます。
めでたし、めでたし😇

f:id:acro-engineer:20180207012532p:plain:w700


おまけ(その他考慮すべきこと)

Kibanaは、DevToolsに関しても使用不可にすることができます。
こちらはkibana.ymlに下記の1行を追加することで使用不可にできます。
(古いバージョンでは、Kibana画面のadvanced settingsから設定できたと記憶しています)

console.enabled: false

興味のある方は試してみてください。

まとめ

  • kibanaのダッシュボード情報などは、専用のindexに保持されている
  • X-Pack Securityの機能で権限を制御できる
  • 現実的にはkibanaのインスタンスをテナント毎にわけるのが良さそう

※テナント数自体が膨大になった場合は、別の手段を考えたほうが良いケースもあるかもしれません

以上です。ツッコミ等あれば是非ご指摘ください。
お読みいただき、ありがとうございました。

Acroquest Technologyでは、キャリア採用を行っています。

  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。


少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
データ分析基盤Elasticsearchを使い倒したいエンジニア募集! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

Kibanaのマルチテナント運用について考えてみた(前編)

こんにちは。
@です😊

最近Elasticsearch + Kibanaをマルチテナントで利用する方を多く見かけます。
そういったときに問題になってくるのが、セキュリティですね。

たとえば

  • 「一部のダッシュボードだけを見せたい」
  • 「編集できないようにしたい」
  • ダッシュボードの存在を知られたくない」

など、色々とセキュリティ要件が発生するはずです。

この記事では、実際に上記のような設定ができるのか、どうやって設定するのかといったところを
改めて整理してみます。
※多少回りくどい検証過程を書いているので、「結局どうしたらいいの?」という部分のみ知りたい方は、後編にご期待ください。

バージョン情報など

macOS High Sierra version 10.13.2
Elasticsearch 6.1.1
Kibana 6.1.1
Logstash 6.1.1
x-packはElasticsearchとKibanaにインストールしています(試す場合はトライアル版で構いません)

目次

  1. 下準備(サンプルデータの内容など)
  2. indexごとに制御
  3. ダッシュボードの閲覧専用ユーザー(後編)
  4. ダッシュボードの存在を隠す(後編)

下準備

まずは、今回の記事で使うサンプルデータについてです。

想定として、自分がkibanaによるログ可視化サービスを提供しており、クライアントとしてA社およびB社がいると仮定します。
さらにクライアントの中にも、管理者と一般ユーザーがいると仮定しましょう。
整理すると下のような4種類になります(厳密にはサービス自体の管理者を含むと5種類)

A社 B社
admin A社のダッシュボードを編集できる B社のダッシュボードを編集できる
一般社員 A社のダッシュボードの閲覧のみ可能 B社のダッシュボードの閲覧のみ可能

作成してあるダッシュボード

f:id:acro-engineer:20180105155411p:plain:w800

ダッシュボード名 使用index 概要
[A社]売り上げ推移 company_a A社の売り上げ推移を可視化したダッシュボード
[B社]売り上げ推移 company_b B社の売り上げ推移を可視化したダッシュボード
[管理者]売り上げ推移ダッシュボード company_a, company_b A社B社のデータを横断して推移を可視化したダッシュボード

それぞれのダッシュボードは下の画像のようになっています。
(機能確認用のサンプルなので必要最低限の内容です)

  • [A社]売り上げ推移

f:id:acro-engineer:20180105161123p:plain:w500

  • [B社]売り上げ推移

f:id:acro-engineer:20180105161158p:plain:w500

f:id:acro-engineer:20180105161303p:plain:w500


各ユーザーごとの権限は下記の通りです。

[A社]売り上げ推移 [B社]売り上げ推移 [管理者]売り上げ推移ダッシュボード
admin 編集可能 編集可能 編集可能
userA_admin 編集可能 閲覧不可 閲覧のみ※
userA_general 閲覧のみ 閲覧不可 閲覧のみ※
userB_admin 閲覧不可 編集可能 閲覧のみ※
userB_general 閲覧不可 閲覧のみ 閲覧のみ※

※自社データのみ閲覧可能

index毎に制御

まず、もっともシンプルなアクセス制御方法として、index毎の権限を設定する方法があります。
例えば「userA_adminにはcompany_a indexへのall権限」、「userB_generalにはcompany_b indexへのread権限のみ」といった具合です。
この部分は非常にシンプルですが、実際にKibanaで設定してみます。

既に使ったことのある方はご存じかと思いますが、
Elasticsearchのアクセス制御の仕組みは、Roleとして権限グループを作成し、そこにUserを結びつけることで実現します。

ではまず、A社のadminである「userA_admin」について見ていきます。

最初に、Roleとして「roleA_admin」を作成します。
f:id:acro-engineer:20180106065722p:plain:w700

Create roleを選択し...
f:id:acro-engineer:20180106070305p:plain:w700

Role名および権限を設定します。
ここではcompany_aというindexにall権限を付与しています。
※Cluster Privilegesに関する説明は本記事では割愛します。要望があれば別途まとめる....かもしれません。
f:id:acro-engineer:20180106070828p:plain:w800

次にroleA_adminのロールに紐付くユーザーとしてuserA_adminを作成します。
f:id:acro-engineer:20180106071246p:plain:w700

Create userを選択します。
f:id:acro-engineer:20180106071452p:plain

userA_adminという名前のユーザーを作り、Roleとして、「roleA_admin」「kibana_user」を付与します。
(kibana_userについては後述します。kibanaを使うために必要な権限だと考えてください。)
f:id:acro-engineer:20180121211001p:plain:w700

userA_adminでログインして、ダッシュボードを確認してみます。
f:id:acro-engineer:20180121214558p:plain:w700

上がA社のダッシュボード、下がB社のダッシュボードです。
B社のダッシュボードは見えなくなっていますね。
※ただし、「B社のダッシュボードが存在すること」がわかってしまいます。この問題については後述します。
f:id:acro-engineer:20180121215244p:plain:w600
f:id:acro-engineer:20180121214935p:plain:w600


他のユーザーなども同様に作ります。
f:id:acro-engineer:20180121221821p:plain:w700

試しにuserA_generalも試してみます。
期待する挙動はA社ダッシュボードの閲覧のみができることです。

しかし....編集できてしまいました....
f:id:acro-engineer:20180121225436p:plain:w700

そうなんです。
Kibanaのダッシュボード自体の情報は、.kibanaというindexに保存されているので、
company_aのindexを制御しても、ダッシュボードの編集や削除ができてしまうのです。
B社のダッシュボードが一覧に表示されてしまったのもこのためです。
つまり、ダッシュボードの編集権限をカットするには、.kibana indexへの権限を制限する必要があります。
f:id:acro-engineer:20180121232810p:plain:w700


少し長くなってしまったので、その方法に関しては、後編で書くことにします。
ご期待ください☺️

Acroquest Technologyでは、キャリア採用を行っています。

  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。


少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
データ分析基盤Elasticsearchを使い倒したいエンジニア募集! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

モブプログラミング×ブログ =「モブブロギング」に挑戦しました

皆さんこんにちは。
@です。最近とっても暑いですね。

社内で試しにモブブロギングをやってみました。
モブブロギングはモブプログラミングが派生した活動で、
皆で1つのブログを書く取り組みです。このやってみたモチベーションは次のとおりです。

  1. 特定の人が書き続けている。
  2. 書き慣れている人の暗黙知がある。
  3. 知識の共有をしたい。

そこで、会社の寮でモブブロギングを当社の若手で試しに行ってみました。
モブブロギングの成果物はこちらです。

acro-engineer.hatenablog.com

モブブロギング

作業内容

本日の作業は次の通り行いました。

  1. 導入・・・モブプログラミングとは何かの説明
  2. 設計・・・課題感・作業内容を明確にする。
  3. 実装・・・検証内容の実装・検証
  4. 執筆・・・ブログの執筆を行う

13:30〜

まずは、導入です。
モブプログラミングとはどういったものかを説明しています。
説明には、次のスライドを利用しました。

speakerdeck.com

特にモブブロギングはおろかモブプログラミングがはじめてなので、
心理的安全性の箇所に書いてある「ヤッター!!」という部分を主に説明しました。
うまくいった時にうまくいったことを共有して、モチベーションを保っています。結構難しいものです。

13:45〜

まずは、お題の整理をしました。
お題は上司から言われて検証したいと依頼された内容です。
そのため、課題のイメージの認識あわせと作業を明確化し、
時間がかかりそうな部分はワークフローを分担しました。

14:00〜

データの投入の時間長いので、その間に執筆していました。
今回、執筆は普段書き慣れていない人に担当してもらいました。
というのも、書き方を共有をしたいとの考えがあり、暗黙知的な何かを共有するために実際にやってみました。

15:15〜

2.2GBのApacheのログを利用し、投入していました。
別途、裏で何人かで準備を進めていた内容が終了し、「やったー」みたいな感じになりました。

f:id:acro-engineer:20180212173931j:plain:w500

検証内容の都合上、もう一つIndexが必要となったので、その間にReindexを開始しています。

16:00〜

だんだんとブログの内容が固まってきました。
ただ、細かい説明の記載が難しくなってきているので、
より正しい理解を共有するために皆でディスカッションしています。
詳しい人が複数人集まると議論ができて勉強になります。

16:15〜

Reindexが完了し、実装側の画面を写しています。
参加者で状況を共有しつつブログも併せてブラッシュアップしています。

16:50〜

作業用BGMの変更とforce mergeを開始しました。
皆でいけっーとかいっていました。(あっという間に終わりましたが・・・)

17:00〜

検証で必要な結果を出し終えたので、ブログの仕上げを開始しました。
結果を出してみての確認やフッダー、タグなどの確認をしています。

17:30

Finish!! 最後の喜びのポーズ

f:id:acro-engineer:20180212174017j:plain:w500

やってみてどうだったか?

良かった点

技術的な知見を共有できた。

Elasticsearchを深く使っている人からそれなりに使っている人もいたので、知識の差がありました。
この記事を書いている私も知らないことが多く、非常に勉強になりました。

心理的安全があった

皆で検証していたので仮説の誤りが少なく、
一人では、はまったところでも助け合えました。
もちろん、皆で感動を分かち合いました。

改善点

いろんな人が様々な話をしだした。

モブプログラミングだけに皆が自由に発言をしすぎて
ドライバを混乱させてしまった場面が時々ありました。
この点は発言の内容や論点を明確に話す必要があると感じています。

最後に

モブブロギング楽しい!
暗黙知・知識の共有といった点は、途中の議論のタイミングで適宜、認識を合わせられたことにより、
得られるものが多く、非常に良かったと思っています。
しかし、ドライバがよりうまくやっていくためには、各々が整理して話していくことが課題になるとも感じました。

今後も皆で共有したい!と思うことを書いてみると成果が出ると感じました。
実際のモブプログラミングもやってみたいです!
次回はもっと面白い内容をやってみます。

Acroquest Technologyでは、キャリア採用を行っています。


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com