ホームページ  >  記事  >  バックエンド開発  >  ceph管理プラットフォームの拡張機能開発 Calamari_PHPチュートリアル

ceph管理プラットフォームの拡張機能開発 Calamari_PHPチュートリアル

WBOY
WBOYオリジナル
2016-07-12 09:00:371140ブラウズ

ceph管理プラットフォームCalamariの開発延長

怠けてしまったのか半年近くログを書いていませんでした。でも、書くことで気持ちが落ち着く場合もあるので、戻ってきて記録したほうがいいかもしれません。私は半年以上働いており、いくつかの関連業務に慣れてきましたが、現在は主に分散システムの研究開発に従事しており、まだ開発には至っていません。コードを変更します。過去 6 か月間で、私は 2 つの非常に優れた分散システム、glusterfs と Ceph に精通しました。どちらの分散ストレージ製品にも独自の利点があり、その中でも Glusterfs は、Ceph システムでは提供できないファイル サービスを提供します。 Ceph のブロックデバイス、オブジェクトストレージ、およびファイルシステムの統合アーキテクチャは、GlusterFs では満たすことができません。したがって、それぞれに独自の利点があります。

コードレベルで見ると、GlusterFs のコードは比較的単純で、レイヤーは明白で、スタック処理フローは非常に明確です。ファイルシステムの機能拡張は非常に簡単です(クライアントとサーバーに処理モジュールを追加するだけです)。サーバー側とクライアント側のコードは 1 つのコードですが、全体のコードは比較的明確であり、コード量は少なくなります。小さい。

Ceph は C++ を使用して開発されており、システム自体は複数のプロセスを備えており、複数のプロセスが大きなクラスターを形成し、クラスター内には小さなクラスターもあります。Glusterfs と比較すると、コードははるかに複雑であり、Ceph 自体が Self-調整と自己修復。ソフトウェア システムのカスタマイズをサポートし、Crush アルゴリズムを通じてオブジェクトの保存場所を見つけます。

現在の人気の点では、Ceph が比較的人気がありますが、提供されるファイル システムとしては、やはり Glusterfs が良い選択です。

私は最近 Ceph 関連の管理プラットフォームの開発に携わっており、公式に提供されている Calamari プラットフォームに精通しています。このプラットフォームは現在主に Ceph 分散ストレージ システムの管理作業を提供しています。 Cephのページ管理。現在の実装の観点から見ると、プラットフォームにはまだ特定の制限があり、強力な機能を完了できないか、現在提供されているバージョンではいくつかの基本的な機能しか提供できません。しかし、Calamari フレームワークは本当に優れています。 Ceph はオープン ソース ソフトウェアであり、Calamari もオープン ソース ソフトウェアであり、Calamari は一連のオープン ソース ソフトウェアを組み合わせたものです。これらのオープン ソース ソフトウェアは、それぞれの特定の機能のみを完成させます。この管理プラットフォームのフレームワークはつなぎ合わせられていますが、全体としては学ぶ価値があります。
以下の部分は http://www.openstack.cn/?p=2708 を参照しています。
Calamari アーキテクチャ図

赤枠部分は Calamari コードで実装された部分、赤枠以外の部分は Calamari で実装されていないオープンソースフレームワークです。

Cephserver ノードにインストールされるコンポーネントには、Diamond と Salt-minion が含まれます。 Diamond は、監視データの収集を担当します。上図では、各タイプのデータがコレクターとして機能するほか、主要なリソースの使用状況やパフォーマンスのデータも収集できます。 、CPU、メモリ、ネットワーク、I/O 負荷、ディスク メトリクスを含みます。 Collector はローカル コマンド ラインを使用してデータを収集し、それを Graphite に報告します。

Graphite はエンタープライズレベルの監視ツールであるだけでなく、リアルタイムで描画することもできます。カーボンキャッシュは、Python で実装された拡張性の高いイベント駆動型 I/O アーキテクチャのバックエンド プロセスであり、多数のクライアントと効果的に通信し、低オーバーヘッドで大量のビジネスを処理できます。

Whisper は RRDtool に似ており、特別な形式で保存されたファイル データ (時間データ ポイント データ) を操作および取得するためのアプリケーション用のデータベース開発ライブラリを提供します。Whisper の最も基本的な操作は、新しい Whisper ファイルを作成し、更新し、新しいファイルを書き込むことです。データ ポイントはファイルに保存され、取得されたデータ ポイントは、ユーザーが URL を介して画像を生成するために使用されるユーザー インターフェイスです。

Calamari は、Saltstack を使用して Calamari サーバーと Ceph サーバーノード間の通信を行います。 Saltstackは、ChefやPuppetと同様の機能を備えたオープンソースの自動運用保守管理ツールです。 Salt-master は、指定された Salt-minion に指示を送信して、Cpeh クラスターの管理を完了します。Salt-minion は、Ceph サーバーノードのインストール後に、マスターから ceph.py ファイルを同期してインストールします。このファイルには、Ceph 操作用の API が含まれています。 librados またはコマンドラインを呼び出して、最終的に Ceph Cluster と通信します。

calamari_rest は Calamari REST API を提供します。詳細なインターフェイスについては公式ドキュメントを参照してください。 Ceph の REST API は低レベルのインターフェースであり、各 URL は同等の CEPH CLI に直接マッピングされます。Calamari REST API は高レベルのインターフェースを提供し、API ユーザーは GET/POST/PATCH メソッドを使用してオブジェクトを操作できます。それらの主な違いは、Ceph の REST API のユーザーは Ceph 自体をよく知っている必要があるのに対し、Calamari の REST API は Ceph リソースの記述に近いため、上位層のアプリケーションを呼び出すのにより適していることです。

cthulhu は、Calamari Server のサービス層として理解できます。上位側で API のインターフェイスを提供し、下位側で Salt-master を呼び出します。

calamari_clients は、インストール プロセス中に、Calamari サーバーが最初に opt/calamari/webapp ディレクトリを作成し、webapp/calamari の下に manager.py (django 設定) ファイルを入力します。これを opt/calamari/webapp の下に配置して、UI アクセス ページを提供します。

calamari-web パッケージの下のファイルは、calamari_rest および calamari_clients によって使用されるすべての Web 関連の構成を提供します。

このフレームワークは多くのオープンソース ソフトウェアを使用していますが、Saltstack は管理ノードとサーバー ノード間の通信リンクを実装し、複数のノードの管理をサポートしているため、拡張の観点から学ぶ価値があります。管理ノードを考慮してください。サーバーとの通信の問題については、サーバー側に特定のビジネス ロジックを実装するだけ、つまり特定の管理タスクを実装する必要があります。同時に、Saltstack は Python を使用して開発されているため、迅速なシステム開発が容易になり、管理者が現場でデバッグして問題を特定するのに非常に便利です。 Ceph 自体も Python API インターフェースを提供しており、Ceph の API を通じてクラスター制御を直接実現できます。 SaltStack を使用すると、クラスターを一定の規模に達することができます。 SaltStack のマスター側は実際には管理側の制御インターフェイスとして機能し、SaltStack はサーバーのエージェント側として機能します。 Calamari では、Saltstack 経由でハートビート メッセージが送信され、サーバー情報とクラスター情報が確認され、コマンドの配布が制御されます。 SaltStack の基本モデルを理解すれば、Calamari の開発と拡張を理解できると言えます。

このフレームワークにおけるもう 1 つの非常に重要なオープンソース ソフトウェアのセットは、ダイヤモンド + グラファイトです。ダイヤモンドはサーバー側の情報の収集を完了し、グラファイトはチャート情報の提供を実装します。 Diamond は現在、ほとんどのオープン ソース システムの情報収集を提供しており、基本的なサーバー情報 (CPU、メモリ、ディスクなど) の収集も提供しており、Python で実装されており、拡張とデバッグが非常に簡単です。現在、Ceph の情報収集はすでに Diamond に存在しています。 Graphite は主にフロント デスクに時系列データを提供し、特定のビジネス ロジックの書き換えを簡素化します。

Calamari を学び理解するには、いくつかの基本コンポーネントを理解し、これらのコンポーネントの機能と目的を習得する必要があります。以下では、Calamari をコード レベルから拡張する方法について説明します。

1 Calamari の拡張

Calamari をベースにした新機能を開発します。主に以下のモジュールに分かれています。この部分には、Rest-API 部分、Cthulhu、および Salt クライアント拡張機能が含まれます。新しい関数を拡張するための基本的な手順は次のとおりです:

>> URL モジュールを展開し、対応する応答インターフェイス パラメーターと、ViewSet 内の対応する応答インターフェイスを決定します。

>> ViewSet のいくつかのインターフェイスの実装を完了します。この部分には主に cthulhu との対話、データ情報の取得方法が含まれます。場合によっては、シリアライザーでのオブジェクトのシリアル化操作も取得する必要があります。

>> バックグラウンドの rpc.py で対応する型の展開を完了します。この部分は主にいくつかの事後操作に使用されます。

>> 操作を提供する一部の関数は、作成、更新、削除などの操作をサポートする必要があり、対応する RequestFactory を提供する必要があります。 cluster_monitor.py では、対応する RequestFactory をコードに追加する必要があります。

>> 対応する RequestFactory クラスの記述を完了します。この部分は主にコマンド操作のカプセル化を完了します。そして、対応するリクエスト操作を構築します。

>gt;>salt-minion の拡張子、この部分は主に ceph.py ファイルの拡張子用ですが、もちろん、新しい xxx.py ファイルも提供できます。

次に、PG の制御と操作を例に説明します。

1.1URL モジュール拡張子

現在、Calmamari は Rest-API 形式を採用しており、この部分は Django の Rest-Framework フレームワークによってサポートされています。 Django は URL とコードロジックを分離する実装方法を採用しているため、URL を独立して展開することができます。

次の PG 関連の URL をrest-api/calamari-rest/urls/v2.py に追加します:

url(r'^cluster/(?P[a-zA-Z0-9-] + )/pool/(?Pd+)/pg$', calamari_rest.views.v2.PgViewSet.as_view({'get': 'list'}), name='cluster-pool-pg-list' ) ,

url(r'^cluster/(?P[a-zA-Z0-9-]+)/pool/(?Pd+)/pg/(?P[ 0 -9a-fA-F]+.[0-9a-fA-F]+)/command/(?P[a-zA-Z_]+)$',

calamari_rest.views.v2. .as_view({'post': 'apply'}),

name='cluster-pool-pg-control'),

上記は 2 つの URL を定義しています:

api/v2/cluster/ xxxx/ pool/x/pg

api/v2/cluster/xxxx/pool/x/pg/xx/command/xxx

上記2つのURLはそれぞれPgViewSetのインターフェースを指定しており、URLのgetメソッドがリストに相当しますインターフェース 。 post インターフェイスに対応する apply インターフェイス。これら 2 つのインターフェイスは PgViewSet に実装する必要があります。

1.2 ViewSet の拡張

URL を拡張した後の次のステップは、対応する応答インターフェイスを拡張することです。拡張機能のこの部分は主に、URL で指定されたインターフェイス クラスを実装します。以前の PG では、取得コマンドと操作コマンドという 2 つの異なるインターフェイスが指定されていました。対応するコード パスは /rest-api/calamari-rest/view/v2.py です。具体的なコードは次のとおりです。 ):

serializer_class= PgSerializer

deflist(self, request, fsid, pool_id):

poolName = self.client.get(fsid, POOL, int(pool_id))['pool_name']

pg_summary = self.client.get_sync_object(fsid, Pgsummary.str)

pg_pools = pg_summary['pg_pools']['by_pool'][int(pool_id)]

forpg in pg_pools:

pg['pool'] = poolName

return Response(PgSerializer(pg_pools, many=True).data)

defapply(self, request, fsid, pool_id, pg_id, command):

return Response(self.client.apply(fsid, PG) , pg_id, command), status=202)

上記の実装から、コードが 2 つのインターフェイス、つまり、前の get 操作と post 操作に対応する list インターフェイスと apply インターフェイスを実装していることがわかります。上記の 2 つの操作は、背景のクトゥルフと対話します。パラメータを取得してリクエストを送信します。返されるコンテンツにも特定の違いがあります。

同時に、リストインターフェイス、つまりrest-api/calamari-rest/serializer/v2.pyに実装されているPgSerializerでシリアル化設定が行われます。

1.2.1 シリアル化操作

通常、Rest-Apiでデータをシリアル化する部分は、変更が必要な操作では必要ありません。以下は Pg のシリアル化操作です:

class PgSerializer(serializers.Serializer):

classMeta:

fields = ('id', 'pool', 'state', 'up', 'acting', 'up_primary ' ,'acting_primary')

id =serializers.CharField(source='pgid')

pool =serializers.CharField(help_text='プール名')

state =serializers.CharField(source='state', help_text = 'pg state')

up =serializers.Field(help_text='pg Up set')

acting =serializers.Field(help_text='pg Acting set')

up_primary =serializers.IntegerField(help_text='pg up Primary')

acting_primary =serializers.IntegerField(help_text='pg Acting Primary')

この部分は必要ありません。一部のモジュールにはこの部分の操作がない場合があります。前の 3 つの手順で、Rest-API 部分の拡張は基本的に実装されましたが、その中で主要な拡張は ViewSet でした。関連する ViewSet は、実際に cthulhu とrest-api の間の対話メソッドを実装します。

ViewSet の拡張では、rpc は実際にバックグラウンドと対話するために使用されるため、cthulhu の実装部分は主に対応する rpc リクエストを処理します。

1.3rpc 拡張機能

rpc.py は、要求されたすべての操作を実装しますが、新しい拡張操作も拡張機能をサポートする必要があります。例として pg を使用して説明を続けます。

defapply(self, fs_id, object_type, object_id, command ) :

"""

クラスター内のオブジェクトを変更しないコマンドを適用します。

"""

cluster = self._fs_resolve(fs_id)

ifobject_type == OSD:

#不明な場合に例外をスローすることを解決します

self._osd_resolve(cluster, object_id)

return cluster.request_apply(OSD, object_id, command)

elifobject_type == PG:

return cluster.request_apply(PG, object_id, command)

else:

raise NotImplementedError(object_type)

そして Pg のリストは Pgsummary を通じて取得されます。この部分は以前の実装ですでに存在していました。前のコードは次のように実装されました:

defget_sync_object(self, fs_id, object_type, path=None):

"""

ClusterMonitor がコピーを保持するオブジェクトを取得します。クラスターマップなどの mon。

:param fs_id: クラスターの fsid

:param object_type: 文字列、SYNC_OBJECT_TYPES の 1 つ

:param path: リスト、オプション、オブジェクト内のパス全体の代わりに返す

:return: 要求されたデータ、または見つからなかった場合は None (``path``

の要素が見つからなかった場合を含む)

"""

ifpath:

obj = self._fs_resolve(fs_id).get_sync_object(SYNC_OBJECT_STR_TYPE[object_type])

try:

パス内の一部の場合:

if isinstance(obj, dict):

obj = obj[part]

else:

obj = getattr(obj, part)

以外 (AttributeError, KeyError) as e:

log.Exception("%s をトラバースする例外 %s: obj=%s" % (e, path,obj ))

raise NotFound(object_type, path)

return obj

else:

returnself._fs_resolve(fs_id).get_sync_object_data(SYNC_OBJECT_STR_TYPE[object_type])

1.4cluster_monitor.py 拡張機能

関連する操作は、クラスタ 、この部分は、 pg を例にして説明すると、cluster_monitor を通じて実装できます。

def__init__(self、fsid、cluster_name、notifier、persister、servers、eventer、requests):

super(ClusterMonitor, self).__init__()

self.fsid = fsid

self.name = クラスター名

self.update_time = datetime.datetime.utcnow().replace(tzinfo=utc)

self._notifier = notifier

self._persister=persister

self._servers =servers

self._eventer =eventer

self._requests =requests

#リクエストの実行に現在使用しているモン、

#ミニオンIDで識別

self._favorite_mon = None

self._last_heartbeat = {}

self._complete = gevent.event.Event()

self.done = gevent.event.Event()

self._sync_objects = SyncObjects(self.name)

self._request_factories = {

CRUSH_MAP: CrushRequestFactory,

CRUSH_NODE: CrushNodeRequestFactory、

OSD: OsdRequestFactory、

POOL: PoolRequestFactory、

CACHETIER: CacheTierRequestFactory、

PG: PgRequestFactory、

ERASURE_PROFILE: プロファイルRequestFactory,

ASYNC_COMMAND: AsyncComRequestFactory

}

自身。 _plugin_monitor = PluginMonitor(servers)

self._ready = gevent.event.Event()

この部分は主に、適切なリクエストを生成できるように、対応するリクエストを対応するリクエスト ファクトリ クラスにバインドすることです。

1.5 ファクトリ クラスの作成

このファクトリ クラスは主に、さまざまなニーズに合わせて特定のインターフェイス クラスを実装するように設計されています。Pg を例に挙げます。

from cthulhu.manager.request_factory importRequestFactory

from cthulhu.manager .user_request importRadosRequest

from calamari_common.types importPG_IMPLEMENTED_COMMANDS, Pgsummary

class PgRequestFactory(RequestFactory):

def scrub(self,pg_id):

return RadosRequest(

" b on {cluster_name}- pg{id }".format(cluster_name=self._cluster_monitor.name,id=pg_id),

self._cluster_monitor.fsid,

self._cluster_monitor.name,

[('pg スクラブ', {'pgid' : pg_id} )])

defdeep_scrub(self, pg_id):

return RadosRequest(

"{cluster_name}-osd.{id} でディープ スクラブを開始しています。".format(cluster_name=self._cluster_monitor.name ,id= pg_id),

self._cluster_monitor.fsid,

self._cluster_monitor.name,

[('pg deep-scrub', {'pgid': pg_id})])

defrepair(self , pg_id) :

return RadosRequest(

"{cluster_name}-osd.{id} の修復を開始しています".format(cluster_name=self._cluster_monitor.name,id=pg_id),

self._cluster_monitor.fsid,

self. _cluster_monitor.name,

[('pg Repair', {'pgid': pg_id})])

defget_valid_commands(self, pg_id):

ret_val = {}

file('/tmp /pgsummary. txt', 'a+').write(Pgsummary.str + 'n')

pg_summary = self._cluster_monitor.get_sync_object(Pgsummary)

pg_pools = pg_summary['pg_pools']['by_pool']

pool_id = int (pg_id.split('.')[0])

pool= pg_pools[pool_id]

forpg in pool:

if pg['pgid'] == pg_id:

ret_val[pg_id ] = { 'valid_commands': PG_IMPLEMENTED_COMMANDS}

else:

ret_val[pg_id] = {'valid_commands': []}

return ret_val

このクラスは 3 つの異なるコマンドの実装を実装します。コマンドは主にそれに応じてカプセル化されます。これらのキーワードは、ceph ソース コード内のパラメーターに基づいて選択する必要があるため、コーディングの際は、ceph ソース コード内の対応するコマンドの json パラメーター名を参照する必要があります。

1.6 Salt-minion の拡張

この部分は Salt の拡張モジュールで、主に対応するデータ情報の取得、対応する操作コマンドの実行などに使用されます。 cthulhuではsalt経由で対応する操作コマンドを実行します。 Ceph.py には、ceph コマンドの実行に使用できる rados.commands などのインターフェイスがあります。ファクトリ クラスにカプセル化されたコマンドは、最終的にはこのインターフェイスを通じて実行されます。

まとめ
全体として、Calamari のコード構造は比較的明確であり、後続の分散管理システムでは、前者は制御ロジックを実装することもできます。後者の 2 つは、データの収集とデータの保存と表示を実現します。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/1092984.html技術記事 ceph 管理プラットフォーム Calamari の拡張開発のログを半年近く書いていませんでした。怠けてしまったのかもしれません。でも、書いていると落ち着くときもあるので、また戻ってきて記録したほうがいいです...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。