Ansilbe 管理员节点和远程主机节点经过 SSH 协议进行通讯。因此 Ansible 配置的时候只须要保证从 Ansible 管理节点经过 SSH 可以链接到被管理的远程的远程节点。html
每一台被 ansible 远程管理的主机,都须要配置基于 key 的 ssh 链接python
# Readhat/CentOS Linux, Ansible 目前放在 epel 源中 yum install -y epel-release yum install -y ansible # Mac brew install ansible
安装 ansible 在管理节点,那么,须要配置管理节点->远程主机之间基于 key 的免密访问:nginx
# 生成 ssh key,若是你以前配置过 Git,那么已经生成过一个了 ssh-keygen -t rsa -C "649168982@qq.com" # 拷贝 ssh key 至远程主机,下次管理节点就能够免密访问远程主机了 ssh-copy-id remote_user@remote_server # ssh 的时候不会提示是否保存 key ssh-keyscan remote_servers >> ~/.ssh/known_hosts
这时候在管理节点登陆远程节点时,就不会输入密码也不会提醒你存储key,以前写过一篇文章,记录设置免密登陆的文章Linux 双向 SSH 免密登陆:git
ssh remote_user@remote_server
Host Inventory 是配置文件,用来告诉Ansible须要管理哪些主机。而且把这些主机根据按需分类。github
能够根据用途分类:数据库节点,服务节点,nginx 节点、构建机器节点shell
默认的配置文件在:/etc/ansible/hosts
,能够经过 -i
参数指定配置文件的,参考问题:数据库
ansible 的配置文件有多个位置,查找顺序以下:macos
ANSIBLE_CONFIG
所指向的位置ansible.cfg
~/.ansible.cfg
/etc/ansible/ansible.cfg
本文 ansible.cfg:ubuntu
[defaults] # 这个参数表示主机清单 inventory 文件的位置 inventory = ./inventory # 并发链接数,默认为5 forks = 5 remote_user = root # 设置默认执行命令的用户,~~sudo_user~~ 参数在 ansbile 2.8 版本将会做废的 become_user = root #指定一个存储ansible日志的文件(默认不记录日志) log_path = ./ansible.log
指定用户名除了在 ansible.cfg
中指定 remote_user
以外,还能够:centos
ansible_user
或 ansible_ssh_user
-u
参数指定用户名更多 ansbile.cfg
的配置参考连接
inventory: 英 ['ɪnv(ə)nt(ə)rɪ] 美 ['ɪnvəntɔri] n. 存货,存货清单;详细目录
Ansible 可同时操做属于一个组的多台主机,组和主机之间的关系经过 inventory 文件配置。
inventory:
[centos] 192.168.3.43 [centos:vars] ansible_ssh_user=root
[]
中是组名,用于对主机进行分类,便于对不一样主机进行个别的管理[组名:vars]
定义了「组的变量」拓展:
能够把一个组做为另外一个组的子成员,以及分配变量给整个组使用. 这些变量能够给 /usr/bin/ansible-playbook
使用,但不能给 /usr/bin/ansible
使用
[atlanta] host1 host2 [raleigh] host2 host3 [southeast:children] atlanta raleigh
Inventory 参数能够控制 ansible 与远程主机的交互方式:
ansible_ssh_host 将要链接的远程主机名.与你想要设定的主机的别名不一样的话,可经过此变量设置. ansible_ssh_port ssh端口号.若是不是默认的端口号,经过此变量设置. ansible_ssh_user 默认的 ssh 用户名 ansible_ssh_pass ssh 密码(这种方式并不安全,咱们强烈建议使用 --ask-pass 或 SSH 密钥) ansible_sudo_pass sudo 密码(这种方式并不安全,咱们强烈建议使用 --ask-sudo-pass) ansible_sudo_exe (new in version 1.8) sudo 命令路径(适用于1.8及以上版本) ansible_connection 与主机的链接类型.好比:local, ssh 或者 paramiko. Ansible 1.2 之前默认使用 paramiko.1.2 之后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行. ansible_ssh_private_key_file ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的状况. ansible_shell_type 目标系统的shell类型.默认状况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'. ansible_python_interpreter 目标主机的 python 路径.适用于的状况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",好比 \*BSD, 或者 /usr/bin/python 不是 2.X 版本的 Python.咱们不使用 "/usr/bin/env" 机制,由于这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python之外的名字(实际有可能名为python26). 与 ansible_python_interpreter 的工做方式相同,可设定如 ruby 或 perl 的路径....
参考
ansible 的主要使用形式分为两种:
本文就先从 ad-hoc 方式开始学习。
ansible -h
中将命令行工具叫作 Ad-Hoc Commands
,格式是:
Usage: ansible <host-pattern> [options]
ad hoc——临时的,在ansible中是指须要快速执行,而且不须要保存的命令。说白了就是执行简单的命令——一条命令。对于复杂的命令后面会说playbook。关于命令中使用的模块,以后专门详细再作功课,这里先简单意会入门吧。
个人目录初始化时的组成:
. ├── ansible.cfg └── inventory
这里的 host-pattern
既能够是一个具体的主机 IP,也能够是 inventory 中的组名。
经常使用的命令选项示例:
ansible all --list-hosts
列出全部主机的 IP,这里的 all
不是组名,而是只 inventory 中全部的主机在进入下面的小节学习相关模块简单用法以前,我们先学习一个命令,这对于从此的使用颇有帮助:
$ansible-doc <module_name>
在未进行批量授信以前,可使用 --ask-pass
参数来进行认证,例如:ansible all -m ping --ask-pass
。可是这样并不方便,能够经过将 ansible server 机器上的公钥复制到远程主机 ~/.ssh/authorized_keys
文件中,实现免密登陆。机器不少时,这样作就比较麻烦了,能够用以下模块实现:
ansible centos -m authorized_key -a "user=root key='{{ lookup('file', '/Users/michael/.ssh/id_rsa.pub') }}' path=/root/.ssh/authorized_keys manage_dir=yes" --ask-pass
ping 模块用于测试 ansible server 到 inventory 主机的连通性,这是官网的介绍ping – Try to connect to host, verify a usable python and return pong on success
$ ansible -i inventory centos -m ping -u root 192.168.3.43 | SUCCESS => { "changed": false, "ping": "pong" }
-i
指定了 inventory
文件,后面要接着目标主机名,否则会报错-m
后面接使用的 module
-u
只以什么用户登陆到目标主机下面实例中,没有加目标主机名,就报错了:
ansible -i inventory centos -m ping -u root
ERROR! Missing target hosts
下面错误示例,指定的用户名 hh
没法免密登陆到目标主机:
$ ansible -i inventory centos -m ping -u hh 192.168.3.43 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: hh@192.168.3.43: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true }
此时,我在这篇文章中看到了这样的用法也能够指定登陆远程主机的用户名,而且,优先级比 -u
或者在 ansible.cfg
中指定都高:
[centos] 192.168.3.43 [centos:vars] ansible_ssh_user=michael
command模块为ansible默认模块,不指定-m参数时,使用的就是command模块;comand模块比较简单,常见的命令均可以使用,但其命令的执行不是经过shell执行的,因此,像这些 "<", ">", "|", and "&"操做都不能够,固然,也就不支持管道;
在远程主机上执行命令 pwd
:
$ ansible centos -a 'pwd' 192.168.3.43 | CHANGED | rc=0 >> /home/michael
缺点:不支持管道,就无法批量执行命令
-i
参数指定 inventory 文件,由于我运行 ansible --version
时,看到了它识别到了我当前目录下的 ansible.cfg
文件centos
就是必不可少的参数 host-pattern
,让咱们复习一下用法 ansible <host-pattern> [options]
-a
/--args
模块参数使用shell模块,在远程命令经过/bin/sh
来执行;因此,咱们在终端输入的各类命令方式,均可以使用; 可是咱们本身定义在.bashrc/.bash_profile
中的环境变量shell模块因为没有加载,因此没法识别;
若是须要使用自定义的环境变量,就须要在最开始,执行加载自定义脚本的语句;
对shell模块的使用能够分红两块:
1.若是待执行的语句少,能够直接写在一句话中:
$ ansible all -m shell -a ". ~/.bashrc;ps -fe |grep sa_q" 192.168.3.43 | CHANGED | rc=0 >> root 2849 2844 2 14:58 pts/0 00:00:00 /bin/sh -c . ~/.bashrc;ps -fe |grep sa_q root 2866 2849 0 14:58 pts/0 00:00:00 grep sa_q
2.若是在远程待执行的语句比较多,可写成一个脚本,经过 copy
模块传到远端,而后再执行;但这样就又涉及到两次ansible调用;对于这种需求,ansible已经为咱们考虑到了,script模块就是干这事的。
使用 scripts
模块能够在本地写一个脚本,在远程服务器上执行(远程服务器不须要python环境):
ansible all -m script -a "./test-20190224.sh"
test-20190224.sh
位于当前目录下,表示在全部的远程主机上执行 test.sh
脚本,省略了先把文件复制过去的步骤参考
拷贝本地文件 /Users/michael/Code/05-Github-Own/ansible-learn/file_mbp.txt
至远程主机的 /tmp
目录下:
ansible centos -m copy -a "src=//Users/michael/Code/05-Github-Own/ansible-learn/file_mbp.txt dest=/tmp/ [owner=root group=root mode=0755]"` ansible centos -m copy -a "src=//Users/michael/Code/05-Github-Own/ansible-learn/file_mbp.txt dest=/tmp/centos.txt [owner=root group=root mode=0755]"
上面 []
中的内容表示非必须。这个 copy
模块挺智能,若是目标没有写文件名,那么传过去的文件就同名,若是自定义了文件名,就进行了重命名:
$ ansible centos -m yum -a "name=lrzsz state=latest" 192.168.3.43 | SUCCESS => { "ansible_facts": { "pkg_mgr": "yum" }, "changed": false, "msg": "", "rc": 0, "results": [ "All packages providing lrzsz are up to date", "" ] }
yum
模块来安装软件包name
指定安装的软件包的名字state
指定安装软件包时的行为,它有几个选项值,
installed
/present
它俩是等价的,表示若是远程主机上有这个包了,则不从新安装了;latest
顾名思义,会去安装最新版的,这个对于生产是比较危险的,有可能所以破坏了生产的环境Yum 模块
state
值得具体区别,参考了这个问题:
ansible centos -m user -a "name=foo password=<crypted password here>" //移除用户 ansible all -m user -a 'name=foo state=absent'
$ ansible centos -m git -a "repo=https://github.com/Michael728/my-config-files.git dest=/tmp/my-config-files version=HEAD" 192.168.3.43 | CHANGED => { "after": "6faf55b17a1d7c25dfda6f6197839deaa2aa2bd5", "before": null, "changed": true }
repo
是必选参数dest
也是必选参数,指定代码库的下载路径代码库地址除了选择用 https
连接以外,还能够用 ssh
地址,事实上,公司中大多使用 ssh
地址会更方便:
ansible centos -m git -a "repo=git@github.com:Michael728/my-config-files.git dest=/tmp/my-config-files version=HEAD accept_hostkey=yes"
远程主机首次使用 git clone
命令时,是须要手动接受 knows_hosts 的,这时候加上 accept_hostkey=yes
能够避免出错
参考:
# 启动服务 ansible centos -m service -a "name=httpd state=started" # 重启服务,效果相似 stopped+started,若是服务已经中止的,执行完,会重启 ansible centos -m service -a "name=httpd state=restarted" # 重载服务,不会中断服务,若是服务以前未启动,那么会启动服务,若是启动了不必定会使用新的配置文件,仍是推荐重启 ansible centos -m service -a "name=httpd state=reloaded" # 中止服务 ansible centos -m service -a "name=httpd state=stopped"
state 有几个可选值(Choices: reloaded, restarted, started, stopped)[Default: (null)]
:
started'/
stopped` are idempotent[幂等] actions that will not run commands unless necessary.restarted
will always bounce the service.reloaded
will always reload. At least one of state and enabled are required. Note that reloaded will start the service if it is not already started, even if your chosen init system wouldn't normally.参考
$ansible centos -a "/sbin/reboot" -f 10
-f
参数会 fork 出 10 个子进程,以并行的方式这个命令虽然显示是出现问题了,可是我发现虚拟机确实重启了:
$ ansible all -a "reboot" -f 6 192.168.3.43 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: Shared connection to 192.168.3.43 closed.\r\n", "unreachable": true }
ansible all -m setup # 经过 filter 获取某一个 fact 变量 ansible all -m setup -a 'filter=ansible_*mb'
能够发现,ansible Ad-Hoc 的命令使用比较简单,适用于不复杂的场景,若是须要实现复杂的任务,那么就须要经过 ansible-playbook 的方式执行了,下一篇文章中学习它。
service 模块的 restarted reload 区别?