The Beginning Of The End

そこはかとなく技術的なことを

新しいブログ環境の設計について

求める要件

  1. 高速であること
  2. セキュアであること
  3. markdownで記述できること
  4. クライアントマシンに依存しないこと
  5. 面倒くさくないこと

高速であること

  • 動的なサイトよりも静的なサイトが早いので、サイトの構成は静的なものとする
  • webサーバとなるミドルウェアは、経験上apacehよりもnginxが早いのでnginxを使用する
  • http/1.xよりもhttp/2の方が高速なようなので、http/2に対応させる

セキュアであること

  • ホスティングの運用を行っていてつくづく思うのが、普通に使っているだけなのに、使用しているプログラムの脆弱性を突かれると意図も簡単に改竄されてしまう
  • 静的なコンテンツであれば、その心配もないのでセキュアであると考えている

markdownで記述できること

  • htmlで書くことは今後無いだろうと思うくらいmarkdownにお世話になっている
  • markdownで書けて、静的なコンテンツ(ブログ)を作るとなると静的サイトジェネレータかな
  • pythonが好きなので、pythonベースのものとなると、Pelicanの一択な気がする

クライアントマシンに依存しないこと

  • 今までPelicanを使ってブログ書いていた時期もあるのですが、ビルドがクライアントの環境に依存してしまい、書きたい時にかけないということが何度かあった
  • 今回はその問題を解決したい
  • なので、pythonのビルド環境をdockerを使ってVPS上に用意してみる

面倒くさくないこと

  • 長く続けるためにもすごく重要なことだと考えてます
  • あまり複雑にならないように、また、markdownで書いてサクッと公開できるような仕組みにしたい

公開用のサーバは作れそうなイメージはあるのですが、markdownで記述してから、ビルドするまでと、ビルド後の記事を公開用サーバにどうやって設置するか、というところはいまいちいい案がない

  1. markdownで記事を書く
  2. git commit -> git pushする
  3. commitなのかpull req後のmergeなのかをトリガーとして、ビルドサーバからmarkdownの記事をpullしてビルド
  4. 生成されたファイルを公開用サーバに配布

という感じになるのかな。。。

ビルドサーバのビルド後のアウトプット先と公開用サーバのドキュメントルートを共有でmountとかしておくと楽なのかな。
そこら辺は試行錯誤して進めていこう。

今年も残りわずかなので、急がねば。

簡易メールサーバをdockerを利用して無理やり作った

今年もあと少しですね。

新年からブログをリニューアルしたいなと思い、
nginx + http2 + ssl + サイトジェネレーター(Pelicanの予定)の構成を考えております。
そのための証明書をstartsslで取得しようとしたところ、
domainのverifyの部分で、取得したいドメインのメールアカウントへ認証コードを送信する箇所に出くわしました。

gyazo.com

該当のドメインwebサービス以外での利用を考えていなかったので積んでしまいましたw
ただ、ブログのリニューアルはしたかったので、いろいろと調べていたところ、
pythonのsmtplibのdebugが使えそうだったので、dockerで仕組みを作ってみました。

流れとしては

  1. muumuu-domainのカスタムDNSで、tsh.techのMXレコードをtsh.techに設定
  2. dockerのlogを見れる環境を整備する

    • smtplibのdebugモードが標準出力にメールのヘッダーを出力する
    • dockerの標準出力は、docker logsで確認できるが、
    • docker用のcoreosにログインして、docker logs イメージIDが面倒
    • curl tsh.tech:8000/logsでログが見れるのは便利
    • しかも必要なときにだけterraform applyで環境するできるので、良い!
    • 構築はterraformで

    gist.github.com

  3. dockerのpython imageを使って、smtpサーバを起動

    • smtpサーバはワンライナーのコマンド python -m smtpd -c DebuggingServer 0.0.0.0:25
    • 構築はterraformで

    gist.github.com

  4. テストメールを送信して、本文の内容を参照できることを確認する

    • telnet使ったら通信できなくてだいぶハマりました
      • portを25から2525などに変更して切り分けした結果、さくらVPSでは25番portへの接続プロトコル制限されている
    • 普通にメールを送ったらログが出力された

    gist.github.com


やってみて

  • 当たり前ですが、メールアドレスの概念がなく、どんなメール宛のメールも受け取れるのがなんか不思議な感じがしました
  • とりあえず、メール本文はわかるので目的は果たせたのですが、もうちょっといいやり方がないのかなと思いました
  • 後は、telnetではまった時に/usr/bin/toolboxというものを知ったのがとても良かった
    • dockerでの通信の切り分けとかどうすればいいのかよくわからなかったですが、toolboxで起動して普通にtcpdumpとか良いです!
  • とりあえず、SSL証明書取得できたので良かったです!

本題に進みたいと思います。

大掃除がてらにX200sに ChromeOSをインストール

7歳の子供に上げたX200s(USキーボード)が使われないままホコリをかぶり放置されたいたので、 綺麗に掃除をしていたら、ふとChromeOSをインストールしたくなり、いろいろと終わらせて早速インストール!

  1. boot用のUSBメモリの作成
  2. USBbootで起動確認
  3. ディスクにChromeOSをインストール

ここら辺までは、ググればいっぱい情報が出てきます。

私が時間をかけて調べたのは、CtrlとCapsLockを入れ替えるところ 一般的な方法はここの通りです。

ただ、これだと肝心のCapsLockを何か別のキーに置き換えるということができないのです。

そこで参考になったサイトはここ Linuxとほぼ同じみたいで、このままコマンドが通り無事思い通りの動きになりました。

crosh> shell
chronos@localhost / $ setxkbmap -option "ctrl:swapcaps"

なんだかんだ時間を使った。。。

これができるようになったからと言って、 ChromeOSが格段に使いやすくなるわけではありません。

やっぱり、癖が強いです。

もう少し触って開発環境としてカスタマイズしてみます。

coreosで、Docker Remote APIを有効にした際のセキュリティについて

remoteからdockerのimageを起動できるのは便利!

ただ、有効にしてしまうとIPアドレスとport番号がバレたら誰でもバンバンimageを起動できてしまいます。。。
それはやっぱり困るので、自分以外のアクセスは制限したい

どうするか

ぱっと思いついたのは、iptablesで特定のIPからのみ接続を受け入れるようにする
ただ、自宅はDHCPなので、いろいろと面倒そうと思い調べていたら、TLS!! 本家のサイトでは、ここらへんに書かれている。
参考にしたのは、このサイト

terraformの設定を変更して試しに接続

  • TLS用に設定を変更
 provider "docker" {
-    host = "tcp://153.126.155.210:2375/"
+    host = "tcp://153.126.155.210:2376/"
+    cert_path  = "/Users/t-shuichi/Dropbox/Public/docker_tls"
 }
  • 変更後の設定ファイル

gist.github.com

  • ついでにアカウントとパスワードの部分を環境変数に変更
 # Configure the Docker provider
+variable "user" {}
+variable "passwd" {}

-    env  = ["USER=ユーザ名", "PASSWORD=パスワード"]
+    env  = ["USER=${var.user}", "PASSWORD=${var.passwd}"]
# こんな感じで、起動時に指定するようにしました
$ terraform apply -var 'user=ユーザ名' -var 'passwd=パスワード'

VPS上にdockerを使って、RStudio-Serverをたてる

まるで3分間クッキングのように

環境整備についての考え

統計解析や機械学習をすすめるにあたって、環境をどのように整備していこうかと考えてました。
自宅のPCに環境を整えるのも良いのですが、出先でも、会社でも空いた時間を利用して気になった時に手が動かせたほうが良いと思い、VPSに環境を整備することにしました。
dockerが動かせる環境がVPS上にあることを前提として進めていきます。

RStudio-Serverを起動する

RStudioはRを使っていくうえでとても便利なツールです。
それを複数人が利用できるように、サーバ/クライアント形式にしたパッケージがrstudio-serverと認識してます。
その環境を整えていくのですが、docker imageが優秀すぎて特に何もすることがなかったです。

  • terraformのファイル作成

gist.github.com

  • ファイルができたら、terraform applyを実行するだけ
terraform plan
terraform apply

ポート変えるだけで複数人で利用可能!

  • docker imageが優秀なので、環境変数でユーザ名とパスワードを与えて、port番号を割り当てておけば、複数人で使用することが可能
  • terraformが実行できる環境が手元にあれば、テンプレートとなるファイルを共有するだけで、誰でもこのVPS上にRStudio-Serverを起動できる!恐ろしい。。。

機械学習入門

gihyo.jp

概要を把握するには、このシリーズはおすすめです。

ざっと目を通してみたんですが、 機械学習やる前に統計解析の部分は一通りやっておいたほうが理解が早そうな印象です。

gihyo.jp

機械学習とは

  • データの集合からその法則性を効率的に発見するための手法の集合
  • 法則性を学ぶことができれば、将来を予測したり、未知のデータに対してその法則性に則った推定を行うことができる

具体的な作業の流れ

  1. 生データから特徴ベクトルへの変換
    • 特徴ベクトルとは対象の特徴を示す数値を並べたもの
    • 法則性を導き出すために適切な形式に変換する前処理のこと
  2. 機械学習アルゴリズムの適用
    1. どう定式化するのか
    2. どのアルゴリズムを適用するのか
    3. アルゴリズムの選択によって機械学習モデルの種類とそのパラメータ/構造と初期状態が決まる

分類アルゴリズムの学習

上記で分類アルゴリズムを選択した場合、以下のように作業が続く

  1. 訓練データの入力
    • 機械はデータを与えただけでは学ぶことができない
    • 正解事例がなければ、法則を学習することはできない
    • データと正解がペアになったデータの集合を訓練データ、学習データと呼ぶ
    • 正解情報は手動でひとつひとつ正解をつけてやるか、何らかの基準によって自動的に与える
  2. 訓練データの入力により、モデルが更新される
  3. できあがったモデルを用いてテストするデータの入力に対して予測を返す

このようにして、十分な学習を進めていくと、
汎用的なモデルが得られ、訓練データに含まれていないデータに対しても正しく予測することが可能となる

モデルとプロセス(「機械学習アルゴリズムの適用」の詳細)

  • モデル

    • 学習の結果得られた法則性を表すもの
  • プロセス

    • 与えられたデータをもとに何らかの基準について、より望ましい出力が得られるようにモデルを改変する
    1. 初期状態が設定された初期モデルに対し、データを与えてアルゴリズムを適用すると、パラメータが更新された学習済みモデルが得られる
    2. そのモデルに対して新たなデータを入力する
    3. 学習した法則にもとづいて計算された認識や予測の結果が出力される

最良のモデルを得るために

このような作業を繰り返すことが機械学習適用におけるデータサイエンティストの役割であり、腕の見せどころでもあるとな。

どういうツールを使えば良いの?

データ分析者が使用するツールのアンケート結果を見ると以下のものが使えるようになると良さそうです

加えて、以下も使えると良さそう

これらのツールを使いつつ具体的な機械学習を進めていきたいと思います

coreosでHashicorpのTerraformを試す

coreosでHashicorpのTerraformを試す

いろいろと調べているとなんとなく、前回の記事Nomadよりも
こっちを先にやった方が良いのではないかと漠然と思ったので、触ってみる

Terraformって何?

  • 「インフラの構築、変更、バージョン管理を安全かつ効率的に行うツール」らしいです
  • 何かふわっとしていて、しっくりこないのは、以下の疑問があるからかも
    • うちのチームではpuppet使っているけど、puppetと何か違いがあるの?puppetに勝る点はどこ?
    • サイトを読んでいるとProviderとしてpuppetを指定することも可能という記載もある。?共存するの?
    • どういうふうに使えば一番メリットを享受できるのかがわからない

悩んでいてもしょうがないので、手を動かそう

何をするのか

  • dockerでイメージを起動するまでをやってみる
  • Terraformを使ってpuppetを実行してみる

dockerでイメージを起動するまでをやってみる

構成

  • Mac Book Air (Manager)
  • さくらVPS (agent)

coreosのdockerの設定変更

[Unit]
Description=Docker Socket for the API

[Socket]
ListenStream=2375
BindIPv6Only=both
Service=docker.service

[Install]
WantedBy=sockets.target
  • 設定反映
systemctl enable docker-tcp.socket
systemctl stop docker
systemctl start docker-tcp.socket
systemctl start docker
  • 動作テスト
docker -H tcp://127.0.0.1:2375 ps
  • coreosでiptables
    • 今回はテストなので、設定自体は行わないが、本番運用では設定必須かな

terraformでイメージインストール

  • trファイルの作成 github.com

  • terraform plan実行

Refreshing Terraform state prior to plan...


The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ docker_container.foo
    bridge:           "" => "<computed>"
    gateway:          "" => "<computed>"
    image:            "" => "${docker_image.ubuntu.latest}"
    ip_address:       "" => "<computed>"
    ip_prefix_length: "" => "<computed>"
    must_run:         "" => "1"
    name:             "" => "foo"

+ docker_image.ubuntu
    latest: "" => "<computed>"
    name:   "" => "ubuntu:latest"


Plan: 2 to add, 0 to change, 0 to destroy.
  • terraform apply実行
[7:37] % terraform apply
docker_image.ubuntu: Creating...
  latest: "" => "<computed>"
  name:   "" => "ubuntu:latest"
docker_image.ubuntu: Creation complete
docker_container.foo: Creating...
  bridge:           "" => "<computed>"
  gateway:          "" => "<computed>"
  image:            "" => "ca4d7b1b9a51f72ff4da652d96943f657b4898889924ac3dae5df958dba0dc4a"
  ip_address:       "" => "<computed>"
  ip_prefix_length: "" => "<computed>"
  must_run:         "" => "1"
  name:             "" => "foo"
Error applying plan:

1 error(s) occurred:

* docker_container.foo: Container a81909ca4572a0ee7547abab5c02d0d6c85cca483b70abaa96d004aa80837b7f exited after creation, error was:

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
  • 実行前のdocker images
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
matsumotory/ngx-mruby   latest              6b082de49287        12 days ago         578.7 MB
redis                   latest              05babbd460f7        2 weeks ago         109.1 MB
  • 実行後のdocker images
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                  latest              ca4d7b1b9a51        46 hours ago        187.9 MB
matsumotory/ngx-mruby   latest              6b082de49287        12 days ago         578.7 MB
redis                   latest              05babbd460f7        2 weeks ago         109.1 MB
  • imageは追加されている
  • どこが問題なのか、引き続きエラーについて調べる

coreosでHashiCorpのNomadを試す

Nomadとは

  • マシンや実行中アプリケーションのクラスタ管理のためのソフト
  • 興味本位で触っているだけなので、技術的なところはもう少し触ってからということで
  • coreosのfleatとの違いなどはおいおい

環境の準備

  • さくらvpsにインストールしたcoreosの環境を使用する
  • NomadはGo製なので、ファイルを落として解凍するだけで使用できる
wget https://releases.hashicorp.com/nomad/0.1.2/nomad_0.1.2_linux_amd64.zip
unzip nomad_0.1.2_linux_amd64.zip

agentの起動

  • Getting Startedを参考に進めていく
  • テスト用途なので、-devオプションでagentの起動
$ sudo ./nomad agent -dev
  • 起動しているか確認
$ ./nomad node-status
ID                                    DC   Name      Class   Drain  Status
c2d5a0b7-9df0-a579-03b1-f48797191f49  dc1  tshvm001  <none>  false  ready
  • 停止はCtrl+C

  • DC名を変更してみる

$ sudo ./nomad agent -dev -dc sakura-ishikari
$ ./nomad node-status
ID                                    DC               Name      Class   Drain  Status
224d9fdc-b1c3-eff8-4dbc-c73c357756db  sakura-ishikari  tshvm001  <none>  false  ready

jobを実行してみる

  • jobの作成
  • 以下のコマンドを実行するとサンプルファイルができる
./nomad init
  • DC名変更したので、example.nomadのdc名を「sakura-ishikari」に修正

  • jobの実行

$ ./nomad run example.nomad
  • 実行時のログ
    2015/11/01 22:25:21 [DEBUG] driver.docker: docker pull redis:latest succeeded
    2015/11/01 22:25:21 [DEBUG] driver.docker: using image 05babbd460f79692240213d98c6e3d8aeb7d3e391f94a95ac6866e5ab207c8fd
    2015/11/01 22:25:21 [INFO] driver.docker: identified image redis:latest as 05babbd460f79692240213d98c6e3d8aeb7d3e391f94a95ac6866e5ab207c8fd
    2015/11/01 22:25:21 [DEBUG] driver.docker: using 268435456 bytes memory for redis:latest
    2015/11/01 22:25:21 [DEBUG] driver.docker: using 500 cpu shares for redis:latest
    2015/11/01 22:25:21 [WARN] driver.docker: no mode specified for networking, defaulting to bridge
    2015/11/01 22:25:21 [DEBUG] driver.docker: using bridge as network mode
    2015/11/01 22:25:21 [DEBUG] driver.docker: allocated port 153.126.155.210:35096 -> 6379 (mapped)
    2015/11/01 22:25:24 [INFO] driver.docker: created container 39f4ad6e24b51821651734d88b3a4fad3ac223e14eb2a7b441f78143b264a9b9
    2015/11/01 22:25:25 [INFO] driver.docker: started container 39f4ad6e24b51821651734d88b3a4fad3ac223e14eb2a7b441f78143b264a9b9
  • jobのstatus
$ ./nomad status example
ID          = example
Name        = example
Type        = service
Priority    = 50
Datacenters = sakura-ishikari
Status      = <none>

==> Evaluations
ID                                    Priority  TriggeredBy   Status
1ffa48a9-b6bd-f368-4995-78f72bf148a9  50        job-register  complete
6837350e-ed60-09a3-8c0c-d3d373c1de4b  50        job-register  complete
618fb2ed-af65-ff3c-8b02-3f9d03275f1d  50        job-register  complete

==> Allocations
ID                                    EvalID                                NodeID                                TaskGroup   Desired  Status
84ca6861-8c74-3a02-dac0-811173dd9110  1ffa48a9-b6bd-f368-4995-78f72bf148a9  224d9fdc-b1c3-eff8-4dbc-c73c357756db  cache       run      pending
  • docker psの結果
$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                             NAMES
39f4ad6e24b5        redis:latest        "/entrypoint.sh redi   16 minutes ago      Up 16 minutes       153.126.155.210:35096->6379/tcp   kickass_engelbart

起動している!
これだけでもなんとなく便利な感じがしてくる
クラスタ組んでもっと触ってみよう

さくらのVPSにcoreosをインストール

さくらのVPSにcoreosをインストール

coreosのインストール

1. イメージのダウンロード

  • このページからインストールしたいイメージをローカルにダウンロードする

2. sftpでさくらのVPSにuploadする

  • 2-1.「ISOイメージインストール」を選択

    gyazo.com

  • 2-2. sftpのアカウントを発行し、ファイルをアップロードする

  sftp アカウント@ホスト
  sftp> cd iso
  sftp> put coreos_production_iso_image.iso

3. coreosのboot

  • 3-1. 「ISOイメージインストール」を選択後、下の方にスクロールすると「設定内容を確認する」ボタンがあるので、クリックする

    gyazo.com

  • 3-2. 「インストールを実行する」ボタンをクリックしてbootする

    gyazo.com

4. 初期設定

sudo ifconfig eth0 xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx
sudo route add default gw xxx.xxx.xxx.xxx
sudo vi /etc/resolv.conf
  • 4-4. iterm2等のターミナルから接続を行う
ssh core@xxx.xxx.xxx.xxx

5. coreosインストール

  • 5-1. cloud-config.ymlファイルの作成
vim cloud-config.yml
#cloud-config

hostname: xxxxxx

write_files:
  - path: /etc/systemd/network/static.network
    permissions: 0644
    content: |
      [Match]
      Name=eth0

      [Network]
      Address=xxx.xxx.xxx.xxx/23
      Gateway=xxx.xxx.xxx.xxx
      DNS=xxx.xxx.xxx.xxx
      DNS=xxx.xxx.xxx.xxx

users:
  - name: xxxxxx
  - passwd: `openssl passwd -l`
  - groups:
    - sudo
    - docker
  ssh_authorized_keys:
    - ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxxx

※ coreユーザの設定を行いたい場合は、usersの部分に同様に設定を追加する必要がある
※ passwdの部分は、openssl passwd -lの実行結果を記載すること

  • 5-2. coreosインストール
## fdiskでインストール対象のディスクを確認
sudo fdisk -l

## インストール
sudo coreos-install -d /dev/vda -c cloud-config.yml -C stable
  • インストール完了のログ
2015-11-01 04:47:30 URL:http://stable.release.core-os.net/amd64-usr/766.4.0/coreos_production_image.bin.bz2 [195077671/195077671] -> "-" [1]
gpg: Signature made Wed Sep 16 23:11:07 2015 UTC using RSA key ID 1CB5FA26
gpg: key 93D2DCB4 marked as ultimately trusted
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: Good signature from "CoreOS Buildbot (Offical Builds) <buildbot@coreos.com>" [ultimate]
Installing cloud-config...
Success! CoreOS stable 766.4.0 is installed on /dev/vda
  • 5-3. インストールが成功したら、強制再起動

    gyazo.com

    • 強制再起動後、正常にIPアドレスの設定が反映されなかったので、
      コンソールから作成したユーザでログインし、再度再起動を実施した
reboot

確率分布(正規分布)

確率分布

  • 統計モデルの本質的な部品であり、データに見られる様々な「ばらつき」を表現します
  • 確率変数の値とそれが出現する確率を対応させたもの

用語

  • 確率変数(かくりつへんすう、英: random variable, aleatory variable, stochastic variable)とは、確率論並びに統計学において、ランダムな実験に拠り得られ得る全ての結果を指す変数である
  • μ(ミュー)は平均
  • σ(シグマ)は標準偏差
  • 確率密度関数(かくりつみつどかんすう、英: probability density function、PDF)とは、連続確率変数が取り得る或る値での相対尤度を記述する関数である
  • 尤度関数(ゆうどかんすう)とは統計学において、ある前提条件に従って結果が出現する場合に、逆に観察結果からみて前提条件が「何々であった」と推測する尤もらしさ(もっともらしさ)を表す数値を、「何々」を変数とする関数として捉えたものである

正規分布

  • 平均値の付近に集積するようなデータの分布を表した連続的な変数に関する確率分布である

  • 式

R

拡大

f:id:tshst:20151019075055p:plain