Beyond The Limit

はじまりは2001年

Dockerメモ4

ホストOSからコンテナへディレクトリを共有する

  • DockerはホストOSのディレクトリをコンテナ側へ見せることが可能になっている
  • -vオプションを利用して-v <ホスト側ディレクトリ>:<コンテナ側ディレクトリ>とする
  • docker run -v /root/docker-testdir:/root/docdoc -it --name test0x1 centos:centos6.6 /bin/bashこんな感じ、ホスト側の/root/docker-testdirをコンテナ側の/root/docdocディレクトリに割り当てる
  • コンテナ側で/root/docdocの中にファイルを作成すると、ホスト側では/root/docker-testdirの中にコンテナ側で作成したファイルが存在する
  • つまりホスト/コンテナ側から読み書きできる状態になっている

書き込み不可でコンテナへディレクトリを共有する

  • -v <ホスト側ディレクトリ>:<コンテナ側ディレクトリ>:roとする

共有可能なディレクトリの確認

  • docker inspect <container id> | <container image>で表示される
  • こんな感じで出てくる、docker inspectコマンドで色々と情報が取れる
    "Mounts": [
      {
        "Source": "/root/docker-testdir",   #コンテナ側ディレクトリ
        "Destination": "/root/docdoc",      #ホスト側ディレクトリ
        "Mode": "",                         #読み込み専用ならroと表示
        "RW": true,                         #読み書き出来るのでtrueになっている
        "Propagation": "rprivate"
      }

コンテナ間でのディレクトリの共有

  • docker run -v /root/dockertest -itd --name test0x4 centos:centos6.6 /bin/bashこれでコンテナtest0x4の/root/dockertestディレクトリができる
  • docker run --volumes-from test0x4 -it --name test0x5 centos:centos6.6 /bin/bashこれでコンテナtest0x5のroot/dockertestはtest0x4のディレクトリと共有されている -- --volumes-from <container id>オプションが必要 -- --volumes-from:ro <container id>にすると書き込み不可で共有されるが、提供側のコンテナでは読み書きが出来る

Dockerメモ3

Dockerコンポーネント

  • Docker エンジン:Docker本体のこと
  • Docker コンテナ:Dockerエンジンが実行するコンテナのこと
  • Docker クライアント:Dockerデーモンが提供する各種コマンドなどのIFのこと
  • DockerコンテナはホストOS上で複数同時に起動することができる、ホストOSから見ると分離された名前空間として見える

コンテナの起動

  • 例えば"/bin/bash"でコンテナを起動した後のプロンプトで"root@11450a5780f2"等と表示されるが、@の後ろはコンテナID
  • hostnameはコンテナIDが自動的に設定されるが、-hオプションで設定することも可能
  • コンテナをバックグラウンドで稼働させる場合は-dオプションを強する
  • 起動のコマンドはdocker start <container id>でOK、起動後はdocker psで確認ができるが、バックグラウンドで動いている

コンテナのイメージ化

  • 作成したコンテナをイメージ化することができる
  • docker commit <container id> <repository name>:<tag name> -- docker commit c7c2983acd46 local:test-run こんな感じ
  • アプリケーションごとにコンテナを作成してイメージ化しておけば、必要な時に必要なものをすぐ実行可能な状態でコンテナの再利用をすることができる
  • docker images --no-truncで本来のイメージID64文字で表示が可能、通常は12文字。イメージIDのみ出力したい場合はdocker images -qでOK

シェル変数にコンテナIDを入れると便利

  • abc=$(docker run -d --name centos-test -i -t centos:centos6.6 /bin/bash)を実行すると、コンテナIDがabcに代入される
  • コンテナIDは長いので便利そう?

コンテナの停止

  • docker stop <container id>でOK

コンテナのアタッチ

  • 一度停止したコンテナはdocker start -i -a <コンテナID>で再接続ができる -- iは標準入力を受け付けるオプション、-aはアタッチ
  • バックグラウンドで動作しているコンテナはそのままdocker attach <container id>でOK

コンテナとコンテナイメージの削除

  • docker rm <container id>でコンテナは削除可能 -- docker ps -a | awk '{print $1}' | xargs docker rmでまとめて一括で消せる -- 起動中のコンテナは削除できないが、-fオプションを付与することで強制的に削除可能
  • docker rmi <Image id>でコンテナは削除可能 -- docker images | awk '{print $3}' | xargs docker rmiでまとめて一括で消せる

コンテナの自動廃棄

  • docker runコマンドに--rmオプションを付与して起動すると、コンテナ停止時に自動的に廃棄される
  • -dオプションとはセットで利用できないので注意

Dockerメモ2

導入について

  • CPU:ハイパーバイザー型の仮想化ソフトウェアはCPUコアあたりのゲストOS数の目安があるが、Dockerの場合はそれがない
  • メモリ:ホストOS分+全コンテナで使用するメモリ容量を考慮して計算する
  • ディスク:Docker領域はユーザーの数やコンテナ数によって使用量が変わるので、OS領域とは別でディスクを確保した方が良い
  • devicemapper関連のパラメーターはDocker運用後には簡単に変更がきかないため、事前に注意が必要

コマンド

  • docker info:Dockerの設定値他の状態を取得できる
  • docker version:ClientとServerのバージョン情報を取得できる

Dockerメモ

改めてDockerの本を読んでいるのでメモ

Dockerコンテナのアーキテクチャ

コンテナ毎に空間を分離してくれる

  • ただしLinuxの基盤上でWindowsのコンテナを動かすことは出来ない
  • コンテナにはLinuxコンテナ(LXC)というものがあり、古いバージョンのDockerはLXCの機能を利用していた
  • LXDというものが最近出てきた
  • 現在のDockerはlibcontainerというドライバを利用しており、LXCには依存していない(Docker0.9以上)
  • Dockerはプロセスレベル、ファイルシステムレベルでの分離を行う

ハイパーバイザー型とコンテナ型の違い

  • ハイパーバイザー型は自身のゲストOS上のMBR領域に対してブートローダーをインストールする等の必要がある(物理OSを起動する時と同じような感じ)、コンテナ型はそういったものがないため、起動・停止が非常に高速。
  • ハイパーバイザー型はハードウェアをエミュレーションしているが、コンテナ型は名前空間とcgroupを利用してコンテナがプロセスとして稼働するだけなので、リソースが少なくて済む
  • コンテナ型はアプリケーションが分離されるが、ホストOS環境から直接実行されるため、ホストOSと同等の性能を発揮出来る

名前空間

  • プロセスでの分離が出来る、分離した空間同士を見えないように制御を行う
  • 名前空間にはいくつか種類があり、名前空間ごとにハードウェアリソースを割り当てているのがcgroup
  • Dockerコンテナを立ち上げると、ipc/mnt/net/pid/user/utsの名前空間が作られる

Docker導入準備

コンテナ専用OS

  • コンテナを稼働させること以外のパッケージやアプリケーションは極力排除されている、サーバーOSと比較してセキュリティ・性能面などで優位性がある
  • CoreOSとかPorject Atomicとか

Dockerにおけるドライバ

  • Dockerのバックエンドの仕組みとして、コンテナの生業を行う実行ドライバ、ファイルシステム関連の制御を行うストレージドライバの2種類がある
  • 実行ドライバは名前空間やcgroupを利用するのに必要
  • Dockerシステムの裏側で動作するバックエンドの実行ドライバーとしてlibcontainerがある
  • Docker0.9から組み込まれているので、DockerとLinuxカーネルの間にLXCなどのドライバを挟まなくても良くなった

もうすぐ一年が経ちます

転職してからもうすぐ一年が経ちます。気がついたら早いもので、この一年で公私ともに色々とありました。

転職して一年が経つということは、セールスエンジニアのキャリアも一年が経つということになります。 半年ぐらい前にはてなアドベントカレンダーにて、仕事のこととか書いてました。

sharatani.hatenablog.com

セールスエンジニアという肩書きで一年間ほど仕事をしてきたのですが、面白い仕事だな〜って一言に尽きます。 一生懸命やっているので、しんどいこともあれば、楽しいこともあるのが仕事なのですが、これまでの社会人としての人生を振り返っても面白い仕事です。

一年前を振り返ると、だいぶ成長した感はあるのですが、まだまだいけるしまだまだやれるし、まだまだやりたいことはたくさんあるので頑張ります。 弊社のCTOが「自分に限界を定めると、それが仕事の限界になる」というようなことを言っていて、厳しくなるとその言葉をよく思い出したりしています。

やりたいこと、知りたいこと、気になる技術はまだまだたくさんあるので頑張る!

MackerelでWindowsイベントログ監視とプロセス監視をする

ちょっと触ってちょっと検証したため、メモしておきます。

MackerelはWindowsでも利用可能ですが、公式のcheckプラグインWindowsに対応していないため、個別に用意する必要があります。

※プロセス監視のcheck-procsは公式に用意してあるのですが、自分でビルドする必要があります。

環境

Mac OSXを利用しています、gitやhomebrewなどは予め環境が出来ているという状況です。

Go環境の整備

Goの環境整備にあたっては、弊社のSongmuさんの記事を利用させてもらいました。

www.songmu.jp

check-procsのビルド

予め"$HOME/repos"というディレクトリを作っておきました。

git clone https://github.com/mackerelio/go-check-plugins.git

git cloneしてローカル環境にデータを持ってきます。

GOOS=windows GOARCH=386 go build -o check_procs_windows.exe

でビルドすると、こんなエラーが出ました。

check_procs.go:9:2: cannot find package "github.com/jessevdk/go-flags" in any of:
    /usr/local/Cellar/go/1.6/libexec/src/github.com/jessevdk/go-flags (from $GOROOT)
    /Users/sharatani/dev/src/github.com/jessevdk/go-flags (from $GOPATH)
check_procs.go:10:2: cannot find package "github.com/mackerelio/checkers" in any of:
    /usr/local/Cellar/go/1.6/libexec/src/github.com/mackerelio/checkers (from $GOROOT)
    /Users/sharatani/dev/src/github.com/mackerelio/checkers (from $GOPATH)

パッケージが見つからないと出ているので、以下のコマンドを実行します。

go get github.com/jessevdk/go-flags
go get github.com/mackerelio/checkers

その後で改めて以下のコマンドでビルドをします。

GOOS=windows GOARCH=386 go build -o check_procs_windows.exe

すると、check_procs_windows.exeが出来ています。

検証

AWSのWindowsServer2012R2で試してみました。

  • タスクマネージャー起動させる
  • コマンドプロンプトで"check_procs_windows.exe --pattern Task"実行
    • "Procs OK: Found 1 matching processes; cmd /Task/"が表示されたのでOK
  • タスクマネージャーを終了させて、再度コマンド実行して確認
    • "Procs CRITICAL: Found 0 matching processes; cmd /Task/"が表示されたのでOK

mackerel-agent.confへ記述するには、こんな感じです。

[plugin.checks.taskmanager-procs]
command = "C:\\Users\\Administrator\\Downloads\\check_procs_windows.exe --pattern Task"

confを変更して有効化するには、サービスからmackerel-agentを再起動させる必要があります。

Windowsのイベントログ監視

イベントログを監視するにはいくつか方法があるのですが、試した結果、パワーシェルを使うよりもexeを使った方が楽でした。

一旦こちらからexeプログラムをダウンロードします。

check_winevent - NRPE check plugin for Windows eventlogs | itefix.net

単体でコマンドプロンプトから実行したら、こんな感じでした。

C:\> check_winevent.exe --log application --type error

EVENT OK - 2 events|events=2;;;

これはアプリケーションログに対して、タイプがエラーになっているものが2件見つかったため、2と表示されています。 2と言ってもログの確認範囲(いつからいつまでなのか)が分からなかったので、いくつか試したところ・・・・

試しにコマンドをちょっと変えて実行してみました。

C:\> check_winevent\\check_winevent.exe --log application --type error --critical 0

EVENT CRITICAL - 2 events|events=2;;0;

0以上の場合はCRITICALにするオプションを付与したところ、CRITICALが返ってきています。

--verboseオプションを付与して、出力を詳細に出してみました。

C:> check_winevent.exe --log application --type error --verbose

Event log(s): application
Event code(s): all
Event type(s): error
Event sources: all
Time window: 3600 seconds, timestamp: 20160517043648.000000+000
Eventlog application - 2 selected events
Total number of events selected: 2

EVENT OK - 2 events|events=2;;;

これを見ると、Time windowという項目が有り、3600秒=60分が検出の対象になっているようです。 --windowオプションで秒数を変更出来るようなので、60秒にして実行した見たところ、今度はCRITICALではなくOK表示でした。

C:> check_winevent.exe --log application --type error --critical 0 --window 60

EVENT OK - 0 events|events=0;;0;

他にもいくつかオプションはあるようなのですが、ちゃんと動いていそうなので、細かい所はまた後で。

mackerel-agent.confにはこのように記述します、記述後はサービスからmackerel-agentを再起動させて反映します。

[plugin.checks.windowsApp-exe]

command = "C:\\Users\\Administrator\\Downloads\\check_winevent\\check_winevent.exe --log application --type error --critical 0"

IDCFクラウドMeetup!in Osaka vol.1に参加してきました

昨日はこちらのイベントに参加してきました。

idcfugosaka.doorkeeper.jp

今回の会場はファーストサーバーさんの会議室をお借りしていて、会議室は満席の状態。 大阪では初開催だったのですが、とにかく人が多くて、利用者からの愛され感が伝わる会場でした。

さいとうさん(IDCF-UG代表)の発表

  • 会場にいる人達へのアンケート・・・「使っている人手を挙げて下さい」
  • 単純比較はできないが、IDCFクラウドは他クラウドと比較して起動速度が速い
    • その中でもradianリージョンが一番早い、東日本リージョンはradianがおすすめ
  • オールフラッシュ本当に速いのか?
    • さいとうさんがRead速度を検証した結果、目を疑うレベルで速い!
      • 元々速かったけど、より速くなった
  • クーポンフル活用案
    • 3千円クーポンで500円サーバーを一時的に利用して、検証・ハッカソンなどをしてみる
  • ユーザーグループを立ち上げた理由
    • ユーザー目線で本音のフィードバックをしたいというのが主な理由
  • コミュニティテンプレートのハッカソンを企画中!

IDCF藤城さんの発表

  • 趣味活動で72Core/128GBmemのマシンを利用して、自宅でベンチマークやってる
  • 「実はIDCFって○○なんです」×7!
    • 実はIDCFクラウドが300円くらいでも十分使えます

      • サーバーS1+ボリューム4GBだと280円
        • ブラウザ上でKVMコンソールが使えるから、何かあった時には色々と便利
        • コンソールの利用時にはVMware Toolsのインストールがオススメ
    • 実は無料でロードバランサーがあり、それなりに使えます

      • Active-Standbyの冗長構成、ヘルスチェックもある、パーシステンスもある、レポート情報も見られる
      • 仮想ルーターはMackerelで監視可能
    • 実は標準でDDoS対策がついてます

      • 利用者側は何もしなくてもOK!
      • レポーティング・コンサルティング・チューニングの有償プランもあり
    • 実は今後新しいゾーンはすべてオールフラッシュです

      • I/Oが超高速、IOPSも安定、値段も据え置き
        • でも従来のストレージも結構速い
    • 実はサーバーを起動した状態でスペックアップができます

      • あんまり知られていないが、実は目玉機能の「ダイナミックスケール」
        • いくつか制限はあるので、詳細はFAQやテックブログを
    • 実はメタデータサーバーがあります

    • 実は「ほぼ毎週リリースをしています」

      • Mackerelの毎週リリースを意識して対応してくれてる(嬉しい)
      • 機能要望はチケット経由がベスト!

はてなSongmuさんの発表

  • 「Mackerelはこう使え!」
    • IDCFのVM作成からMackerelのインストールを兼ねたデモ、Mackerelの紹介やロードマップ紹介など

IDCFクラウドユーザーグループ大阪は逢坂さん一人なので、メンバーを募集しているそうです。 まだ立ち上げたばかりと言っても、今回だけでたくさんの方が来場されているので次回がとても楽しみですね。

Python学習メモ7

位置引数のタプル化

関数の引数を可変にして仮引数にセットしている。

>>> def print_kahen(*args): *は必要だが、argsじゃなくても良い。慣習的にargsになっている。
...     print ('kahen argument:',args)
...
>>> print_kahen(1,2,3)
kahen argument: (1, 2, 3)
>>>
>>> print_kahen()  引数が何もない場合は何も無い
kahen argument: ()
>>>
>>> def print_kahen2(need1,need2,*args):   引数1と引数2、その他は全てotherに入る
...     print ('need1=',need1)
...     print ('need2=',need2)
...     print ('other=',*args)
...
>>>
>>> print_kahen2(1,2,3)


need1= 1
need2= 2
other= 3
>>> print_kahen2(1,2,3,45)
need1= 1
need2= 2
other= 3 45
>>> print_kahen2('App','Disk',3,'Memory')
need1= App
need2= Disk
other= 3 Memory
>>>

docstring

関数内にドキュメントを残す場合、help(関数名)で関数の中に残されたドキュメントを整形して表示してくれる

関数の定義

>>> def add_args(args1,args2):  引数1と引数2を合算する関数
...     print (args1 + args2)
...
>>> add_args(100,29)
129
>>> def run_some2(func,args1,args2):   run_some2関数は引数を3つ取る
...     func(args1,args2)   func=引数1つめの関数を実行する、funcの引数はrun_some2の引数2と引数3を指す
>>> def run_some2(func,arg1,arg2):
...     func(arg1,arg2)
...
>>> run_some2(add_args,50,80)  run_some2関数にadd_args関数、50、80を引数として渡した
130 add_args関数が実行され、50+80=130が結果として帰ってきた
>>>

Python学習メモ6

内包表記

  • リスト内包表記

[expression for item in iterables] コンパクトに構文を作成できる

>>> num_list = []
>>> for num in range(1,6):
...     num_list.append(num)
...     (forの処理の終わりは何も入力せずにEnterを押す)
>>> num_list
[1, 2, 3, 4, 5]
>>>
    上も下も同じ事を実施したということ
>>> num_list = [num for num in range(1,6)]
>>> num_list
[1, 2, 3, 4, 5]
>>>
  • 辞書内包表記

{key_item:value_item for item in iterable}

辞書でも同じようにできる

>>> let_count = {letter:words.count(letter) for letter in words}
>>> let_count
{'l': 1, 't': 2, 's': 1, 'r': 1, 'e': 2}
>>>
  • 集合内包表記

{item for item in iterable}

  • ジェネレータ内包表記

タプル()には内包表記がない、リスト内包表記の[]を()に変えても正常動作するが、これはジェネレータ内包表記となる

ジェネレータは一度しか実行出来ない、一度作ると値をイテレータに渡してしまうので作った物を再利用できない。

>>> num_list = (num for num in range(1,6))  こんな感じでジェネレータ内包表記を作る
>>> for numb in num_list : こんな感じで取り出す
...     print (numb)
...
1
2
3
4
5
>>>     print (numb)
  File "<stdin>", line 1
    print (numb)
    ^
IndentationError: unexpected indent
>>>

関数

  • 最初にdef、次に関数名を各、関数に対する入力引数をかっこに囲んで各、最後にコロンを書く
>>> def com(color):
...     if color == 'red':
...             return 'color is red'
...     elif color == 'blue':
...             return 'color is blue'
...     elif color == 'green':
...             return 'color is greeeeeen'
...     else:
...             return 'other'
...
>>>
>>> com('red')
'color is red'
>>> com('blue')
'color is blue'
>>> com('greeen')
'other'
>>> com('green')
'color is greeeeeen'
>>>
>>> com2 = com('white')
>>> com2
'other'
>>> com3 = com('red')
>>> com3
'color is red'
>>>

位置引数

  • 先頭から順番に対応する位置の仮引数にコピーされる位置引数、関数の引数が何をどの順番にしているのかを覚えておかないといけない
>>> def menu(a,b,c):    位置引数から辞書を作って返す
...     return {'drink':a,'food':b,'etc':c} aの引数はdrinkに対応する、bの引数ははfoodに対応する、cの引数はetcに対応する
...
>>> menu('coffee','cake','cherry')
{'food': 'cake', 'etc': 'cherry', 'drink': 'coffee'}    ただし対応しているが、返ってくる順番はバラバラ
>>>

キーワード引数

  • 位置引数で定義した仮引数の名前を指定して実引数を指定する、順番はばらばらでも構わない
>>> menu(c='beer',b='apple',a='niku')
{'food': 'apple', 'etc': 'beer', 'drink': 'niku'}   drink,food,etcにそれぞれ対応している
>>>
>>> menu('beer',c='apple',b='niku')    位置引数と併用する場合、先に位置引数を指定する必要がある
{'food': 'niku', 'etc': 'apple', 'drink': 'beer'}
>>>
>>> menu('beer','apple',c='niku')  cだけ後で指定した場合
{'food': 'apple', 'etc': 'niku', 'drink': 'beer'}
>>> menu('beer',b='apple','niku')  この場合はエラーになる
  File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>>

デフォルト引数値の指定

  • 引数が何も指定されなかった場合など、デフォルト値を設定することができる
>>> def menu(a,b,c='prin'): cに何も設定されなかった場合は'prin'を返す
...     return {'tabemono':a,'nomimono':b,'etc':c}  その場合はetc:printとなる
...
>>>
>>> menu('ebi','ikura')    a,bは指定、cは何もなし
{'nomimono': 'ikura', 'etc': 'prin', 'tabemono': 'ebi'} etc:prinが返ってきた
>>>

Puthon学習メモ5

  • リストは、タプルは()、辞書は{}で作る
  • いずれにしてもを使って値を取り出す、辞書の場合はキーを入れる、それ以外は整数のオフセットを入れる

  • Pythonには複数行コメントはない、複数の場合も頭に#を付ける

辞書を使ったfor文

>>> e2f
{'cat': 'chat', 'walrus': 'morse', 'dog': 'chien'}
>>> for i in e2f:
...     print (i)   キーが返ってくる
...
cat
walrus
dog
>>>
>>> for i in e2f.values() :    values()関数を付けると、キーではなく値が返ってくる
...     print (i)
...
chat
morse
chien
>>>
>>> for i in e2f.items() : items()関数を付けると、キーと値がタプルで返ってくる
...     print (i)
...
('cat', 'chat')
('walrus', 'morse')
('dog', 'chien')
>>>
>>> for i1,i2 in e2f.items() :
...     print ('one is',i1,'two is',i2) i1にkey、i2にvalueを入れた場合


...
one is cat two is chat
one is walrus two is morse
one is dog two is chien

リストの場合はこんな感じ

>>> a
[1, 2, 3]
>>> for i in a :
...     print (i)
...
1
2
3
>>>