この投稿では、 SaltStack構成管理システム、特にsalt-sshコンポーネントを使用したマスターレスモードでのアプリケーションの使用経験を共有したいと思います。
実際、 salt-sshはAnsibleシステムの類似物です。
salt-ssh '*-ec2.mydomain.com' test.ping
次のトピックについて説明します。
なぜSaltStackの主な機能
数年前、パペット(複数の環境、100以上のノード)でいっぱいだったときに、新しいプロジェクトに新しい構成管理システムを選択したとき、 マスターレス操作が重要な要件でした。 しかし、 マスタースレーブモードの動作の可能性も維持したいと考えました。 充実した優れたドキュメントと柔軟性が必要でした。 クラウドインフラストラクチャを管理できるようになりたかった。
また、さまざまな環境が簡単に共存できるシステムを構築したいと考えました。 これはすべて、salt-sshを使用して行われました。
Salt-sshはSaltStackのコンポーネントです。Ansibleと同様に、sshを使用してリモートマシンに接続し、リモートマシンからの事前設定は不要です。 エージェントなし。 純粋なssh!
もちろん、システムを選択するときには、Ansibleも検討しました。 しかし、その後、スケールはSaltStackに傾いた。
Ansibleとは異なり、SaltStackはテンプレートの処理とロジックの構築の両方にJinja2を使用します。
さらに、このロジックはほとんどすべての方法で構築できます。 一方で、それは良い面と悪い面の両方です。 いいから 柔軟性を提供します。 しかし、悪い、なぜなら 実装に対する標準的な方法とアプローチはありません。 この点で、SaltStackはデザイナーのようです。
また、テンプレートとロジックのレンダリングは、起動段階で発生します。 結果のテンプレート、設定、および指示のパッケージがリモートサーバーにコピーされ、実行されます。 実行が完了すると、salt-sshは何が行われ、エラーが発生した場合にエラーの原因をコンソールに報告します。 ここで、ansibleとの違いは非常に顕著です。 後者は、シェルスクリプトモードでタスク\プレイブックを順番に実行します。 ansibleスクリプトの進行を観察する方が楽しいことを隠しませんが、ホストの数が数十を超えると、これらすべてが徐々に背景に消えていきます。 また、ansibleと比較して、SaltStackは抽象化のレベルが高くなっています。
可能性としては、ansibleとsalt-sshの両方が2つの非常に興味深いツールであり、それぞれに長所と短所があります。
基本的なSaltStackの概念
SaltStackは、構成およびインフラストラクチャ管理システムです。 個々のサーバーのレベルでも、さまざまなクラウドプラットフォーム( SaltCloud )でも。 リモートコマンド実行システムでもあります。 Pythonで書かれています。 非常に急速に発展しています。 Salt-ApiやSalt-Syndic (マスターのマスターまたはマスターサーバーの階層を構築できるシステム、つまりシンジケート)など、さまざまなモジュールと機能を備えています。
デフォルトでは、SaltStackはマスタースレーブモードの動作を意味します。 ノード間のメッセージングは、 ZeroMQプロトコルを介して行われます。 MultiMaster設定を使用して水平方向にスケーリングできます。
しかし、最良の部分は、Saltがエージェントレスモードで動作できることです。 状態のローカル起動またはこのトピックのヒーローであるsalt-sshを使用して実装できるもの。
ソルトマスター -接続されたエージェントの管理が行われるマシンで実行されるプロセス。 salt-sshの場合、状態と柱のデータがあるノードをマスターと呼ぶことができます
ソルトミニオン -管理されたマシン上で実行されるプロセス、すなわち 奴隷。 salt-sshミニオンの場合、これは任意のリモートサーバーです
状態 -システムの状態の宣言的表現(ansibleのプレイブックのアナログ)
穀物 -リモートミニオンに関する静的情報(RAM、CPU、OSなど)
柱-1つ以上のミニオンの変数
top.sls-割り当てるミニオンに状態データとピラーデータを割り当てるロジックを実装する中央ファイル
highstate-ミニオンのすべての定義済み状態データ
SLS-これは、YAMLを使用したSaltStackのピラー\状態のすべての設定ファイルの名前です
SaltStackシステムの欠点の1つは、エントリーしきい値が高いことです。 次に、この素晴らしいシステムを簡単に使い始めるための例を示します。
Salt-sshのインストールと使用
salt-sshのインストールは簡単です。
サイトhttps://repo.saltstack.com/には、必要なすべてのリポジトリと、それらをさまざまなシステムに接続するための指示があります。
インストールにはsalt-sshのみが必要です。
sudo apt-get install salt-ssh
(例としてDebシステムを使用)
テスト環境とVagrantの準備
salt-sshの使用を開始するには、インストールするだけです。 少なくとも、ローカルマシン、またははるかに視覚的なリモートサーバーを制御できます。
この例では、テストのためにVagrantを使用して作成された2つの仮想マシンを使用します。 そのうちの1つにsalt-ssh自体がインストールされ、もう1つはクリーンになり、最初のマシンから接続された公開鍵をカウントしません。
Vagrantfile自体と必要なソルト状態は、リポジトリhttps://github.com/skandyla/saltssh-introにアップロードされます 。
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure(2) do |config| # VM with salt-ssh config.vm.define :"saltsshbox" do |config| config.vm.box = "ubuntu/trusty64" config.vm.hostname = "saltsshbox" config.vm.network "private_network", ip: "192.168.33.70" config.vm.provider "virtualbox" do |vb| vb.memory = "512" vb.cpus = 2 end config.vm.synced_folder ".", "/srv" # Deploy vagrant insecure private key inside the VM config.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "~/.ssh/id_rsa" # Install salt-ssh config.vm.provision "shell", inline: <<-SHELL wget -O - https://repo.saltstack.com/apt/ubuntu/14.04/amd64/latest/SALTSTACK-GPG-KEY.pub | sudo apt-key add - sudo echo 'deb http://repo.saltstack.com/apt/ubuntu/14.04/amd64/latest trusty main' > /etc/apt/sources.list.d/saltstack.list sudo apt-get update sudo apt-get install -y salt-ssh SHELL end # VM for testing config.vm.define :"testserver" do |config| config.vm.box = "ubuntu/trusty64" config.vm.hostname = "testserver" config.vm.network "private_network", ip: "192.168.33.75" config.vm.provider "virtualbox" do |vb| vb.memory = "512" end # Deploy vagrant public key config.vm.provision "shell", inline: <<-SHELL curl https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub >> ~/.ssh/authorized_keys2 2>/dev/null curl https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub >> /home/vagrant/.ssh/authorized_keys2 2>/dev/null SHELL end end
聴衆はVagrantに精通していると思いますが、念のため: Vagrantは、開発プロセスを簡素化して再現可能にするように設計された仮想化システムの一種のフレームワークです。 仮想マシンを起動するには、VagrantとVirtualboxがインストールされている必要があります。
次に、リポジトリのクローンを作成します。
git clone https://github.com/skandyla/saltssh-intro
その中でVagrant仮想マシンを初期化します。
vagrant up
後者を起動した後、saltsshboxに移動します。
vagrant ssh saltsshbox
以降のすべての作業は、この仮想マシンから実行されます。 デフォルトでは、SaltStackはルートとして動作すると想定しているため、すぐに実行します。
vagrant@saltsshbox:~$ sudo -i
塩名簿を理解する
ターゲットホストは/ etc / salt / rosterファイルに登録されていますが、サードパーティのロスターファイルを指定できます。 ある意味では、 インベントリファイルをansibleにたとえることができます。 名簿ファイルはYAMLであり、さまざまなオプションがあります。 以下に、同じホストを記録するいくつかの方法を示します。
testserver: host: 192.168.33.75 priv: /home/vagrant/.ssh/id_rsa thesametestserver: host: 192.168.33.75 user: vagrant sudo: True thesametestserver2: host: 192.168.33.75 user: vagrant passwd: vagrant sudo: True
次に、名簿に指定されているすべてのホストに対してtest.ping
コマンドを試してみましょう。
root@saltsshbox:~# salt-ssh -i --roster-file=/srv/saltstack/saltetc/roster_test '*' test.ping Permission denied for host thesametestserver, do you want to deploy the salt-ssh key? (password required): [Y/n] n thesametestserver: ---------- retcode: 255 stderr: Permission denied (publickey,password). stdout: testserver: True thesametestserver2: True
ご覧のように、salt-sshはリモートサーバーにアクセスできないことをわずかに呪い、そこにキーを展開するよう提案しましたが、キャンセルしました。 残りの2台のサーバー(実際には、1つは異なる名前で)は肯定的に応答しました。 これは、sshキーが定義されていないルートとして実行しているために発生しました。 したがって、 ssh-agentを介してキーを追加し、コマンドを再試行するだけです。
root@saltsshbox:~# eval `ssh-agent`; ssh-add /home/vagrant/.ssh/id_rsa Agent pid 2846 Identity added: /home/vagrant/.ssh/id_rsa (/home/vagrant/.ssh/id_rsa) root@saltsshbox:~# salt-ssh -i --roster-file=/srv/saltstack/saltetc/roster_test '*' test.ping testserver: True thesametestserver: True thesametestserver2: True
これですべて順調です! さらに、ssh-agentを介してパスワード付きのキーを簡単に追加できます。 ただし、saltが提供するキーをデプロイする場合、デフォルトでは次のようになります: /etc/salt/pki/master/ssh/salt-ssh.rsa
ここでは、テストのために、面白いニュアンスを示すために意図的に別の名簿ファイルを使用しました。 さらなる作業のために、必要な場所( / etc / salt / roster )のシンボリックリンクを介して既に示されているため、名簿を指定する必要はありません。 -iスイッチは、新しいホストで作業を開始するときに必要です;これは、単にStrictHostKeyCheckingを禁止し、新しいホストキーを受け入れることを可能にします。 さらなる作業のために、それも必要ありません。
root@saltsshbox:~# salt-ssh '*' test.ping testserver: True
デフォルトで、saltはここで名簿を見ることに注意してください: / etc / salt /名簿では、現在定義されているホストは1つだけです。
リモートコマンド実行
salt-sshを搭載したマシンが名簿で指定されたテストサーバーを完全に認識していることが確認できたので、アドホックスタイルで作業します。
root@saltsshbox:~# salt-ssh testserver cmd.run "uname -a" testserver: Linux testserver 3.13.0-87-generic #133-Ubuntu SMP Tue May 24 18:32:09 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
cmd.runは基本的に、 ansibleの-a
スイッチの類似物です。
組み込みのソルトスタックモジュールを使用することもできます。例:
salt-ssh testserver service.get_enabled salt-ssh testserver pkg.install git salt-ssh testserver network.interfaces salt-ssh testserver disk.usage salt-ssh testserver sys.doc
最後のコマンドは、モジュールに関するドキュメント、そして最も重要なことには、それらの使用例を生成します。 さらに、 利用可能なSaltstackモジュールの完全なリストを見ることができます 。
塩粒またはシステムの事実
Grainsは、リモートシステムに関する一連の事実を提示する強力なメカニズムです。 将来、Grainsに基づいて、さまざまなロジックを構築することもできます。
しかし、最初に、それらの使用を開始する方法を見てみましょう。
root@saltsshbox:~# salt-ssh testserver grains.items testserver: ---------- SSDs: biosreleasedate: 12/01/2006 biosversion: VirtualBox cpu_flags: - fpu - vme - de - pse - tsc ... cpu_model: Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz cpuarch: x86_64 disks: - sda ...
コマンドの出力はトリミングされます。
直接指定することにより、目的のGrainsブランチにアクセスできます。
root@saltsshbox:~# salt-ssh testserver grains.get 'ip4_interfaces' testserver: ---------- eth0: - 10.0.2.15 eth1: - 192.168.33.75 lo: - 127.0.0.1
またはさらに具体的に:
root@saltsshbox:~# salt-ssh testserver grains.get 'ip4_interfaces:eth1' testserver: - 192.168.33.75
ソルトマスターファイルとtop.sls
ここで、別の重要なファイル/ etc / salt / masterについて説明します。 一般に、 salt-masterパッケージにバンドルされており、 saltが状態とピラーデータを検索するいくつかの重要なログオプションとディレクトリを定義します。 状態のデフォルトのディレクトリは/ srv / saltです。 しかし実際には、これらの例を含めて、異なる構造を使用する方が合理的です。
/ etc / salt / master:
state_verbose: False state_output: mixed file_roots: base: - /srv/saltstack/salt pillar_roots: base: - /srv/saltstack/pillar
state_verboseおよびstate_outputは、画面に実行ステータスを表示するための変数です。 私の意見では、このような組み合わせが最も実用的ですが、実験することをお勧めします。
file_rootsとpillar_rootsは、それぞれ州と柱のデータへのパスを示します。
重要! これらのパスにはいくつかあります。 さまざまな環境、さまざまなデータなどの原則に従って など。ただし、これはマルチ環境環境のセットアップに関する別の記事のトピックです。初心者は、saltがそれらを見つけるために状態ファイルを置く場所を知る必要があります。
さらに、これらの各ディレクトリ( file_rootsおよびpillar_roots )で、saltはtop.slsファイルを検索し、 saltファイルを処理するためのさらなるロジックを決定します。
私たちの場合:
/srv/saltstack/salt/top.sls:
base: '*': - common - timezone 'testserver': - chrony
つまり、すべてのホストに共通の状態とタイムゾーンが適用され、 テストサーバーにもchrony (時間同期サービス)が適用されます。
柱には、top.slsファイルも必要です。 どの順序でどのように変数が割り当てられるかを決定します。
/srv/saltstack/pillar/top.sls:
base: '*': - timezone 'testserver': - hosts/testserver
私たちの場合、このファイルは非常に単純です。timezone.slsファイルのすべての変数を含めることと、 testserverのhosts / testserverファイルの変数を接続することだけが示されていますが、この単純さは強力な概念を隠しています。 変数は任意の環境に割り当てることができます。 確かに、変数のオーバーラップとマージ(変数のオーバーライドとマージ)は別のトピックです。今のところ、優先度は上から下に与えられると言います。 つまり ここで、hosts / testserver.slsファイルにタイムゾーンを持つ変数があれば、有利になります。
top.slsファイルでは、すべてが.sls拡張子なしで指定されます。
塩の状態で作業する
簡単な状態に進みましょう。
/srv/saltstack/salt/packages.sls :
# Install some basic packages for Debian systems {% if grains['os_family'] == 'Debian' %} basepackages: pkg.installed: - pkgs: - lsof - sysstat - telnet {% endif %}
ご覧のとおり、ここではjinjaとgrainの両方とpkgモジュール自体を使用しました。
この状態をテストモードで適用してみましょう。
root@saltsshbox:/srv/saltstack# salt-ssh testserver state.sls packages test=true [INFO ] Fetching file from saltenv 'base', ** done ** 'packages.sls' testserver: Name: basepackages - Function: pkg.installed - Result: Differs Summary for testserver ------------ Succeeded: 1 (unchanged=1) Failed: 0 ------------ Total states run: 1
そして実際には:
root@saltsshbox:/srv/saltstack# salt-ssh testserver state.sls packages [INFO ] Fetching file from saltenv 'base', ** skipped ** latest already in cache 'salt://packages.sls' testserver: Name: basepackages - Function: pkg.installed - Result: Changed Summary for testserver ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1
塩柱または変数
次に重要なリンクはPillarです。 そのため、SaltStack変数では、リモートシステムのウィザードによって設定されるすべての変数が呼び出されます。 部分的には、これらはすでに上からあなたによく知られているので、要点をまっすぐに進んでください。
すべての柱のホスト固有の変数を取得します。
root@saltsshbox:~# salt-ssh testserver pillar.items testserver: ---------- chrony: ---------- lookup: ---------- custom: # some custom addons # if you need it timezone: ---------- name: Europe/Moscow
Grainsと同様に、単一の変数をリクエストできます。
salt-ssh testserver pillar.get 'timezone:name'
柱のある状態を使用する
次の状態を考慮してください。
/srv/saltstack/salt/timezone.sls:
{%- set timezone = salt['pillar.get']('timezone:name', 'Europe/Dublin') %} {%- set utc = salt['pillar.get']('timezone:utc', True) %} timezone_settings: timezone.system: - name: {{ timezone }} - utc: {{ utc }}
ここでは、ピラーからのデータに基づいて変数を設定します。 そして、この設計では:
{%- set timezone = salt['pillar.get']('timezone:name', 'Europe/Dublin') %}
何らかの理由で塩がPillarから値を取得できない場合、 ヨーロッパ/ダブリンがデフォルト値です。
root@saltsshbox:/srv/saltstack# salt-ssh testserver state.sls timezone [INFO ] Fetching file from saltenv 'base', ** skipped ** latest already in cache 'salt://timezone.sls' testserver: Name: Europe/Moscow - Function: timezone.system - Result: Changed Summary for testserver ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1
実生活の例
そして今、ついに、私たちは実生活の例に到達しました。 状態時間の同期を考慮してください-慢性。 ここにあります:
/srv/saltstack/salt/chrony/init.sls
さらに、 init.slsはデフォルトのインデックスであり、saltは自動的に検索しますが、他のファイルを使用できます。
ここでは、別の典型的なソルトコンストラクトmap.jinjaを紹介します。
/srv/saltstack/salt/chrony/map.jinja:
{% set chrony = salt['grains.filter_by']({ 'RedHat': { 'pkg': 'chrony', 'conf': '/etc/chrony.conf', 'service': 'chronyd', }, 'Debian': { 'pkg': 'chrony', 'conf': '/etc/chrony/chrony.conf', 'service': 'chrony', }, }, merge=salt['pillar.get']('chrony:lookup')) %}
その目的は、システムに必要な静的変数のセットを作成することですが、突然変数を指定する必要がある場合は、ピラーからの変数とマージする可能性があります。
次は/srv/saltstack/salt/chrony/init.sls自体です:
{% from "chrony/map.jinja" import chrony with context %} chrony: pkg.installed: - name: {{ chrony.pkg }} service: - name: {{ chrony.service }} - enable: True - running - require: - pkg: {{ chrony.pkg }} - file: {{ chrony.conf }} {{ chrony.conf }}: file.managed: - name: {{ chrony.conf }} - source: salt://chrony/files/chrony.conf.jinja - template: jinja - user: root - group: root - mode: 644 - watch_in: - service: {{ chrony.service }} - require: - pkg: {{ chrony.pkg }}
salt://chrony/files/chrony.conf.jinja jinja形式は、ここで特に注意する必要があります。
/srv/saltstack/salt/chrony/files/chrony.conf.jinja:
# managed by SaltStack {%- set config = salt['pillar.get']('chrony:lookup', {}) -%} {%- set vals = { 'bindcmdaddress': config.get('bindcmdaddress','127.0.0.1'), 'custom': config.get('custom', ''), }%} ### chrony conf server 0.centos.pool.ntp.org iburst server 1.centos.pool.ntp.org iburst server 2.centos.pool.ntp.org iburst server 3.centos.pool.ntp.org iburst stratumweight 0 driftfile /var/lib/chrony/drift rtcsync makestep 10 3 bindcmdaddress {{ vals.bindcmdaddress }} bindcmdaddress ::1 keyfile /etc/chrony.keys commandkey 1 generatecommandkey noclientlog logchange 0.5 logdir /var/log/chrony {% if vals.custom -%} {{ vals.custom }} {%- endif %}
このテンプレートでは、Pillarから変数をリクエストして処理します。 state.show_slsを使用して、この状態がsaltによってどのように認識されたかを確認できます。
root@saltsshbox:/srv/saltstack# salt-ssh testserver state.show_sls chrony [INFO ] Fetching file from saltenv 'base', ** done ** 'chrony/init.sls' [INFO ] Fetching file from saltenv 'base', ** done ** 'chrony/map.jinja' testserver: ---------- /etc/chrony/chrony.conf: ---------- __env__: base __sls__: chrony file: |_ ---------- name: /etc/chrony/chrony.conf |_ ---------- source: salt://chrony/files/chrony.conf.jinja |_ ---------- template: jinja |_ ---------- user: root |_ ---------- group: root |_ ---------- mode: 644 |_ ---------- watch_in: |_ ---------- service: chrony |_ ---------- require: |_ ---------- pkg: chrony - managed |_ ---------- order: 10002 chrony: ---------- __env__: base __sls__: chrony pkg: |_ ---------- name: chrony - installed |_ ---------- order: 10001 service: |_ ---------- name: chrony |_ ---------- enable: True - running |_ ---------- require: |_ ---------- pkg: chrony |_ ---------- file: /etc/chrony/chrony.conf |_ ---------- order: 10000 |_ ---------- watch: |_ ---------- file: /etc/chrony/chrony.conf
次に、実行します。
root@saltsshbox:/srv/saltstack# salt-ssh testserver state.sls chrony testserver: Name: chrony - Function: pkg.installed - Result: Changed Name: /etc/chrony/chrony.conf - Function: file.managed - Result: Changed Name: chrony - Function: service.running - Result: Changed Summary for testserver ------------ Succeeded: 3 (changed=3) Failed: 0 ------------ Total states run: 3
ここで、saltは、関連するモジュールの総数によって実行された3つの状態について報告します。 再度実行すると、変更が加えられていないことは明らかです。
root@saltsshbox:/srv/saltstack# salt-ssh testserver state.sls chrony testserver: Summary for testserver ------------ Succeeded: 3 Failed: 0 ------------ Total states run: 3
chronyの構成ファイルがどのように形成されたかをすぐに確認できます。
salt-ssh testserver cmd.run 'cat /etc/chrony/chrony.conf'
最後に、 state.highstateコマンドに言及する価値があります。
salt-ssh testserver state.highstate
彼女はテストサーバーにすべての規定の状態を適用します。
おわりに
それで、SaltStackバンドルのsalt-sshとは何か、そしてその使用方法を学びました。 salt-sshが機能するために必要な環境を構築する重要な特徴を学びました。 Vagrantを使用してテスト環境をセットアップします。 そして、Grains、States、Pillarなど、SaltStackの基本的な概念を使用して実験を体系的に実施しました。 また、単純なものから複雑なものまで状態を記述する方法を学び、実際の例に到達することで、ベースでさらに自動化を構築できます。
今のところすべてです。 まだたくさんの興味深いトピックが残っていますが、この情報がこの素晴らしい構成管理システムでの作業を開始するのに役立つことを願っています。
有用な情報:
best_practices
ウォークスルー
starting_states
柱
公式
チュートリアル