2017年3月31日金曜日

golang 製のベンチマークツール boom 改め hey を使ってみた

概要

golang で Web アプリケーションをベンチマークするのに boom というツールがありました
これが hey という名前に変わって作り直されていたので試してみました

環境

  • CentOS 7.3.1611
  • golang 1.8
  • hey

go の最新版と hey のインストール

GOPATH=/root/go
PATH=$PATH:$GOPATH/bin
  • go get -u github.com/rakyll/hey

httpd の起動

  • yum -y install httpd
  • service httpd start

hey の実行

とりあえず試す

結果は以下の通り

44 requests done.
52 requests done.
68 requests done.
100 requests done.
164 requests done.
All requests done.

Summary:
  Total:        5.0214 secs
  Slowest:      5.0181 secs
  Fastest:      0.0002 secs
  Average:      0.7435 secs
  Requests/sec: 39.8296
  Total data:   979400 bytes
  Size/request: 4897 bytes

Status code distribution:
  [403] 200 responses

Response time histogram:
  0.000 [1]     |
  0.502 [160]   |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
  1.004 [0]     |
  1.506 [2]     |∎
  2.007 [0]     |
  2.509 [4]     |∎
  3.011 [0]     |
  3.513 [8]     |∎∎
  4.015 [0]     |
  4.516 [16]    |∎∎∎∎
  5.018 [9]     |∎∎

Latency distribution:
  10% in 0.0003 secs
  25% in 0.0005 secs
  50% in 0.0012 secs
  75% in 0.0046 secs
  90% in 4.1796 secs
  95% in 4.1853 secs
  99% in 5.0095 secs

-n でリクエスト数を調整できます
デフォルトは 200 です
オプションでリクエストのボディやヘッダ、ベーシック認証などを設定することもできます
また http2 にアクセスするオプションもあります

最後に

hey を試してみました
シンプルで使いやすかったです

特徴としては http2 が試せる点でしょうか

参考サイト

2017年3月30日木曜日

VMware harbor を ova からインストールしてみた

概要

前回 harbor を CentOS 上で動作させました
今回は ova ファイルから harbor を構築し使ってみたいと思います

環境

  • Ubuntu 16.04 (docker client)
  • harbor 0.5.0 (ova)
  • docker 17.03
  • docker-compose 1.8.0

ova ファイルのダウンロードとデプロイ

まずは ova ファイルをダウンロードします
https://github.com/vmware/harbor/releases/download/0.5.0/harbor_0.5.0-9e4c90e.ova

ダウンロードしたら vSphere Client を開いてデプロイしていきます

最後に harbor の設定を行う項目があるので設定します
パスワード (root, admin-ui, mysql) を 3 つ設定します
あとプロトコルを https -> http に変更します
ドメインや証明書が用意できれば https でも問題ないです
vmware-harbor-ova-deploy1.png

設定しデプロイが完了したらパワーオンしましょう
起動までにやや時間がかかりました (10, 20 分程度)
IP が取得できれば OK です

とりあえず取得できた IP にブラウザでアクセスすれば harbor の管理画面を確認できると思います
ユーザ名は admin でパスワードは ova デプロイ時に設定したものになります

docker client の設定

前回の CentOS7 のときも行いましたが Ubuntu 上で動作している dockerd に --insecure-registry オプションを追加する必要があります

  • mkdir -p /etc/systemd/system/docker.service.d/
  • vim /etc/systemd/system/docker.service.d/docker.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 192.168.100.102

192.168.100.102 は harbor が取得した IP を設定してください
あとはプロセスを再起動します

  • systemctl daemon-reload
  • systemctl restart docker

動作確認

harbor にログインしてイメージを push するところまで試します

  • docker login 192.168.100.102
Username: admin
Password:
Login Succeeded
  • docker pull alpine
  • docker tag alpine 192.168.100.102/library/alpine
  • docker push 192.168.100.102/library/alpine

で harbor に push できると思います
UI で library プロジェクト配下を確認すると alpine イメージがあるのを確認できると思います

Tips

結構はまったポイントがあったので紹介します

まず https のまま harbor をデプロイし証明書もドメインも何も設定しないと以下のエラーとなりログインできません

Error response from daemon: Head https://192.168.100.102/v2/: x509: certificate signed by unknown authority

そして https -> http 変更後、dockerd のオプションを変更しないでログインしようとしても以下のエラーとなります

Error response from daemon: Head https://192.168.100.102/v2/: dial tcp 192.168.100.102:443: getsockopt: connection refused

--insecure-registry オプションを追加を追加すると問題なくアクセスできます
あと当然ですが、可能であればドメインを張って SSL 証明書を harbor に登録したほうがセキュリティ的に良いです

VCH から harbor を使ってみた

ついでに Ubuntu からではなく VCH から harbor が使えるかも試してみました
VCH を作成する際のオプションに dockerd 同様 --insecure-registry オプションがあるのでそれを使って harbor の IP を指定して VCH を作成します

そして作成後にイメージをタグ付けして push してみようと思ったのですが、

Error response from daemon: vSphere Integrated Containers does not yet implement image.PushImage

になりました
どうやら VCH から push はできないようであくまでも harbor からの pull のみが出来るようです
試しに先程 pull イメージを VCH から pull してみたらそれはできました
(192.168.100.110 は VCH の IP)

  • docker -H 192.168.100.110:2375 pull 192.168.100.102/library/alpine

最後に

ova テンプレートから harbor をデプロイし Ubuntu 上の docker client から試してみました
いろいろと問題はありましたが、適切な設定をすれば問題なく使うことができました

前回の CentOS と比べるとデプロイの方法に関してはどちらも簡単なのでそれほど変わらないと思います
運用面的にも、デプロイ時に SSH を有効にするオプションがありそれを有効にすることで SSH ログインすることができます
ova 版でも SSH ができるので、それほど CentOS と変わるということはないかなと思います

ova の場合 harbor が動作している OS は PhotonOS になります
Photon OS 上にログインするとわかりますが、実は内部では CentOS 時同様 docker が動作しており harbor がコンテナで動作していることがわかると思います
これも CentOS の時と同じ仕組みになっています

ただ、ova の場合は vSphere 環境でしか使えません
CentOS は普通に VPS やクラウド上で動作させることができます
その辺の環境の違いに応じて適切なインストール方法を選択する感じかなと思います

2017年3月29日水曜日

VMware 製の docker レジストリ「harbor」を使ってみた

概要

harboar は VMware がオープンソースで開発している docker レジストリです
今回は CentOS 上にインストールし簡単な push まで行ってみました

環境

  • CentOS 7.3.1611
  • harbor 0.5.0
  • docker 17.03
  • docker-compose 1.9.0

事前準備

docker と docker-compose は事前にインストールしておいてください

harbor のインストール

hostname = 192.168.100.101

この IP は作業している CentOS マシンの IP を入力してください
localhost と 127.0.0.1 のローカル用のホスト名、IP では動作しないので注意してください
他にも email や ladp, https などの設定ができるので必要であれば設定してください

  • ./install.sh

でインストールします
一応全ログを記載しておきます

[Step 0]: checking installation environment ...

Note: docker version: 17.03.0

Note: docker-compose version: 1.9.0


[Step 1]: preparing environment ...
generated and saved secret key
Generated configuration file: ./common/config/nginx/nginx.conf
Generated configuration file: ./common/config/ui/env
Generated configuration file: ./common/config/ui/app.conf
Generated configuration file: ./common/config/registry/config.yml
Generated configuration file: ./common/config/db/env
Generated configuration file: ./common/config/jobservice/env
Generated configuration file: ./common/config/jobservice/app.conf
Generated configuration file: ./common/config/ui/private_key.pem
Generated configuration file: ./common/config/registry/root.crt
The configuration files are ready, please use docker-compose to start the service.


[Step 2]: checking existing instance of Harbor ...


[Step 3]: starting Harbor ...
Creating network "harbor_default" with the default driver
Pulling log (vmware/harbor-log:0.5.0)...
0.5.0: Pulling from vmware/harbor-log
93b3dcee11d6: Pull complete
5c14e4bdfb0b: Pull complete
e4dee8a574ca: Pull complete
64897311fadc: Pull complete
9b18f82d0181: Pull complete
Digest: sha256:81db268fa32ed35274f88f0e9f6e8c8fe36fdfe3247a7c75cef3d526814755ad
Status: Downloaded newer image for vmware/harbor-log:0.5.0
Pulling ui (vmware/harbor-ui:0.5.0)...
0.5.0: Pulling from vmware/harbor-ui
93b3dcee11d6: Already exists
a91de92f52f5: Pull complete
341612b46e3b: Pull complete
c1a53f812656: Pull complete
9a9aa413559a: Pull complete
e1b377650dfc: Pull complete
be5517028022: Pull complete
726f4e0b4799: Pull complete
08639f4ec97a: Pull complete
Digest: sha256:677776af19c774f665565486ef0ec3ab37e55c6738a471942e3ea841b3e1821c
Status: Downloaded newer image for vmware/harbor-ui:0.5.0
Pulling mysql (vmware/harbor-db:0.5.0)...
0.5.0: Pulling from vmware/harbor-db
43c265008fae: Pull complete
d7abd54d3b34: Pull complete
92b527830a1b: Pull complete
44839710d611: Pull complete
3828a16bed5c: Pull complete
fb91763f6b4e: Pull complete
892bfb27c685: Pull complete
02874ec7a2dc: Pull complete
861c1296cc0d: Pull complete
d611998d5598: Pull complete
09037dc5a941: Pull complete
448973dd2180: Pull complete
c0a51ede01de: Pull complete
54c4b53ba168: Pull complete
Digest: sha256:4bc45566b8aab9288e76ac8a36e604aecf05ba9b25e22f5a9cd5e9686978b78b
Status: Downloaded newer image for vmware/harbor-db:0.5.0
Pulling jobservice (vmware/harbor-jobservice:0.5.0)...
0.5.0: Pulling from vmware/harbor-jobservice
93b3dcee11d6: Already exists
a91de92f52f5: Already exists
cdeb4de41efe: Pull complete
ce3594a70659: Pull complete
Digest: sha256:9c2d927f6e59fafcc930a5f738d713bde7d101cecd4e110a570a7b499d69ff68
Status: Downloaded newer image for vmware/harbor-jobservice:0.5.0
Pulling registry (library/registry:2.5.0)...
2.5.0: Pulling from library/registry
e110a4a17941: Pull complete
2ee5ed28ffa7: Pull complete
d1562c23a8aa: Pull complete
06ba8e23299f: Pull complete
802d2a9c64e8: Pull complete
Digest: sha256:1b68f0d54837c356e353efb04472bc0c9a60ae1c8178c9ce076b01d2930bcc5d
Status: Downloaded newer image for registry:2.5.0
Pulling proxy (nginx:1.11.5)...
1.11.5: Pulling from library/nginx
386a066cd84a: Pull complete
7bdb4b002d7f: Pull complete
49b006ddea70: Pull complete
Digest: sha256:9038d5645fa5fcca445d12e1b8979c87f46ca42cfb17beb1e5e093785991a639
Status: Downloaded newer image for nginx:1.11.5
Creating harbor-log
Creating harbor-db
Creating registry
Creating harbor-ui
Creating nginx
Creating harbor-jobservice

✔ ----Harbor has been installed and started successfully.----

Now you should be able to visit the admin portal at http://192.168.100.101.
For more details, please visit https://github.com/vmware/harbor .

見て分かる通り harbor はコンテナで動作します
解凍したフォルダ内に docker-compose.yml ファイルも存在しています

完了したら harbor 用のコンテナを確認してみましょう

  • docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                                      NAMES
405c46a5cf48        vmware/harbor-jobservice:0.5.0   "/harbor/harbor_jo..."   13 minutes ago      Up 13 minutes                                                  harbor-jobservice
c1e65c00f50d        nginx:1.11.5                     "nginx -g 'daemon ..."   13 minutes ago      Up 13 minutes       0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   nginx
c62583b09c91        vmware/harbor-ui:0.5.0           "/harbor/harbor_ui"      13 minutes ago      Up 13 minutes                                                  harbor-ui
8e5a36f0268d        library/registry:2.5.0           "/entrypoint.sh se..."   13 minutes ago      Up 13 minutes       5000/tcp                                   registry
667a6045716a        vmware/harbor-db:0.5.0           "docker-entrypoint..."   13 minutes ago      Up 13 minutes       3306/tcp                                   harbor-db
24e21ba0af2c        vmware/harbor-log:0.5.0          "/bin/sh -c 'crond..."   13 minutes ago      Up 13 minutes       0.0.0.0:1514->514/tcp                      harbor-log

こんな感じで起動していれば OK です

試してみる、その前に

dockerd のオプションに --insecure-registry というオプションがあります
これに今回構築した harbor の IP を追加する必要があります
そうしないと Error response from daemon: Get https://192.168.100.101/v1/users/: dial tcp 192.168.100.101:443: getsockopt: connection refused と言われて怒られます

  • vim /etc/systemd/system/docker.service.d/docker.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --insecure-registry 192.168.100.101
  • systemctl daemon-reload
  • systemctl restart docker

で registry が http でも試すことができます

試してみる

  • docker login 192.168.100.101
Username: admin
Password: Harbar12345
Login Succeeded

でログインできます
パスワードはデフォルトです
この設定は harbor.cfg で変更することができます
では実際に registry にイメージを登録してみます

  • docker pull alpine
  • docker tag alpine 192.168.100.101/library/alpine
  • docker push 192.168.100.101/library/alpine

でイメージを登録することができます
harbor にはデフォルトで library というプロジェクトが用意されているのでそれを使っています
それ以外のプロジェクト名をデフォルトで指定すると push できません

UI で確認してみる

harbor にはデフォルトで UI がついています
ブラウザで http://192.168.100.101 にアクセスしてみましょう
ユーザ名とパスワードは先程のデフォルトのものになります

するとプロジェクト「library」があることが確認できると思います
選択すると先程 push した alpine のイメージがあると思います
first_vmware_harbor1.png

別のプロジェクトに対して push したい場合はここでプロジェクトを作成後 push してください

最後に

VMware の harbor を試してみました
実は内部的には dockerhub で公開されている docker 純正の registry を使っています
それに UI やログ置き場、ジョブワーカー、ユーザ管理、メール送信などの機能がデフォルトで用意されている感じになります

今回は簡単に試しただけなので、いろいろと触ったら Tips 的なのも別途紹介したいと思います

参考サイト

2017年3月28日火曜日

docker レジストリを使ってみた

概要

docker レジストリを使ってみました
コンテナ版があるのでそれを使っています

環境

  • Mac OS X 10.12.3
  • docker registry 2.6.0
  • docker 17.03

registry インストール

  • docker pull registry
  • mkdir -p /path/to/registry
  • cd /path/to/registry
  • docker run -d -p 5000:5000 -v $(pwd):/var/lib/registry registry

で完了です
localhost の 5000 番で動作させます

イメージを push してみる

構築したレジストリ上にイメージを push してみます

  • docker pull alpine
  • docker tag alpine localhost:5000/hawksnowlog/alpine
  • docker push localhost:5000/hawksnowlog/alpine

tag を付与するフォーマットは「ホスト名/リポジトリ名/イメージ名」になります
イメージが小さいのもありますが、ローカルホストなので速度も速いです

今回の場合 Mac マシンのカレントディレクトリをコンテナのデータボリュームとして使っています
上記のタグの付け方だと

  • ls docker/registry/v2/repositories/hawksnowlog/alpine/

という感じでイメージ情報を確認することができます

イメージを pull してみる

push したイメージを使ってみます

  • docker rmi localhost:5000/hawksnowlog/alpine
  • docker pull localhost:5000/hawksnowlog/alpine

問題なく pull できると思います

UI を使ってみる

  • docker pull konradkleine/docker-registry-frontend:v2
  • docker run -d -e ENV_DOCKER_REGISTRY_HOST=192.168.100.101 -e ENV_DOCKER_REGISTRY_PORT=5000 -p 8080:80 konradkleine/docker-registry-frontend:v2

192.168.100.101 は docker が動作しているホストの IP です
今回であれば Mac マシンの IP になります

でブラウザで localhost の 8080 にアクセスしてみましょう
管理画面が確認出来ると思います
基本はビューワーなので、画面からイメージを push, pull したりすることはできません

最後に

コンテナバージョンの docker レジストリを使ってみました
個人で使う場合にはレジストリも同じマシンで良いですが、サービスなどで使う場合は専用のマシンと専用のストレージがあったほうが良いかと思います

よくあるのは s3 などと組み合わせるとレジストリのストレージ容量を管理しなくて済むので良いかと思います

2017年3月27日月曜日

progressbar.js の circle を試してみた

概要

progressbar.js を試してみました
いろいろな形でプログレスバーを作成できるライブラリです
今回はサークルのプログレスバーを試してみました
HTML + JavaScript ファイルを作成して nginx の DocumentRoot に対してしてサクッと Chrome で確認します

環境

  • Mac OS X 10.12.3
  • Chrome 56.0.2924.87 (64-bit)
  • progressbar.js 1.0.1

workspace 準備

  • nginx
  • cd /usr/local/var/www/
  • mkdir p
  • cd p

で作業します
nginx を想定しています

ライブラリインストール

index.html の作成

  • vim index.html
<html>
<head>
  <link href="https://fonts.googleapis.com/css?family=Raleway:400,300,600,800,900" rel="stylesheet" type="text/css">
  <link href="./myprogress.css" rel="stylesheet" type="text/css">
  <script type="text/javascript" src="./progressbar.min.js"></script>
</head>
<body>
  <div id="container"></div>
  <script type="text/javascript" src="./myprogress.js"></script>
</body>
</html>

container の div タグにプログレスバーを描画します
ダウンロードした progressbar.min.js のインクルードの他に自作の css と js とフォント用の CSS もインクルードしています

myprogress.js の作成

  • vim myprogress.js
var bar = new ProgressBar.Circle(container, {
  color: '#aaa',
  strokeWidth: 4,
  trailWidth: 1,
  easing: 'easeInOut',
  duration: 1400,
  from: { color: '#aaa', width: 1 },
  to: { color: '#848484', width: 4 },
  // Set default step function for all animate calls
  step: function(state, circle) {
    circle.path.setAttribute('stroke', state.color);
    circle.path.setAttribute('stroke-width', state.width);

    var value = Math.round(circle.value() * 10);
    if (value === 10) {
      circle.setText('<font size="5px">Max</font><br><div align="center">' + value + '</div>');
    } else {
      circle.setText('<font size="5px">Containers</font><br><div align="center">' + value + '</div>');
    }

  }
});
bar.text.style.fontFamily = '"Raleway", Helvetica, sans-serif';
bar.text.style.fontSize = '2rem';

bar.animate(1.0);  // Number from 0.0 to 1.0

描画のメイン処理になります
今回の記事のポイント部分になります

描画する id タグ container を指定して ProgressBar.Circle でオブジェクトを作成しています
その引数としていろいろな値を与えることでデザインがアニメーション速度などを変更することができます

最後の bar.animate でどこまで描画するか割合を指定します
1.0 なら最後まで描画します

myprogress.css の作成

  • vim myprogress.css
#container {
  margin: 20px;
  width: 200px;
  height: 200px;
  position: relative;
}

動作確認

あとはブラウザで http://localhost:8080/p/ にアクセスするとプログレスバーのデモが確認できると思います
try_progressbar_js.png

最後に

progressbar.js を試してみました
アニメーションやデザインが今風でキレイなところが気に入りました

円グラフではないので、凡例などで 2 色分表示とかはできないみたいです

参考サイト

2017年3月26日日曜日

Ubuntu 16.04 で hugo を試してみた

概要

Ubuntu で hugo をインストールしてクリックスタートを試してみました

環境

  • Ubuntu 16.04
  • hugo 0.19

インストール

  • sudo apt install hugo

だと 0.16 になってしまうので deb パッケージからインストール

スキャホールドする

  • hugo new site bookshelf

で一式作成してくれます

記事作成

  • cd bookshelf
  • hugo new post/good-to-great.md
  • vim content/post/good-to-great.md

で markdown 本文を記載できます

テーマを当てる

hugo はデフォルトでテーマが何もないので記事を作成してもテーマを当てないと何も表示されません

http://localhost:1313 にアクセスすると画面が表示されます

テーマを変える

でテーマを変えることができます
自分の場合このテーマだと起動した時にエラーが表示されました
おそらく Params が config.toml に記載されていないためエラーが出ているんだと思います
表示はされるので気にしなくても OK です

設定ファイルを編集する

設定ファイルを変更することでサイトのタイトルなどを変更することができます

  • vim config.toml
baseURL = "http://localhost/"
languageCode = "en-us"
title = "hawksnowlog Book Reviews"

[Params]
  Author = "hawksnowlog"
  • hugo server --baseURL=localhost --bind=0.0.0.0 --theme=hugo_theme_robust --buildDrafts

でサイトのタイトルなどが変わると思います

画像をオーバライトする

テーマで使われている画像を別の画像でオーバライトします
テーマのファイルを自体をいじるわけではなく適切なパスに配置することでオーバライトできます

画像が変わらない場合はブラウザキャッシュしている可能性があるのでキャッシュを削除するかプライベートブラウズで確認してください
Chrome の場合は Ctrl + Shift + R で強制リロードすれば OK です

レイアウトファイルをオーバライトする

画像だけでなくレイアウトファイルもオーバライトできます

  • mkdir -p layouts/_default
  • cp ./themes/hugo_theme_robust/layouts/_default/li.html layouts/_default
  • vim layouts/_default/li.html

で適当に html ファイルを編集するとデザインを変更することができます
基本的にはテーマに含まれているファイルを適切なパスにコピーしてそれを編集する方針で OK です
フッターを変える場合は以下の通り

  • mkdir -p layouts/partials
  • cp ./themes/hugo_theme_robust/layouts/partials/default_foot.html layouts/partials
  • vim layouts/partials/default_foot.html

記事をカスタマイズする

画像を差し替えてみます

+++
date = "2016-02-14T16:11:58+05:30"
draft = true
title = "Good to Great Book Review"
image = "book1.jpg"
+++

追記するのは先頭の toml フォーマットの部分になります
で画像のサムネイル部分を変更できます

ビルドして静的ファイルを作成する

例えば nginx でホスティングしたい場合に使えます

  • hugo --theme=hugo_theme_robust --buildDrafts

で public/ というディレクトリ配下に静的ファイルができあがります
これを例えば

  • cp -ipr public /var/www/html/

とかすれば nginx でホスティングすることができます
ビルド時に --baseURL を指定していないので config.toml で baseURL の設定を行っておいてください
基本はホスティングするサイトの IP を指定しておけばいいと思います
サブディレクトリ使う場合は、そのパスも入力しましょう

Tips

hugo undraft というコマンドがありそれで記事をドラフトからプロダクションにすることで --buildDrafts がなくても表示の対象にすることができる

最後に

hugo を Ubuntu で試してみました
基本的にクイックスタートをやっただけですが、hugo の最新版ないと動かないテーマもありました

あとはクイックスタートのページに github pages で公開する方法も載っていましたが公開する予定はなかったのでスルーしました
git で管理する場合は public と themes ディレクトリは .gitignore に記載したほうが良いと思います

参考サイト

2017年3月25日土曜日

AWS の Storage Gateway のデータボリューム (iSCSI) を VM でマウントしてみた

概要

前回 Storage Gateway のボリュームゲートウェイで iSCSI インタフェースを作成しました
前回は ESXi でマウントしたのですが、今回は VM (Ubuntu) でマウントしてみたいと思います
iSCSI インタフェースを持った Storage Gateway は前回の記事を参考に事前に作成しておいてください

環境

  • VMware vCenter Server 6.0.0u2
  • VMware ESXi 6.0.0 3620759
  • AWS Storage Gateway (20170322 時点)
  • AWS Storage Gateway Appliance
  • Ubuntu 16.04

iSCSI イニシエータのインストール

  • apt -y install open-iscsi

iSCSI イニシエータの設定

  • vim /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1997-05.com.amazon:volume1

InitiatorName は Storage Gateway のコンソールにログインし「ボリューム」の一覧の「ターゲット名」で確認してください

  • systemctl restart iscsid open-iscsi

iSCSI デバイスの認識

  • iscsiadm -m discovery -t sendtargets -p xxx.xxx.xxx.xxx

IP アドレスは Storage Gateway のコンソールにログインし「ボリューム」の一覧の「ホスト IP」で確認できる

  • iscsiadm -m node -o show
  • iscsiadm -m node --login
Logging in to [iface: default, target: iqn.1997-05.com.amazon:volume1, portal: xxx.xxx.xxx.xxx,3260] (multiple)
Login to [iface: default, target: iqn.1997-05.com.amazon:volume1, portal: xxx.xxx.xxx.xxx,3260] successful.
  • iscsiadm -m session -o show
tcp: [1] xxx.xxx.xxx.xxx:3260,1 iqn.1997-05.com.amazon:volume1 (non-flash)
  • fdisk -l
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: B1599688-376B-4FFB-AFF4-732C1A7258B8

iSCSI デバイスのフォーマット

  • parted --script /dev/sdb "mklabel msdos"
  • parted --script /dev/sdb "mkpart primary 0% 100%"
  • mkfs.ext4 /dev/sdb1
mke2fs 1.42.13 (17-May-2015)
/dev/sdb1 contains a VMFS_volume_member file system
Proceed anyway? (y,n) y
Creating filesystem with 5242624 4k blocks and 1310720 inodes
Filesystem UUID: 94b8fed5-af73-4c27-b882-0fe26671a1b9
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

iSCSI デバイスのマウントと利用

  • mkdir -p /mnt
  • mount /dev/sdb1 /mnt
  • df -h /dev/sdb1
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1        20G   44M   19G   1% /mnt

これで普通のディスクとして使えるはずです
もちろん s3 側にもボリュームのスナップショットが作成され Storage Gateway 経由でリストアなどできるようになります

最後に

Storage Gateway の iSCSI インタフェースを Ubuntu にマウントしてみました
前回は ESXi 上のデータストアとして認識させた上で VM のディスクに割り当てていたのですが、うまく動作しなかったので VM でも試してみたところうまくいきました

本当は ESXi のデータストアとしてして使えたほうが何かと便利なのですが、、、
その問題はそのうち解決できればなと思います

参考サイト

2017年3月24日金曜日

AWS Storage Gateway のファイルゲートウェイを使って nfs のデータストアを VMware 上に構築してみた

概要

前回 Storage Gateway のファイルゲートウェイで nfs インタフェースを作成しました
前回は VM でマウントしたのですが、今回は ESXi でマウントしてみたいと思います
nfs インタフェースを持った Storage Gateway の作成は前回の記事を参考してください

環境

  • VMware vCenter Server 6.0.0u2
  • VMware ESXi 6.0.0 3620759
  • AWS Storage Gateway (20170322 時点)
  • AWS Storage Gateway Appliance
  • Ubuntu 16.04

nfs デバイスのマウント

vSphere Client を開いて

ホスト -> アクション -> ストレージ -> 新しいデータストア

を選択します
タイプの選択で「NFS」を選択します
バージョンは NFS3 を選択します

データストア名とフォルダ、サーバを入力する画面で Storage Gateway に作成したファイル共有の情報を入力します
フォルダには設定したバケット名をサーバ名は Storage Gateway の IP アドレスを設定します
aws_storage_gateway_nfs_mount1.png

これで OK し作成を完了します
Storage Gateway の nfs インタフェースを使ったデータストアが一覧に表示されると思います

試し手に VM のディスクとしてに割り当ててみる

以下のような感じで VM にディスクを割り当てます
データストアを追加したデータストアに変更するので注意してください
今回は20GB 分割り当てます
aws_storage_gateway_nfs_mount2.png

そしてフォーマットしマウントします

  • parted --script /dev/sdb "mklabel msdos"
  • parted --script /dev/sdb "mkpart primary 0% 100%"
  • mkfs.ext4 /dev/sdb1
  • mkdir -p /mnt
  • mount /dev/sdb1 /mnt
  • df -h /dev/sdb1

VMware 環境の場合はディスクは vmdk ファイルとしてデータストアに保存されます
そしてこの状態で s3 を見ると s3 側にも vmdk ファイルが存在することが確認できると思います
aws_storage_gateway_nfs_mount3.png

aws_storage_gateway_nfs_mount4.png

最後に

Storage Gateway の nfs を ESXi のデータストアとしてでマウントする方法を紹介しました
iSCSI のときは ESXi にはマウントできたのですが、それを VM に割り当てるとうまくフォーマットできませんでした
nfs だとうまくフォーマットし、マウントすることで VM 上でファイルシステムとして使用することができました

きっと iSCSI もできるはずですが、原因は未だに不明です

2017年3月23日木曜日

AWS Storage Gateway のファイルゲートウェイを使って s3 にデータを保存する

概要

AWS Storage Gateway にはファイル共有という機能があり nfs フォーマットでマウントすることができます
マウントした領域にデータを保存するとそのまま s3 にも保存することができます
今回は Appliance を VMware 環境にデプロイし VM から Storage Gateway で作成した nfs をマウントして s3 にデータを保存してみます
基本的な手順は前回の iSCSI の回と同じなのでそちらをご覧ください

環境

  • VMware vCenter Server 6.0.0u2
  • VMware ESXi 6.0.0 3620759
  • AWS Storage Gateway (20170322 時点)
  • AWS Storage Gateway Appliance

ファイルゲートウェイ用 AWS Storage Gateway Appliance のデプロイ

以下からアプライアンスをダウンロードし VMware 環境にデプロイしてください
https://dslbbkfzjw91h.cloudfront.net/AWS-Storage-Gateway-File.zip

デプロイ後に設定変更するので起動しないようにしてください

Appliance の設定変更

設定変更から以下を変更します

  • 50GB のディスクを 1 本追加する (ストレージの容量に余裕がなければ 50GB もなくても OK です)
  • 仮想マシン オプション -> VMware Tools -> 時刻 にチェックを入れる

設定変更したら起動します
IP が取得できれば OK です

AWS 側に Storage Gateway を追加する

Storage Gateway のコンソールで作業します

ゲートウェイの種類を選択で「ファイルゲートウェイ」を選択します
ホストプラットフォームの選択で「VMware ESXi」を選択します

あとはゲートウェイに接続してアクティブ化すれば OK です
追加した 50GB 分のストレージもローカルストレージとして作成してください

ファイル共有を作成します

続けてファイル共有を作成します
左メニューの「ファイル共有」を選択します

作成時にデータを保存するバケットを指定する必要があるので入力します
s3 へのアクセス用の IAM ロールを設定する必要がありますが、新規で作成することもできるので設定が面倒であれば新規で作成してください

あとは作成されるのを待ちます

nfs として VM にマウントする

では VM にマウントしてみましょう
コンソールにコマンドが出ているのでそのまま利用すれば OK です
もちろん Appliance の IP アドレスにアクセスできる VM から試してください
今回は Ubuntu 16.04 から試しています

  • apt -y install nfs-common
  • mkdir -p /sg
  • mount -t nfs -o nolock xxx.xxx.xxx.xxx:/my-sg-test-bucket /sg
  • echo hoge > /sg/hoge.txt

という感じでマウントしてファイルを作成してみましょう
すると s3 側にもデータが保存できているのが確認できると思います
aws_storage_gateway_nfs1.png

最後に

Storage Gateway のファイル共有機能を使って s3 をバックグランドにした nfs をマウントしてみました
感覚的には s3fs などのファイルシステムツールに近い感じです

利点としてはマウントには nfs クライアントがあればいいのでいちいち s3fs をインストール必要がありません
また、同じバケットを別の VM でも簡単にマウントすることができるようになります

ESXi にも NFS をマウントする機能があるけどこれでマウントしてデータストアとして認識させてから VM に割り当てることはできるのだろうか

2017年3月22日水曜日

AWS Storage Gateway のボリュームゲートウェイを使って iSCSI のデータストアを VMware 上に構築してみた

概要

AWS Storage Gateway には iSCSI のストレージ I/O があり Linux マシンや Windows マシンに iSCSI デバイスとしてディスクをマウントすることができます
VMware のデータストアにも iSCSI アダプタがあるため iSCSI なデータストアをホストにマウントすることができます
今回は AWS Storage Gateway のボリュームゲートウェイに含まれる iSCSI インタフェースの機能を使って VMware 上に iSCSI なデータストアを構築してみました

環境

  • VMware vCenter Server 6.0.0u2
  • VMware ESXi 6.0.0 3620759
  • AWS Storage Gateway (20170322 時点)
  • AWS Storage Gateway Appliance

AWS Storage Gateway Appliance のデプロイ

以下の URL から ova ファイルをダウンロードすることができます
https://dslbbkfzjw91h.cloudfront.net/AWS-Storage-Gateway.zip

Storage Gateway のコンソール上で作業をすすめる時に表示されるダウンロード URL と同じものです
他に Storage Gateway File という ova もありますが、そちらではないのでご注意ください
ダウンロードしたら解凍しましょう

ova のデプロイは vSphere Client 上でポチポチするだけなので箇条書きで簡単に説明します

  1. vSphere Web Client を開く
  2. ホストを選択 -> アクション -> OVF テンプレートのデプロイ
  3. ローカルファイルの選択で ova ファイルを選択
  4. 詳細の確認をする (特に変更なし)
  5. VM の名前を設定しデプロイするフォルダを選択
  6. デプロイするデータストアを選択 (データストアは 200GB ほど空きがあると嬉しい)、シックを選択
  7. ネットワークを設定
  8. デプロイ後にパワーオンにはチェックを入れずに作成開始

で OK です
デプロイ後に設定の変更を行うのでパワーオンはしないようにしてください
だいたい 10 - 20 分ほどで完了します

Appliance の設定変更

デプロイできた Appliance を選択し「設定の編集」を選択します
以下を修正、追加します

  • 50GB のディスクを 2 本追加する (ストレージの容量に余裕がなければ 50GB もなくても OK です)
  • iSCSI コントローラのタイプを「VMware 準仮想化」に変更
  • 仮想マシン オプション -> VMware Tools -> 時刻 にチェックを入れる

修正できたら OK で完了します
設定変更後は Appliance を起動しましょう
起動して IP アドレスが問題なく取得できれば OK です
これで Appliance の設定は完了です

AWS 側に Storage Gateway を追加する

ここからは AWS のコンソールで作業します
Storage Gateway のコンソールにアクセスしてください

ここで一点注意が必要なのですが、作業する環境から先程構築した Appliance にアクセスできる必要があります
もう少しいうと作業するブラウザが Appliance にアクセスできる必要があります
もし Appliance にリーチャビリティのない環境からやる場合は Appliance 側の環境にデスクトップ環境を用意してそこでブラウザを開いて作業するなどしてください

まずボリュームゲートウェイとして Storage Gateway を作成します
aws_storage_gateway_iscsi1.png

ホストプラットフォームの選択で VMware ESXi を選択します
ここでダウンロードできる zip ファイルは先程ダウンロードした Appliance になります
aws_storage_gateway_iscsi2.png

ゲートウェイに接続で先程起動した Appliance の IP を入力します
ここでブラウザから IP にアクセスできないとエラーになります
aws_storage_gateway_iscsi3.png

ゲートウェイのアクティブ化を行います
タイムゾーンと名前を設定しアクティブ化します
aws_storage_gateway_iscsi4.png

ローカルディスクを作成します
先程追加した 50GB のディスク 2 本をそれぞれ「アップロードバッファ」「キャッシュ」に設定します
aws_storage_gateway_iscsi5.png

これで ボリュームゲートウェイとしての Storage Gateway の作成は完了です

ボリュームを作成する

iSCSI としてマウントするには領域が必要になります
Appliance をデプロイしただけでは、iSCSI のインタフェースが提供されるだけで保存領域がないのでまだ使えません

左メニューのボリュームを選択します
ボリュームの作成から必要な情報を入力していきます
容量は先程作成した 50GB のローカル領域から必要な領域を切り出してください (今回は 20GB)
iSCSI ターゲット名は好きな名前を入れてください
あとで AWS 専用の suffiex と連結してターゲット名が作成されます
aws_storage_gateway_iscsi6.png

その後で CHAP 認証の設定が画面になりますが、今回は認証は設定しないのでスキップします

作成されるまで待ちましょう
だいたい 10 分ほどで作成が完了します

iSCSI アダプタを追加する

ボリュームが作成できたらホストに iSCSI データストアとしてマウントして使えるようにします
ここからの作業は vSphere Client に戻ります

ホストを選択 -> 管理 -> ストレージアダプタ -> iSCSI アダプタを選択 -> ターゲット -> 動的検出 -> 追加
で Appliance を追加します
Appliance の IP アドレスを入力し OK です
ポートはデフォルトの 3260 のままで OK です
aws_storage_gateway_iscsi7.png

追加できたら「最近構成が変更されたため、このストレージ アダプタを再スキャンすることをお勧めします。」と表示されるので素直に再スキャンしましょう
するとストレージアダプタ「ターゲット」と「アダプタ」の欄が 0 -> 1 になっていることが確認できると思います

ボリュームを追加していないとここが増えないので注意してください

iSCSI データストアをホストに追加する

あとはホストに iSCSI データストアをマウントするだけです
ストレージデバイスの一覧を確認すると「Amazon iSCSI Disk (eui.00928a31daae1551c8000000)」というディスクが追加されていると思います

ホストを選択 -> アクション -> ストレージ -> 新しいデータストア

を選択します
そして

VMFS -> データストア名入力、デバイス選択 -> パーティションの設定 (全部割り当てで OK) -> 終了

でマウントしましょう
データストアの一覧で iSCSI のデバイスが追加されていることを確認します
aws_storage_gateway_iscsi8.png

で、このあと

この後実際に VM にディスクを追加してパーティションを作成してフォーマットしてマウントして使おうとしたのですが、実はできませんでした
mkfs したところで止まってしまいうんともすんとも言わなくなってしまいました
いろいろ試したんですが、結局うまく動作せず Appliance のトラシュをする前に力尽きました
もしかしたら何かやり方がおかしかっただけかもしれませんが、、、
(うまく動いたって方がいたら教えてほしいです、、、)
おそらく適当な VM に iSCSI イニシエータとかをインストールして Storage Gateway から直接マウントすれば iSCSI ストレージとして普通に使えるんだと思います
今回はそうではなくて ESXi のデータストアとして使いたかった感じです

あと今回の作業で全く出てこなかった s3 ですが、どうやら Storage Gateway は定期的にスナップショット取っておりそのボリュームデータが s3 に保存されるようです
で、その保存のタイミングとしてキャッシュボリュームと保管型ボリュームがあり、それぞれ s3 にスナップショットを取るタイミングが違うみたいです
またスナップショットはスケジューリングして定期的に取得することもできるみたいです

s3 に溜まったスナップショットのボリュームデータは s3 から直接見ることはできません
EBS ボリュームとして VM を別途作成して、その VM 内で確認するようです

Tips

Appliance にログインする方法はコンソールで sguser/sgpassword でログインできます
基本的な bash のコマンドなどは使えないので難しいトラシュはできないと思いますsshd もあがっていないようでした

最後に

AWS の Storage Gateway を使って VMware 環境上に iSCSI データストアを構築しました
別の機能でファイル共有という機能がそっちだと s3 上でファイルの内容の確認もできるそうなので、次回はそれを試してみたいと思います

参考サイト

2017年3月17日金曜日

docker のネットワーク機能を試してみた

概要

勉強がてら docker のネットワーク機能について基本な操作を行ってみました
既存のネットワークの挙動の確認と独自のネットワークを定義してアタッチするところまで行っています

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

ネットワークを確認する

まずはデフォルトで用意されているネットワークを確認してみましょう

  • docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
fb949b0d7786        bridge              bridge              local
365cbf8a882f        host                host                local
64103726a5d5        none                null                local

こんな感じで 3 つのネットワークが用意されています
docker run をするときに --net オプションがありこれを使うことでコンテナが所属するネットワークを指定することができます
特に指定しない場合は bridge が選択されるようです

では、この 3 つのネットワークの挙動を確認していきます

ネットワークを指定してコンテナを作成する

bridge

まずは bridge を指定します

  • docker run --rm -p 8080:80 --net bridge --name web1 nginx

これで作成した場合バインドしたポートで Mac (ホストマシン (192.168.100.105)) からコンテナへの通信ができ、moby VM からブリッジネットワークを使ってのコンテナへの通信もできます
また、コンテナからホストマシンへの通信もできます
更に NAT でインターネットに接続することもできます

  • ホストマシンから
    • curl localhost:8080
  • moby から
    • ping 172.17.0.2
  • コンテナから
    • ping 172.17.0.1
    • ping 192.168.100.105
    • apt update

注意点として今回 Docker on Mac でやっているのでホストマシンからコンテナへの ping に関しては moby VM にログインしてから試してください

moby へのログインは以下でできます

  • screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

host

次に host を試します
--net オプションの部分を host に変更します

  • docker run --rm -p 8080:80 --net host --name web1 nginx

これで作成した場合、コンテナはホストマシンと同じネットワークインタフェースを使用します
なので、moby VM からコンテナへの通信とコンテナからホストマシンへの通信、NAT でのインターネットに接続はできます

  • moby から
    • ping 172.17.0.2
  • コンテナから
    • ping 172.17.0.1
    • ping 192.168.100.105
    • apt update

null

次に null を試します
--net オプションの部分を none に変更します
null ドライバで作成しれたネットワークの none を指定しています

  • docker run --rm -p 8080:80 --net none --name web1 nginx

この場合、どこからもコンテナにアクセスできなくなります
また、コンテナからホストやインターネットへの通信できなくなります

コンテナに exec して確認してみるとわかりますが、通信するための IP アドレスが何も振られていないことがわかると思います

ネットワークを定義する

デフォルトの 3 つのネットワークの挙動はつかめてので次に独自のネットワークを作成してみます
今回は bridge ドライバを使って定義します

  • docker network create my_network

で作成できます
確認するとネットワークが増えていることが確認できます

  • docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
526531de15db        bridge              bridge              local
365cbf8a882f        host                host                local
4aa22f6b0e5c        my_network          bridge              local
64103726a5d5        none                null                local

詳細を確認するには inspect を使います

  • docker network inspect my_network
[
    {
        "Name": "my_network",
        "Id": "4aa22f6b0e5c3759d80bd717410c9aef70e50a853c4076e9bf972f5ba5132f3a",
        "Created": "2017-03-16T23:51:03.617896532Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Subnet や Gateway はデフォルトで設定されました
既存の bridge ネットワークと比較すると Options が空なだけで後は同じ感じでした

定義したネットワークに接続する

では、定義したネットワークをコンテナに接続してみます
初めに説明すると host と none に対しては接続できませんでした

  • host に対して接続しようとした場合
Error response from daemon: Container sharing network namespace with another container or host cannot be connected to any other network
  • none に対して接続しようとした場合
Error response from daemon: Container cannot be connected to multiple networks with one of the networks in private (none) mode

なので、bridge に接続しているコンテナに対して my_network を接続してみます

  • docker run --rm -p 8080:80 --net bridge --name web1 nginx
  • docker network connect my_network web1

という感じです
insepct で my_network の情報を確認すると Containers の項目が増えていることがわかると思います (以下 inspect 結果の一部抜粋)

"Containers": {
    "cca88927fa6e267e8e552c8a446b5363a29f60f04b2bf534e4cf3cc43fed4047": {
        "Name": "web1",
        "EndpointID": "2bda4228d7930af5ca558aae0e32be545f63018ada5718d80b3daa86bd524fc7",
        "MacAddress": "02:42:ac:12:00:02",
        "IPv4Address": "172.18.0.2/16",
        "IPv6Address": ""
    }
},

また、172.18 帯でも通信できることが確認できると思います
念のためもう一つ my_network に接続しているコンテナを作成してみましょう

  • docker run –rm -p 8081:80 –net my_network –name web2 nginx

で web2 に exec してリーチャビリティを確認すると 172.18 では web1 にアクセスできるが、172.17 ではアクセスできないことが確認できると思います

  • docker exec -it web2 /bin/bash
root@815fc91e6040:/# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.143 ms
--- 172.18.0.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.143/0.143/0.143/0.000 ms

root@815fc91e6040:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

その他のネットワークドライバ

今回は bridge, host, null という 3 種類のドライバを試しましたが、Docker on Mac では別のドライバも用意されています

  • docker info | grep -A 2 Plugins:
Plugins: 
 Volume: local
 Network: bridge host ipvlan macvlan null overlay

ipvlan, macvlan, overlay というのが他にもあるようです
また、ドライバは自分で定義することもできます
この辺りはまた別途検証して紹介できればと思います

最後に

Docker on Mac でネットワーク機能を試してみました
Mac の場合ちょっと特殊な VM が動作しているので少しややこしくなりましたが概念的には他のマシンで試しても同じだと思います

基本は bridge になるかと思います
あとは swarm などを使った場合にホストをまたがってコンテナ同士を通信させるのに overlay を使う感じかなと思います
それ以外のドライバも試してみたいな思っています

参考サイト

2017年3月16日木曜日

docker のデータボリュームの領域を s3 として使用する方法

概要

これまでにコンテナでデータボリュームを使用する方法として

  1. 単独でデータボリュームを作成する方法
  2. 別のコンテナの領域をデータボリュームとして利用する方法
  3. ホストマシンの領域をデータボリュームとして利用する方法

を紹介しました
今回は s3 の領域をデータボリュームとして利用する方法を紹介します

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22
  • goofys 0.0.9

goofys のインストール

  • brew tap homebrew/fuse
  • brew cask install osxfuse
  • brew install goofys

.aws/credentials などの設定は事前に行っておいてください
また us-east-1 に適当にバケットを作成しておいてください
今回は「c1-bd10c735e495」とします

データボリューム領域の追加

事前に Docker on Mac の設定で /data-volume をデータボリューム領域として追加しておきます
Preferences から File Sharing で「/data-volume」を追加します
docker_datavolume_s3.png

s3 のマウント

  • sudo mkdir /data-volume
  • sudo chown -R kakakikikeke:staff /data-volume/
  • goofys c1-bd10c735e495 /data-volume
  • df -h
c1-bd10c735e495  1.0Pi    0Bi  1.0Pi     0%       0 1000000000    0%   /data-volume

こんな感じでマウントできれば OK です
試しにファイルを作成してバケット上にもファイルができるか確認してみてください
アンマウントする場合は

  • umount /data-volume

で OK です

データボリュームとしてコンテナで使ってみる

  • cd /data-volume
  • docker run --name c1 -p 8080:80 -v $(pwd):/test-volume nginx

でコンテナを起動しましょう
そして

  • docker exec -it c1 /bin/bash

でログインして

  • ls /test-volume

すると s3 にあるオブジェクトを確認できると思います
ただ、コンテナから

  • echo fuga > /test-volume/fuga

という感じでデータボリューム領域に書き込もうとしても「bash: fuga: No such file or directory」と怒られてしまいました
なので

s3 -> file -> container

の GET の流れはうまく行ったのですが

container -> file -> s3

の POST の流れはうまく行きませんでした

最後に

データボリュームで s3 を使う方法を紹介しました
ホストマシン側で s3 をマウントしその領域をコンテナのデータボリュームとして利用しています

結果として GET の流れはコンテナ上でもできたのですが、POST の流れはコンテナからはできませんでした
(環境依存という可能性もありますが、、)
これを試していて思ったのですが、おそらくホストでマウントした s3 を更に docker のデータボリュームとしてマウントするのではなく、コンテナはコンテナで s3 をマウントしてホストはホストで s3 をマウントするようにしたほうが良いと思いました

今回 POST ができなかった原因は不明なのですが、おそらく権限とか docker 内部のデータボリュームの流れと goofys の流れがごっちゃになってしまっているせいかなと思います
コンテナ上でも goofys 的なのを動かして s3 をマウントすることはできると思うので、そうしたほうが良いかなと思った次第です

ただ調べてみるとそれも結構大変そうであまりおすすめできる感じではありませんでした、、、
http://qiita.com/kochizufan/items/e0253eeda0cd470c6dc8

あとは「そもそも dockerd 側のデータボリュームの領域を s3 にできないのか」という疑問を抱くと思います
実は dockerd 用のデータボリューム領域には様々なプラグインが用意されています
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins

これを dockerd に組み込めばデーモン側のデータボリューム領域としてクラウドサービスなどを使うことができます
Docker on Mac の場合デフォルトで「local」というプラグインが使われています
docker info コマンドを使えば確認することができます

これまでは dockerd 周りの拡張や検証はほとんど行ってこなかったので、その辺の dockerd 周りの検証もそのうちやりたいなと思っています

参考サイト

2017年3月15日水曜日

docker のデータボリュームで別コンテナの領域をマウントする方法

概要

前回 docker のデータボリュームの使い方を紹介しました
今回は別の使い方として別コンテナの領域をコンテナのデータボリュームとして使う方法を紹介します

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

使い方

  • docker run --name c1 -p 8080:80 -v /share nginx

で「/share」をデータボリュームとして作成します
次に別のコンテナを作成します
このときに初めに起動したコンテナを --volumes-from オプションを付与して起動します

  • docker run --name c2 -p 8081:80 --volumes-from c1 nginx

こうすることで c1 コンテナでマウントした /share 領域が c2 領域でもマウントされています

動作確認

  • docker exec -it c2 /bin/bash

で、c2 コンテナに入って touch /share/hoge.txt します
その後で

  • docker exec -it c1 /bin/bash

をして /share 配下を確認すると hoge.txt が存在することが確認できると思います

root@32896c0881c4:/# ls /share/
hoge.txt

最後に

docker のデータボリュームで別コンテナのマウント領域を使用する方法を紹介しました
この機能はボリュームコンテナと呼ばれる機能でデータを管理する専用のコンテナを作ることでデータの管理を一元化できるメリットがあります

ある一つのコンテナだけデータを永続化する機能を持っており、他のコンテナはそのコンテナを参照するだけになります
すべてのコンテナがデータを永続化する領域をマウントする必要がなくなるので管理が容易になります

参考サイト

2017年3月14日火曜日

docker のデータボリュームでホスト上の領域をマウントする方法

概要

前回 docker のデータボリュームの使い方を紹介しました
今回は別の使い方としてホスト上の領域をコンテナのデータボリュームとして使う方法を紹介します

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

使い方

使い方は簡単で「-v」オプションにホスト上の領域を指定するだけです

  • mkdir /Users/hawksnowlog/data-volume
  • cd /Users/hawksnowlog/data-volume
  • touch hoge.txt
  • docker run --name c1 -p 8080:80 -v $(pwd):/test-volume nginx

これで「/Users/hawksnowlog/data-volume」の領域をコンテナ上でマウントすることができます
確認してみましょう

  • docker exec -it c1 /bin/bash
root@68f23c53f12a:/# ls /test-volume/
hoge.txt

こんな感じです
今回は docker のデータボリューム領域を作成していません
なので、docker volume ls などで領域を確認しても新規で作成されていないのが確認できると思います

最後に

docker のデータボリュームをホスト上の領域として使う方法を紹介しました
この方法が一番単純で直感的で簡単な方法かなと思います

ホスト上の領域を NFS や LVM にすることで拡張することも簡単にできます

2017年3月13日月曜日

docker のデータボリュームを試してみた

概要

docker のデータボリュームの挙動を調べてみました
データボリュームは簡単に言えばデータを永続化するための領域です
コンテナとは別の領域にデータボリュームの領域を作成することで実現します
今回は Docker on Mac で試しました

環境

  • Mac OS X 10.12.3
  • Docker on Mac 17.03.0-ce, build 60ccb22

ボリュームを作成する

まずは単純に領域を作成してみましょう
作成する方法はいろいろありますが、とりあえず run コマンドから作成します

  • docker run --name c1 -p 8080:80 -v /test-volume nginx

「/test-volume」という領域をコンテナ上に新規で作成します
同時にホスト上にも領域が作成されます

  • docker volume ls
DRIVER              VOLUME NAME
local                 3a7ad65099591e7bbe2234aa4db

VOLUME NAME はちょっと長かったので短縮しています
コンテナ上でマウントしている情報を確認するには inspect コマンドを使います

  • docker inspect --format='{{ .Mounts }}' c1
[{volume 3a7ad65099591e7bbe2234aa4db /var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data /test-volume local  true }]

ホスト上の「/var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data」という領域をコンテナ上にマウントすることでデータを永続化しています
コンテナを停止して削除してもデータボリュームは削除されていないことが確認できると思います

ホスト上の領域を確認する

では先ほど確認した「/var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data」の領域をホスト上で確認してみましょう

Docker on Mac の場合はホスト上の領域が少し特殊でデータ領域用の VM が動作しています
なので Mac 上で ls /var/lib/docker/volumes/ とか打っても「そんなディレクトリはありません」と怒られると思います

データ領域用の VM にログインして確認してみます
ログインするには screen コマンドを使います

  • screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

ユーザ名とパスワードは特に要求されないと思います
でプロンプトを表示して ls コマンドを実行してみます

/ # ls -ltrh /var/lib/docker/volumes
total 28
drwxr-xr-x    3 root     root        4.0K Mar 13 01:31 3a7ad65099591e7bbe2234aa4db
-rw-------    1 root     root       32.0K Mar 13 01:40 metadata.db

するとこんな感じで表示されると思います
その配下の _data ディレクトリ配下に実際にコンテナ上で作成したファイルも存在することが確認できると思います

試しにデータボリューム上 or コンテナ上で対象の領域に touch コマンドなどでファイルを作成してデータが共有されているか確認すると良いと思います

  • docker exec -it c1 /bin/bash
  • touch /test-volume/hoge.txt

ホスト側のデータボリュームの領域上で

  • ls -l /var/lib/docker/volumes/3a7ad65099591e7bbe2234aa4db/_data/hoge.txt

で存在が確認できると思います

別のコンテナから使う

これでコンテナからデータを削除してもデータが消失しないことがわかりました
では次に別のコンテナでデータボリュームの領域を使用してみます
-v オプションでデータボリュームの ID を指定すれば OK です

  • docker run --name c2 -p 8080:80 -v 3a7ad65099591e7bbe2234aa4db:/test-volume nginx

という感じです
これでコンテナ上で「/test-volume」の領域を確認すると先ほど別のコンテナで作成した hoge.txt が存在するのが確認できると思います

Tips

データボリューム領域はコンテナを削除しても残ります
データボリューム領域を削除したい場合は rm コマンドを利用します

  • docker volume rm 3a7ad65099591e7bbe2234aa4db

で OK です
当然ですが、データボリュームを使用中のコンテナが動作している場合は削除することができません

今回新規でデータボリュームを作成するのに run コマンドのオプションを使いました
docker volume create というコマンドもあるので、これを使って先に作成しておくことも可能です

  • docker volume create --name v1

--name を指定することでランダムな ID ではなく名前を付与することができます
ただし 1 文字のデータボリュームを作成することはできないようです

データボリュームはコンテナを削除してもなくならないと紹介しました
実は run をしたときに --rm オプションを付与するとコンテナを削除したときにデータボリュームも同時に削除することが可能です

  • docker run --rm --name c3 -p 8080:80 -v /test-volume nginx

とするとコンテナが起動しつづけてる間は docker volume ls で確認できると思いますが、コンテナを削除するとデータボリューム領域がなくなっていることが確認できると思います

最後に

docker のデータボリュームの挙動を実際にコマンドを実行しながら試してみました
基本的にはホスト上に永続化のための領域を作成して、それをコンテナが適宜マウントして使うことで実現しています

データボリュームには他にもホスト上のすでに存在するディレクトリを領域として使う方法や、他のコンテナの領域をデータボリュームとして使う方法もあります
この辺りの別の使い方も次回紹介したいと思います

参考サイト

2017年3月12日日曜日

SSH2 Easy でビルドのパラメータを渡す方法

概要

SSH したホストでコマンドを実行するというジョブは Jenkins ではよくあるケースだと思います
SSH2 Easy もそんなことができるプラグインの 1 つです
今回は SSH2 Easy を使ってビルドのパラメータを SSH したホストに渡す方法を紹介します

環境

  • Mac OS X 10.12.3
  • Jenkins 2.32.3
  • SSH2 Easy 1.4

その前に

今回は Mac 上で Jenkins を動作させ、動作させている Mac に SSH するので Mac の SSH をオンにします
環境設定 -> 共有 -> リモートログインを ON にします
ssh2easy_use_env_val1.png

SSH するホストの設定

Jenkins の管理 -> システムの設定 -> Server Groups Center で SSH するホストを設定します
SSH2 Easy ではグループが設定できます
グループに認証情報を設定し、そのグループの認証情報を使ってログインできるホストをグループにぶら下げることができます
ssh2easy_use_env_val2.png

ジョブの設定

まずはパラメータを渡せるようにします
これは何でも OK です
ssh2easy_use_env_val3.png

次にリモートホストでコマンドを実行するビルドを追加します
「Remote Command」を選択しビルドの設定をします
そのときにパラメータとして設定した値をダラーで参照すればパラメータの値をリモートホストで参照することができます
ssh2easy_use_env_val4.png

動作確認

ジョブを実行してみましょう
するとパラメータに渡した値がリモートホスト上でも展開されて結果に表示されると思います

最後に

SSH2 Easy でビルドパラメータを渡す方法を紹介しました
他の SSH 系のプラグインは試してないですが、同じようにできるかもしれません

2017年3月11日土曜日

hubot と Jenkins を Docker で動作させて Slack から Jenkins のジョブを実行させてみた

概要

構成として以下を実現してみました
hubot_jenkins_on_docker1.png

ユーザは Slack を使って hubot に話かけます
そして hubot から Jenkins のジョブを実行します
そして hubot および Jenkins は docker コンテナとして動作させます

環境

  • Mac OS X 10.12.3
  • docker 17.03.0-ce, build 60ccb22
  • Jenkins 2.32.3
  • hubot 2.19.0

Jenkins コンテナの準備

まずは Jenkins コンテナを準備します
Jenkins の設定ファイルなどの保存は一旦ローカルのストレージにしておきます

  • mkdir /work/local_jenkins_home
  • cd local_/work/jenkins_home
  • docker pull jenkins
  • docker run -d -p 8080:8080 -v $(pwd):/var/jenkins_home jenkins

でコンテナを起動させましょう
localhost:8080 にアクセスすれば設定画面が表示されると思います
簡単に初期設定だけ行っておきます

  • docker exec [container_id] cat /var/jenkins_home/secrets/initialAdminPassword

で初期パスワードを取得して認証します
そして、推奨プラグインたちをインストールします
Jenkins を利用するユーザのユーザ名とパスワード、メールアドレスを入力します (今回は、admin/jenkins とします)

あとは「Jenkins の管理 -> グローバルセキュリティの設定 -> CSRF 対策のチェックを外す」を行っておいてください
これは hubot からアクセスするために利用する設定となります

あとは適当なジョブを 1 つ作成しておいてください
今回は「test」というジョブを作成したことにします

Jenkins コンテナはそのままにして次に進みます

hubot コンテナの準備

hubot コンテナを作成します
hubot-jenkins というプラグインを使って先ほど作成した Jenkins コンテナと連携します
また、Slack アダプタを使って Slack とも連携するのあらかじめ HUBOT_SLACK_TOKEN を取得しておいてください (参考)

  • mkdir /work/hubot
  • cd /work/hubot
  • vim Dockerfile
vim Dockerfile

FROM node

RUN npm install -g yo generator-hubot
RUN npm list -g yo generator-hubot
RUN useradd bot
RUN mkdir /home/bot && chown bot.bot /home/bot

USER bot
WORKDIR /home/bot
RUN npm install hubot-jenkins --save
RUN yo hubot --owner "hawksnowlog" --name "jenkins-bot" --description "A bot which can be kicked any jenkins job" --adapter slack
COPY external-scripts.json /home/bot/

CMD cd /home/bot/hubot; bin/hubot --adapter slack
  • vim external-scripts.json
[
  "hubot-help",
  "hubot-jenkins"
]
  • docker build -t jenkins-bot .

で hubot 用のイメージを作成します
そしてイメージが作成できたら hubot コンテナを起動しましょう
各種、環境変数は各人の環境に合わせて変更してください
HUBOT_JENKINS_URL は Jenkins コンテナが動作している IP アドレスを
HUBOT_JENKINS_AUTH は初期設定で作成した Jenkins のユーザ名とパスワードを入力してください

  • docker run -d -e "HUBOT_SLACK_TOKEN=your-hubot-slack-token" -e "HUBOT_JENKINS_URL=http://172.17.0.2:8080" -e "HUBOT_JENKINS_AUTH=admin:jenkins" -e “PORT=8080" jenkins-bot

起動したら Slack からアクセスできるか確認してみましょう
Slack で作成した Hubot Integration の名前は「@jenkins-bot」とします

  • @jenkins-bot jenkins list

と入力するとジョブの一覧が表示されると思います

  • @jenkins-bot jenkins build test

みたいな感じで test ジョブを実行することができます
Slack 上で実行すると「@hawksnowlog: (201) Build started for test http://172.17.0.2:8080/job/test」みたいな感じでボットは返してくれます
あくまでもジョブの実行だけを行ってくれるのでジョブの経過は Jenkins 上で確認する必要があります

今回の場合 help コマンドも使えるので他の jenkins コマンドを確認したい場合は「@jenkins-bot help」と入力してみてください

docker-compose.yml にする

せっかくなので docker-compose.yml で起動できるようにしてみます
docker-compose を実行する場合は事前に起動しておいた Jenkins と Hubot コンテナは停止しておいてください

  • cd /work/hubot
  • mv ../local_jenkins_home/ .
  • vim docker-compose.yml
hubot:
  build: .
  links:
    - jenkins
  environment:
    - HUBOT_SLACK_TOKEN=your-hubot-slack-token
    - HUBOT_JENKINS_URL=http://jenkins:8080
    - HUBOT_JENKINS_AUTH=admin:jenkins
    - PORT=8080
jenkins:
  image: jenkins:latest
  ports:
    - 8080:8080
  volumes:
    - ./local_jenkins_home:/var/jenkins_home
  • docker-compose up -d

という感じです
ポイントは一番初めに設定した Jenkins のデータを一旦 docker-compose.yml 配下のディレクトリに移動して、docker-compose.yml からマウントできるようにした点です

あとは環境変数やポート、URL の設定をそのまま docker-compose 用に書き直したになります

これで、Jenkins + hubot コンテナがコマンド一発で起動できるようになります

最後に

Docker を使って Jenkins と Hubot のコンテナを作成し、Slack から Jenkins のジョブを実行できるようにしてみました
あとは Jenkins 上でジョブを追加すれば、そのまま Slack からでも実行できるようになります

今回 Jenkins の設定ファイル群はローカルに保存しています
このファイル群が削除またはロストしたりすると Jenkins コンテナが完全初期状態になっていまいます
なので、このディレクトリを tar などに圧縮してどこかにバックアップしておいたりするといいと思います
Jenkinsfile などは使っていないので Jenkinsfile を使ってジョブの設定はどこかのリポジトリで管理してもいいかなと思います

参考サイト

2017年3月10日金曜日

konashi を JavaScript で制御してみた

概要

konashi を自分で書いた JavaScript で制御してみました

環境

  • konashi rev 1.0.3
  • iPhone 6 ( iOS 9.2.1 )
  • konashi.js (2.2.0)
  • jsdo.it (2016/02/10 時点)

事前準備

前回 の記事を参考に konashi を iPhone から制御できるようにしてください
PC に接続して iPhone アプリをインストールするだけなので簡単です
今回はこの環境を使って独自の JavaScript ファイルをデバッグして開発を進める方法を紹介します

jsdo.it の登録

konashi を制御する JavaScript は jsdo.it を使うので、まず登録しましょう
登録は各種 SNS or OpenID を使います
自分は Github のアカウントを使いました
もちろん自分のサーバでホスティングすることも可能ですが、konashi.js のアプリが jsdo.it に特化したアプリになっているので jsdo.it を使うのが無難かと思います

code の作成

jsdo.it でコーディングするためにまず code を作成します

jsdo.it にログインしたら左上の「Start coding」をクリックします
するとブラウザ上のエディタが起動するので、ここで konashi を制御するスクリプトを作成していきます
jsdoit_start_code.png

code を作成すると Hello World のコードが書いてあります
jsdo.it では既にいろいろなサンプルコードが公開されています
これらを fork して code を作成しても問題ありません
自分の場合は前回 使用した LED を点滅させるサンプルコードを fork して始めました
jsdoit_editor_console.png

サンプルの JavaScript ファイルの作成

code が作成できたら konashi を制御するための JavaScript ファイルを作成していきましょう
まず今回自分が作成した JavaScript ファイルの全容です
UI の部分もコーティングしたので HTML と CSS も紹介します

  • HTML
<div class="bar-title">
</div>
<div class="bar-header-secondary">
    <div class="my-title">
        konashi Sample List
    </div>
</div>
<div class="content">
    <a id="find" class="button-positive button-block">Search konashi</a>
    <a id="startBlinkLed2" class="button-negative button-block">Start Blink Led2</a>
</div>
<div class="my-bar-footer">
    <div id="message">Here is debug message</div>
</div>

<!-- for konashijs -->
<script src="http://konashi.ux-xu.com/kjs/konashi-bridge.min.js"></script>

<!-- zepto -->
<script src="http://jsrun.it/assets/1/M/0/f/1M0fl"></script>
<!-- touch.js -->
<script src="http://jsrun.it/assets/g/s/1/M/gs1MI"></script>
<!-- ratchet -->
<link rel="stylesheet" href="http://jsrun.it/assets/h/F/P/P/hFPPa">
<script src="http://jsrun.it/assets/g/3/W/u/g3WuF"></script>
  • JavaScript
// konashi と接続します
$(function(){
    $("#find").on("tap", function(){
        k.find();
    });
});
k.ready(function(){ 
    setUp();
    $("#message").html("<b>Success Connected konashi</b>");
});
function setUp() {
    k.pinMode(k.LED2, k.OUTPUT);
}

// LED2 を点滅させます
$(function(){
    $("#startBlinkLed2").on("tap", function(){
        startBlinkLed2();
    });
});
function startBlinkLed2(){
    var toggle = false;
    setInterval(function(){
        if(toggle){
            // LEDをON
            k.digitalWrite(k.LED2, k.HIGH);
        } else {
            // LEDをOFF
            k.digitalWrite(k.LED2, k.LOW);
        }
        // 次の状態をセット
        toggle = !toggle;
    }, 500);
    $("#message").html("<b>Maybe turning on LED No.2</b>");
}
  • CSS
.my-title {
    padding: 7px;
    text-align: center;
}

.my-bar-footer {
    bottom: 40px;
}

これを jsdo.it のブラウザ上のエディタにそれぞれに貼り付ければ OK です
貼り付けたあとはそれぞれのコードを Save してください

コーディングはすべて jsdo.it 上で行いました
エディタがブラウザだといつものキーバインド操作ができないという方もいると思うのでそういう方は一旦自分のエディタに貼り付けてからコーディングを始めるといいと思います

説明

全体的なコーディングの流れは

  1. HTML と CSS でボタン等のコンポーネントを設置
  2. それらコンポーネントに対するイベントの登録を JavaScript で行う
  3. イベントが発生した際の処理を JavaScript で実装する

という感じかなと思います
一般的な WebUI を開発する方法となんら変わりません
以下でそれぞれのファイルで何をしているか詳細に説明します

HTML と CSS

まず、HTML ファイル内で konashi を扱うためのライブラリを読み込みます

<script src="http://konashi.ux-xu.com/kjs/konashi-bridge.min.js"></script>

今回自分がコーディングした konashi 用の JavaScript ファイルは jQuery ベース (正確には zepto.js ベース) で作成しました
なので、それらのライブラリも読み込んでいます

<script src="http://jsrun.it/assets/1/M/0/f/1M0fl"></script>
<script src="http://jsrun.it/assets/g/s/1/M/gs1MI"></script>

あとはデザインですが、ratchet がデフォルトで使われていたのでそのまま使用しました
他に使用したいモバイル用のデザインテンプレート的なのがあればそれに差し替えても問題ないです

今回は ratchet で定義されている class たちを使って UI を作成しました
足りない部分やカスタマイズしたい部分は独自の CSS を定義すれば OK です

JavaScript

JavaScript で konashi に対する処理やボタンが押された際のイベントの登録処理をします
今回紹介しているコードで実装している機能は大きく以下の 2 つです

  • アドバタイズしている konashi を見つけて接続する
  • LED の 2 番を点滅させる

両者とも実装な大きな流れは同じなので接続を例にして簡単に説明します
まず HTML で作成したボタン ( 正確には a タグ ) の id="find" が押されたときのイベントを登録します

$(function(){
    $("#find").on("tap", function(){
        k.find();
    });
});

id="find" のボタンがタップされると上記 function がコールされて中で k.find() メソッドをコールしています
k.find() メソッドが konashi を探している本体の部分でアドバタイズしている konashi を見つけると表示してくれます

そして、見つけた konashi に接続すると以下のイベントが発生します

k.ready(function(){ 
    setUp();
    $("#message").html("<b>Success Connected konashi</b>");
});

k.ready()は iPhone が 無事 konashi に接続できたときに呼ばれるメソッドで実装しておくと接続時に勝手にコールされます
今回は setUp() メソッドをコールして HTML の id="message" というデバッグ文を表示するための div タグにメッセージを表示する処理を書いています
setUp() はその直後に実装しており、k.pinMode(k.LED2, k.OUTPUT); をコールして LED を使う準備だけをしています ( 実際にはまだ点滅させません )

という感じの実装の流れになります
もうひとつのボタンは準備できた LED No2 を光らせるためのボタンですが、同じようにボタンのイベントを登録してイベントが発生したら k.digitalWrite(k.LED2, k.HIGH); で LED を点滅させる処理を実装しています

動作確認

各種コードを jsdo.it に貼り付けたら作成した自分のコードの動作確認をしてみましょう
動作確認はブラウザではなく iPhone を使って行います
konashi.js を起動しましょう

起動したら User タグから自分のアカウントを検索してみましょう
見つかったらアカウントをタップすると登録している codes の一覧が表示されるので作成したコードをタップします
jsdoit_run_mycode.png

そして左の三角ボタンを押すと自分が作成したコードを実行することができます
jsdoit_show_mycode.png

今回は起動すると konashi に接続するためのボタンと LED No2 を光らせる 2 つのボタンが出てくると思います
まず、接続してから LED を光らせてください
たぶん問題なく動作すると思います

最後に

jsdo.it を使って konashi を制御できる JavaScript ファイルを開発する一連の流れを紹介しました
ボタンを押してから konashi を制御するまでの実装方法がわかったかと思います

LED を制御する系のサンプルはごろごろ転がっているので次は PIO を制御して他のデバイスとの連携を試してみたいと思っています
その場合は konashi を制御する API もいろいろ知らないとダメなので興味ある方は参考サイトにある API リファレンスを眺めるといいと思います

参考サイト