kikumotoのメモ帳

インフラ・ミドル周りを中心に、興味をもったことを適当な感じで。twitter : @takakiku

当日朝に繰り上がって次世代Webカンファレンスに行ってきた!

なんとか当日朝に繰り上がって、次世代Webカンファレンス

nextwebconf.connpass.com

に行ってきました。 参加したセッションは下記です。

  • server_perf
  • server_arch
  • webrtc
  • https
  • monitoring

各セッション内容の録画やまとめは別途公開されるということですし、まとめ系はいろんな方がしてくれるでしょうからそこは書きません。

ざっくり感想を。

このイベントは全セッション、トークセッションというちょっとあまりないパターンでしたが、登壇さらた方々すごすぎるのもあって、参加した身としては非常に充実した1日を過ごさせていただきました。 Jackさんはじめ、運営・登壇者の皆様ありがとうございました!

Webという題材で各テーマに応じて、今何が起こっているか?」と「これからどうなっていくのか?」について様々な議論・意見を、まさにこの人たちから聞きたいというのを聞くことが、しかもまとめてというのはそうそうあることではないので、というか今までなかったので、とてもよいイベントでした。感謝しかないです。 また、よくある事前打ち合わせありきのものではなく、話したいレベルで話すというスタンスも非常に良かったと思います。

まぁ、スタッフは登壇者以外でボランティアあたりは募っても良かったのかもしれませんね。

また次回があることを期待しつつ、その時にはなにか協力できるくらいになれればと思いながら帰宅しましたぁ。 いやぁ、充実した1日でした。

あらためて、皆様ありがとうございました。

GCPサービスアカウントでgsutilを利用したりAPIアクセスする方法

GCPのリソース、例えばGoogle Cloud Storageにアクセスする際に個人のアカウントを使って gcloud auth login などで認証すればgsutilでアクセスできるけれど、サーバーサイドのアプリケーションなどからアクセスする場合は個人のアカウントで認証したくはないですね。

このような用途のためにGCPにはサービスアカウントというのがあるようです。このサービスアカウントを使ってGCPリソースにアクセスする方法についてメモっておきます。

サービスアカウントの取得

Google Developer Consoleの "APIs & auth" -> "Credentials" -> "Add credentials" から "Service account" を選択します。

そうすると Key type として "JSON" か "P12" を選択できるので、"JSON"を選択して "Create" します。そうすると、json ファイルがダウンロードされます。

過去の情報ではJSONファイルを利用した認証にはバグがあってP12で回避しているものがありますが、今では解消されておりJSONを推奨しているようなので、JSONを利用します。

取得したJSONファイル内にも記載されていますが、コンソールにもEmail addressが表示されるのでこれは後で使います。このEmail addressで認証してアクセスするような感じとなっているようです。

APIアクセスでの使い方

Goであれば、

go-docs-samples/listbuckets.go at master · GoogleCloudPlatform/go-docs-samples · GitHub

にサンプルがあります。これを動かすにはまず以下のように go get します。

$ go get golang.org/x/oauth2/google
$ go get google.golang.org/api/storage/v1

ビルド後、

  • JSONファイルを指定するGOOGLE_APPLICATION_CREDENTIALS 環境変数
  • プロジェクトを指定する TEST_PROJECT_ID 環境変数(これはこのサンプル特有のもの)

を指定して、実行します。以下のような感じです。

$ GOOGLE_APPLICATION_CREDENTIALS=/path/to/myproject-9999-9c82deb7e430.json TEST_PROJECT_ID=myproject-9999 ./listbuckets

これで、Google Cloud Storage のBucketが表示されます。

gcloud(gsutil)での使い方

gcloud(gsutil)の場合、

$ GOOGLE_APPLICATION_CREDENTIALS=/path/to/myproject-9999-9c82deb7e430.json gsutil ls -p myproject-9999

でいけるかと思いきや、これは認証を通りませんでした(jsonファイルを読んでいない感じ)。

なので、以下のようにして key file を使ってサービスアカウントをActivateします。Mail Address部分は上記で出てきたメールアドレスです。JSONファイル内にも記載されています。

$ gcloud auth activate-service-account XXXXXXX-zzzzzzzzzzzzzzzzzzzzzzzzzz@developer.gserviceaccount.com --key-file /path/to/myproject-9999-9c82deb7e430.json --project myproject-9999

これで、gcloud auth list で確認すると

$ gcloud auth list
Credentialed accounts:
 - XXXXXXX-zzzzzzzzzzzzzzzzzzzzzzzzzz@developer.gserviceaccount.com (active)

To set the active account, run:
  $ gcloud config set account ``ACCOUNT''

のようになっています。

この状態で

$ gsutil ls

とすれば、Bucket一覧が表示されます。

参考にした情報

Rundeckで始めるstretcherによるPull型デプロイ

オートスケールとかもろもろの理由からPull型デプロイに変えていきたいと思い、そうすると

github.com

を使いたいなぁとか思うわけです。 でも、Consul やら Serf まで今必要ないよなぁ、ということで Rundeck と組み合わせてみるといい感じになるのではと思いやってみました。

stretcher 作者である id:sfujiwara さんのエントリー YAPC::Asia 2015で発表してきました & ConsulとStretcherについて - 酒日記 はてな支店 にもある通り、stretcher は Consul / Serf なしに使えます。

Rundeck はインストール済みとします。Rundeck については下記リンクあたりをご参照いただくのがよいかと。

上記あたりを参照して、まず適当にProjectを作成しておきます。

ノード

ここでのノード構成は以下のような感じです。各デプロイ先にはRundeckで設定したSSHキーを使ってログインできる状態にしておきます。

  • 10.240.0.2 - Rundeckサーバ
  • 10.240.0.3 - デプロイ先その1
  • 10.240.0.4 - デプロイ先その2
  • 10.240.0.5 - デプロイ先その3

Projectを作成すると /var/rundeck/projects/<プロジェクト名>/etc/resources.xml というファイルができているはずなので、これにデプロイ先のノード情報を登録します。以下のような感じ。

<?xml version="1.0" encoding="UTF-8"?>

<project>
  <node name="localhost" description="Rundeck server node" tags="" hostname="localhost" osArch="amd64" osFamily="unix" osName="Linux" osVersion="3.19.0-28-generic" username="rundeck"/>
  <node name="node1" description="app node 01" tags="" hostname="10.240.0.3" username="appuser"/>
  <node name="node2" description="app node 02" tags="" hostname="10.240.0.4" username="appuser"/>
  <node name="node3" description="app node 03" tags="" hostname="10.240.0.5" username="appuser"/>
</project>

各デプロイ先に、stretcher をインストールしておきます。おおよそ下記手順です。

$ go get github.com/fujiwara/stretcher
$ cd $GOPATH/src/github.com/fujiwara/stretcher
$ make get-deps
$ make
$ make install

なお、ここではmakeしてできたバイナリファイル:stretcherを、/usr/bin にコピーしてあることを前提としています。

Job 登録

実際に Job を作成していきます。

Options

マニフェストファイルを指定できるように Options を使います。

f:id:kikumoto:20150916182731p:plain

"Required" も "Yes" にしておきます。

Workflow

Step を追加します。ここでは inline script を追加います。 以下はスクリプトの内容です。

echo $1 | AWS_CONFIG_FILE=/path/to/aws_credentials /usr/bin/stretcher

また、"Arguments" には、

${option.manifest_url}

を指定しておきます。これにより、上記の Options で入力されたマニフェストURLが使われます。

Nodes

上記で登録したノードで実行されるようにします。下記のような感じです。

f:id:kikumoto:20150916183827p:plain

Thread Count

ここで1より大きい値を設定すれば、Rundeckは複数のノードに対して並行で処理を実行してくれます。

ただ、台数が数十台とかそれなりの台数になるなら Consul とかの別な方法で stretcher をキックする方が良さそうな気はします。

If a node fails

これ重要な設定です。これを下記のようにしておかないと、どこかのノードでデプロイが失敗すると、残りのノードで処理が実行されません。

f:id:kikumoto:20150916184520p:plain

あとは、好みで設定して Job を登録します。

Job 実行

Rundeckを使って stretcher をキックしていればその成否もわかるので、consul-kv-dashboardとかも不要で Rundeckに情報が集約されるのもよいです。

成功例

Job を実行して成功すると、以下のような結果を見ることができます。 f:id:kikumoto:20150916184906p:plain

"Log Output" に切り替えれば、stretcherの出力も見れます。

失敗例

デプロイに失敗しているホストも、下記のような感じで一目でわかります。 f:id:kikumoto:20150916185110p:plain

実行中

並列に実行されている様子も下記のようにわかります。(以下は、"Thread Count" を "2" にしています) f:id:kikumoto:20150916185421p:plain

と、こんな感じで結構気軽に stretcher の導入ができるので Rundeck との組み合わせはオススメですね。

これに先立ち個人的に IAM Role を割り当てたEC2インスタンスで stretcher を動かしたかったので、その Pull Request を出してマージしてもらいました。id:sfujiwara さん Thanks!

みなさんも stretcher 使って、Pull型デプロイしましょう。

h2oのsystemd unitファイル

h2oのsystemd unitファイルってみなさんどんな感じなんでしょう?

https://github.com/h2o/h2o/issues/84 をみつつ、& でバックグラウンドってのもどうなの?って気がしたので、自分は以下のように書いてます。

[Unit]
Description=h2o optimized HTTP server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
WorkingDirectory=/etc/h2o
PIDFile=/var/run/h2o.pid
ExecStart=/usr/local/bin/h2o -m master -c /etc/h2o/conf/h2o.conf
ExecReload=/bin/kill -HUP $MAINPID
PrivateDevices=yes
PrivateTmp=true
LimitNOFILE=infinity

[Install]
WantedBy=multi-user.target

-m masterはforegroundで動作するから、Type=simpleでOKですよね。 Type=simpleだからPIDFile別にいらないかぁと思いつつ書いてます。

HashiCorp Vault + LDAP で MySQL のアカウント管理

ようやくはてなブログに移りました。 ということでその最初の記事を書く。

LinuxのアカウントはLDAP(やらIPA Server)とか使えば統合管理できるのだけど、MySQLのアカウント管理を一箇所で統合的に管理しようと思うと、その権限なども含めるとなんかよいソリューションがないように思える。 イヤ、こういうのあるよってあれば教えてください。

そこで、HashiCorpのVaultとLDAPを組み合わせると、ちょっとそれらしくMySQLのアカウント管理できるのではないかと思ってそれを試してみた。

Vault 起動

今回は、おおよそこういうことができる、ということを確認することが目的なので、Vault自体の可用性とかまで考えない。

dev モードで起動する。

$ vault server -dev

表示される root Token を使って、root として Vault にログインする。以下のような感じ。

$ vault auth 4a1eea82-facd-c7d3-e9c7-c0bb4b04e81f

MySQL Secret Backend の設定

Vaultには機密情報(Secret)を保持したり生成したりするコンポーネントである Secret Backends というのがあり、そのうちの1つに MySQL のアカウントを生成しその権限も設定してくれる MySQL Secret Backend というのがある。

今回の目的のためにこの MySQL Secret Backend を利用する。

複数のデータベースを想定して(ここでは1つしか設定しないが)、db1 というパスにマウントする。

$ vault mount -path=db1 mysql
Successfully mounted 'mysql' at 'db1'!

db1に対応するデータベースへの接続情報を登録する。GRANT OPTION権限をもつユーザを登録する必要がある。

$ vault write db1/config/connection value="admin:adminpass@tcp(db1.example.com:3306)/" 
Success! Data written to: db1/config/connection

このMySQL Secret Backedが払い出してくれるアカウントとパスワードの有効期限を設定する。

$ vault write db1/config/lease lease=10m lease_max=1h
Success! Data written to: db1/config/lease

Roleを登録。以下では、"readonly" という Role を登録している。権限は任意のDBに対するSELECT だけ。

$ vault write db1/roles/readonly sql="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" 
Success! Data written to: db1/roles/readonly

強い権限をもつアカウントが必要であれば、さらに別の Role を作ればよい。

LDAP Auth Backendの設定

認証し、ユーザにVaultのポリシーを割り当てる Auth Backends というのがある。そのうちの1つにLDAPを使って認証し、LDAPのグループとポリシーを対応づけてくれる LDAP Auth Backend というのがある。

自分の環境では IPA Server が稼働しており、こことつなぐためにこの LDAP Auth Backends を使う。

下記のコマンドで有効にする。

$ vault auth-enable ldap
Successfully enabled 'ldap' at 'ldap'!

IPA Server(LDAP)への接続情報を登録。

$ vault write auth/ldap/config url="ldap://ipa.example.com" \
         userattr=uid \
         userdn="cn=users,cn=accounts,dc=example,dc=com" \
         groupdn="dc=example,dc=com" \
         upndomain="EXAPMPLE.COM" \
         insecure_tls=true \
         starttls=true
Success! Data written to: auth/ldap/config

ポリシー

db1 に Role "readonly" としてアクセスする情報を読むことができる Policy を作成。 readonly.hcl として下記内容のファイルを用意。

path "db1/creds/readonly" {
    policy = "read" 
}

このポリシーをポリシー名 "readonly" として登録。

$ vault policy-write readonly readonly.hcl
Policy 'readonly' written.

IPA Server(LDAP)のグループ: "readers" に "readonly" ポリシーを割り当てる。

$ vault write auth/ldap/groups/readers policies=readonly
Success! Data written to: auth/ldap/groups/readers

動作確認

以上の設定により、IPA Serverのグループ:"readers"に所属するユーザで、Vault にログインすると、db1/creds/readonly を読むことができ、その結果 SELECT のみが許可されるユーザ・パスワードが払い出される。

Vault にログインする。

$ vault auth -method=ldap username=kikumoto
Password (will be hidden): <IPA Serverのユーザ kikumoto に対するパスワード>
Successfully authenticated! The policies that are associated
with this token are listed below:

readonly, readonly

このように、readonly というポリシーが関連づけれらたことがわかる。

引き続き、DBアクセス情報の取得。

$ vault read db1/creds/readonly
Key                Value
lease_id           db1/creds/readonly/3bc89d58-fe04-8e2e-0ab4-419cacc618eb
lease_duration     600
lease_renewable    true
password           8c0f7f32-1739-1911-41e5-c9565af7289a
username           ldap-kikum-c8129

この username / password を用いて db1.example.comMySQL にアクセスできる。

$ mysql -u ldap-kikum-c8129 -h db1.example.com -p
Enter password:

> create database mydb;
ERROR 1044 (42000): Access denied for user 'ldap-kikum-c8129'@'%' to database 'mydb'

という感じで、CREATE はできない。

そして10分ほど経過すると、Vault のログに下記のような表示されて、アクセス情報が廃止されたことがわかる。

2015/09/06 21:22:53 [INFO] expire: revoked 'db1/creds/readonly/3bc89d58-fe04-8e2e-0ab4-419cacc618eb'

そして、MySQL にはアクセスできなくなる。

$ mysql -u ldap-kikum-c8129 -h db1.example.com -p
Enter password:
ERROR 1045 (28000): Access denied for user 'ldap-kikum-c8129'@'localhost' (using password: YES)

課題

ポリシーに正規表現が使えないので、対象DBノード数が増えると、その分だけポリシーファイル内のエントリーが増える。 これは Consul Template で解決できればまだ助かるかなぁ。でも、正規表現欲しい。

Vaultがダウンしていたりとかすると DB にゴミユーザが残る気もするので、このあたりどこまで面倒見てくれるのかもう少し確認が必要そう。それでもゴミが残るケースはあると思うので、適宜ゴミ掃除をする仕組みがいるかも。

まとめ

Vault + LDAP を使うと MySQL のアカウント・権限を一元管理的なことができそうなことを試した。

そこそこいけそうな感じではあるが、まだまだ確認しなければいけないことはある。

あとは、Vaultについて詳しいかたと話してみたい。

また、進展があればエントリーを書こうと思う。

いじょう -

[YAPC] YAPC::Asia 2014 感想エントリ

最近、全く、Qiitaにも何も書いてなくて、ほんとに久しぶりの記事作成です。誰にというわけでなく、ごめんなさい。。。

ということで、YAPC::Asia 2014 に参加してきました。今年も個人スポンサーで参加させてもらいました。
パーカー、とても良いですね!8月だというのに、気温が高くないせいで、パーカーが早速役立つとは思いませんでした。それに、これがあればデータセンター作業も安心ですね(嘘、今は行くことはない。。。)。

主に、インフラ関係のトークを聞いてきましたが、今年は本当にどのトークも人が一杯で、自分のようについにアラフィフとなった体には椅子にすわれないのは苦行になってしまいます。
もっと広いところ、どなたか貸してくれませんかねー。

懇親会とか休憩時間などに、前にしばらくだけ在籍した会社の方々と話すことができたので非常によかったです。@takhito さん、 @kenjiskywalker さんに感謝です。個人的には @songmu さんが覚えていてくれたのはとても嬉しかった。
単にトークを聞くだけでなく、こういう機会も得られる YAPC はやはりサイコーですね。

ところで、なぜ今更、というツッコミがありそうなのですが、Perl入学式 in YAPC::Asia に参加しました。
知識の整理と、人間関係の拡大のために、参加させていただきましたが、大変良かったです。@xtetsuji さん、@hoto17296 さんお世話になりました。
次回も参加予定です(体が元気なら、、、)。

以上、まとまりのないエントリーを終わりにします。
ただ、来年も是非参加しようと思います。それまでまた日々精進します。

最後に、スピードの皆様、スタッフの皆様、大変ご苦労様でした。ありがとうございました。

[nginx][mpeg-dash] 第1回 html5j TV部 勉強会LT枠で参加して玉砕してきた

ブログに書くまで勉強会、という古き良きルールのもと、
第1回 html5j TV部 勉強会 に参加してきた、記事です。

今回は、一般枠が埋まってしまったのでLT枠で参加してきました。
通常セッションの方は、Azureやるなー、普及率なめんな、という感じで非常に勉強となりました。
LTの方も他の人のセッションは、勉強会らしくその場で問題解決もあるなどすばらしかったです。

詳しくは以下あたりを見るのがよいんじゃないかと思います。

で、自分の資料は、以下です。


動画にしっかり記録されてしまっていますが、デモが動かず玉砕してきました。
LT前の動作確認では動いていて、(自宅遠いので先に帰ったのですが)帰宅後再確認すると問題なく動くという、まさにデモでよくありがちなパターンを踏んでしまったという流れでした。

機会があるなら是非リベンジLTをしたいですね。

ということで、今後ともお邪魔させていただきたい勉強会の1つになりました。
よろしくお願いします。

      • -