tshohe's memo

おぼえたことをかく

HashiCorpの学習プラットフォーム体験(Vault編)

HashiCorpの学習プラットフォームがどんな感じか把握するために、まずは現時点で出来るVaultのをやってみることに。
バージョンは最新のVault 1.0 beta1で試してみました。

learn.hashicorp.com

元の紹介Blog
https://www.hashicorp.com/blog/hashicorp-learn-platform-with-vault

まずは入門編

Install Vault

Linux用のバイナリをダウンロードして適当なディレクトリに配備し、PATHを通します。

$ wget https://releases.hashicorp.com/vault/1.0.0-beta1/vault_1.0.0-beta1_linux_amd64.zip
$ unzip vault_1.0.0-beta1_linux_amd64.zip 
Archive:  vault_1.0.0-beta1_linux_amd64.zip
  inflating: vault      

Starting the server

機能を簡単に試すために、devモードで起動します。

$ vault server -dev
==> Vault server configuration:

             Api Address: http://127.0.0.1:8200
                     Cgo: disabled
         Cluster Address: https://127.0.0.1:8201
              Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: (not set)
                   Mlock: supported: true, enabled: false
                 Storage: inmem
                 Version: Vault v1.0.0-beta1
             Version Sha: ebc733f4ca5d362fdfb302ac75953228585c54a2

WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.

You may need to set the following environment variable:

    $ export VAULT_ADDR='http://127.0.0.1:8200'

The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.

Unseal Key: axPVwrt+K79ELEc4lxe8FJQAXgRVJ8vq9WBfkbf8dFU=
Root Token: s.7mWsQehqKQ9C1QvKlFPwF6CO

Development mode should NOT be used in production installations!

==> Vault server started! Log data will stream in below:

UnsealするためのKeyや、Root Tokenが表示されます。

状態確認

$ export VAULT_ADDR='http://0.0.0.0:8200'
$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.0.0-beta1
Cluster Name    vault-cluster-44b32083
Cluster ID      83ca2d85-08a4-5c78-e412-b62be7f1923f
HA Enabled      false

Your First Secret

Secretのread/writeを試します。
devモードでは情報はin-memoryに格納され、永続化はされません。(productionの場合はDisk or Consulに格納) Secretは値を暗号化してからストレージドライバに渡されるので、ストレージの情報だけではどうやっても復号化できないようになっています。

Secretの書き込み

$ vault kv put secret/hello foo=world
Key              Value
---              -----
created_time     2018-10-28T07:43:17.857896039Z
deletion_time    n/a
destroyed        false
version          1

kvはkey value
secret/helloは保存するパス
foo=worldはkey=value

valut kvは強力ですが、stdinから読めてしまうとのこと。 https://www.vaultproject.io/docs/commands/index.html

Secretの取得

$ vault kv get secret/hello
====== Metadata ======
Key              Value
---              -----
created_time     2018-10-28T07:43:17.857896039Z
deletion_time    n/a
destroyed        false
version          1

=== Data ===
Key    Value
---    -----
foo    world

レーニング資料の出力とちょっと違っていて、1.0ではMetadataとDataが完全に別に表示されるようになっています。
出力がspace区切りなのでawkとかで整形しやすい、とのこと。
またJSON outputもあって、jqで整形することもできます。

$ vault kv get -format=json secret/hello | jq -r .data.data.foo
world

フィールドを指定して出力

$vault kv get -field=foo secret/hello
world

削除

$ vault kv delete secret/hello
Success! Data deleted (if it existed) at: secret/hello

Secrets Engines

各エンジンの操作を紹介するTopic。

kv engine以外にも色々

engine summary
aws AWS IAM アクセスキーを生成
database 時間制限付きのデータベースクレデンシャルを生成

様々なパスでSecret Engineを有効化することが出来、各パスは完全に分離しているとのこと。

有効化

$ vault secrets enable -path=kv kv
Success! Enabled the kv secrets engine at: kv/

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_7b73491b    per-token private secret storage
identity/     identity     identity_5c77b9e7     identity store
kv/           kv           kv_8842fe62           n/a
secret/       kv           kv_fdfd9f35           key/value secret storage
sys/          system       system_89f66b37       system endpoints used for control, policy and debugging

デフォルトパスはsecret engineと同名になるのでkv/としなくてもkv/になります。

無効化
moveも出来るがsecretはパスに紐付いているので消えてしまうとか。

$ vault secrets disable kv/

Dynamic Secrets

読み取るときに生成されるSecret
使用後すぐに失効させることも可能

AWSアクセスクレデンシャルを生成

$ vault secrets enable aws

AWSと通信するときに利用するRoot Accountを登録

$ vault write aws/config/root \
    access_key=[自分のAWSアカウントのアクセスキー] \
    secret_key=[アクセスキーに対応したSecret]

Success! Data written to: aws/config/root

IAMロール作成 aws/roles/[ロール名]でポリシーをマップ

$ vault write aws/roles/my-role policy=-<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1426528957000",
      "Effect": "Allow",
      "Action": [
        "ec2:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
EOF

キーペア生成

$ vault read aws/creds/my-role
Key                Value
---                -----
lease_id           aws/creds/my-role/8PShhjAzbP8rAPHp8sgs2mNe
lease_duration     768h
lease_renewable    true
access_key         [生成されたアクセスキー]
secret_key         [生成されたSecret]
security_token     <nil>

aws/creds/[ロール名]をreadすることでキーペアを生成出来ます。 デフォルトでは768H後に失効になります。 lease_idは更新、失効、検査に使うので大事。

手動失効

$ vault lease revoke aws/creds/my-role/8PShhjAzbP8rAPHp8sgs2mNe
All revocation operations queued successfully!

Built-in Help

Secret Engineのヘルプや、各パスのヘルプが参照可能

$ vault path-help [path]

Authentication

Vault自体の認証

devだと管理者権限を持つrootユーザーとして自動的にログインします。

vault token

トークン認証はデフォルト有効。rootトークンは最初のVault設定に利用します。

追加で作成する場合
現在のトークンの子トークンとして作成、ポリシーは継承される

$ vault token create
Key                  Value
---                  -----
token                s.61VESdUhJwbhyvtKsXODPLAg
token_accessor       4fNTeZ6OiQGxhYP3b0Op9vkt
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

Revoke

$ vault token revoke s.61VESdUhJwbhyvtKsXODPLAg

Login

$ vault login s.61VESdUhJwbhyvtKsXODPLAg
Success! You are now authenticated. The token information displayed below
~

実際はToken生成コマンドの使用は推奨されておらず、Github, LDAP, AppRoleとか使ってねとのこと。

$ vault auth enable -path=github github
$ vault write auth/github/config organization=hashicorp
$ vault write auth/github/map/teams/my-team value=default,my-policy
$ vault login -method=github

Policies

ユーザーがアクセス出来るものを定義するためのポリシーの設定方法。

  • ルートポリシー: 管理者権限
  • デフォルトポリシー: デフォルトで付与されるポリシー

JSONと互換性のあるHCL(HashiCorp Configuration Language)形式

フォーマット確認

$ vault policy fmt my-policy.hcl
Success! Formatted policy: my-policy.hcl

ポリシーのアップロード
$ vault policy write my-policy my-policy.hcl
Success! Uploaded policy: my-policy

$ vault policy list
default
my-policy
root

ポリシーを指定してTokenを作成します。(secret/forに対してはread権限しかないので書き込めない)

$ vault token create -policy=my-policy
Key                  Value
---                  -----
token                s.4TeHDA1TjOP5HsadzSMULLMz
token_accessor       nCgkAftm5LEl7GXUvlmx5y39
token_duration       768h
token_renewable      true
token_policies       ["default" "my-policy"]
identity_policies    []
policies             ["default" "my-policy"]

$ vault kv put secret/bar robot=beepboop
Key              Value
---              -----
created_time     2018-10-28T12:34:00.914846589Z
deletion_time    n/a
destroyed        false
version          1
$ vault kv put secret/foo robot=beepboop
Error writing data to secret/data/foo: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/secret/data/foo
Code: 403. Errors:

* 1 error occurred:
    * permission denied

Deploy Vault

Vaultの設定、起動、Seal/Unseal、Scaling

設定

HCL
storage "consul" {
  address = "127.0.0.1:8500"
  path    = "vault/"
}

listener "tcp" {
 address     = "0.0.0.0:8200"
 tls_disable = 1
}

作業端末からもアクセス出来るように127.0.0.1を0.0.0.0:8200に変更しています。

storageにはinmem(in-memory), file, consulがある。

Consulを起動

$ wget https://releases.hashicorp.com/consul/1.3.0/consul_1.3.0_linux_amd64.zip
$ unzip consul_1.3.0_linux_amd64.zip 
Archive:  consul_1.3.0_linux_amd64.zip
  inflating: consul                  
$ consul agent -dev

設定ファイルを指定してVaultを起動

$ vault server -config=config.hcl
==> Vault server configuration:

             Api Address: http://127.0.0.1:8200
                     Cgo: disabled
         Cluster Address: https://127.0.0.1:8201
              Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: (not set)
                   Mlock: supported: true, enabled: true
                 Storage: consul (HA available)
                 Version: Vault v1.0.0-beta1
             Version Sha: ebc733f4ca5d362fdfb302ac75953228585c54a2

==> Vault server started! Log data will stream in below:

初期化

$ vault operator init
Unseal Key 1: AcZqa1USsWoBXNd2a2bK6KzTK1oWF/qPOUZU/RFhjHJb
Unseal Key 2: lbiYiY6223BTwrm4cDCwdVgMcqQujQsr/bfZHX0/TCEX
Unseal Key 3: W/7cB42huTlQzC/bNAkPzKSSHT+8Jv3ZPiKdY4M2dAmr
Unseal Key 4: iMKSypAkMpEJZfpva6BYEp6HWYeYg5gQKqkg83q42nDV
Unseal Key 5: ERjqoCZXs30R7i0ltZ1WHu8+lc5antaAPcdv1qrYU0g9

Initial Root Token: s.2DKlat1pC8HByEdCOi9uvNEj

Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.

Vault does not store the generated master key. Without at least 3 key to
reconstruct the master key, Vault will remain permanently sealed!

It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See "vault operator rekey" for more information.

Unsealするためにはキーを3つ以上入れる必要があり、それぞれ別々に管理することによって、単一オペレータだけではUnsealできないように設計されています。

$ vault operator unseal
Unseal Key (will be hidden): 
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    1/3
Unseal Nonce       8ee6ba25-6ccd-95ed-3ef6-4d581ef2c386
Version            1.0.0-beta1
HA Enabled         true

追加で+2つ入力

$ vault operator unseal
Unseal Key (will be hidden): 
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    2/3
Unseal Nonce       8ee6ba25-6ccd-95ed-3ef6-4d581ef2c386
Version            1.0.0-beta1
HA Enabled         true
$ vault operator unseal
Unseal Key (will be hidden): 
Key                    Value
---                    -----
Seal Type              shamir
Initialized            true
Sealed                 false
Total Shares           5
Threshold              3
Version                1.0.0-beta1
Cluster Name           vault-cluster-68c28fd9
Cluster ID             79e183ac-9928-2838-ebac-55c946f0acf1
HA Enabled             true
HA Cluster             n/a
HA Mode                standby
Active Node Address    <none>
  • Sealedがfalseになり、Unseal状態に。
  • 最後にinitial Root tokenを使ってvault loginします。
  • 再びSeal状態に戻すのは単一ユーザのみので可能で、Seal状態に戻るとメモリから全ての状態がクリアされます

Using the HTTP APIs with Authentication

CLI以外にもHTTP APIで利用することが出来ます。

$ export VAULT_TOKEN=s.2DKlat1pC8HByEdCOi9uvNEj

unseal
$ curl \
    --request POST \
    --data '{"key": "AcZqa1USsWoBXNd2a2bK6KzTK1oWF/qPOUZU/RFhjHJb"}' \
    http://host1:8200/v1/sys/unseal

read
$ curl \
    --header "X-Vault-Token: $VAULT_TOKEN" \
http://host1:8200/v1/secret/foo | jq
{
  "request_id": "cc46f5d9-db11-d3f4-544b-b7db66ee7db5",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 2764800,
  "data": {
    "foo": "bar"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

以上で入門編は終了ですが、色々なユースケースに対応したAdvanced Tracksも大量に存在するのでまだまだ色々出来そうです。

あと個人的にはTerraformのAdvanced Tracksに期待大です。

NoOps Meetup #2 のメモ

参加したので酔った頭でメモ。
「システム運用保守の"嬉しくないこと"をなくそう!」 がテーマの勉強会。

https://noops.connpass.com/event/103846/

オープニング

  • 岡 大勝さん@okahiromasa NoOps Japan 発起人

  • どなたかの言葉

    • Opsは嫌い
    • べきじゃなくて武器
    • Noを掲げてやめる(やめるのが難しい)
    • 運用をやめるということではない
    • これ以上Opsが減らないというスイートスポットを目指す
    • Toil削減、可観測性の向上といったことはSREとしてやることをやっていれば行き着くところ
    • 堅牢性 より Resiliency
  • 前回のsummary

    • 「”やめる”ことを決める」事が大事
    • NoOpsに向かう準備は整っている
    • みんな違ってみんないい
  • NoOps Japan Community: ナレッジを集めてOSSで公開するとか

  • SRCAサイクル(共感 → 尊重 → 貢献 → 感謝)

MicroserviceでのNoOps戦略

  • 鈴木 雄介さん@yusuke_arclamp グロースエクスパートナーズ
  • NoOpsの歴史
  • 2001年にアジャイルソフトウェア開発宣言
  • アジャイルをインフラにも適用したい -> DevOps
  • 2009年 Velocity 2009
    • DevOps Daysが始まる
  • 2011年: NoOps登場
    • Argument DevOps With NoOps
    • NoOpsは協業ではなくて自動化を目指す
    • I Don't want DevOpsとも...
      • Opsを敵に回し炎上
  • 2012年: Ops, DevOps and PaaS
    • Netflixではビルドデプロイの自動化はされていてデプロイはDevでやっている
    • 各チームが好きなタイミングで実施
    • ツールの開発はDevOps/SREチーム
    • 単純なオペレータは存在しない
    • 開発者はツールを使って運用作業を実施する
  • NoOpsが変えたこと
    • 作ると動かすの距離がなくなる
    • アプリケーションエンジニアはアプリを作るのではなくサービスを作る(機能要件に従ってコードを書くだけではない)
  • 2014年: Microservice

    • 「Microservice Java the Unix way」がバズる
    • サービス全体を止めずに一部を変更する(それぞれの変更タイミングはバラバラ)
    • 変更発生単位でサービスを分割
  • NoOpsとは「サービス全体を止めずに一部を変更する、ために、主に、運用作業の自動化とツール化を推進すること」

    • ビジネス価値を最大化するのが対局目標
  • 代表的な取り組み

  • 障害からの自動復旧
  • ミドルバージョンアップ自動化
  • 日中無停止リリース

  • アプリとインフラをセットで管理する、というのがまだない?

    • PaaS: 層が上がると制約が上がる
    • コンテナ: 構成の変更をセットで扱える
  • 動かすときにインフラ調達

  • 「インフラを用意してアプリを置く」、ではなく「アプリを動かそうとするときにインフラを調達する」
  • PaaSがまさに

  • バッチサーバは不要(バッチ実行時にインフラを調達する)

  • 固定IP/ドメイン -> 使わずに、自動払い出ししてサービスリポジトリに登録しに行く
  • 設定ファイルはサービス起動したら撮ってくるようにするとか

  • その先

    • k8s, istio
    • イベントソーシング: CQRS

ITインフラの NoOps を実現する戦略と方法論

中島 倫明さん @Irix_jp レッドハット

  • Ansible案件がメイン
  • 戦う階層を変えること = NoOps
    • UncomfortableなOpsをやめて一つ上の階層で戦う
  • これまで
    • 安全に確実に動かす、コストを最適化する
    • ずっと変化せずに減価償却期間中ずっとそのまま
  • そのままにはできない
  • どうすればComfortable?
  • 戦略
    • 状態を作る
    • クラウドファースト、コンテナファースト、自動化ファースト
    • 状態に行き着くためのギャップを抽出
    • 解消できるギャップ、できないギャップを整理
    • 到達可能なToBeを決める
  • バリューストリームマップで現状を可視化
  • すぐ解消できるもの、将来的にやること、やらなくていいこと に分類する
  • プロセスの再定義、自動化実装

  • 自動化の方法

    • 置換 -> AnsibleのPlaybook化とか
    • 機械化 -> 別の人に実行してもらう
    • 連結 -> 複数の機能をつなげて実行できるようにする
  • 環境は変えてもいい

なかなか楽にならない証明書の話 各パブリッククラウドの証明書周りの自動化についてお話します

  • しばやん さん @shibayan

  • 12ヶ月に一度くらいの頻度なので忘れがち

  • こういうのこそ自動化すべき
  • 自動化されない理由

    • 手順がむずい: CSRの作成、ドメイン所有の確認、配置場所がWebサーバによってまちまち
    • 認証局APIとか提供してくれてない
  • 更新を忘れると警告画面が出るしやばい

  • 常時SSLが当たり前
  • HSTSでHTTPSの使用を強制されているともう証明書治すしかない
  • Azureも過去に更新に失敗して11時間証明書が失効していたことも

  • ACM

  • 外部の認証局とパートナーシップを結んでいる
    • Azure Key Vault / App Service Certificate
  • Let's/ACME

  • Azure Key Vault

    • DigiCert/GlobalSignと連携
    • アカウント情報を入れておく
    • 事前に登録したポリシーに従って更新してくれる
    • 自己署名証明書も作れるらしい
  • App Service Certificate

    • GoDaddyと連携
    • Azure Potalから購入
    • 有料
  • Let's Encrypt

  • キー管理

    • HSM: hardware security module
    • AWSはKMS/CloudHSM
    • GCPはCloudKMS
    • AzureはKeyVauld
  • 結論としてはACM最強

  • Azureは無料で使えるSSL証明書がない
  • AzureとLet's Encryptの連携があれなのはパートナーに配慮した結果...?

  • Let's Encrypt感謝(大事)

  • Key VaultはCSR作成機能がある

  • キーの漏洩の心配がない

iOS12のショートカットの便利な使い方

色々と話題になってますが、最近リリースされたiOS12のショートカット便利ですね。(もともとWorkflowってのがあったみたいですが)
一つのショートカットで複数のアクションを定義することができるのでちょっとしたプログラミング的なことも出来るみたいです。(変数定義まで出来るとは...)

おまけにWidgetとして配備しておくことでロック解除せずに最小限のアクションで処理が実行できます。

普段使い出来そうな便利そうな使い方まとめてみました。

WiFi ON/OFF

色んな所で紹介されているやつ。
Wi-Fiを設定」で勝手に自動ONになるWiFiをお手軽に永続無効化出来ます。

SSHスクリプト実行

SSHログインして任意のコマンドを実行するというもの。

  • Raspberry Piの頻出操作(shutdown等)
  • サーバのリソース確認コマンド

とか登録しておいたら便利そう

URLの内容を取得

指定したURLに対してリクエストを実行可能です。
固定のURLはもちろん変数で指定した値が埋め込めたり、リストで選択した値が埋め込めたりと自由度が高いです。

ショートカットは下記のように作ります

  1. リスト
    • URLに埋め込む候補を全部登録
  2. リストから選択
  3. URL
    • URL内に「選択した項目」を挿入
  4. URLの内容を取得

家のRaspberry Piで、URLで指定した赤外線信号をTV等に送付するようなアプリケーションを実行しているのですが、これまで 「iPhoneロック解除 -> Safari起動 -> リモコン用Webページに移動 -> ボタンタップ」だったものが「iPhoneロック画面でスワイプ -> ボタンタップ」で済むようになりました。便利。

iPhoneのヘルスケアのデータをKibanaで見てみる

ウェアラブルバイスを使っているとiPhoneのヘルスケアにいろいろな情報が蓄積されていくので、それらのデータをエクスポートして可視化してみます。

勿論各デバイスごとの可視化ツールやヘルスケア自身のグラフがあるので、普通に波形が見たいだけであればそれで十分かと思いますが、Aggregationやらなんやらをやりたい場合はElasticsearchに投入してKibanaで見るほうがいろいろと便利かなーと思います。

ヘルスケアデータのエクスポート

ヘルスケアアプリケーションの右上の人型のアイコンを選択し、プロフィール画面に移動します。

f:id:tshohe:20180810013836p:plain

プロフィール画面の一番下にある「ヘルスケアデータを書き出す」というところからエクスポート出来ます。

f:id:tshohe:20180810013849p:plain

LogstashからElasticsearchへ投入

xml filter を利用することで、XML形式のヘルスケアデータをElasticsearchへ投入します。

conf

input {
  file {
    path => "/tmp/healthcare.xml"
    type => "helthcare"
    start_position => "beginning"
  }
}

filter {
  if [type] == "helthcare" {
    xml {
      source => "message"
      store_xml => "false"
      remove_namespaces => "true"
      xpath => ["Record/@type", "metricsType"]
      xpath => ["Record/@sourceName", "sourceName"]
      xpath => ["Record/@creationDate", "creationDate"]
      xpath => ["Record/@value", "value"]
    }
  }
  if [creationDate] != "" {
    mutate {
      replace => {"metricsType" => "%{metricsType[0]}"}
      replace => {"sourceName" => "%{sourceName[0]}"}
      replace => {"creationDate" => "%{creationDate[0]}"}
      replace => {"value" => "%{value[0]}" }
    }
  }
}

output {
  if [metricsType] != "" {
    elasticsearch {
      hosts => localhost
      index => "healthcare-%{+YYYY.MM.dd}"
    }
  }
}

template

PUT _template/healthcare
{
  "index_patterns": "healthcare-*",
  "mappings": {
    "doc": {
      "dynamic_templates": [
        {
          "integers": {
            "match_mapping_type": "long",
            "mapping": {
              "type": "long"
            }
          }
        },
        {
          "strings": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ],
      "properties": {
        "creationDate": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss Z"
        },
        "value": {
          "type": "long"
        }
      }
    }
  }
}

indexはこんな感じ

GET healthcare-*/_search?size=1

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 10639,
    "max_score": 1,
    "hits": [
      {
        "_index": "healthcare-2018.08.10",
        "_type": "doc",
        "_id": "5hdrJGUBVvfK6smIRtRR",
        "_score": 1,
        "_source": {
          "metricsType": "HKQuantityTypeIdentifierHeartRate",
          "value": "98",
          "path": "/tmp/healthcare.xml",
          "@version": "1",
          "@timestamp": "2018-08-10T15:18:41.852Z",
          "host": "hostname",
          "type": "helthcare",
          "sourceName": "iPhone",
          "creationDate": "2017-11-27 21:56:01 +0900"
        }
      }
    ]
  }
}

どのmetricsType(/HealthData/Record/@type)がどんな意味を持っているかはAppleのDocumentに記載されています。

Data Types | Apple Developer Documentation

日毎の心拍数の最大値のグラフを描画するとこんな感じ(時計付けてない日も多くて結構抜けてる...)

f:id:tshohe:20180811002938p:plain

心拍数ランキングとかも描画できる

f:id:tshohe:20180811003347p:plain

他にも

  • GPS情報のTileMapへの描画
  • 睡眠時間のグラフ化
    • 一定基準下回るとアラート上げたり

等色々と遊べそうです。

より便利にするためには

今はiPhoneでエクスポートして、移動して、展開して...みたいな手順で何かと手間がかかりますが、エクスポート先としてSlackやGoogle Driveが選択できるので、例えば

といったこともできるはずです。

Mercari meetup for SRE のメモ

メルカリさんが開催しているSREイベントに参加したのでそのメモ。

mercari.connpass.com

発表

オープニング&SREチームのご紹介 by @masartz

  • 2015/11から発足
  • Application ~ Infrastructureまで見る
  • 全員で16人。内訳は下記の通り。
    • ML Platform * 1
    • Microservice * 5
    • Reliability, Scalability * 9 ★今日はココ
    • Engineering Manager * 1
  • 朝の監視は当番制
    • 打刻から出社確認
  • 朝会はSlackで実施。スレッドにずらっとやること書いていく。
  • ITSはJIRA
    • Slackから「add todo (.*)」というメッセージで起票できるようにしている。
  • ポストモーテム残す文化あり
    • 批判しない、原因特定に集中
    • 障害報告や再発防止策の振り返りは全員参加

Traffic Optimization by @cubicdaiya

  • API通信に関する話
  • コンテンツ配信ではakamai, fastlyといったCDNを利用
  • モバイルは通信速度遅いのを前提とする。WiFiは前提にしない。
  • アプリのデータ通信量は極力減らし低速でもストレスが貯まらないように作る
  • JSONgzip圧縮
  • レイテンシのほうが圧縮オーバヘッドより圧倒的に高いらしい。
    • コストもネットワークのほうがCPUよりも高くつく

構成

API Gateway --gRPC--> 各種Service --JSON over HTTPS--> Sakura(旧API)
  • nginxはgzipのデフォルト圧縮レベルが低い2(apacheは6)
    • メルカリは6指定
  • マスターデータのJSONのサイズが大きい

    • 基本はgzip
    • zopfliはgzipの最高レベルより圧縮率が高いが処理時間が長すぎ
    • brotliも高圧縮率だが、CPUコストが大きく対応プラットフォームが限られており使っていない
  • アクセス数等は10ヶ月で1.5倍くらいのペースだけど帯域幅は変化なし

    • --> akamai <--> imageFlux(画像変換) <--> s3
    • imageFluxによるリサイズ/WebP化が効果的(半分くらいになるものも)
    • 変換はオンザフライ、リサイズのCPUコストは無視できるレベル
    • iOSはWebP非サポート、Android5+なら使える
  • "ネットワークはCPUより高い"

Expanding World of Data @kazeburo

  • DCが石狩にある(Sakura Internet)
  • GCP東京リージョンとのレスポンスタイムは205ms
  • DatabaseはMySQLを利用中
    • 現在はMySQL5.6~5.7を利用
    • 出品数が10億個超えたのでitemテーブルも10億レコード
    • 400,000 qps
    • outbound 14Gbps
  • 東京DCMySQLのマネージドサービスを提供検討中
    • 3台構成クラスタ(Galera Clusterとか検討中)
    • innodb clusterは来年から(FBが使い始めたら...)
  • データベース運用
    • DBクラスタはサービスごとに分ける。小さいものはCloud SQL
    • ストレージは6.4TB
    • 1U4TBのが出るらしいのでストレージはしばらく耐えられそう?(メモリが高いから辛いとか)
    • RAID0

GitLab Meetup #9 のメモ

GitLab Meetup Tokyo #9: Auto DevOps GA 記念」に参加したのでそのメモ。

発表

「GitLab Auto DevOps & K8S をオンプレ環境に構築してみた」 by @h-kob & @sh-miyoshi

  • オンプレ案件が多くGitLab.com/GKE使えないらしい
  • 素のk8sクラスタ構築は大変らしいので、kubeadmで構築しているらしい。
    • デフォルトでセキュアなクラスタ作れる
    • ただデフォルト権限ではgitlab-runner動かないらしい(pod作成権限が必要)
  • Auto DevOpsはまだRBAC非対応なのでABACで対応
  • Auto Review Appsはブランチごとの動作確認環境を立ててくれる
  • MergeRequestからテスト結果、静的/動的解析結果が参照できる

「GitLab CE で取得する監査ログ」 by @teyanol

  • 監査についての話
  • 監査ログはEE Premium, Ultimateのみ
    • イベントの監査ログであっても、clone等は監査不可能
  • /var/log/gitlab/gitlab-(rails|shell)/にログが出力されている。
    • application.log: login
    • gitlab_access.log:
    • gitlab-shell.log: git command(ssh), zipダウンロード, Web編集
    • production_json.log: git command(http)

「Update of GitLab GCP migration」 by @Guenjun (GitLab Inc.)

  • gitlab.comはgithubに比べると遅い。
  • gitlab.comはGitLab GEOという仕組みでデータのレプリケーションをしている。(レイテンシは30ms程度, DR的な目的)

「GitLab helm chart beta版:AWS/Azure/GCP徹底比較」 by @jvasseur

  • GitLabをhelm chartでGKEにインストールできる
    1. kubectlで接続可能にする
    2. RBAC設定
    3. ストレージ設定
    4. helm/tillerインストール
    5. helm chartリポジトリ設定
    6. helmコマンド
    7. DNSレコード登録
  • AWS, Azure, GCPによる比較。GCPがいい感じだったらしいが動かなくて逆転負け。

「www.gitlab.jp on GitLab Pages」 by @hiroponz

  • Jekyll, Hugo使える
  • Let's Encryptの更新が面倒、issueは上がっているのでそのうち自動化になるかも?
  • http://www.gitlab.jp/ をGitLab Pagesで作成中とか

「GitLab から GitLab に移行したときの思い出」 by @YOMOGItaro & @ysaotome

  • 部内GitLabから全社公式のGitLabへ移行した話
  • Export/Import APIが当時なかったらしく手動で移行したらしい。(今はあるとか)
    • Importはprivateが参照可能なユーザじゃないと失敗するとか
  • Jenkins等他に依存しているものがあると辛い

その他

これまでぎっとらぼとか言ってたけど、ぎっとらぶが正しいのかな?
Yomikataだとぎっとらぼのほうが順位高いな。色々おかしいけど。

gitlab の読み方|YOMIKATA

ログの発表のときにマケプレで入れたGitLabのログを見てみたら、コンテナが細かく分離しているので少しパスが違ってました。

$ kubectl exec -it gitlab-1-unicorn-xxxxxxxxxx-xxxxx /bin/bash

$ cd /var/log/gitlab
git@gitlab-1-unicorn-xxxxxxxxxx-xxxxx:/var/log/gitlab$ cat application.log
# Logfile created on 2018-07-23 15:02:12 +0000 by logger.rb/56815
July 23, 2018 15:02: Failed Login: username=admin ip=x.x.x.x
July 23, 2018 15:03: User Created: username=tshohe email=xxxx@xxx.xxxip=124.34.121.45 confirmed:true
July 23, 2018 15:07: User Logout: username=tshohe ip=x.x.x.x
July 23, 2018 15:07: Failed Login: username=admin ip=x.x.x.x
July 23, 2018 15:08: Successful Login: username=root ip=x.x.x.xmethod=standard admin=true
July 24, 2018 10:14: Administrator created a new project "Administrator / test"

GCP MarketplaceでGitLabをGKEにデプロイ

7/18のアップデートでMarketplaceから様々なコンテナアプリケーションをGKEにもデプロイできるようになったらしいので試してみます。
GKEの画面の左のパネルからMarketplaceを選択することでKubernetesアプリ選択画面を開くことができます。

f:id:tshohe:20180723234459p:plain

デプロイできるアプリケーションのラインナップはこんな感じ。

  • Aerospike Enterprise Edition
    • flash-optimized, in-memory KVS
  • Aqua Security
    • cloud native container platform
  • Cassandra
  • CloudBees Core
    • CI/CD Automation Engine
  • Couchbase Autonomous
    • Couchbase management
  • CyberArk Conjur Open Source
    • Enterprise class secrets management system
  • Datastax
    • Cassandra based database
  • DivvyCloud Enterprise
    • guard rails for cloud infrastructure
  • Elastic GKE Logging
  • Elasticsearch
  • Elastifile
    • k8s volume provider
  • GitLab
  • Grafana
  • InfluxDB
  • Jenkins
  • Kasten K10
    • Data management platform for stateful application on k8s
  • Memcached
  • neo4j
  • nginx
  • Prometheus & Grafana
  • RabbitMQ
  • Seldon Core
  • Spark Operator
  • Wordpress

ぱっと見興味を惹かれたのはKasten, Elastifile, Seldonとかですが、GitLab meetupが明日開催されるということもあり今回はGitLab環境を用意してみます。

f:id:tshohe:20180723231852p:plain

構成を押してクラスタを選択(無ければ作成)し、アプリインスタンス名とベースドメインを入力、デプロイを押下します。

f:id:tshohe:20180723233504p:plain

10分弱くらいでデプロイできました。

f:id:tshohe:20180723235629p:plain

f:id:tshohe:20180723235702p:plain

https://gitlab.[base domain]/ で接続できます。(DNS, TLS certificate設定とかは別途必要です)

f:id:tshohe:20180724000010p:plain

rootユーザのパスワードはkubectlコマンドで取得します。

$ kubectl get secret \
  --namespace default \
  gitlab-1-gitlab-initial-root-password \
  -ojsonpath={.data.password} \
  | base64 --decode

料金調査

Understanding Billing for GCP Marketplace  |  GCP Marketplace  |  Google Cloud

商用ソリューションを購入した場合は、ソフトウェア使用量 + Google Cloud Platformリソース使用量となるみたいです。ソフトウェア使用料は、Google Cloud Platform請求書に個別の広告申込情報として表示されるとのこと。