我团队中的任何人都可以通过SSH连接到我们的特殊部署服务器,并从那里运行Ansible playbook将新代码推送到计算机.
如果两个人试图同时进行部署,我们会担心会发生什么.我们想要这样做,以便如果其他人正在运行它,剧本将会失败.
有关如何做到这一点的任何建议?标准解决方案是使用pid文件,但Ansible没有内置支持.
Phi*_*mes 27
我个人使用RunDeck(http://rundeck.org/)作为我的Ansible剧本的包装器有多种原因:
当然还有很多很好的理由,但我的手指已经厌倦了打字;)
leu*_*cos 18
您可以为ansible命令编写一个包装器,如下所示:
ansible-playbook() {
lock="/tmp/ansible-playbook.lock"
# Check if lock exists, return if yes
if [ -e $lock ]; then
echo "Sorry, someone is running already ansible from `cat $lock`"
return
fi
# Install signal handlers
trap "rm -f $lockfile; trap - INT TERM EXIT; return" INT TERM EXIT
# Create lock file, saving originating IP
echo $SSH_CLIENT | cut -f1 -d' ' > $lock
# Run ansible with arguments passed at the command line
`which ansible-playbook` "$@"
# Remove lock file
rm $lock
# Remove signal handlers
trap - INT TERM EXIT
}
Run Code Online (Sandbox Code Playgroud)
~/.bashrc在部署框中的用户中定义此功能,然后进行设置.ansible如果你愿意,你也可以为命令做同样的事情,但考虑到问题,我不确定是否需要.
编辑:重写信号处理程序,以防止用户按Ctrl-C时锁定文件悬空.
EDIT2:修正了拼写错误
pop*_*nic 11
之后,我把它放在我的主要剧本中
hosts: all.
Run Code Online (Sandbox Code Playgroud)
lock_file_path:这是一个文件,其存在表明当前正在运行ansible部署,或之前有部署,由于某种原因中止.
force_ignore_lock:默认为false,由选项标志重置,您可以在命令行包装器中将其设置为ansible.它使ansible能够继续部署.
pre_tasks第一个pre_task检查是否lock_file_path存在,并将结果记录在一个名为的寄存器中lock_file.
然后,下一个任务检查文件是否存在,以及部署人员是否选择忽略它(希望在与其他队友通信之后).如果没有,则作业失败,并显示有用的错误消息.
如果用户选择继续部署即使存在lock_file,则下一个任务将删除先前创建的lock_file并创建一个新任务.然后,所选角色中的其他任务继续愉快.
post_tasks这是在部署中的所有任务完成后立即调用的挂钩.这里的任务删除了lock_file,让下一个人快乐地部署,没有任何问题.
vars:
lock_file_path=/tmp/ansible-playbook-{{ansible_ssh_user}}.lock
pre_tasks:
- stat: path={{lock_file_path}}
register: lock_file
- fail: msg="Sorry, I found a lockfile, so I'm assuming that someone was already running ansible when you started this deploy job. Add -f to your deploy command to forcefully continue deploying, if the previous deploy was aborted."
when: lock_file.stat.exists|bool and not force_ignore_lock|bool
- file: path={{lock_file_path}} state=absent
sudo: yes
when: "{{force_ignore_lock}}"
- file: path={{lock_file_path}} state=touch
sudo: yes
post_tasks:
- file: path={{lock_file_path}} state=absent
sudo: yes
Run Code Online (Sandbox Code Playgroud)
你考虑过设置maxsysloginslimits.conf吗?您可以按组限制.
# for a group called 'deployers'
@deployers - maxsyslogins 1
Run Code Online (Sandbox Code Playgroud)
这比你要求的要严重得多.您可能希望首先在VM上尝试它.请注意,如果系统上有任何其他用户,则部署者中没有人可以访问,1限制不仅仅计算部署者.此外,如果您作为用户多路复用您的ssh连接(ControlMaster auto),您仍然可以多次登录; 这是其他被锁定的用户.
小智 5
您可以使用flock命令,它将使用基于文件系统的flock(2)包装您的命令:
$ flock /tmp/ansible-playbook.lock ansible-playbook foo bar baz
Run Code Online (Sandbox Code Playgroud)
尽管它最适合您的用户.这将使在/ tmp下的持久锁文件,但要注意它是不是安全地删除[1].它是原子的,非常简单.
[1]
A: flock /tmp/foo.lock -c "echo running; sleep 5; rm /tmp/foo.lock"
B: flock /tmp/foo.lock -c "echo running; sleep 5; rm /tmp/foo.lock"
B blocks waiting for lock on /tmp/foo.lock
A: Finish, deleting /tmp/foo.lock
B: Runs, using lock on now deleted /tmp/foo.lock
C: flock /tmp/foo.lock -c "echo running; sleep 5; rm /tmp/foo.lock"
Creates new /tmp/foo.lock, locks it and runs immediately, parallel with B
Run Code Online (Sandbox Code Playgroud)
小智 5
当可以从多个构建主机运行部署作业时,包装脚本无用。对于这种情况,锁定必须由剧本处理。
Ansible现在有一个wait_for模块,可用于锁定。这是一个简短的示例(不考虑过时的锁定):
vars:
lock_file: "{{ deploy_dir }}/.lock"
pre_tasks:
- name: check for lock file
wait_for:
path: "{{ lock_file }}"
state: absent
- name: create lock file
file:
path: "{{ lock_file }}"
state: touch
post_tasks:
- name: remove lock file
file:
path: "{{ lock_file }}"
state: absent
Run Code Online (Sandbox Code Playgroud)
Ansible将在可配置的超时期限内检查锁定文件,然后在该期限内未将其删除则放弃。
| 归档时间: |
|
| 查看次数: |
14787 次 |
| 最近记录: |