
通过 systemd 服务的形式部署管理,然后把升级操作也集成了,如果数据量不是特别大,那么整个安装以及后续升级过程应该是很舒服的。
这是我开发的第一个 role ,用 AI 那是肯定的了,不过也是进行了比较充分的测试,最主要的是对整个流程熟悉了。熟悉了以后,愈发喜欢 ansible 了,开发测试充分的前提下,后续使用非常可靠,幂等带来的安全感真是无与伦比的
]]>pct 调用示例:
- name: Use USTC mirrors pct: cmd: "exec" host: "{{ inventory_hostname }}" extra_args: "sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories" 仓库代码: https://b64s.uk/._RfMW0hMR6Qd9sfCWtiBNzD29yQ2EqgricfX9birZyDB5efBOxEV
基本上就是调用 pct 命令,比如安装 memos:
ansible-playbook -i pve apps_memos.yml
比如批量更新全部 vm 、lxc ,这个特殊点应该机型多,直接写了个通用脚本复制到远程执行:
只更新 vm: STATUS=running ansible-playbook -i pve update.yml --limit vm
只更新 lxc: STATUS=running ansible-playbook -i pve update.yml --limit lxc
去掉 limit 就是全部更新。
没咋写过 python ,ansible 也是这几天才开始熟悉,有问题的地方欢迎指出。
]]>这个也导致了我使用 ansible 安装的时候也会失败,我的 ansible 编排如下
- name: add docker repo shell: yum-config-manager --add-repo {{ docker.repo }} - name: install docker-ce yum: name={{ docker.version }} state=present update_cache=True 请问在 shell 脚本和 ansible 中分别如何避免这个确认的操作?
]]>第一次接触 ansible 。
需求如下:
假设我的用户只能是无密码切换到 root ,怎么用 ansible ad-hoc 方式远程执行需要 root 的命令。
我 foo 用户权限:
foo ALL=(ALL) NOPASSWD: /bin/su 计划执行(批量更新 hosts 文件):
ansible --private-key xxx -u foo all -m copy -a "src=http://www.v2ex.com/etc/hosts dest=/etc/hosts" -become --become-user root --become-method 'sudo' 报错:
1.2.3.4 | FAILED! => { "msg": "Missing sudo password" } 谷歌的方法基本试过了不太奏效。据说 playbook 可以,但是目前想了解 ad-hoc 方式是否能直接支持。
]]>首先因为 ansible 核心功能 play 是基于文件和 role 目录来执行可复用的任务,而目标机器组( inventory )也是记录在文件内的。
最简单办法,就是文件读取和解析,然后映射到界面上,但这其中还涉及 play 文件内的各种变量和关键词,还有频繁的文件操作,不认为是一个最佳的解决方案。 比较合理的办法,是自行开发 ansible 模块或插件,以实现从你的 web api 获取资源。
inventory 的解决办法比较简单,写一个 inventory 插件,从你的 api 接口获取主机列表,然后组装成 ansible 能识别的数据结构,实际上 AWX 的源码里也是写了这样的插件InventoryModule(BaseInventoryPlugin)。
这个插件使用了 awx 写的另一个 module_util:ControllerModule(AnsibleModule),用来从他的 web api 里获取资源。
... module = ControllerAPIModule(argument_spec={}, direct_params=module_params, error_callback=handle_error, warn_callback=self.warn_callback) ... inventory = module.get_endpoint(inventory_url, data={'hostvars': '1', 'towervars': '1', 'all': '1'})['json'] 而 play 的执行,awx 则是使用了ansible-runner这个库,这个库可以通过读取一个固定结构的目录直接执行 play ,也提供 python 接口可以传递 play 的必要参数来执行 play 。
awx 是让用户自行提供一个 play 文件,然后保存到固定的目录下,inventory 也是保存到固定位置的文件里,然后调用 ansible-runner 执行。
params = { 'ident': self.instance.id, 'private_data_dir': private_data_dir, 'playbook': self.build_playbook_path_relative_to_cwd( self.instance, private_data_dir ), 'inventory': self.build_inventory(self.instance, private_data_dir), 'passwords': expect_passwords, 'envvars': env, 'settings': { 'job_timeout': self.get_instance_timeout(self.instance), 'suppress_ansible_output': True, }, } ... if isinstance(self.instance, SystemJob): res = ansible_runner.interface.run( project_dir=settings.BASE_DIR, event_handler=self.event_handler, finished_callback=self.finished_callback, status_handler=self.status_handler, **params, ) ... 这个 task 的执行是通过 Job 模型保存时的信号来决定,task 的执行是维护在另一个线程内(这里还没摸透,只大致知道是通过信号引发执行)
不解的地方在于:
就是把目标 IP 加到目标机器的环境变量中。 主要不知道该怎么传递这个变量。
]]>if [ -f ~/.ssh/id_rsa.pub ] then cat ~/.ssh/id_rsa.pub elif [ -f ~/.ssh/id_rsa ] && [ ! -f ~/.ssh/id_rsa.pub ] then echo -e "\ny\n\n\n" | ssh-keygen -t rsa cat ~/.ssh/id_rsa.pub else echo -e "\n\n\n\n" | ssh-keygen -t rsa cat ~/.ssh/id_rsa.pub fi 改成 play
- hosts: 192.168.8.128 tasks: - name: create host ssh rsa shell: if [ -f ~/.ssh/id_rsa.pub ];then cat ~/.ssh/id_rsa.pub;elif [ -f ~/.ssh/id_rsa ] && [ ! -f ~/.ssh/id_rsa.pub ];then echo -e "\ny\n\n\n" | ssh-keygen -t rsa; cat ~/.ssh/id_rsa.pub;else echo -e "\n\n\n\n" | ssh-keygen -t rsa; cat ~/.ssh/id_rsa.pub; fi 但似乎 echo -e "\ny\n\n\n" | ssh-keygen -t rsa; 这一句并没有起效果, 有遇到过这种问题的吗? 如果还是不行的话, 那就只能 script 模块传送脚本, 或者用 paramiko 封装一个, 之前在其他项目用的是 fabric, 但这个想用 ansible 做
]]>[root@master ansible]# ansible node1 -B 3600 -P 0 -m yum -a "name=ansible" -vv Using /etc/ansible/ansible.cfg as config file META: ran handlers 192.168.77.129 | SUCCESS => { "ansible_job_id": "23974611070.37468", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/23974611070.37468", "started": 1 } [root@master ansible]# ansible node1 -m async_status -a "jid=23974611070.37468" 192.168.77.129 | SUCCESS => { "ansible_job_id": "23974611070.37468", "changed": false, "finished": 1, "msg": "", "rc": 0, "results": [ "ansible-2.3.1.0-1.el6.noarch providing ansible is already installed" ] } playbook 也是可以指定参数启用异步的。
# asynctest.yml --- - hosts: node1 tasks: - shell: sleep 100 && hostname async: 100 poll: 0 register: result - debug: var=result - async_status: jid={{ result.ansible_job_id }} register: job_result until: job_result.finished retries: 30 那么在 ansible api 里对于 ad-hoc 和 playbook 怎么启用这个异步任务的,不然页面有时候要卡好久在那的。
# create play with tasks play_source = dict( name = "Ansible Play", hosts = 'all', # 这里指定 all gather_facts = 'no', tasks = [ dict(action=dict(module='shell', args='ls'), register='shell_out'), dict(action=dict(module='debug', args=dict(msg=''))) ] ) play = Play().load(play_source, variable_manager=variable_manager, loader=loader) # actually run it tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, optiOns=options, passwords=passwords, stdout_callback=results_callback, # Use our custom callback instead of the ``default`` callback plugin ) result = tqm.run(play) finally: if tqm is not None: tqm.cleanup() 之前在 django 中会使用 celery 做一些异步任务的工作。
现在想了解 ansible 在使用 api 时候,有没自己的一些异步方式的,我能在 django 中直接使用的。
]]>现在 ansible 连接管理服务器也是通过自己的秘钥+passphrase 进行操作
我看了文档,里面有关于关于秘钥路径的参数ansible_ssh_private_key_file
不知道秘钥+passphrase 要如何处理?
]]>从官方文档的解释是这样 “当以 --check 参数来运行 ansible-playbook 时,将不会对远程的系统作出任何更改.” 从-h 中看到 “ -C, --check don't make any changes; instead, try to predict some of the changes that may occur -D, --diff when changing (small) files and templates, show the differences in those files; works great with --check ”
但其实还是不明白,尤其是使用 command 或者 shell 模块的时候,更是一点区别也感觉不出来,求大神解释,谢谢
]]>-S, --su run operations with su (deprecated, use become)
-R SU_USER, --su-user=SU_USER run operations with su as this user (default=root) (deprecated, use become)
但是我执行的时候,看日志,应该是登陆上去了,再切换用户的时候貌似好想不行,也看不懂是啥意思?
有大神帮助看下没?
]]>ansible web -m win_shell -a 'start nginx chdir=C:\\nginx-1.13.0' 结果命令执行完返回后,windows 上没有 nginx 的进程,但 nginx 有生成 logs,感觉是刚启动完随着 ansible 的返回又被杀掉了 我看了 ansible 官方文档 http://docs.ansible.com/ansible/win_shell_module.html 下面有说“ WinRM will not return from a command execution until all child processes created have exited. Thus, it is not possible to use win_shell to spawn long-running child or background processes. Consider creating a Windows service for managing background processes.” 但我确实要启动 nginx 并且不希望用服务的方式,不然没办法 -s reload
也尝试过运行一个 cmd 然后里面写 start nginx,还有自己写一个小程序去运行 nginx,都不行,要么是没有 nginx 进程,要么是 nginx 启动成功但 ansible 一直挂起没有返回
]]>https://docs.ansible.com/ansible/intro_dynamic_inventory.html 这部分 好像 EC2 的话可以通过 Tag 来分别,有一个 ansible -i ec2.py tab_TagName_TagValue 的办法可以来指定 那么 Linode 和 DigitalOcean 等服务商有什么办法来区分么? 同时这个有没有办法写一个 file 来?也就是说通过 Script 来获取所有,然后另一个文件来分类不同用途的 Host ?
]]>
已经配置了 host 为 ansible_ssh_user=root
使用 root 账号,为什么还要问 sudo 密码?
]]>我平时在 win10 开发完成,然后想在 win10 上用 ansible 控制远程 linux
但是实际操作中 总是出现各种问题
网上看到有人说 ,这个东西现在不支持 win 作为控制端
是这样的吗
有办法解决吗
]]>