OpenStackのGnocchiについて

従来Ceilometerは仮想マシン等のステータス情報をMongo DB等の各種DBを利用していました。このCeilometerの時系列データーを保存する先として従来のDBではスケール上の問題点を抱えていたとの事で、専用のDB ProjectがCeilometer Projectから独立しました。このProjectがGnocchiです。GnocchiはRDOでPackstackを使ってインストールする場合も選択可能となっています。また、RHOSP 9からもRHOSP Directorを利用してのインストールでも利用出来る用になってます。

RHOSP9 Release Note

Gnocchiについて

Gnocchiは時系列データーを保存するデーターベースです。OpenStackが必須ではなく独立してインストールする事も可能です。データーの保存先は、2016年8月時点でFile / Swift / Cephから選択可能です。データーはRESTを使って保存が可能となっています。

Gnocchi Storage Driver

 Gnocchiのインストールについて

GnocchiはRDOで簡単に利用してみることが出来ます。PackstackのAnswer Fileで以下の項目を変更する事で、Ceilometerの情報がGnocchiに保存されます。

CONFIG_GNOCCHI_INSTALL=y
CONFIG_CEILOMETER_METERING_BACKEND=gnocchi

データーの保存について

Gnocchiではインデックスデーターと、時系列データーの保存先を選択出来ます。インデックスデーターはMariaDBやMySQL等に保存します。時系列データーは2016年8月時点では File / Swift / Cephから選択可能です。ファイルの形式は、Gnocchi用に作成されたcarbonara形式となっています。FIleで冗長構成を取る場合はGnocchiが動作しているノード間でNFSで保存先のフォルダの共有が必要になります。ファイルの場合は実データーは/var/lib/gnocchiにファイルとしてデーターが保存されます。実際のデーターは以下の用に保存されます。

# ls -la
total 56
drwxr-xr-x. 17 gnocchi gnocchi 4096 Aug 27 19:21 .
drwxr-xr-x. 56 root root 4096 Aug 27 19:36 ..
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 02fc50b4-95c4-463f-8e5a-c74f142c5931
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 1af707c0-59dd-4eaf-a53a-f4589624818f
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 34c1d5cf-e3c2-41fc-8434-32e8254f7013
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 3d0c4f61-de35-433b-881f-8d5726536c4c
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 3e56d049-e8df-46dd-ba7b-9be24641f057
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 434056ec-2ce8-4257-ac4b-bdfb570f792e
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 613c399e-7267-48f3-8690-f8d06bf4fe97
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 6d472998-5ba0-4b0d-a1cc-8b735eb8c237
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 949b11c5-7385-4d0f-9b37-9070d2694449
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 a14151c5-aa9d-47a4-996a-f7cfa20c5fc9
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 a2ebaaa5-05d6-4825-b88c-dfdf329d4058
drwxr-x---. 10 gnocchi gnocchi 4096 Aug 27 19:21 ce74fcee-efd0-41af-a1ce-8a7c785e6d46
drwxr-xr-x. 2 gnocchi gnocchi 6 Aug 27 19:42 .matplotlib
drwxr-xr-x. 2 gnocchi gnocchi 6 Aug 27 19:21 measure
drwxr-xr-x. 2 gnocchi gnocchi 6 Aug 27 19:21 tmp

大規模環境ではCephへの保存が推奨されています。データーの保存期間や形式はArchiving Policyによって指定されます。Archive PolicyはDefaultではLow / Medium / Highが設定されていますが、自作することも出来ます。Ceilometerの生成するデーターのArchive Policyはceilometer.confで指定する事が出来ます。

コマンドラインでの操作

GnocchiはCLIが用意されてます。GnocchiをKeystoneの認証を連携させている場合は設定ファイルをsourceしてコマンドを実行します。RDOの場合はkeystonerc_adminのファイルをsourceします。gnocchiでは以下のようにコマンドを発行します。

# gnocchi resource list
+------------------------+------------------------+------------------------+------------------------+------------------------+------------------------+----------+-----------------------------+--------------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end |
+------------------------+------------------------+------------------------+------------------------+------------------------+------------------------+----------+-----------------------------+--------------+
| 5e3fcbe2-7aab-475d- | generic | None | None | None | 2016-08-26T03:15:03.33 | None | 2016-08-26T03:15:03.335031+ | None |
| b42c-a440aa42e5ad | | | | | 5006+00:00 | | 00:00 | |

+------------------------+------------------------+------------------------+------------------------+------------------------+------------------------+----------+-----------------------------+--------------+

詳しくは以下に記載されています。

http://gnocchi.xyz/gnocchiclient/shell.html

Grafanaでの可視化

Gnocchiに保存されているデーターはGrafanaで可視化出来ます。Grafanaで可視化する場合はGnocchi用のプラグインがリリースされているためそれをインストールして連携を行います。

$ sudo grafana-cli plugins install sileht-gnocchi-datasource

プラグインをインストールするとGrafana上のデーターソースにGnocchiが出てきます。データーソースとしてGnocchi IPを指定するか、Keystone経由でGnocchiを見つける事が出来ます。データーはブラウザから直接Gnocchiに接続して取得するdirectか、一度Grafanaサーバーで受けるかのproxy指定が出来ます。proxyの時はGrafanaの制約で複数のサーバーに問い合わせが出来ないとの事でKeystoneが利用出来ません。

screencapture-10-44-58-140-3000-datasources-new-1472448833970

DataソースとしてGnocchiを指定してQueryを発行すると、取得したデーターからグラフの作成が出来ます。以下は特定のホストに載っている仮想マシンのCPU使用率を表示しています。

screencapture-10-44-58-140-3000-dashboard-db-new-dashboard-1472535027549

まとめ

Gnocchiは、Projectが発足して時間が経っていないので、まだまだ採用されないと思っていました。RedHatが積極的に採用していく流れのようなので、今後とも注目していきたいと思っています。

OpenStackのGnocchiについて

OpenStack上のNWトラフィックをKibanaで可視化する

Logの可視化として、FuluentdとElasticsearch/Kibanaの組み合わせが使われています。今回のこの組み合わせで、OpenStackのOVS上に流れるトラフィックを可視化します。NWトラフィックを可視化する場合にOpenStack環境の物理スイッチ側でトラフィックを取ることも出来ますが、仮想マシン間の通信がホスト内で完結されてしまうと、その部分のトラフィックの様子を見る事が出来ません。OpenStackの構造上、各ホスト上のbr-int上を流れるトラフィックを可視化出来れば仮想マシン間も含めたすべての通信を見ることが出来ると考えられます。

Netflow / sFlowについて

NetflowはCisco機器が備えているNW可視化の仕組みです。ポートミラーリングはトラフィクをコピーする仕組みですが、NetflowはIPアドレスやポート番号等の情報を抜き出して、指定のホストに対して情報を送信する仕組みです。sFlowはNetflowを一般化したものになります。Fluentd用にNetflowプラグインが開発されていますので、Netflowで出力すれば簡単にElasticsearch側にデーターを出力出来ます。しかしながらOVSはNetflowでの出力も備えていますが、サンプリングレートや出力先のインターフェースの指定を備えていないようです。今回br-intのトラフィックを取るためにインターフェース自体にIPは振られていないため、出力先インターフェースの指定が必要です。そのため今回はOVSからはsFlowで出力して、それをNetFlowに再変換してElasticsearchに入力します。

OVSの設定を行う

OVS上でのsFlowの設定方法は以下に詳しく述べられています。

http://openvswitch.org/support/config-cookbooks/sflow/

OpenStackのコンピュートノードや、コントローラーノード上で以下の設定を行いbr-int上に流れるトラフィックのsFlowのデーターを送付します。送信先はsFlow Toolが動作するホストになります。sFlow Toolが動作するホストは10.0.0.1の想定で設定しています。

ovs-vsctl — –id=@sflow create sflow agent=eth1 target=”10.0.0.1:6343″ header=128 sampling=64 polling=60 — set bridge br-int sflow=@sflow

sFlow Toolを使う

sFlow ToolはsFlowを可視化してくれたり、NetFlowへの変換行ってくれるツールです。基本的に以下のレポジトリからCloneして、makeすればバイナリを生成して利用出来ます。

https://github.com/sflow/sflowtool

以下のコマンドで起動しておけばsFlow ToolがsFlowのデーター受け取った後に、Netflowに変換して送信してくれます。以下はLocalのFluentdに送信する想定です。

sflowtool -p 6343 -c 127.0.0.1 -d 5140

FluentdのNetflow Pluginを使う

Fluentd用のNetflow Pluginは以下で開発されています。

https://github.com/repeatedly/fluent-plugin-netflow

FluentdのコマンドでこのNetflow Pluginをインストールします。

td-agent-gem install fluent-plugin-netflow

インストール後にFluentdのtd-agent.confで以下の設定を行えば変換されたNetflowのトラフィックを受け取る事が出来ます。受け取ったNetflowのトラフィックにはgeo.netflowのタグ付けをして次の処理を行います。

<source>
  type netflow
  tag geo.netflow
  port 5140
  versions [5]
</source>

IPアドレス情報からGeoLocationを生成する

sFlowで収集した情報にSourceやDestのIPアドレスを元に、GeoLocatoinのタグを付与してあげれば、Kibana上で通信の場所をプロット出来ます。今回はFluentdのIPアドレスからGeoLocationタグを生成出来る以下のプラグインを利用します。

https://github.com/y-ken/fluent-plugin-geoip

以下のコマンドでインストールします。Developer Tool等のインストールも必要になります。

# sudo yum group install "Development Tools"
# sudo yum install geoip-devel --enablerepo=epel
# td-agent-gem install fluent-plugin-geoip

以下の設定をtd-agent.confに追加するとGeo Locationへの変換を行ってくれます。今回の設定ではDestination IPを元にGeoタグを付与しています。

<match geo.netflow>
  type geoip
  geoip_lookup_key ipv4_dst_addr
  <record>
    geoip_pin ${latitude["ipv4_dst_addr"]},${longitude["ipv4_dst_addr"]}
  </record>
  remove_tag_prefix geo.
  tag es.${tag}
  skip_adding_null_record
</match>

Elasticsearchにデーターを送る

データーを送信し始める前にElasticsearch側が必要なデーターをGeo Tagとして認識出来るようにテンプレートを定義しておきます。

curl -XPUT localhost:9200/_template/flow -d '
{
  "template" : "flow-*",
  "mappings" : {
    "netflow" : {
      "properties" : {
        "@timestamp" : {
          "type" : "date",
          "format" : "dateOptionalTime"
        },
        "ipv4_src_addr" : {
          "type" : "string"
    },
        "geoip_pin" : {
          "type" : "geo_point"
        }
      }
   }
  }
}'

FluentdのElasticsearchプラグインをインストールします。

# td-agent-gem install fluent-plugin-elasticsearch

FluentdのElasticsearchプラグインでデーターを送付します。td-agnt.confの設定は以下の通りです。以下の例ではLocalのElasticsearchにデーターを送信しています。

<match es.netflow>
  type elasticsearch
  host 127.0.0.1
  port 9200
  type_name netflow
  logstash_format true
  logstash_prefix flow
</match>

Kibanaで可視化する

Elasticsearchで集めたデーターはKibanaを使って、以下のように可視化出来ます。

図1

まとめ

実運用で使うなら、sFlow toolを挟まずにFluentdかLog StashのsFlowプラグインを開発した方が良い気がします。

OpenStack上のNWトラフィックをKibanaで可視化する

Hyper-V上へのOpenStackインストール

OpenStackのPOC環境でOpenStackの動作を確認する場合に、物理マシンを使うのが正解ですが再インストールを繰り返すなら仮想化環境上の仮想マシンにインストールすると色々便利です。仮想化環境はKVMやVMwareを利用しても良いですが、今回はHyper-Vを利用してみます。KVMやVMwareはよく利用されますがHyper-Vはあまり経験が無かったので共有します。

仮想マシンの作成とインストール

今回は、OpenStackの外部接続用とマネジメント+Data用の2つのNWを用意します。仮想スイッチは外部で作成するため、Hyper-Vのホストに2つのNICを用意しておきます。まずは仮想マシンをマネジメント+Data用のNWに接続して起動します。仮想マシンは第1世代で作りました。またメモリはOpenStackを動作させるなら最低でも4G以上の設定をしておきます。今回はRDOでPackstackを使ってインストールするのでCentOS7.1のISOをマウントして、仮想マシンへのインストールを行います。2台目を用意して、複数のComputeを試してみたい場合は同様の設定の仮想マシンをもう一台用意します。 “Hyper-V上へのOpenStackインストール” の続きを読む

Hyper-V上へのOpenStackインストール

DatadogでOpenStackをモニターする

DatadogモニタリングをSaaSで提供しているサービスですが、OpenStackと接続出来るIntegrationが提供されています。今回はOpenStack Integrationを利用して、DatadogからOpenStackをモニターします。

Datadogについて

DatadogはSaaSベースで提供されていますモニタリングサービスです。各種アプリケーションや、サービスに対応したIntegrationが提供されており簡単にメトリックの追加を行うことが出来ます。PythonベースでIntegrationを自作する事も出来ます。

Datadogの利用開始

Datadogは以下サイトでサインアップをすると無料枠で利用出来ます。

https://www.datadoghq.com/

サインアップ後の画面を進めると、Datadog Agentのインストール画面が出てきます。利用するOSを選択して、Datadog Agentのインストール方法を確認します。CentOSであれば、ワンライナーでインストールからDatadog Agentの起動が行われます。このスクリプトはYumレポジトリの登録と、Datadog Agentのインストール後にDatadog Agentの設定を行ってくれます。Agentをインストールすると自動的にDatadogのサービスに対してデーターが送信されます。AgentのステータスはCent OSであれば以下のコマンドで確認が可能です。内部的には複数のサービスが動作しているため、こののコマンドでの正常動作の確認は必須です。

service datadog-agent info

“DatadogでOpenStackをモニターする” の続きを読む

DatadogでOpenStackをモニターする

OpenStack IronicでVirtualBoxを操作する

Ironicは物理マシンと接続して、電源管理等を行うために様々な機器に対応したドライバーが提供されています。その中で、検証等に使えるVirtual Box用のドライバーも提供されています。Vitual boxが操作出来るドライバーはSSHを使ってコマンドを発行するSSHドライバーとVirtual BoxのSOAP APIに接続する2種類提供されています。

SSHドライバーについて

SSHドライバーはVirtual Boxを含む仮想化環境に対応しています。virtual box / virsh / vmware / parallels / xenserverと多種多様な仮想化環境に対応しています。SSHドライバーは仮想化基盤にSSHで入ってコマンドを発行して操作するためにSSHのホスト側の機能が必要です。例えばVirtual BoxであればVBoxManageコマンド、VMware(ESXi)であればvim-cmdコマンド、virshであればvirshコマンドで操作を行います。

https://github.com/openstack/ironic/blob/master/ironic/drivers/modules/ssh.py

Virtual Boxドライバー

SSHのサーバーを立てれない場合の為に、Virtual Boxが提供しているWeb Serviceを使うドライバーも提供されています。これはKiloで提供されました。これを使えばMACやWindowsでVirtual Boxを動作させて手軽にIronicの試験が出来るようになります。今回はRDOのLiberty版を利用して、両方のドライバーの使い方を解説します。

http://docs.openstack.org/developer/ironic/drivers/vbox.html

“OpenStack IronicでVirtualBoxを操作する” の続きを読む

OpenStack IronicでVirtualBoxを操作する

GoでOpenStackを操作する

OpenStackを操作するGoのSDKとして、OpenStackコミュニティ側にGoのSDKがあります。現在は残念ながら開発は止まっているようです。その代わりにRackspaceが開発を行っているGopher CloudがOpenStack用のGoのSDKとして活発に開発が行われています。

http://gophercloud.io/

今回はこのGopher Cloudを利用して、Goを使ってOpenStackの操作を行いたいと思います。

インストール

Goは以下からDownloadしてインストールを行います。主要Platformではインストーラー形式で提供されています。

https://golang.org/dl/

環境変数GOPATH配下にパッケージがインストールされるため、まずは環境変数を設定しておきます。自分で作成するのコードはsrc配下にフォルダ等を作成して配置します。githubアカウントがある場合はgithub.com配下にアカウント名でフォルダを作成するか、github側の自分のレポジトリを作ってgo getしても良いです。その後以下のコマンドでgophercloudのインストールを行います。これにより、$GOPATH/src/github.com/rackspace/gophercloud配下にコードがDownloadされます。

go get github.com/rackspace/gophercloud


認証

“GoでOpenStackを操作する” の続きを読む

GoでOpenStackを操作する

Cisco SparkのAPIを利用してみる

CiscoがリリースしているSlack的なサービスとしてCisco Sparkがあります。企業向けのCollaboration製品(電話やビデオ会議)と連携出来る特徴があります。

https://web.ciscospark.com

このCisco Sparkですが、これまではAPIは非公開で様々な連携は出来ませんでしたが、12月にAPIが公開されました。APIはREST APIで実装されています。以下に詳細の使い方が書かれていますがざっとした使い方を解説します。

https://developer.ciscospark.com/getting-started.html

Tokenについて

APIはTokenを添付して送信することで利用可能となっています。Tokenはユーザー毎の固定TokenとApplication毎に発行されるTokenがあります。2016/1/3現在は検証を行うのであればユーザー毎のTokenは期限が無く利用が容易になっています。ApplicationのTokenはOauth2を使っての発行と、2時間毎にリフレッシュ処理、60日毎に再取得が必要となります。このため、まずはユーザーTokenを使って検証してその後Application Tokenを使うことが推奨されています。ユーザーTokenは上記のCisco SparkのDeveloperサイトでログイン後、右上に表示される自分のアイコンをクリックすると取得出来ます。Tokenはリクエスト時にHeaderに添付して送信します。HeaderへのTokenの添付は、キーがAuthorizationで”Bearner “の後に取得したTokenを追加します。Pythonで書くと以下の例になります。

token = "Bearer " + TOKEN
header = {"Authorization": "%s" % token}

情報の取得(Room一覧の取得)

上記で取得したTokenを添付して、HTTPのGET Requestを発行すると各種情報を取得出来ます。以下はPythonでRoom一覧を取得する例です。-tokenで各自取得したTokenを添付します。以下のコードをgetrooms.pyと保存した場合は以下のように実行します。

# python getrooms.py -token TOKEN

import requests
import argparse


def main():
    p = argparse.ArgumentParser()
    p.add_argument("-token", default="")
    args = p.parse_args()
    token = "Bearer " + args.token

    header = {"Authorization": "%s" % token}
    requests.packages.urllib3.disable_warnings()
    get_rooms_url = "https://api.ciscospark.com/v1/rooms"

    api_response = requests.get(get_rooms_url, headers=header)
    response_json = api_response.json()
    print(response_json)

if __name__ == '__main__':
    main()

投稿(Roomの作成とメッセージの投稿)

Cisco Sparkに対してPost Messageを送信すると各種作成や、メッセージの投稿が出来ます。

Roomの作成

上記と同様にTokenを添付して、Postを送信するとRoomを作成出来ます。-tokenでTokenを添付して、-titleでルーム名を指定します。

import requests
import argparse


def main():
    p = argparse.ArgumentParser()
    p.add_argument("-token", required=True)
    p.add_argument("-title", required=True)
    args = p.parse_args()

    token = "Bearer " + args.token
    header = {"Authorization": "%s" % token}
    post_room_url = "https://api.ciscospark.com/v1/rooms"
    payload = {"title": args.title}
    api_response = requests.post(post_room_url, json=payload, headers=header, verify=False)
    response_json = api_response.json()
    print(response_json)

if __name__ == '__main__':
    main()

メッセージの投稿

HTTPのPOSTをRequestを発行すると、各種メッセージを投稿出来ます。-tokenでTokenを指定し、-roomで投稿先のルームのID、-textで送信するメッセージを指定します。

import requests
import argparse


def main():
    p = argparse.ArgumentParser()
    p.add_argument("-token", default="")
    p.add_argument("-room")
    p.add_argument("-text")
    args = p.parse_args()

    token = "Bearer " + args.token
    header = {"Authorization": "%s" % token, "content-type": "application/json"}
    post_message_url = "https://api.ciscospark.com/hydra/api/v1/messages"
    payload = {
        "roomId": args.room,
        "text": args.text
    }
    api_response = requests.post(post_message_url, json=payload, headers=header, verify=False)
    response_status = api_response.status_code
    print(response_status)

if __name__ == '__main__':
    main()

WebHookについて

登録しておくと指定のFilter(Meeting Room等)で指定のAction(Messageがポストされた等)が行われると、指定のサーバーに対してメッセージが送信されます。WebHookを受けるサーバーはGlobal IPアドレスを持っておく必要が有ります。WebHookの参照/登録/削除は今のところAPI経由でしか行えません。

WebHookの登録状況の確認

登録状況を参照するPython Scriptです。-tokenでTokenを指定します。

import argparse
import requests
import json

def main():
    p = argparse.ArgumentParser()
    p.add_argument("-token", default="")
    args = p.parse_args()

    token = "Bearer " + args.token
    header = {"Authorization": "%s" % token}
    get_webhooks_url = "https://api.ciscospark.com/v1/webhooks"
    api_response = requests.get(get_webhooks_url, headers=header)
    response_json = api_response.json()
    print(json.dumps(response_json ,sort_keys=True, indent=4))

if __name__ == '__main__':
    main()

WebHookの登録

以下はWebHookを新たに登録するScriptです。-tokenでTokenの指定、-urlでWebHookを送るURLの指定、-roomでWebHookをTriggerするルームIDを指定します。Messageが新規で投稿されるとWebhookがCisco Sparkのサービスから送信されて来ます。

import requests
import argparse

def main():
    p = argparse.ArgumentParser()
    p.add_argument("-token", default="")
    p.add_argument("-url", default="")
    p.add_argument("-room", default="")
    args = p.parse_args()

    token = "Bearer " + args.token
    header = {"Authorization": "%s" % token, "content-type": "application/json"}
    post_message_url = "https://api.ciscospark.com/v1/webhooks"
    payload = {
        "resource": "messages",
        "event": "created",
        "filter": "roomId="+args.room,
        "targetUrl": args.url,
        "name": "bot"
    }
    api_response = requests.post(post_message_url, json=payload, headers=header)
    response_status = api_response.status_code
    print(response_status)

if __name__ == '__main__':
    main()

WebHookの削除

以下は削除するScriptです。実行時に-tokenでTokenの指定、-webhookでWebhookの名前を指定します。

import requests
import argparse

def main():
    p = argparse.ArgumentParser()
    p.add_argument("-token", default="")
    p.add_argument("-webhook", default="")
    args = p.parse_args()

    token = "Bearer " + args.token
    header = {"Authorization": "%s" % token}
    delete_webhooks_url = "https://api.ciscospark.com/v1/webhooks"
    payload = {"webhookId": args.webhook}
    api_response = requests.delete(delete_webhooks_url, headers=header, verify=True, params=payload)
    print(api_response.url)
    response_status = api_response.status_code
    print(response_status)

# run main function
if __name__ == '__main__':
    main()

まとめ

Cisco SparkのAPIを利用すると簡単に各種システムと連携出来ます。上手く連携出来れば、Cisco SparkからOpenStackのインスタンスを起動等も出来るようになります。

 

Cisco SparkのAPIを利用してみる