#author("2022-09-06T23:31:54+00:00","default:sysosa","sysosa") #author("2025-02-23T15:18:00+00:00;2022-09-06T23:31:54+00:00","default:sysosa","sysosa") [[kickstart]]で大本は作れたが、細かい箇所もサーバ構築の自動化するのに使ってみた &size(10){はじめChefを使ったが分かりにくかったのでこちらへ転向した}; [[Ansible/Playbook]] ***インストール [#q58b4a08] 作業するマシンにインストールします。作業対象にインストールする必要はありません。 ここでは管理サーバ c.sybyl.local にAnsibleをインストールします パッケージは epel リポジトリに存在しているので #code(nonumber){{ [root@c ~]# yum install epel-release [root@c ~]# yum install --enablerepo=epel install ansible [root@c ~]# yum install --enablerepo=epel ansible }} これで完了みたい ***管理対象の登録 [#m1b4a6ae] ansibleのインストールが完了すると /etc/ansible が作られる。 そこに &color(magenta){hosts};ファイルが存在する。ここに管理対象のホストを記載します #code(nonumber){{ [root@c ~]# ls -l /etc/ansible/ 合計 24 -rw-r--r-- 1 root root 18066 6月 2 06:49 ansible.cfg -rw-r--r-- 1 root root 1016 6月 2 06:49 hosts drwxr-xr-x 2 root root 6 6月 2 06:49 roles [root@c ~]# }} &color(magenta){hosts};ファイルには記載例が書かれており、単純に対象を個別に登録するほか、グループを作ったりホスト名の連番とかにも対応するみたい. ホスト名でもIPアドレスでも可 ここではグループ名 &color(orangered){cluster}; を作り、その中に連番のホスト( n[1:4].sybyl.local )とを持たせてみた #code(nonumber){{ [root@c ~]# cat /etc/ansible/hosts [cluster] n[1:4].sybyl.local <-- グループとの区切りは空行 nfs.sybyl.local <-- 単発指定 [root@c ~]# }} このファイルは各自のユーザにて用意して、「」 ***ssh接続 [#i39de3f4] ansibleはsshで相手方(管理対象)に接続して操作を行う 基本「パスワード」入力無しで接続を前提にしているようで、相手方(illya@nfs.sybyl.local)へはパスワードが必要な状態だと #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m ping nfs.sybyl.local | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true } [illya@c ~]$ }} と言われる. この場合は「--ask-pass」を入れて、パスワード入力を有効にする必要がある. #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m ping --ask-pass SSH password: <-- ここで相手方(illya@nfs.sybyl.local)のパスワードを入力する nfs.sybyl.local | SUCCESS => { "changed": false, "ping": "pong" } [illya@c ~]$ }} 相手側が自分ではない他のユーザ(root@nfs.sybyl.local)として接続したいのなら、「--user」で指定する &size(10){ 「[illya@c ~]$ ssh -l root nfs.sybyl.local」な感じで、nfsにrootで接続して、--ask-passでパスワードを入力な感じ。}; #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m ping --ask-pass --user root SSH password: <-- ここで相手方(root@nfs.sybyl.local)のパスワードを入力する nfs.sybyl.local | SUCCESS => { "changed": false, "ping": "pong" } [illya@c ~]$ }} もし自分の公開鍵が相手側の .ssh/authorized_keys に登録されていれば パスフレーズ が自動的に求められる. #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m ping Enter passphrase for key '/home/illya/.ssh/id_rsa': <-- ここにパスフレーズを入力 nfs.sybyl.local | SUCCESS => { "changed": false, "ping": "pong" } [illya@c ~]$ }} さらに鍵の作成時に パスフレーズ を指定しない場合だと、当然ながらパスフレーズを問わず実行できます #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m ping nfs.sybyl.local | SUCCESS => { "changed": false, "ping": "pong" } [illya@c ~]$ }} 自分の(パスフレーズなしな)公開鍵を相手側の root の .ssh/authorized_keys に入っているなら #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m ping --user root nfs.sybyl.local | SUCCESS => { "changed": false, "ping": "pong" } [illya@c ~]$ }} ssh-agentを使っても構わない [[ssh/ssh-agent]] &color(red){*};&size(10){[[ホストベース認証>ssh/ホストベース認証]]も有効でした}; 凝った方法.「-k(--ask-pass)」と「--user ABC」で相手先にユーザABCでログインして、 その後に「-b(--become)」で別ユーザになってコマンドを実行させる. その際「--become-method=su」と「su」で「--become-user root」とユーザ「root」になるために「-K(--ask-become-pass)」でパスワード入力をさせる #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m ping -k -u illya -b --become-method=su -K (ansible nfs.sybyl.local -m ping --ask-pass --user illya --become --become-method=su --ask-become-pass) SSH password: <-- 「-k」で要求される「--user」のパスワード (illya@nfs.sybyl.local) BECOME password[defaults to SSH password]: <-- 「-K」で要求される「--become-user」のパスワード(root@nfs.sybyl.local) nfs.sybyl.local | SUCCESS => { "changed": false, "ping": "pong" } [illya@c ~]$ }} ***root権限操作 [#cbe88943] 一般ユーザで相手側にログインするので、当然その権限はそのユーザの範囲内に制限される. 相手方に/dataディレクトリを作る場合 #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m file -a "path=/data state=directory mode=0755" --ask-pass SSH password: nfs.sybyl.local | FAILED! => { "changed": false, "failed": true, "msg": "There was an issue creating /data as requested: [Errno 13] 許可がありません: '/data'", "path": "/data", "state": "absent" } [illya@c ~]$ }} と当然ながら拒否される。 リモートから直接rootになれる環境なら単に「--user root」でもいいのだが、 sshdの設定で「&color(magenta){PermitRootLogin no};」とあった場合、自分のアカウントとかで相手先(illya@nfs.sybyl.local)に接続して その後 su して root(root@nfs.sybyl.local) に switch する必要がある。 下記は、 「--ask-pass」で相手先(illya@nfs.sybyl.local)のパスワード入力を行い 「--su」で相手マシン(nfs.sybyl.local)で「su」を行い 「--su-user root」で「su」の対象はroot(root@nfs.sybyl.local)で 「--ask-su-pass」で「su」の際のパスワード入力を行う &size(10){「--su-user=」は既定でrootですが、明示的に指定しました}; #code(nonumber){{ [illya@c ~]$ ansible nfs.sybyl.local -m file -a "path=/data state=directory mode=0755" --ask-pass --su --su-user=root --ask-su-pass SSH password: <-- 相手方へのログインパスワード SU password[defaults to SSH password]: <-- 相手方でrootになるためのパスワード nfs.sybyl.local | SUCCESS => { "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/data", "size": 6, "state": "directory", "uid": 0 } [illya@c ~]$ }} 相手方への接続は パスフレーズ なしの接続、ホストベース認証、kerberos認証らでパスワード無しができる。 &size(10){ssh-agentを使う方法もあるけど}; そして、相手方でroot権限で作業する際には「--su」より「--sudo」とsudoを用いる事でパスワード無しにも出来る sudoでパスワード無しでroot権限が使えるようになるには [[visudo]] で /etc/sudoers の修正が必要です(相手側の/etc/sudoers). ***モジュール [#t66c05cb] ansibleにて使用できるコマンドは[[http://docs.ansible.com/ansible/latest/modules_by_category.html>+http://docs.ansible.com/ansible/latest/modules_by_category.html]]に記載されている。 ここでは「System Modules」に存在するpingで死活監視、「Files Modules」に存在するfileにてディレクトリを作ってみた. モジュールを見てみると、windowsマシンへの対応もあるようです ***Playbook [#i2796f47] これら一番大事な箇所かも. ansibleでの操作をファイルに記述して、それを実行する。そうすればそのマシンに対する作業履歴として残せる. yum updateさせるファイル #code(nonumber){{ [illya@c ~]$ cat yumupdate.yml - hosts: nfs.sybyl.local tasks: - name: yum update yum: name=* state=latest [illya@c ~]$ }} そして、このファイルの文法チェックを行って #code(nonumber){{ [illya@c ~]$ ansible-playbook yumupdate.yml --syntax-check playbook: yumupdate.yml [illya@c ~]$ }} 実際に実行します #code(nonumber){{ [illya@c ~]$ ansible-playbook yumupdate.yml --ask-pass --su --su-user=root --ask-su-pass SSH password: SU password[defaults to SSH password]: PLAY [nfs.sybyl.local] ************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************** ok: [nfs.sybyl.local] TASK [yum update] ******************************************************************************************************* changed: [nfs.sybyl.local] PLAY RECAP ************************************************************************************************************** nfs.sybyl.local : ok=2 changed=1 unreachable=0 failed=0 [illya@c ~] }} yumupdate.ymlファイルの「hosts:」をグループ名とか「all」とかすれば、漏れなくyum updateができる。 っと言ってもこれはごくごく簡単な例。 実際にはcentos6とcentos7を区別して起動させるchkconfig/systemctlらを有効にして、実行とか 新たなマウントポイントのための/etc/fstabの書き換えとmountコマンドの実行とかがメインになるのかも ***Playbook(再起動) [#g0c701ca] 登録マシンを一斉に再起動させたいなら #code(nonumber){{ - hosts: e tasks: - name: reboot shell: "sleep 5 && reboot" async: 1 poll: 0 ignore_errors: true - name: wait wait_for_connection: connect_timeout: 20 sleep: 5 delay: 5 timeout: 120 - name: ping ping: }} とした reboot.yml を作って #code(nonumber){{ [illya@c ~]$ ansible-playbook e.yml --user root --ask-pass }} と実行する。 ***Playbook(一斉停止) [#q8fcd768] &color(red){*};pukiwikiの表記規則から、「{{」を「{ }」に。「}}」を「} }」にしています。 #code(nonumber){{ - hosts: em tasks: - name: shutdown command: "/sbin/shutdown -h 1" - name: wait go down wait_for: host: "{ { inventory_hostname } }" port: 22 state: stopped delegate_to: 127.0.0.1 }} #code(nonumber){{ ansible-playbook shutdown.yml --user root --ask-pass }} ***/etc/ansible/hostsに登録されていないマシンへの適用は? [#h895d160] どうやらできるみたい 例えば、ad.sybyl.localに対して、environment-modulesを入れたいとして、 #code(nonumber){{ - hosts: all tasks: - yum: name=environment-modules state=latest - name: stat modulespath stat: path=/usr/share/Modules/init/.modulespath register: modulespath_stat - name: back up command: mv /usr/share/Modules/init/.modulespath /usr/share/Modules/init/.modulespath.orig when: modulespath_stat.stat.exists - name: modulespath.orig copy: dest: /usr/share/Modules/init/.modulespath content: | /home/Common/modules }} を用意したら #code(nonumber){{ ansible-playbook -i ad, --user root ./EnvironmentModules.yml }} で成功した。要は「ad,」みたい。 &color(red){*};「- hosts: all」が前提みたい