在操作系统启动时使用systemd,执行ansible操作
概述
由于内容较长,最好查阅目录。
目标
在大量设置节点时,有没有办法能让这个过程变得更轻松一点呢?
比如,操作系统可以通过PXE进行安装,而应用程序的安装可以通过某个服务器使用ansible等工具来执行。
这样操作人员就可以参与其中了。(现在可能通过k8s等自动化完成了吧)
我不知道这是否是常态,但是节点部署的数量越多,操作系统和应用程序的安装就会交叉进行。
也许我仍在做一些过时的事情,但我并不确定这种情况。
是否有可能在操作系统启动时自动完成应用程序的安装?
我试着以“关于这个话题进行思考”。
但是,我还是觉得这只是个表面现象,我最想了解的还是最近的趋势。
我认为现在已经没有人介入的时代了,从操作系统的设置到应用程序的安装等等。
大家都是怎么做的呢(==;
方法
在通过PXE进行操作系统安装时,需要在目标节点上构建ansible执行环境。
在systemd上添加自动部署机制(仅仅是触发ansible的服务),并将该服务设置为自动启动。
这次我考虑了一下这个部分的准备工作。
选择使用systemd的原因
以下是采用systemd的原因:可以在启动时使用各种工具构建脚本,如rc.local等。
-
- 出来るだけスクリプト系は使いたく無い。(汎用性は得るが管理が面倒)
-
- ansibleはssh.service等のサービス起動後に実施する必要がある。故にサービス実行順序を制御したい
- 成功要否を容易く見れるようにしたい(systemd statusで結構わかりやすく見れた)
确认环境
-
- conoha VPS(break & buildで重宝させていただいてます(:DTZ
-
- OS : ubuntu16.04.5
- ansible : 2.7.7(using pip)
结果
完成以上两个文件后,可以执行ansible。
在本节中,将描述要点。
root@118-27-10-158:~/auto-deploy_ansible/ansible# cat /etc/systemd/system/auto-deploy.service
[Unit]
Description = Auto Deploy using Ansible.
After = ssh.service apt-daily-upgrade.timer apt-daily.timer
[Service]
EnvironmentFile = /etc/default/auto-deploy
ExecStart = /usr/local/bin/ansible-playbook -i inventories/staging/hosts ${PLAYBOOK} -t ${TAG} -l ${HOSTNAME}
WorkingDirectory = /root/auto-deploy_ansible/ansible/
Type = oneshot
[Install]
WantedBy = multi-user.target
root@118-27-10-158:~/auto-deploy_ansible/ansible#
root@118-27-10-158:~/auto-deploy_ansible/ansible# cat /etc/default/auto-deploy
TAG="auto-deploy"
PLAYBOOK="auto-deploy.yml"
HOSTNAME="118-27-10-158"
root@118-27-10-158:~/auto-deploy_ansible/ansible#
文件单位的重点
-
- 変数化した方が扱い易いのでEnvironmentFileに変数定義ファイルを用意する
ExecStartはansibleのフルパスを指定する。(パスが通っててもNG)
WorkingDirectoryにansibleの実行パスを記述する。
ansible.cfgはWorkingDirectory配下もしくは「/etc/ansible」等実行時に参照出来る状況にする
Afterの節はssh.service起動後が前提条件
apt-daily-upgrade.timeの記述理由は当該サービスがEnableの場合、aptのインストール時に競合する可能性があるから待つ。
Typeをoneshotにしているのは1回のみ実行に明示的に定義するため。(成否問わず1回のみだ)
服务执行时的日志,成功时。
服务运行时会执行ansible。
执行后,状态将变为inactive(loaded)。
根据最新的日志输出可以判断出ansible的执行日志。
root@118-27-10-158:~# systemctl start auto-deploy.service
root@118-27-10-158:~# systemctl status auto-deploy.service
● auto-deploy.service - Auto Deploy using Ansible.
Loaded: loaded (/etc/systemd/system/auto-deploy.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Feb 11 15:19:40 118-27-10-158 ansible-playbook[6990]: ok: [118-27-10-158]
Feb 11 15:19:40 118-27-10-158 ansible-playbook[6990]: TASK [systemd : disable auto-deploy service] ***********************************
Feb 11 15:19:41 118-27-10-158 ansible-playbook[6990]: ok: [118-27-10-158]
Feb 11 15:19:41 118-27-10-158 ansible-playbook[6990]: TASK [apt : Only run "update_cache=yes"(apt-get update)] ***********************
Feb 11 15:19:43 118-27-10-158 ansible-playbook[6990]: changed: [118-27-10-158]
Feb 11 15:19:43 118-27-10-158 ansible-playbook[6990]: TASK [libvirt : Install libvirt-bin] *******************************************
Feb 11 15:19:44 118-27-10-158 ansible-playbook[6990]: ok: [118-27-10-158]
Feb 11 15:19:44 118-27-10-158 ansible-playbook[6990]: PLAY RECAP *********************************************************************
Feb 11 15:19:44 118-27-10-158 ansible-playbook[6990]: 118-27-10-158 : ok=6 changed=1 unreachable=0 failed=0
Feb 11 15:19:44 118-27-10-158 systemd[1]: Started Auto Deploy using Ansible..
root@118-27-10-158:~#
在服务执行时的日志,当出现失败时
导入与成功时相同。
执行后将为“活动:失败”,只需在此处查看即可判断结果。
root@118-27-10-158:~/auto-deploy_ansible/ansible# systemctl start auto-deploy.service
Job for auto-deploy.service failed because the control process exited with error code. See "systemctl status auto-deploy.service" and "journalctl -xe" for details.
root@118-27-10-158:~/auto-deploy_ansible/ansible# systemctl status auto-deploy.service
● auto-deploy.service - Auto Deploy using Ansible.
Loaded: loaded (/etc/systemd/system/auto-deploy.service; disabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Mon 2019-02-11 15:24:11 JST; 8s ago
Process: 7742 ExecStart=/usr/local/bin/ansible-playbook -i inventories/staging/hosts ${PLAYBOOK} -t ${TAG} -l ${HOSTNAME} (code=exited, status=4)
Main PID: 7742 (code=exited, status=4)
Feb 11 15:24:10 118-27-10-158 systemd[1]: Starting Auto Deploy using Ansible....
Feb 11 15:24:11 118-27-10-158 ansible-playbook[7742]: ERROR! Syntax Error while loading YAML.
Feb 11 15:24:11 118-27-10-158 ansible-playbook[7742]: found unexpected end of stream
Feb 11 15:24:11 118-27-10-158 ansible-playbook[7742]: The error appears to have been in '/root/auto-deploy_ansible/ansible/roles/common/tasks/debug/debug_mes.yml': line 4, column 1,
Feb 11 15:24:11 118-27-10-158 ansible-playbook[7742]: be elsewhere in the file depending on the exact syntax problem.
Feb 11 15:24:11 118-27-10-158 ansible-playbook[7742]: (specified line no longer in file, maybe it changed?)
Feb 11 15:24:11 118-27-10-158 systemd[1]: auto-deploy.service: Main process exited, code=exited, status=4/NOPERMISSION
Feb 11 15:24:11 118-27-10-158 systemd[1]: Failed to start Auto Deploy using Ansible..
Feb 11 15:24:11 118-27-10-158 systemd[1]: auto-deploy.service: Unit entered failed state.
Feb 11 15:24:11 118-27-10-158 systemd[1]: auto-deploy.service: Failed with result 'exit-code'.
root@118-27-10-158:~/auto-deploy_ansible/ansible#
ansible日志管理
这不是本页面的目的。正常情况下,可以通过在ansible.cfg中定义日志输出路径来确保日志与常规的ansible执行一样。
亲自动手
因为重复实验太麻烦了,所以我制作了样本素材,可以共享给大家。使用ansible自动部署。
這個執行步驟是在使用上述資材的前提下進行描述。
准备ansible自动执行环境。
目前正在做的事情是安装Ansible包并配置systemd相关文件。接下来是对自身进行SSH无密码设置和确认。最后,在Ansible的清单中添加主机名就完成了准备工作。资料内容并不复杂,如果查看github就可以理解。
-
- git clone https://github.com/maki0922/auto-deploy_ansible
-
- cd auto-deploy_ansible/prepare/
-
- bash -x setting_systemd.yml
-
- bash -x prepare_pip.sh
-
- bash -x install_package.sh
-
- ssh-keygen -t rsa -b 4096 -C “your_email@example.com”
-
- ssh-copy-id
-
- ssh
-
- exit
- edit ../ansible/inventories/staging/hosts (add hostname to computer block)
服务状态
只要自动启动设置已经启用,就可以了。
root@118-27-24-70:~/auto-deploy_ansible/prepare# systemctl status auto-deploy.service
● auto-deploy.service - Auto Deploy using Ansible.
Loaded: loaded (/etc/systemd/system/auto-deploy.service; enabled; vendor preset: enabled)
Active: inactive (dead)
root@118-27-24-70:~/auto-deploy_ansible/prepare#
root@118-27-24-70:~/auto-deploy_ansible/prepare#
开始自动执行
使用reboot命令重新启动操作系统。(在通过PXE构建之后应该通过重新启动来实现)
部署后的服务状态
可以通過以下方式確認auto-deploy.service已經完成。
※如前所述,如果失敗,則狀態為failed。
root@118-27-24-70:~# systemctl status auto-deploy.service
● auto-deploy.service - Auto Deploy using Ansible.
Loaded: loaded (/etc/systemd/system/auto-deploy.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Feb 11 16:00:52 118-27-24-70 ansible-playbook[1195]: changed: [118-27-24-70]
Feb 11 16:00:52 118-27-24-70 ansible-playbook[1195]: TASK [systemd : disable auto-deploy service] ***********************************
Feb 11 16:00:53 118-27-24-70 ansible-playbook[1195]: changed: [118-27-24-70]
Feb 11 16:00:53 118-27-24-70 ansible-playbook[1195]: TASK [apt : Only run "update_cache=yes"(apt-get update)] ***********************
Feb 11 16:00:55 118-27-24-70 ansible-playbook[1195]: changed: [118-27-24-70]
Feb 11 16:00:55 118-27-24-70 ansible-playbook[1195]: TASK [libvirt : Install libvirt-bin] *******************************************
Feb 11 16:01:08 118-27-24-70 ansible-playbook[1195]: changed: [118-27-24-70]
Feb 11 16:01:08 118-27-24-70 ansible-playbook[1195]: PLAY RECAP *********************************************************************
Feb 11 16:01:08 118-27-24-70 ansible-playbook[1195]: 118-27-24-70 : ok=6 changed=4 unreachable=0 failed=0
Feb 11 16:01:08 118-27-24-70 systemd[1]: Started Auto Deploy using Ansible..
root@118-27-24-70:~#
Ansible日志
我查看了在ansible.cfg中定义的日志,发现没有失败的记录。看起来很不错(陶醉)
root@118-27-24-70:~# cat /tmp/ansible_logfile
2019-02-11 16:00:49,466 p=1195 u=root | PLAY [auto-deploy] *************************************************************
2019-02-11 16:00:49,478 p=1195 u=root | TASK [Gathering Facts] *********************************************************
2019-02-11 16:00:51,718 p=1195 u=root | ok: [118-27-24-70]
2019-02-11 16:00:51,736 p=1195 u=root | TASK [common : debug messages] *************************************************
2019-02-11 16:00:51,861 p=1195 u=root | ok: [118-27-24-70] => {
"msg": "auto deploy start."
}
2019-02-11 16:00:51,878 p=1195 u=root | TASK [common : sample template 001] ********************************************
2019-02-11 16:00:52,461 p=1195 u=root | changed: [118-27-24-70]
2019-02-11 16:00:52,477 p=1195 u=root | TASK [systemd : disable auto-deploy service] ***********************************
2019-02-11 16:00:53,243 p=1195 u=root | changed: [118-27-24-70]
2019-02-11 16:00:53,259 p=1195 u=root | TASK [apt : Only run "update_cache=yes"(apt-get update)] ***********************
2019-02-11 16:00:55,654 p=1195 u=root | changed: [118-27-24-70]
2019-02-11 16:00:55,671 p=1195 u=root | TASK [libvirt : Install libvirt-bin] *******************************************
2019-02-11 16:01:08,084 p=1195 u=root | changed: [118-27-24-70]
2019-02-11 16:01:08,091 p=1195 u=root | PLAY RECAP *********************************************************************
2019-02-11 16:01:08,091 p=1195 u=root | 118-27-24-70 : ok=6 changed=4 unreachable=0 failed=0
root@118-27-24-70:~#
資材上的重點 001
aptパッケージのインストールに成功したのはやはり大きいです。
chefなどと競合していたが、apt-daily-upgrade.timeなどの自動でaptが自動的に
動作するサービスと競合しないようにすることができるのは、systemdの設定の良い点です。
ログ上でも、問題なくlibvirt-binパッケージがインストールされています。
2019-02-11 16:00:55,671 p=1195 u=root | TASK [libvirt : Install libvirt-bin] *******************************************
2019-02-11 16:01:08,084 p=1195 u=root | changed: [118-27-24-70]
002的关键点在于供应材料。
关闭了自动部署服务。
这是为了在操作系统安装后重新启动时进行部署而设置的,部署后不会自动启动的配置。
或许也可以考虑使用屏蔽设置,但我选择了禁用设置(这取决于用途和个人喜好)。
root@118-27-24-70:~# systemctl is-enabled auto-deploy.service
disabled
root@118-27-24-70:~#