こちらの投稿は vExperts Advent Calendar 2021 の 13 日目になります。
今回は大変長くなっております(`・ω・´)
adventar.org
Salt とは?
SaltStack 社により開発が行われていた Python 製のオープンソースな構成管理ツール。
構成管理ツールというと Chef や Puppet、Ansible が有名。
後発だが、初版リリースは Ansible より早いらしい。
2020 年に VMware 社が SaltStack 社を買収したことにより、VMware ファミリーの一員となり、vRealize Automation 8.3 から「vRealize Automation SaltStack Config」、「vRealize Automation SaltStack SecOps」として組み込まれています。
blogs.vmware.com
www.vmware.com
なお、Salt のコア部分については VMware 社支援のもと、今まで通りオープンソースプロジェクトとして開発が進んでいます。
github.com
なので…
Salt は VMware のポートフォリオの 1つです
Salt は VMware のポートフォリオの 1つです
大事なことなので(ry
アーキテクチャ
Salt はクライアント/サーバモデルとなっており、Master と呼ばれるコントローラサーバと Minion と呼ばれる各クライアント環境で動くエージェントで構成されます。
Master-Minion 間は SSH は使わず、4505/TCP、4506/TCP で ZeroMQ によるメッセージングライブラリを介して通信を行います。
エージェントとなると各 OS にインストールとなるので、Linux や Windows 等の PC 用の汎用的な OS になってしまうのですが、Salt Proxy Minion を利用することで、Proxy Minion から制御対象に対し API や SSH 経由で構成管理を行うことができます。
基本は Minion インストールによるエージェント型なのですが、Salt SSH という方式を使うことで、対象に Minion をインストールすることなく、Master から SSH 経由で管理を行うことも可能。
ただし、Minion に比べると遅いので、初回の Minion インストールや事情により Minion が利用できないケースに使うことが推奨なようです。
インストール
今回は Ubuntu 20.04 の VM に公式リポジトリからapt
でインストール。
repo.saltproject.io
Master
mirie@salttest01:~$ sudo curl -fsSL -o /usr/share/keyrings/salt-archive-keyring.gpg https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest/salt-archive-keyring.gpg mirie@salttest01:~$ echo "deb [signed-by=/usr/share/keyrings/salt-archive-keyring.gpg arch=amd64] https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest focal main" | sudo tee /etc/apt/sources.list.d/salt.list mirie@salttest01:~$ sudo apt update mirie@salttest01:~$ sudo apt install salt-master
salt-master はとりあえずであれば設定不要。
コレで salt-master のプロセスが起動し、4505/TCP、4506/TCP が LISTEN になっていればおけ。
Minion
リポジトリは同じで、インストール対象が salt-minion に。
mirie@minion01:~$ sudo apt install salt-minion
salt-minion の設定として、salt-master の指定を conf に行う。
mirie@minion01:~$ echo "master: 192.168.100.153" | sudo tee -a /etc/salt/minion mirie@minion01:~$ sudo systemctl restart salt-minion
こちらは salt-minion のプロセスが起動すれば一旦おけ。
ちなみに Windows もインストーラで Minion をインストールできます。(Master は無さげ)
インストーラでのインストール
インストーラのダウンロードはこちらから。
docs.saltproject.io
インストーラの中で Master 指定/識別名指定。
Minion の認証
Master 指定があっていれば、salt-master で Minion の Key が見えるように。
mirie@salttest01:~$ sudo salt-key -L Accepted Keys: Denied Keys: Unaccepted Keys: minion01 Rejected Keys:
心当たりがあれば Accept してやる。
mirie@salttest01:~$ sudo salt-key -A
The following keys are going to be accepted:
Unaccepted Keys:
minion01
Proceed? [n/Y] Y
Key for minion minion01 accepted.
これで Master と各 Minion がやりとりするように。
機能
結構多機能なようで触り切れてないのですが、ひとまず自動化・構成管理まわりのトピックとして "Grains"、"Remote Execution"、"State" を紹介。
他にも beacon とか reactor とか salt-runner とか色々あるらしいのですが、また機会があれば(←まだ触れてない)
Grains
Salt において、 管理対象のハード情報や OS 情報、ネットワーク情報などあまり変更されない静的に近いシステム情報のことを Grains と言います。
Master から対象 Minion の Grains を取得し参照が可能です。
grains.items の結果(長い)
mirie@salttest01:~$ sudo salt 'minion01' grains.items minion01: ---------- biosreleasedate: 11/12/2020 biosversion: 6.00 cpu_flags: - fpu - vme - de - pse - tsc - msr - pae - mce - cx8 - apic - sep - mtrr - pge - mca - cmov - pat - pse36 - clflush - mmx - fxsr - sse - sse2 - syscall - nx - mmxext - fxsr_opt - pdpe1gb - rdtscp - lm - constant_tsc - rep_good - nopl - tsc_reliable - nonstop_tsc - cpuid - extd_apicid - pni - pclmulqdq - ssse3 - fma - cx16 - sse4_1 - sse4_2 - x2apic - movbe - popcnt - aes - xsave - avx - f16c - rdrand - hypervisor - lahf_lm - extapic - cr8_legacy - abm - sse4a - misalignsse - 3dnowprefetch - osvw - topoext - ssbd - ibpb - vmmcall - fsgsbase - bmi1 - avx2 - smep - bmi2 - rdseed - adx - smap - clflushopt - clwb - sha_ni - xsaveopt - xsavec - xgetbv1 - xsaves - clzero - wbnoinvd - arat - umip - rdpid - overflow_recov - succor cpu_model: AMD Ryzen 7 4800U with Radeon Graphics cpuarch: x86_64 cwd: / disks: - sr0 dns: ---------- domain: ip4_nameservers: - 192.168.100.2 ip6_nameservers: nameservers: - 192.168.100.2 options: search: - home.lab sortlist: domain: efi: False efi-secure-boot: False fqdn: minion01 fqdn_ip4: - 127.0.1.1 fqdn_ip6: fqdns: - minion01 gid: 0 gpus: |_ ---------- model: SVGA II Adapter vendor: vmware groupname: root host: minion01 hwaddr_interfaces: ---------- ens192: 00:50:56:8d:87:a3 lo: 00:00:00:00:00:00 id: minion01 init: systemd ip4_gw: 192.168.100.1 ip4_interfaces: ---------- ens192: - 192.168.100.154 lo: - 127.0.0.1 ip6_gw: False ip6_interfaces: ---------- ens192: - fe80::250:56ff:fe8d:87a3 lo: - ::1 ip_gw: True ip_interfaces: ---------- ens192: - 192.168.100.154 - fe80::250:56ff:fe8d:87a3 lo: - 127.0.0.1 - ::1 ipv4: - 127.0.0.1 - 192.168.100.154 ipv6: - ::1 - fe80::250:56ff:fe8d:87a3 kernel: Linux kernelparams: |_ - BOOT_IMAGE - /boot/vmlinuz-5.4.0-91-generic |_ - root - None |_ - ro - None |_ - maybe-ubiquity - None kernelrelease: 5.4.0-91-generic kernelversion: #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 locale_info: ---------- defaultencoding: UTF-8 defaultlanguage: en_US detectedencoding: utf-8 timezone: UTC localhost: minion01 lsb_distrib_codename: focal lsb_distrib_description: Ubuntu 20.04.2 LTS lsb_distrib_id: Ubuntu lsb_distrib_release: 20.04 lvm: ---------- machine_id: 23480b5e791e447eb52bd5e85909d52f manufacturer: VMware, Inc. master: 192.168.100.153 mdadm: mem_total: 7962 nodename: minion01 num_cpus: 2 num_gpus: 1 os: Ubuntu os_family: Debian osarch: amd64 oscodename: focal osfinger: Ubuntu-20.04 osfullname: Ubuntu osmajorrelease: 20 osrelease: 20.04 osrelease_info: - 20 - 4 path: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin pid: 227322 productname: VMware Virtual Platform ps: ps -efHww pythonexecutable: /usr/bin/python3 pythonpath: - /usr/bin - /usr/lib/python38.zip - /usr/lib/python3.8 - /usr/lib/python3.8/lib-dynload - /usr/local/lib/python3.8/dist-packages - /usr/lib/python3/dist-packages pythonversion: - 3 - 8 - 10 - final - 0 saltpath: /usr/lib/python3/dist-packages/salt saltversion: 3004 saltversioninfo: - 3004 serialnumber: VMware-42 0d f1 47 3e f6 10 7b-57 b0 71 dc af 55 22 6c server_id: 1293882994 shell: /bin/sh ssds: - sda swap_total: 4095 systemd: ---------- features: +PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid version: 245 systempath: - /usr/local/sbin - /usr/local/bin - /usr/sbin - /usr/bin - /sbin - /bin - /snap/bin transactional: False uid: 0 username: root uuid: 47f10d42-f63e-7b10-57b0-71dcaf55226c virtual: VMware zfs_feature_flags: False zfs_support: False zmqversion: 4.3.2
システム情報以外にも、/etc/salt/grain
に YAML 形式でユーザ定義することが可能です。
これを使うことで、例えばサーバグルーピングやメタ情報付与といったことが可能になり、また、それらを利用した対象指定の条件ができます。
# Grains より OS が Ubuntu のものに test.ping を実行 # (1台しかないので分かり難いけど…) mirie@salttest01:~$ sudo salt -G 'os:Ubuntu' test.ping minion01: True
Remote Execution
端的に言うと pssh や fabric みたいなもので、Minion としてぶら下がっている対象に対して一斉にコマンドを発行することができます。
mirie@salttest01:~$ sudo salt '*' cmd.run 'uname -a' minion01: Linux minion01 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
コマンド実行ができればどうにでもなりますが、汎用的なものや API を叩くようなものは Execition Module として用意されています。
また、それでも足りないものは自分で独自に拡張することも可能です。
# nginx インストール mirie@salttest01:~$ sudo salt '*' pkg.install nginx minion01: ---------- fontconfig-config: ---------- new: 2.13.1-2ubuntu3 old: 【中略】 nginx: ---------- new: 1.18.0-0ubuntu1.2 old: nginx-common: ---------- new: 1.18.0-0ubuntu1.2 old: nginx-core: ---------- new: 1.18.0-0ubuntu1.2 old: # nginx の configtest mirie@salttest01:~$ sudo salt '*' nginx.configtest minion01: ---------- comment: Syntax OK result: True stdout: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # systemctl からの nginx restart mirie@salttest01:~$ sudo salt '*' service.restart nginx minion01: True
Execution Module として準備されてるものは以下のページに。
docs.saltproject.io
State
基本的な実行
IaC 的に構成をファイルに記述し、ツールがそれに従って一連のコマンドを実行し、構成や設定を投入するやり方。
Salt だとそのファイルは State と呼ばれ、YAML 形式の sls ファイルで構成を記述します。
↑ と同じように nginx インストール → configtest → restart を構成すると以下。
# デフォルトだと /srv/salt の下を見に行く。 mirie@salttest01:~$ cat /srv/salt/nginx_install.sls nginx_test: pkg.installed: - pkgs: - nginx configtest: cmd.run: - name: /usr/sbin/nginx -t - require: - nginx_test nginx_restart: cmd.run: - name: 'salt-call service.restart nginx' - require: - nginx_test
これで、salt コマンドで state.apply にて、対象ホストと state を指定すると定義した内容に従ってインストールやコマンドが実行されます。
mirie@salttest01:~$ sudo salt '*' state.apply nginx_install minion01: ---------- ID: nginx_test Function: pkg.installed Result: True Comment: The following packages were installed/updated: nginx Started: 14:00:22.884601 Duration: 5405.443 ms Changes: ---------- nginx: ---------- new: 1.18.0-0ubuntu1.2 old: ---------- ID: configtest Function: cmd.run Name: /usr/sbin/nginx -t Result: True Comment: Command "/usr/sbin/nginx -t" run Started: 14:00:28.291968 Duration: 11.563 ms Changes: ---------- pid: 352955 retcode: 0 stderr: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful stdout: ---------- ID: nginx_restart Function: cmd.run Name: salt-call service.restart nginx Result: True Comment: Command "salt-call service.restart nginx" run Started: 14:00:28.303740 Duration: 875.27 ms Changes: ---------- pid: 352957 retcode: 0 stderr: stdout: local: True Summary for minion01 ------------ Succeeded: 3 (changed=3) Failed: 0 ------------ Total states run: 3 Total run time: 6.292 s
State でのホスト指定
数台規模であれば CLI からのホスト指定/ state 指定でもどうにかなりますが、多数のホストに多数の state を管理となってくるとどのホストにどの state かをイチイチ指定していくのはシンドい…
top.sls というファイルに対象ホストや state を指定することで対象と state の管理が可能。
mirie@salttest01:~$ cat /srv/salt/top.sls base: '*': - init_server 'minion01': - nginx_install 'minion02': - mysql_install
salt
の state.apply
にて state 指定なしで top.sls の定義に従って実行されます。
# top.sls に従って全 Minion を実行 mirie@salttest01:~$ sudo salt '*' state.apply # 特定の対象だけも指定可能 mirie@salttest01:~$ sudo salt 'minion01' state.apply
補:State ファイルの話
State は YAML ファイルと言ったな
あれは嘘だ
State ファイルは YAML 形式のファイルと書きましたが、実は Jinja2 テンプレートなので、ちょっとしたロジックを仕込むことも可能です。
例えば Grains の OS 種類から apache のパッケージ指定するとこんな感じに。
apache: pkg.installed: {% if grains['os'] == 'RedHat' %} - name: httpd {% elif grains['os'] == 'Ubuntu' %} - name: apache2 {% endif %}
docs.saltproject.io
ちなみに State ファイルにはパスワードとか暗号化キー、可変的な Value を直書きするのはよろしくなく、その辺は pillar という別の機構に格納し、State からは {{ pillar['hoge] }}
みたいな形で参照するのがお作法的には正しいようです。
所感
エージェント型となると導入が面倒ではありますが、その分できることは豊富。
Remote Execution だったり、今回は試してないですが、beacon とか salt-runner 辺りが使いこなせればさらに構成管理や日常運用が楽になりそう?
また、エージェント導入も Salt SSH でカバーできたりで大きなマイナスではないかも。
ネックはとにかく情報量の少なさ…
利用が増え、情報量が増えたりモジュール開発がより活発になれば、他の構成管理ツールより強力なツールになり得るポテンシャルは十分に秘めていそうです。
ところで vRealize Automation SaltStack Config は何するの?
そんな Salt の GUI やダッシュボード、統合管理、認証、監査ログなどなど、エンタープライズ向け機能が追加されているものが旧 SaltStack Enterprise で、現在で言うところの vRealize Automation SaltStack Config になります。
(Ansible における Ansible Tower みたいな感じ?)
で、試してみようと思うわけですが…MyVMware を見てみると
Download できず。試用不可。
vExpert Portal 上にも何もなく、入手すら不可という状態…orz
(ライセンスは vRealize Suite でいける?)
そのうち検証版出たりするかなぁ。
Appendix
2021/12/15 に開催される VMware DevOps Meetup #11 にて Salt で話をします! vmware.connpass.com ブログ内容ベースにこぼれたネタ + デモを入れる予定ですが、話のボリュームが…