Saltについていまいまわかってること

いろいろ構築し始める前に、いまいまわかってる範囲でSalt(SaltStack)についてまとめる。

確認バージョン:

マスター、ミニオンともに
# salt --version
  salt 2016.11.3 (Carbon)


概要(なんとなくわかったこと)

  • Pythonで動いてる。

  • マスター上のtcp4505でZeroMQが待ってて、そこにミニオンが常時接続する。
    ミニオンはジョブをこのキューから受け取って実行する。
    ミニオンからの返答を受け取る為にマスターはtcp4506で待っている。
    ミニオンは結果を報告するときにこのポートに送信する。

  • Stateというものに対象ミニオンの状態の定義する。
    Pillarというものに変数を定義する。
    おのおのの保存場所のデフォルト値は /etc/salt/master
    file_roots:」と「pillar_roots:」という項目で場所を設定する。
    なんかお約束では /srv/saltと /srv/pillarらしい。

  • マスターと ミニオンは公開鍵認証している。
    ミニオンのプロセス起動時に マスターに対して公開鍵が送信される。
    マスター側がこの公開鍵を承認すると接続可能になる。
    ミニオンに対してジョブが送られたときに、マスターの公開鍵が送信されてミニオンに格納される。


とりあえず動かす

  • salt masterの作業

    # yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el7.noarch.rpm
    # yum install salt-master
    # vim /etc/salt/master
      file_roots:
          base:
              - /srv/salt
      pillar_roots:
          base:
              - /srv/pillar
    
      default_include:
          master.d/*.conf   ← 今後はここに個別に設定ファイルを作る
    
    # systemctl start salt-master
    # systemctl enable salt-master
    
  • salt minionの作業

    # yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el7.noarch.rpm
    # yum install salt-minion
    # vim /etc/salt/minion
      master: salt1   ← Saltマスターを指定
    
    # systemctl start salt-minion
    # systemctl enable salt-minion
    
  • Saltマスター側でミニオンの鍵の受諾

    # salt-key -L   ←マスターが認識している鍵の一覧
      Accepted Keys:
      Denied Keys:
      Unaccepted Keys:
      salt2        ←Unacceptedに入ってる
      Rejected Keys:
    
    # salt-key -A
      The following keys are going to be accepted:
      Unaccepted Keys:
      salt2
      Proceed? [n/Y] y
      Key for minion salt2 accepted.
    
    # salt-key -L
      Accepted Keys:
      salt2
      Denied Keys:
      Unaccepted Keys:
      Rejected Keys:
    
    # salt "*" test.ping   ←動作確認
      salt2:
          True
    


使い方

大きく二種類の使い方がある。

  1. モジュールを指定して実行。
    Saltに用意されているモジュールを単発で実行する場合は下記のようなコマンドを実行する。

     # salt '対象ミニオン' モジュール名.ファンクション名  
    


    ちなみに対象の指定方法は何パターンかある。

    • 「salt-key」コマンドで出てくるミニオン全部に対してジョブ発行。

       # salt '*' モジュール名.ファンクション名
      
    • ミニオンの内、名前がパターンに合っているものにジョブ発行。

       # salt 'hoge*' モジュール名.ファンクション名
      
    • SaltにはGrainsというミニオンから構成情報を収集して保持しておく為のモジュールがある。
      その構成情報から対象を絞り込んで対象ミニオンを指定する。

       # salt -G 'os:CentOS' モジュール名.ファンクション名
      
    • 正規表現で指定

       # salt -E 'hoge[0-9]' モジュール名.ファンクション名
      
    • 対象をリスト形式で指定

       # salt -L 'hoge1,hoge2' モジュール名.ファンクション名
      
    • AND条件とかもできる

       # salt -C 'G@os:CentOS and E@hoge[1-5]' モジュール名.ファンクション名
      

    例:ロードアベレージを確認

     # salt -L 'salt2' status.loadavg  ←対象をリスト形式で指定
       salt2:
           ----------
           1-min:
               0.0
           15-min:
               0.05
           5-min:
               0.01
    


2. SLSモジュールを指定してStateの内容を実行
 下の方の「シンプルなStateファイルの使い方 」以降を参照。


下記のコマンドで使えるモジュールを一覧表示できる。

# salt '*' sys.doc


ミニオンのグループ化の設定

Saltの対象ミニオンをいくつかにまとめてグループ名をつける。

# mkdir /etc/salt/master.d
# vim /etc/salt/master.d/nodegroups.conf
  nodegroups:
    group01: 'L@salt1,salt2'
    group02: 'E@salt[1-5]'
    group03: 'G@os:CentOS'

# systemctl restart salt-master
# salt -N 'group02' firewalld.list_services  ←こんな感じで「-N」で指定できる


シンプルなStateファイルの使い方

Stateファイルの拡張子は「.sls」。

# mkdir /srv/salt
# vim /srv/salt/default.sls
  install_wget:        ←wgetをインストールするジョブ
    pkg.installed:
      - name: wget

# salt "salt2" state.sls default    ←「state.sls」と Stateファイルを指定して実行する
  salt2:
  ----------
            ID: install_wget
      Function: pkg.installed
          Name: wget
        Result: True
       Comment: Package wget is already installed.
       Started: 04:40:00.117065
      Duration: 535.179 ms
       Changes:

  Summary
  ------------
  Succeeded: 1
  Failed:    0
  ------------
  Total states run:     1

確認してみる。

# salt "salt2" cmd.run 'rpm -q wget'
  salt2:
      wget-1.14-13.el7.x86_64


環境を一発でデプロイしたい場合

こんな感じらしい。

# vim /srv/salt/top.sls   ←てっぺんのStateファイル。「top.sls」は固定値。
  base:           ←「/etc/salt/master」の「file_roots:」で指定したenvironment。
    '*':           ←対象の指定。「'kube-master*'」とかにもできる。マッチしたとこが全部実行される。
      - default

下記でtop.slsの内容を対象ミニオンすべてに適用できる。
「base」の階層から複数セット記載しておけば、「開発環境用」とかデプロイするミニオンをわけられる。

# salt "*" state.apply saltenv=base   ←「top.sls」の中に書かれている内容を適用。
  salt2:
      ----------
      pkg_|-install_wget_|-wget_|-installed:   ←実行されたコマンド
          ----------
          __run_num__:
              0
          changes:
              ----------
          comment:
              Package wget is already installed.
          duration:
              557.722
          name:
              wget
          result:
              True
          start_time:
              04:48:49.113817


階層構造

StateもPillarも、下記のようにディレクトリを階層構造にできる。

/srv/salt/mysql/files/    ←ミニオンに転送するファイルの置き場がよく用意される
/srv/salt/mysql/client.sls
/srv/salt/mysql/map.jinja
/srv/salt/mysql/python.sls
/srv/salt/mysql/server.sls

# vim /srv/salt/top.sls
  base:
    'web*':
      - mysql.client
      - mysql.python
    'db*':
      - mysql.server


Stateのインクルード

複数のディレクトリにわかれてるStateとかをまとめて呼び出したりする。
git cloneとかでもらってきたStateを使うときとか。

# pwd
  /srv/salt

# ls -l
  drwxr-xr-x. 2 root root 40 Apr  1 12:46 testdir
  -rw-r--r--. 1 root root 45 Apr  1 12:47 test.sls

# cat testdir/test2.sls
  test_cmd1:
    cmd.run:
      - name: 'uname -n'

# cat testdir/test3.sls
  test_cmd2:
    cmd.run:
      - name: 'who -r'

# cat test.sls
  include:       ←ここでインクルードできる
    - testdir.test2
    - testdir.test3

# salt 'kube-minion1' state.sls test  ←てっぺんだけ呼び出せば全部実行される


Pillar

変数の定義の機能。AnsibleみたいにJINJA2を使ってるらしい。
定義の仕方は、Stateによく似ている。

# vim /srv/pillar/top.sls
  base:
    '*':
      - packages

# vim /srv/pillar/apache.sls
  {% if grains['os'] == 'CentOS' %}
  apache: httpd           ←キー:バリュー
  {% elif grains['os'] == 'Debian' %}
  apache: apache2
  {% endif %}

上みたいに定義した上で、Stateファイル中でこんな感じで使える。

# vim /srv/salt/top.sls
  base:
    '*':
      - packages

# vim /srv/salt/packages.sls
  apache:
    pkg.installed:
      - name: {{ pillar['apache'] }}   ←「pillar[キー]」でバリューを取り出せる

かなり手の込んだpillarオブジェクトを定義することもできる様子。 SALTSTACK社のベストプラクティスより。

# vim /srv/pillar/apache.sls
  apache:
    lookup:
      config:
        tmpl: salt://apache/files/httpd.conf ←「/srv/salt/apache/files/httpd.conf」に置いてあるファイル

# vim /srv/salt/apache/map.jinja
  {% set apache = salt['grains.filter_by']({ ←OSごとにまとめて「apache」の中に定義を入れる。
      'Debian': {
          'server': 'apache2',
          'service': 'apache2',
          'conf': '/etc/apache2/apache.conf',
      },
      'RedHat': {
          'server': 'httpd',
          'service': 'httpd',
          'conf': '/etc/httpd/httpd.conf',
      },
  }, merge=salt['pillar.get']('apache:lookup')) %}  ←apache.sls内の「lookup」の内容も読み込まれる。


# vim /srv/salt/apache/init.sls
  {% from "apache/map.jinja" import apache with context %} ←StateからJINJAファイルをインポート

  apache:
    pkg.installed:
      - name: {{ apache.server }}  ←ミニオンのOSを気にせずに指定できる。
    service.running:
      - name: {{ apache.service }}
      - enable: True

  apache_conf:
    file.managed:
      - name: {{ apache.conf }}  ←転送されてくるファイルの配置時の名前。
      - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }} ←マスタ上のファイルが転送されてくる。
      - template: jinja
      - user: root
      - watch_in:
        - service: apache


ベストプラクティス

SALTSTACK社の提示してるもの。

https://docs.saltstack.com/en/latest/topics/best_practices.html


その他

なんかいろいろ便利コマンドがある様子。
使ったことはない。
SALTSTACK社のドキュメントにしこたま載ってる。
https://docs.saltstack.com/en/latest/contents.html

  • salt-cpコマンド
    ファイルを転送する

    # salt-cp '*' test1.txt /root/test1.txt
    
  • salt-cloudコマンド クラウドVMをつくる

    # vim /etc/salt/cloud.profiles
      fedora_rackspace:
        provider: my-rackspace-config
        image: Fedora 17
        size: 256 server
        script: bootstrap-salt
    
    # salt-cloud -p fedora_rackspace fedora_http_01