SaltStack:依存または参照サービス構成の作成

この記事は何についてですか?



相互に依存するサービス構成を作成するためのSaltStackの機能に精通している。 他のまたはすべての他の下位システムなどにあるサービスから。より単純な場合は、構成の作成および配布時に各下位システムが他の類似システムからデータを受信する方法を検討します。



これは、SaltStackシリーズの3番目の記事です 。最初の記事はこちら 、2番目の記事はこちらです。



タスク:サービスのクラスターを展開し、ノード構成にこのクラスターの他のすべてのノードへのリンクがあるようにします



自動化の最も簡単なタスクは、前述のサービスの構成を使用して多くのノードを作成し、これらの構成を配置して利益を得ることです。 SaltStackを含む多くのガイドがそのような標準的なケースを説明しているので、それらに焦点を合わせません。 これらのノードが自動化プロセスに含まれる他のノードの状態とパラメーターについて知る必要がない限り、これはすべて問題ありません。



説明したタスクの最も単純なバージョンを検討してください-クラスター内の他のすべてのノードのアドレスと名前を各ノードの/ etc / hostsファイルに書き込む。



SaltStackでこれを解決する方法は? 頭に浮かぶ最も簡単なことは、すべてのノードの名前とアドレスを柱ファイルに書き込み、それをすべてのノードのすべての状態に接続することです。



柱/ cluster-nodes.sls

cluster-nodes: node1: name: node1.domain.com ip: 10.0.0.1 node2: name: node2.domain.com ip: 10.0.0.2 node3: name: node3.domain.com ip: 10.0.0.3 ....... nodeN: name: nodeN.domain.com ip: 10.0.0.N
      
      







柱/ top.sls

 base: '*': - cluster-nodes
      
      







このデータを/ etc / hostsに入力する状態を作成します。 このためにsalt.states.hostを使用します



状態/ cluster-nodes.sls

 {% for node in salt['pillar.get']('cluster-nodes', []) %} cluster-node-{{node['name']}}: host.present: - ip: {{node['ip']}} - names: - {{node['name']}} - {{node['name'].split('.')[0]}} {% endfor %}
      
      







状態を適用すると、すべてのノードで/ etc / hostsのようなものが得られます



 127.0.0.1 localhost 10.0.0.1 node1.domain.com node1 10.0.0.2 node2.domain.com node2 10.0.0.3 node3.domain.com node3 ......... 10.0.0.N nodeN.domain.com nodeN
      
      





他の人はすべてのホストから見える-目標が達成されているようだ。 この種のソリューションはエレガントではありませんが、なぜなら 新しいノードをクラスターに追加するときに柱ファイルに変更を加える必要がありますが、すべてのノードの名前とアドレスが既知で修正されている場合に存在する権利があります。



しかし、各ノードが、たとえばDHCPを介してアドレスを取得した場合はどうなりますか? または、Amazon EC2、GoGrid、Google GridなどのIaaSプロバイダーがノード生成に従事していますか? 事前にアドレスやノード名はありません。また、固定アドレスに対して追加料金を支払う必要があります。



(歌詞の余談-近い将来、Sa​​ltStackを使用してEC2で独自のインフラストラクチャを作成する方法に関する記事を書きます)



原則として、ノードにミニオンをインストールした後、その名前とアドレスに関する情報はsalt-grainsを使用して取得できます。



たとえば、次のようなミニオンでこのデータを取得できます。



 #salt-call grains.item fqdn fqdn_ip4 local: ---------- fqdn: ip-10-6-0-150.ec2.internal fqdn_ip4: - 10.6.0.150
      
      







または状態の説明で:



 {% set host_name = salt['grains.get']('fqdn') %} {% set host_ip = salt['grains.get']('fqdn_ip4') %}
      
      





すべては何もありません-しかし、重要なもの 1つありますが、それはマスターですべて利用可能であり、個々のミニオンでは利用できません。 つまり、各ミニオンの構成を生成する時点で、ミニオン自体のデータ、ウィザードの一部、および残りのミニオンに関する絶対的なデータは表示されません。



ここで疑問が生じます-特定のミニオンの構成を生成するときに他のミニオンからデータを取得する方法は?



答えは簡単です。これには塩鉱山を使用できます。 ドキュメントにはあまり記述されていませんが、このサービスの一般的な目的を理解するには十分です。 彼はどのように働いていますか? マスターは、各ミニオンから特定のデータセットを一定の周期でキャッシュし、キャッシュされたデータへのアクセスをすべてのミニオンに提供します。



これを実装する方法は?

1. mine_functionsを設定します-ミニオンから個々のデータを受信およびキャッシュするための関数の説明。 これらは、各ミニオンの/ etc / salt / minionの直接説明を使用するか、各ミニオンのウィザードでこれらの機能の説明と柱ファイルを接続することで定義できます。

2.しばらく待つか(mine_interval sec。-ミニオンの構成で指定できます)、 ソルト '*' mine.updateを使用して手で強制的に更新します。

3.現在のミニオンを構成するときに、mine.get関数を使用して、ウィザードから必要なデータを取得します。



説明されている手順を使用して、ホストの問題を解決する方法を考えてみましょう。 だから:



1.柱ファイルにエントリを作成し、すべてのミニオンに接続します。



柱/ minefuncs.sls

 mine_functions: grains.item: [fqdn, fqdn_ip4]
      
      







柱/ top.sls

 base: '*': - minefuncs
      
      







2.ミニオンからのForsimデータ収集。



3. / etc / hostsの状態を作成します



 {% for node, fqdn_data in salt['mine.get']('*', 'grains.item', expr_form='glob').items() %} cluster-node-{{fqdn_data['fqdn']}}: host.present: - names: - {{fqdn_data['fqdn'].split('.')[0]}} - {{fqdn_data['fqdn']}} - ip: {{fqdn_data['fqdn_ip4'][0]}} {% endfor %}
      
      





その結果、すべてのミニオンの名前と住所を含む自動生成されたホストファイルを取得します。



状態が使用される特定のミニオンセットを分離する必要がある場合(たとえば、クラスターの一部のノードには1つの役割があり、他のノードには異なる役割があり、特定の役割を持つノードのみを分離する必要がある場合)、次の推奨事項を使用できます:



1.すべてのミニオンに対して、 カスタムグレイン (これは単純で、標準ドキュメントで説明されています)を定義します。たとえば、grains:roles:name_nodeおよびgrains:roles:data_nodeです。

2. mine.getで指定されたロールを選択します。 たとえば、次のように:



 {% for node, fqdn_data in salt['mine.get']('roles:data_node', 'grains.item', expr_form='grain').items() %} cluster-node-{{fqdn_data['fqdn']}}: host.present: - names: - {{fqdn_data['fqdn'].split('.')[0]}} - {{fqdn_data['fqdn']}} - ip: {{fqdn_data['fqdn_ip4'][0]}} {% endfor %} {% for node, fqdn_data in salt['mine.get']('* and not G@roles:data_node', 'grains.item', expr_form='compound').items() %} cluster-node-{{fqdn_data['fqdn']}}: host.present: - names: - {{fqdn_data['fqdn'].split('.')[0]}} - {{fqdn_data['fqdn']}} - ip: {{fqdn_data['fqdn_ip4'][0]}} {% endfor %}
      
      





これらの場合、 expr_formおよび選択の式の説明に注意してください



ここで、実際には、上記の問題に対する解決策があります-そのため、手先から構成データを受け取ることが可能です。



説明した手法を使用して、構成を生成するプロセスでミニオン間でさまざまなデータを転送することもできます。



この記事が、SaltStackをかなり重要な構成で使用するすべての人に役立つことを願っています。



読んでくれてありがとう。



All Articles