3.3 定义主机和组
Inventory 配置文件遵循 INI 文件风格, 中括号中的字符为组名. 其支持将同一个主机同时归并到多个不同的组中, 分组的功能为 IT 人员维护主机提供了非常大的便利. 此外, 若目标主机使用了非默认的 SSH 端口, 还可以在主机名称之后使用冒号加端口号来标明, 以行为单位分隔配置
- /etc/ansible/hosts
- # "#" 开头表示注释行, 不生效
- # Inventory 可以直接为 IP 地址
- 10.0.0.151
- # Inventory 同样支持主机名 (hostname) 的方式, 后跟冒号加数字表示端口号, 默认 22 号端口
- MySQL-151:5636
- MySQL-151
- # 中括号的内容表示一个分组的开始, 紧随其后的主机均属于改组成员, MySQL-151 这这台主机属于 [dbsrvs] 组
- [dbsrvs]
- MySQL-151
- MySQL-[151:156] #[151:156] 表示 151~156 之间的所有数字, 即表示 MySQL-151,MySQL-152,MySQL-153,.....,MySQL-156 的所有主机
- MySQL-[b:d] # [b:d] 同理表示 b 到 d 之间的所有字母
3.4 定义主机变量
在日常工作中, 通常会遇到非标准化的需求配置, 考虑到安全性问题, 管理人员有时候可能把 Web 服务的 80 端口, 修改为其他端口号, 而该功能可以直接通过修改 Inventory 配置来实现, 在定义主机时为其添加主机变量
- [atlanta]
- host2 http_port=303 maxRequestsPerChild=909
- # host2 这台主机中, 设置了 http_port 和 maxRequestsPerChild 这两个变量
3.5 定义组变量
可以定义属于整个组的变量
- [atlanta]
- host1
- host2
- [atlanta:vars]
- ntp_server=ntp.atlanta.example.com
- proxy=proxy.atlanta.example.com
- #[atlanta] 这个是组名,[altanta:vars] 表示要为这个组定义变量, 这个组有哪些变量了: ntp_server 和 proxy
3.6 常用 Inventory 参数列表
Ansible 基于 SSH 连接 Inventory 中指定的远程主机时, 还内置了很多其他参数, 用于指定其交互方式
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_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 以外的名字(实际有可能名为 python27).
与 ansible_python_interpreter 的工作方式相同, 可设定如 Ruby 或 perl 的路径....
3.7 一份清单文件列子
一般常用主机清单的例子如下
- /etc/ansible/hosts
- [groupname]
- some_host ansible_ssh_port=2222 ansible_ssh_user=manager
- aws_host ansible_ssh_private_key_file=/home/example/.SSH/AWS.pem
- freebsd_host ansible_python_interpreter=/usr/local/bin/python
- ruby_module_host ansible_ruby_interpreter=/usr/bin/Ruby.1.9.3
- # [组名]
主机名或者 IP 参数
注: 上面很多知识没有, 我只写了常用了, 不知道的去看官方文档
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#inventory-basics-hosts-and-groups
4 ansible 系列命令用法详解与使用场景
ansible 有哪些相关命令了
- ansible
- ansible-galaxy
- ansible-pull
- ansible-doc
- ansible-playbook
- ansible-vault
- ansible-console
这些相关命令, 最常用的还是 ansible,ansible-playbook
上面很多命令我很少用到, 这里就不全部写了, 要用去官方文档查一查
4.1 ansible
ansible 是远程管理命令
ansible 语法如下
- [root@ansible-150 ~]# ansible --help
- Usage: ansible <host-pattern> [options]
ansible 主机表达式 选项参数
主机表达式可以是 Inventory 里面的主机和 IP 或者一些表达式来简易表示主机
选项参数比较多, 这时候就需要经常看 help 和 该选项的所表达意思
常用参数
-m 相应名称的模块被执行,(默认模块为 command)
-a 模块参数信息,-a 后面是要执行的命令
-C 不做任何该变; 只是做预测可能发生的变化
-syntax-checks 行语法检查在剧本上, 但是并不执行剧本相当于 debug
4.1.2 ansible 命令执行结果色彩说明
绿色: 表示没有发生任何改变红色: 执行命令操作出现异常黄色: 执行命令后, 对受控主机产生影响, 发生了配置改变
4.1.3 ansible 使用例子
先看看我的主机配置文件内容
- [root@ansible-150 ~]# egrep -v "^$|^#" /etc/ansible/hosts
- [dbsrvs]
- 10.0.0.151 ansible_ssh_user=ansible
- 10.0.0.152 ansible_ssh_user=ansible
测试连通性
- [ansible@ansible-150 ~]$ ansible all -m ping
- 10.0.0.151 | SUCCESS => {
- "ansible_facts": {
- "discovered_interpreter_python": "/usr/bin/python"
- },
- "changed": false,
- "ping": "pong"
- }
- 10.0.0.152 | SUCCESS => {
- "ansible_facts": {
- "discovered_interpreter_python": "/usr/bin/python"
- },
- "changed": false,
- "ping": "pong"
- }
在被控制机器创建一个目录
- [ansible@ansible-150 ~]$ ansible all -m command -a 'sudo mkdir /opt/xixi'
- [WARNING]: Consider using 'become', 'become_method', and 'become_user' rather than running sudo
- 10.0.0.151 | CHANGED | rc=0>>
- 10.0.0.152 | CHANGED | rc=0>>
- # 验证结果
- [ansible@ansible-150 ~]$ ansible all -m command -a 'ls /opt'
- 10.0.0.151 | CHANGED | rc=0>>
- rh
- xixi
- 10.0.0.152 | CHANGED | rc=0>>
- rh
- xixi
4.2 ansible-doc
ansible-doc 是 Ansible 模块文档说明, 针对每个模块都有详细的用法说明及应用案例介绍, 功能和 Linux 系统 man 命令类似. 该命令使用方式如下:
ansible-doc [options] [plugin]
plugin 就是模块
ansible-doc 命令跟[options] 参数或 [模块名] , 显示模块用法说明, 具体示例如下:
- # 列出支持的模块
- ansible-doc -l
- # 模块功能说明
- ansible-doc ping
- 4.3 ansible-playbook
ansible-playbook 是日常应用中使用频率最高的命令, 其工作机制是: 通过读取预先编写好的 playbook 文件实现批量管理. 要实现的功能与命令 ansible 一样, 可以理解为按一定条件组成的 ansible 任务集. ansible-playbook 命令后跟 YAML 格式的 playbook 文件, 执行事先编排好的任务集
Playbook 具有编写简单, 可定制性高, 灵活方便, 以及可固化日常所有操作的特点, 应熟练掌握
4.4 ansible-galaxy
ansible-galaxy 的功能可以简单地理解为 gitub 的功能, 通过 ansible-galaxy 命令, 可以根据下载量和关注量等信息, 查找和安装优秀的 Roles.roles 集合其实就是多个 playbook 文件的集合. Ansible Galaxy 是 Ansible 的官方社区中心, 用于共享 Ansible 角色. 一个角色是 Ansible 构建自动化内容的方式以及让它可复用. 角色一般用于基于主机构建服务的场景中, 但也可以是用于构建守护进程等场景中. Ansible Galaxy 指的是一个网站共享和下载 Ansible 角色, 也可以是帮助 roles 更好的工作的命令行工具.
- https://galaxy.ansible.com/
- 4.5 ansible-inventory
查看被控制端主机清单的详细信息默认情况下它使用库存脚本, 返回 JSON 格式
语法: ansible-inventory [options] [host|group]
参数: ansible-inventory --help 查看
ansible-inventory --list
5 常用模块
这里只从运维管理角度介绍几个常用的模块
5.1 ping 模块
用途: 尝试连接被控制端主机, 成功返回 pong(ping-pong 是一对的)
使用方法:
[ansible@ansible-150 ~]$ ansible-doc -s ping
示例:
[ansible@ansible-150 ~]$ ansible all -m ping
参数 all 代表被控制端的所有主机
5.2 command 模块
用途: 默认 ansible 使的模块是 command, 即可以执些 shell 命令使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s command
- - name: Executes a command on a remote node
- command:
- argv: # 允许用户以列表和字符串的形式提供命令, 不能同时使用, 也不必须提供其中一种
- chdir: # 在执行命令之前, 先 cd 到指定的目录下
- creates: # 用于判断命令是否要执行, 如果指定的文件存在(可以使用通配符), 则不执行
- free_form: # 默认的选项, 这里只是显示, 实际上是没有的
- removes: # 用于判断命令是否要执行, 如果指定的文件存在 (可以使用通配符) 则执行, 不存在, 则不执行
- stdin: # 将命令的 stdin 直接设置为指定值
- warn: # 设置 command 的警告信息(在 / etc/ansible/ansible.cfg 中有配置项)
示例:
- # 不加参数执行 shell
- [ansible@ansible-150 ~]$ ansible all -a 'ls -a'
- [ansible@ansible-150 ~]$ ansible 10.0.0.151 -m command -a 'chdir=/etc/selinux ls'
- 10.0.0.151 | CHANGED | rc=0>>
- config
- final
- semanage.conf
- targeted
- tmp
注: command 不能解析变量 (如 $HOME) 和某些操作符("<", ">", "|", ";" 以及 "&"), 所以明确要使这些不可解析的操作符时, 使 shell 模块来代替 command
5.3 shell 模块
用途: shell 和 command 的法基本样, 实际上 shell 模块执命令的式是在远程使 / bin/sh 来执的, 如 / bin/sh ping 使用方法:
- ansible-doc -s shell
- - name: Execute commands in nodes.
- shell:
- chdir: # 在执行命令之前, 先 cd 到指定的目录下
- creates: # 用于判断命令是否要执行, 如果指定的文件存在 (可以使用通配符) 存在, 则不执行
- executable: # 不再使默认的 / bin/sh 解析并执命令, 是使此处指定的命令解析(例如使 expect 解析 expect 脚本. 必须为绝对路径)
- free_form: # 默认的选项, 这里只是显示, 实际上是没有的
- removes: # 用于判断命令是否要执行, 如果指定的文件存在 (可以使用通配符) 不存在, 则不执行
- stdin: # 将命令的 stdin 直接设置为指定值
- warn: # 设置 command 的警告信息(在 / etc/ansible/ansible.cfg 中有配置项)
5.4 script 模块
用途: script 模块用于控制远程主机执行脚本, 在执行脚本前, ansible 会将本地脚本传输到远程主机, 然后在执行, 在执行脚本的时候, 其采用的是远程主机上的 shell 环境
- [ansible@ansible-150 ~]$ ansible-doc -s script
- - name: Runs a local script on a remote node after transferring it
- script:
- chdir: # 在远程执脚本前先切换到此录下
- creates: # 当此件存在时, 不执脚本. 可于实现幂等性.
- decrypt: # 此选项使用 vault 控制源文件的自动解密(对使用 ansible-vault encrypt 文件名. YAML 进行加密的文件解密)
- executable: # 不再使默认的 / bin/sh 解析并执命令, 是使此处指定的命令解析(例如使 expect 解析 expect 脚本. 必须为绝对路径)
- free_form: # 本地待执的脚本路径, 选项, 参数. 之所以称为 free_form, 是因为它是脚本名 + 选项 + 参数.
- removes: # 当此件不存在时, 不执脚本. 可于实现幂等性.
示例:
新建一个脚本在 ansible 管理主机上
- [ansible@ansible-150 ~]$ cat keme.sh
- #!/bin/bash
- echo "keme is handsome one."
- # 没加任何参数
- [ansible@ansible-150 ~]$ ansible all -m script -a 'keme.sh'
- # 执行命令前切换到 opt 目录 加了 chdir 参数
- [ansible@ansible-150 ~]$ ansible all -m script -a 'chdir=/opt ./keme.sh'
5.5 copy 模块
用途: copy 模块的作用就是拷贝文件或者目录, 将 ansible 管理主机上的文件拷贝到远程主机中使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s copy
- - name: Copies files to remote locations
- copy:
- backup: # 拷贝的同时也创建个包含时间戳信息的备份件, 默认为 no, 可以指定为 backup=yes 做文件备份
- content: # 当用 content 代替 src 参数的时候, 可以把 content 指定的内容直接写到一个文件
- decrypt: # 此选项使用 vault 控制源文件的自动解密(对使用 ansible-vault encrypt 文件名. YAML 进行加密的文件解密)
- dest: # 标路径, 只能是绝对路径, 如果拷贝的件是录, 则标路径必须也是录
- directory_mode: # 当对录做递归拷贝时, 设置了 directory_mode 将会使得只拷贝新建件旧件不会被拷贝. 默认未设置.
- follow: # 是否追踪到链接的源件(follow=yes|on)
- force: # 设置为 yes(默认)时, 将覆盖远程同名件. 设置为 no 时, 忽略同名件的拷贝.
- group: # 指定文件拷贝到远程主机后的属组, 但是远程主机上必须有对应的组, 否则会报错
- local_follow: # 是否遵循本地机器中的文件系统链接(local_follow=yes|on)
- mode: # 设置远程件的权限. 使数值表时不能省略第位, 如 0644. 也可以使'u+rwx'或'u=rw,g=r,o=r'等式设置
- owner: # 设置远程件的所有者
- remote_src: # 如果 yes 它会从目标机上搜索 src 文件(remote_src=yes|on)
- src: # 拷贝本地源件到远程, 可使绝对路径或相对路径. 如果路径是录, 且录后加了斜杠 "/", 则只会拷贝录中的内容到远程, 如果录后不加斜杠, 则拷贝录本和录内的内容到远程
- unsafe_writes: # 是否以不安全的方式进行, 可能导致数据损坏(unsafe_writes=yes|on)
- validate: # 复制前是否检验需要复制目的地的路径
示例 1 本地文件拷贝到被控端:
- # 新建一个文件, 文件内容如下
- [ansible@ansible-150 ~]$ pwd
- /home/ansible
- [ansible@ansible-150 ~]$ cat kemeaaa.txt
- xixi xixi xixi
- # 把 / home/ansible/kemeaaa.txt/ 拷贝到被控端主机 / opt 下
- [ansible@ansible-150 ~]$ ansible all -m copy -a 'src=/home/ansible/kemeaaa.txt dest=/opt/'
示例 2: 拷贝之前先备份
- # 修改 kemeaaa.txt 内容
- [ansible@ansible-150 ~]$ cat kemeaaa.txt
- xixi xixi xixi
- keme keme keme
- # 加上 backup 这个参数
- [ansible@ansible-150 ~]$ ansible all -m copy -a 'src=/home/ansible/kemeaaa.txt dest=/opt/ backup=yes'
在上面可以看到 backup_file 这个参数, 后面就是备份的路径(在被控制端主机上查看)
示例 3 : 修改 owner,group,mode 参数, 默认是 root 拷贝文件对权限和属主属组进行改变
- # 把权限改为 ansible 用户
- [ansible@ansible-150 ~]$ ansible all -m copy -a 'src=/home/ansible/kemeaaa.txt dest=/opt/ owner=ansible group=ansible mode=0744'
- # 验证
- [ansible@ansible-150 ~]$ ansible all -m shell -a 'ls -l /opt/kemeaaa.txt'
5.6 fetch 模块
用途: 从被控远端机器上拉取文件 (和 COPY 模块整好相反) 使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s fetch
- - name: Fetches a file from remote nodes
- fetch:
- dest: # 本地存储拉取件的录. 例如 dest=/data,src=/etc/fstab, 远程主机名 host.exp.com, 则保存的路径为 / data/host.exp.com/etc/fstab.
- fail_on_missing: # 当设置为 yes 时, 如果拉取的源件不存在, 则此任务失败. 默认为 no.
- flat: # 改变拉取后的路径存储式. 如果设置为 yes, 且当 dest 以 "/" 结尾时, 将直接把源件的 basename 存储在 dest 下. 显然, 应该考虑多个主机拉取时的件覆盖情况.
- src: # 远程主机上的源件. 只能是件, 不持录. 在未来的版本中可能会持录递归拉取.
- validate_checksum: # fetch 到件后, 检查其 md5 和源件是否
示例 1 :src,dest 拉取 10.0.0.151 的文件 到 /home/ansible / 目录下
[ansible@ansible-150 ~]$ ansible 10.0.0.151 -m fetch -a 'src=/etc/hostname dest=/home/ansible/'
示例 2:flat
[ansible@ansible-150 ~]$ ansible 10.0.0.152 -m fetch -a 'src=/etc/hostname dest=/home/ansible/ flat=yes'
拉取后没有主机名文件夹标识
5.7 file 模块
用途: 管理文件, 目录的属性, 也可以创建文件或者目录使用方法: 在 file 模块中 state 参数是十分重要的
- [ansible@ansible-150 ~]$ ansible-doc -s file
- [root@ansible ~]# ansible-doc -s file
- - name: Sets attributes of files
- file:
- follow: # 是否遵循目的机器中的文件系统链接(可选值为: yes|on)
- force: # 当 state=link 的时候, 可配合此参数强制创建链接文件, 当 force=yes 时, 表示强制创建链接文件
- # 不过强制创建链接文件分为三种情况. 情况一: 当要创建的链接文件指向的源文件并不存在时, 使用此参数, 可以先强制创建出链接文件.
- # 情况二: 当要创建链接文件的目录中已经存在与链接文件同名的文件时, 将 force 设置为 yes, 会将同名文件覆盖为链接文件, 相当于删除同名文件, 创建链接文件.
- # 情况三: 当要创建链接文件的目录中已经存在与链接文件同名的文件, 并且链接文件指向的源文件也不存在, 这时会强制替换同名文件为链接文件
- group: # 设置远程件的所属组
- mode: # 设置远程件的权限. 使数值表时不能省略第位, 如 0644. 也可以使
- owner: # 设置远程件的所有者
- path: # 必须的参数, 用于指定要操作的文件或者目录
- recurse: # 当要操作的文件为目录, 将 recurse 设置为 yes, 可以递归的修改目录中的文件属性
- src: # 当 state 设置为 link 或者 hard 时, 表示我们想要创建一个软链接或者硬链接, 所以, 我们必须指明软链接或硬链链接的哪个文件, 通过 src 参数即可指定链接源
- state: # 此参数非常灵活, 其对应的值需要根据情况设定. 比如, 我们想要在远程主机上创建 / testdir/a/b 目录, 那么则需要设置 path=/testdir/a/b,
- # 但是, 我们无法从 "/testdir/a/b" 这个路径看出 b 是一个文件还是一个目录, ansible 也同样无法单单从一个字符串就知道你要创建文件还是目录, 所以, 我们需要通过 state 参数进行说明
- # state=directory: 表示创建目录, 如果 path 指定的不存在则被创建
- # state=touch: 创建文件
- # state=link: 创建软链接文件
- # state=hard: 创建硬链接文件
- # state=absent: 删除文件(删除时不用区分目标是文件, 目录, 还是链接)
- unsafe_writes: # 是否以不安全的方式进行, 可能导致数据损坏(unsafe_writes=yes|on)
5.8 hostname 模块
用途: 管理配置主机名使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s hostname
- - name: Manage hostname
- hostname:
- name: # 必选, 主机名称
使用这个模块存在一个问题就是一改主机名紧跟着应该是在这个清单里面的机器都会被改掉导致主机名完全相同是有解决方法的, 使用变量的方式进行更改
使用 hostname 模块修改主机名是直接生效的并且是永久生效
5.9 yum 模块
用途: 使用 yum 包管理器管理包
- [ansible@ansible-150 ~]$ ansible-doc -s yum
- - name: Manages packages with the `yum' package manager
- yum:
- allow_downgrade: # 是否允许给现有包的版本进行降级
- autoremove: # 卸载包并且删除其所有的依赖包, 如果这个依赖包被其他包所依赖则不会删除(authorremove=yes)
- bugfix: # 如果 bugfix=yes 和 state=latest 则仅安装已标记为与 bug 修复相关的更新
- conf_file: # 指定 yum.repo 配置文件.
- disable_excludes: # 禁用 YUM 配置文件中定义的排除(yum.repo 文件中的某个块).
- # disable_excludes=all 禁用所有排除
- # disable_excludes=main 禁用 yum.conf 中的 [main] 中定义的排除
- # disable_excludes=repoid 禁用未给定 repo id 定义的排除
- disable_gpg_check: # 安装包时禁止 gpgcheck, 仅在 state=present 或者 latest 时生效.
- disable_plugin: # 禁用 yum 的 Loaded plugins(使用 yum repolist all | Less 查看所有插件)
- disablerepo: # 禁止指定的 repo 源, 多个 repo 源使用逗号分隔
- download_only: # 只下载指定的安装包, 不进行安装.
- enable_plugin: # 开启 yum 的 Loaded plugins(使用 yum repolist all | Less 查看所有插件).
- enablerepo: # 明确使用那个 repo 源
- exclude: # 排除那些包不安装, 仅在 state=present 或者 latest 时生效
- installroot: # 指定 yum 安装包的用户, 用此用户安装的只允许 root 和指定用户使用
- list: # 类似于 yum list.
- name: # (必选参数)指定包名, 可以指定版本号, 多个包可以使用逗号分隔
- releasever: # Specifies an alternative release from which all packages will be installed.
- security: # 如果设置为 yes 和 state=latest, 则只安装标记为与安全相关的更新
- skip_broken: # 跳过具有损坏的依赖包
- state: # 用于指定软件包的状态 , 默认值为 present, 表示确保软件包已经安装
- # state=present 安装状态(默认值)
- # state=installed 安装状态
- # state=latest 安装状态(安装最新的版本)
- # state=absent 卸载状态
- # state=removed 卸载状态
- update_cache: # 强制 yum 检查缓存是否过期, 并在需要时重新下载. 仅在 state=present 或者 latest 时生效.
- update_only: # 使用最新软件包时, 只更新已安装的软件包. 不要安装软件包. 仅在 state=present 或者 latest 时生效
- validate_certs: # 这仅适用于使用 https url 作为 rpm 的源的情况. 例如, 用于 localinstall. 如果设置为 no, 则不会验证 SSL 证书
5.10 cron 模块
用途: cron 模块于设置定时任务, 也于管理定时任务中的环境变量使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s cron
- - name: Manage cron.d and crontab entries
- cron:
- backup: # (yes/on)如果设置了, 则会在修改远程 cron_file 前备份这些文件
- cron_file: # 自定义 cron_file 的文件名, 使用相对路径则表示在 / etc/cron.d / 中, 必选同时制定 user 选项
- minute: # 分(0-59,*,/N), 不写时默认为 *
- hour: # 时(0-23,*,/N), 不写时默认为 *
- day: # 日(1-31,*,/N), 不写时默认为 *
- month: # 月(1-12,*,/N), 不写时默认为 *
- weekday: # 周(0-6 for Sunday-Saturday,*), 不写时默认为 *
- disabled: # 禁用 crontab 中的某个任务, 要求 state=present
- env: # (yes/on)设置一个环境变量, 将添加在 crontab 的顶端, 使用 name=value 定义变量名和值.
- job: # 需要执行的命令, 如果设置了 env, 则表示环境变量的值, 此时 job="xxxx" 等价于 value="xxxx"
- name: # 描述 crontab 的字符串, 但如果设置的是 env, 则 name 为环境变量的名称, 要求 state=absent, 注意, 若没有设置 name, 且 state=present, 则总会创建一条新的 job 条目, 即使 cron_file 中已经存在同样的条目.
- reboot: # 如果任务应该在重新启动时运行. 不赞成使用此选项. 用户应该使用 special_time.
- special_time: # 定时任务的别称, 用于定义何时运行 job 条目. 有效值有 reboot/hourly/daily/weekly/monthly/yearly/annually
- state: # job 或者 env 的状态是 present(默认)还是 absent,present 用于创建, absent 用于删除
- user: # 指定那个用户的 crontab 任务将要被修改, 默认 root.
5.11 service 模块
用途: service 模块可以帮助我们管理远程主机上的服务. 比如, 启动或停止远程主机中的 nginx 服务使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s service
- - name: Manage services
- service:
- arguments: # 服务命令行参数传递
- enabled: # 设置服务为开机自启(yes/no), 默认为 no
- name: # (必选项)指定服务名.
- pattern: # 如果服务没有做出相应, 可以通过这个参数指定使用 ps 或者其他方式查看服务的状态.
- runlevel: # 设置服务启动级别
- sleep: # 如果服务正在 "重新启动", 那么在停止和开始命令之间设置休眠时间.
- state: # started 和 stoped 分别是启动和停止服务, 它们是幂等操作, 多次启动或者停止服务都是一样的, 也就是说对于运行中的服务不会再次启动操作, 同理停止也是一样的;
- # restarted 重启服务, restarted 总是重读配置文件如果服务是未运状态, 则 reloaded 会启动服务(state 和 enabled 两者少要给个)
5.12 systemd 模块
用途: systemd 模块可以帮助我们使用 systemd 管理远程主机上的服务. 比如, 启动或停止远程主机中的 nginx 服务
- [ansible@ansible-150 ~]$ ansible-doc -s systemd
- - name: Manage services
- systemd:
- daemon_reload: # 在执行任何其他操作之前运行守护进程重新加载, 以确保 systemd 已经读取其他更改.
- enabled: # 设置服务为开机自启(yes/no), 默认为 no
- force: # 是否覆盖现有符号链接(yes/on).
- masked: # 是否将服务设置为 masked 状态(yes/no), 被 mask 的服务是无法启动的
- name: # 指定服务名称.
- no_block: # 不要同步等待操作请求完成(yes/no)
- state: # started 和 stoped 分别是启动和停止服务, 它们是幂等操作, 多次启动或者停止服务都是一样的, 也就是说对于运行中的服务不会再次启动操作, 同理停止也是一样的;
5.13 user 模块
用途: user 模块可以帮助我们管理远程主机上的用户, 比如创建用户, 修改用户, 删除用户, 为用户创建密钥对等操作使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s user
- - name: Manage user accounts
- user:
- append: # 如果用户原本就存在多个附加组, 那么当使用 groups 参数设置附加组时, 当前设置会覆盖原来的附加组设置
- # 如果不想覆盖原来的附加组设置, 需要结合 append 参数, 将 append 设置为 yes, 表示追加附加组到现有的附加组设置, append 默认值为 no.
- comment: # 设置用户的描述信息
- create_home: # 创建家录, 或者已有的户但家录不存在也会创建. 设置为 no 则不创建家录
- expires: # 此参数用于指定用户的过期时间, 相当于设置 /etc/shadow 文件中的的第 8 列
- # 比如, 你想要设置用户的过期日期为 2018 年 12 月 31 日, 那么你首先要获取到 2018 年 12 月 31 日的 unix 时间戳, 使用命令 "date -d 2018-12-31 +%s" 获取到的时间戳为 1546185600,
- # 所以, 当设置 expires=1546185600 时, 表示用户的过期时间为 2018 年 12 月 31 日 0 点 0 分,
- # 设置成功后, 查看远程主机的 /etc/shadow 文件, 对应用户的第 8 八列的值将变成 17895(表示 1970 年 1 月 1 日到 2018 年 12 月 31 日的天数, unix 时间戳的值会自动转换为天数, 我们不用手动的进行换算,
- # 目前此参数只支持在 Linux 和 FreeBSD 系统中使用.
- force: # 强制删除用户, 用户目录, 只在 state=absent 中生效, 相当于 userdel --force 命令
- generate_ssh_key: # 是否为相关用户生成 SSH 密钥. 这将 "不会" 覆盖现有 SSH 密钥.
- group: # 设置户的 primary group(主组).
- groups: # 将户加到辅助组列表中. 如果设置 "groups=", 则会将此户从所有辅助组中移除
- home: # 指定要创建的家录路径
- move_home: # 如果设置为 yes, 则 "home=" 则表将家录移动到此选项指定的路径下
- name: # (必选项)要创建, 修改, 移除的户名.
- non_unique: # 当与 -u 选项一起使用时, 该选项允许将用户 ID 更改为非唯一值
- password: # 设置户密码. 此处只能使加密密码作为值.
- password_lock: # 锁定用户的密码 (等价于 usermod -L 命令) 这个选项并不总是意味着用户不能通过其他方法登录. 这个选项没有禁用用户, 只锁定密码.
- remove: # 配合'state=absent'时, 等价于'userdel --remove', 即删除家录和邮件列表
- seuser: # 在启用 selinux 的系统上设置 seuser 类型.
- shell: # 设置户的 shell
- ssh_key_bits: # 当 generate_ssh_key 参数的值为 yes 时, 使用此参数指定要创建的 SSH 密钥中的位数.
- ssh_key_comment: # 当 generate_ssh_key 参数的值为 yes 时, 在创建证书时, 使用此参数设置公钥中的注释信息. 但是如果同名的密钥对已经存在, 则并不会修改原来的注释信息, 即不做任何操作.
- # 当不指定此参数时, 默认的注释信息为 "ansible-generated on 远程主机的主机名.
- ssh_key_file: # 当 generate_ssh_key 参数的值为 yes 时, 使用此参数自定义生成 SSH 私钥的路径和名称, 对应公钥会在同路径下生成, 公钥名以私钥名开头, 以 ".pub" 结尾.
- ssh_key_passphrase: # 当 generate_ssh_key 参数的值为 yes 时, 在创建证书时, 使用此参数设置私钥的密码. 但是如果同名的密钥对已经存在, 则并不会修改原来的密码, 即不做任何操作.
- ssh_key_type: # 当 generate_ssh_key 参数的值为 yes 时, 在创建证书时, 使用此参数设置密钥对的类型. 默认密钥类型为 rsa, 但是如果同名的密钥对已经存在, 并不会对同名密钥做任何操作.
- state: # 创建户 (present) 还是删除户(absent). 默认为 present.
- system: # 设置为 yes 表创建个系统户, 只能于创建, 不能于修改已有户为系统户
- uid: # 设置用户的 UID
- update_password: # user 是幂等模块,"always" 将总是修改密码."on_create" 将只在创建户时设置密码
5.14 group 模块
用途: 添加或删除组使用方法:
- [ansible@ansible-150 ~]$ ansible-doc -s group
- - name: Add or remove groups
- group:
- gid: # 用于指定组的 gid
- name: # (必选项) 用于指定要操作的组名称
- state: # 用于指定组的状态, 两个值可选, present,absent, 默认为 present, 设置为 absent 表示删除组.
- system: # 如果是 yes, 表示指定的组是系统组
5.15 小结
上面很多都是模块帮助参数使用说明, 自己多试试, 就知道模块怎么试用了, 还是多看模块帮助信息.
6 使用 playbooks 剧本
Playbooks 是 Ansible 的配置, 部署和编排语言. 他们可以描述您希望远程系统实施的策略, 或者描述一般 IT 流程中的一系列步骤.
6.1 Playbook 语法
Playbook 采用 YAML 语法编写, 该语言在被开发是, 它的意思是: Yet Another Markup Language (仍是一种标记语言). 结合 ansible 中 要用到的 YAML 语法点. 对 YAML 语法简洁总结如下. 看官方文档的一个简易的列子: 一个 playbook 的列子 verify-apache.YAML
- ---
- # 选择的主机
- - hosts: webservers
- #vars 这个是变量
- vars:
- http_port: 80
- max_clients: 200
- # remote_user 远端的执行权限
- remote_user: root
- # 创建一个任务 tasks
- tasks:
- - name: ensure apache is at the latest version
- # 利用 yum 模块才操作
- yum:
- name: httpd
- state: latest
- - name: write the apache config file
- template:
- src: /srv/httpd.j2
- dest: /etc/httpd.conf
- # 触发重启 apache 服务器
- notify:
- - restart apache
- - name: ensure apache is running
- service:
- name: httpd
- state: started
- # 这里的 handlers 和上面的 notify 的触发是配对的. 这就是 handlers 的作用. 相当于 tag
- handlers:
- - name: restart apache
- service:
- name: httpd
- state: restarted
总的来说, Playbook 语法的一些特性:
需要以 "-" 三个减号开始, 且需顶行手写.
次行开始正常写 Playbook 内容.
使用 # 号注释代码.
缩进必须是统一的, 不能将空格和 Tab 混用.
缩进的级别必须是一致的, 同样的缩进代表同样的级别, 程序判别配置的级别是通过缩进结合换行来实现的.
YAML 文件内容 和 Linux 系统大小写判断方式保持一致, 是区别大小写的, k/v 的值均需要大小写敏感.
k/v 的值可同行也可换行写. 同行使用 ":" 分隔, 换行写需要以 "-" 分隔
一个完整的代码块功能需最少元素, 需包括 name:task.
一个 name 只能包括一个 task .
6.1.2 写简单的 Playbook
上面都是语法说明, 自己写一些做简单的列子做练习把示例 1:allping.YAML
- # 建一个目录用来做练习
- [ansible@ansible-150 ansible]$ sudo mkdir learn
- [ansible@ansible-150 ansible]$ cd learn/
- [ansible@ansible-150 learn]$ pwd
- /etc/ansible/learn
- [ansible@ansible-150 learn]$ sudo VIM allping.YAML
- ---
- - hosts: all
- remote_user: root
- tasks:
- - name: test connection
- ping:
- # 执行编写的剧本
- [ansible@ansible-150 learn]$ ansible-playbook allping.YAML
示例 2:install_apache.YAML
- # 在管理主机安装上 httpd 和 httpd-devel 要 httpd.conf 和 httpd-vhosts.conf 文件
- [ansible@ansible-150 learn]$ sudo yum -y install httpd httpd-devel
- # 修改管理主机的 httpd.conf 和 httpd-vhosts.conf 默认没有 httpd-vhosts.conf 自己随便创建的
- # 注配置文件内容无实际意义, 为了实验效果
- [ansible@ansible-150 conf]$ pwd
- /etc/httpd/conf
- [ansible@ansible-150 conf]$ sudo cp httpd.conf /tmp/
- [ansible@ansible-150 conf]$ sudo cp httpd-vhosts.conf /tmp/
- # 编写 install_apache.YAML 剧本
- [ansible@ansible-150 conf]$ cd /etc/ansible/learn/
- [ansible@ansible-150 learn]$ sudo VIM install_apache.YAML
- ---
- - hosts: all
- sudo: yes
- tasks:
- - name: install apache
- yum: name={{ item }} state=present
- with_items:
- - httpd
- - httpd-devel
- - name: copy config file
- copy:
- src: "{{ item.src }}"
- dest: "{{ item.dest }}"
- owner: root
- group: root
- mode: 0644
- with_items:
- - {
- src: "/tmp/httpd.conf",
- dest: "/etc/httpd/conf/httpd.conf" }
- - {
- src: "/tmp/httpd-vhosts.conf",
- dest: "/etc/httpd/conf/httpd-vhosts.conf" }
- name: 检查 Apache 运行状态, 并设置开机启动
- service: name=httpd state=started enabled=yes
- # 写好了剧本是不是要对剧本进行 debug 测试, 测试剧本是否可用
- # 第一语法检测, 第二模拟检测
- [ansible@ansible-150 learn]$ ansible-playbook --syntax-check install_apache.YAML
- [ansible@ansible-150 learn]$ ansible-playbook -C install_apache.YAML
上面检测都没问题了, 该给被控制主机安装 apache 了
- [ansible@ansible-150 learn]$ ansible-playbook install_apache.YAML
- # 验证是否安装成功, 并启动了
- [ansible@ansible-150 learn]$ ansible all -m shell -a 'ss -ntulp | grep httpd'
- # 查看配置文件是否拷贝成功了
- [ansible@ansible-150 learn]$ ansible all -m shell -a 'ls -a /etc/httpd/conf/'
注: 上面有警告信息, 可以自己根据警告信息, 自己调试自己的剧本 (playbook) 和 ansible.cfg 的配置文件
第 1 行,"-" , 这个是 YAML 语法中注释的用法, 就想 shell 脚本中的 "#" 第 2 行:"- hosts: all" , 告诉 Ansible 具体要在哪些主机上运行我的剧本, 在本例中是 all, 即所有主机. 第 3 行,"sudo: yes", 告诉 Ansible 通过 sudo 来运行相应命令, 这样所有命令将会以 root 身份执行. 第 4 行: "tasks:" 指定一系列将要运行的任务每一个任务 "- name: xxxx" 开头."- name:" 字段并不是一个模块不会执行任务实质性的操作, 它只是给 "task" 一个易于识别的名称. 即使把 "- name" 对应的行删除, 也不会有任何问题. 在示例 2 中: 使用 yum 模块来安装 apache 在第一个 "- name" 任务当中, 每个 "- name" 都可以使用 with_items 来定义变量, 并通过 "{{ 变量名 }}" 的形式来直接使用, 2.11 版本应该使用另一种方法, 注意警告信息. 使用 yum 模块的 state=present 选项来确保软件被安装, 或者使用 state=absent 来确保软件被删除.
在第二个 "- name" 当中, 使用 copy 模块来讲 "src" 定义的源文件 (必须是 Ansible 所在服务器上的本地文件) 复制到 "dest" 定义的目的地址 (此地址为远程主机上的地址) 去. 在传递文件的同时, 还定义了文件的属主, 属组和权限. 在这个 "- name" 中, 我们用数组的形式给变量复制, 使用了 { var1: value , var2: value } 的格式来赋值, 变量的个数可以任意多, 不同变量间以逗号分隔, 使用 {{ item.var1 }} 的形式来调用变量, 本示例中为 {{ item.src }}
第三个 "- name" 使用了同样的结构, 调用了 service 模块, 以保证服务的正常开启
6.2 amsob-playbook 小技巧
6.2.1 playbook 语法检测和调试
写完一个 playbook 一定要进行语法检测, 看看自己哪里写的不对, 好及时修改, 警告信息也可以注意一下.
语法检测
ansible-playbook --syntax-check playbook_file.YAML
调试
ansible-playbook -C playbook_file.YAML
在正式运行 playbook 之前, 使用 --check 或 - C 选项来检测 playbook 都会改变哪些内容, 调试显示的结果跟真正执行时一模一样, 但不会真的被管理的服务器产生实际影响
6.3 限定 playbook 执行范围
当 playbook 指定的一批主机有个别主机需进行变更时, 可以不需要去修改 Playbook 文件本身, 而是通过一些选项就可以直接限定和查看 Ansible 命令的执行范围.
--limit 如果允许上面的 install_apache.yum 的剧本, 会发现所有被 ansible 管理的主机都会被操作. 可以通过修改剧本 "- hosts:" 字段来指定哪些主机将会应用 Playbook 的操作.
指定一台主机: ip 或者主机名
指定多台主机: 10.0.0.151,10.0.0.152 逗号分隔, 指定多台主机
指定一组主机: 写上组名 .(这个组名是 / etc/ansibles/hosts 里面定义的那个组名)
当然, 也可以直接通过 ansible-playbook 命令来指定主机:
例如: 只指定 10.0.0.151 执行
ansible-playbook install_apache.YAML --list 10.0.0.151
这样, 即便 playbook 中设定 "- hosts: all" , 但也只对 10.0.0.151 生效
--list-hosts 如果要知道在执行 playbook 是, 哪些主机将会受影响, 则使用 --list-hosts 选项
ansible-playbook install_apache.YAML --list-hosts
6.4 用户与权限设置
--remote-user 在 playbook 中, 如果在 hosts 字段下没有定义 users 关键字, 那么 Ansible 将会使用你在 Inventory 文件 (/etc/ansible/hosts) 中定义的用户, 如果 Inventory 文件中也没定义用户, ansible 将默认使用系统用户身份来通过 SSH 连接远程主机, 在管理控制主机运行 playbook 内容. 也可以直接在 ansible-playbook 中使用 --remote-user 选项来指定用户.
ansible-playbook install_apache.YAML --remote-user=keme
--ask-sudo-pass 在某些情况下, 需要传递 sudo 密码到远程主机, 来保证 sudo 命令的正常运行时, 可以以使用 --ask-sudo-pass(-K)选项来交互式输入密码
--sudo 使用 --sudo 选项, 可以强制所有 playbook 都使用 sudo 用户, 同时使用 --sudo-user 选项指定 sudo 可以执行那个用户的权限. 如果不指定, 则默认以 root 身份运行比如当前 用户 ansible 想以 keme 的身份运行 playbook , 命令如下:
[ansible@ansible-150 learn]$ ansible-palybook install_apache.YAML --sudo --sudo-user=keme --ask-sudo-pass
执行过程中, 会要求用户输入 keme 的密码
6.5 ansible-playbook : 其他常用选项
ansible-playbook 命令还有一些其他选项:
--inventory=PATH (-i PATH): 指定 inventory 文件, 默认文件是 / etc/ansible/hosts
--verbose (-v): 显示详细输出, 也可以使用 - vvvv 显示精确到每分钟的输出
--extra-vars=VARS (-e VARS) : 定义在 playbook 使用的变量, 格式为: "key=value,key=value"
--forks=NUM (-f NUM): 指定并发执行的任务数, 默认为 5, 根据服务器性能, 调大这个值可提高 ansible 执行效率 0
--conection=TYPE (-c TYPE) : 指定远程主机的方式, 默认为 SSH, 设为 local 时, 则只在本地执行 playbook, 建议不做修改
--check (-C) : 检测模式, playbook 中定的所有任务将在每台远程主机上进行检测, 并不真正执行.
7 安全管理优化
使用安全加密的通信方式, 例如: 秘钥对;
在 CentOS/RedHat 中 SSH 服务的主配置文件 /etc/SSH/sshd_config 中设置
- PasswordAuthentication no #禁止 SSH 使用密码认证连接. 如此一来就杜绝了所有针对密码的暴力破解攻击.
- PermitRootLogin no #禁止 root 用户远程登录. 建议只使用普通用户进行远程登录, 并使用 sudo 命令来行使大部分 root 权限. 如果实在需要使用 root 用户进行交互式管理, 可以使用普通用远程连接到主机, 然后通过 su 命令切换到 root 用户, 这样做更加安全
- # 明确指定允许或禁止的远程登录用户. 使用 AllowUser 和 DenyUsers 来指定哪些用户可以登录, 哪些用户不能登录. 比如, 只允许用户 keme 登录, 可以设置为 AllowUsers keme; 允许除了 xixi 以为的其他用户登录, 可以设置为: DenyUsers xixi
- Port 2636 # 使用非默认端口. SSH 的默认端口为 22, 将其改为任意不与其他服务冲突的端口 (建议采用 1024 以上的端口号) 将会使系统更为安全. 在 SSH 配置文件中设置 Port 2636, 即可修改 SSH 默认端口为 2849.
禁止 root 用户远程登录并充分利用 sudo;
- # 充分利用 visudo 命令或者 VIM /etc/sudoers
- #sudo 的目的: 为非根用户授予根用户的权限;
- root ALL=(ALL) ALL
- %wheel ALL=(ALL) ALL
授权用户 / 组 主机名 =(允许转换至的用户) NOPASSWD: 命令动作
# 假如无需密码直接运行命令的, 应该加 NOPASSWD: 参数, 不需要时方可省略,
移除非必需的软件, 只开放需要用的端口;
遵守权限最小化原则;
用户权限管理和文件权限管理, 主机上的用户, 应用以及进程都应该只允许访问它们本身需要访问的信息和资源
及时更新操作系统和软件;
使用合理过的, 有针对性的防火墙;
监测系统登录情况, 封掉可以的 IP 地址;
系统登录日志审计;
8 总结
上面的写的东西, 都是基础, 没写到很高深的东西 , 比如 roles , includes ,jinjia2,tags, 等等 . 如果你有个东西不会, 就要去官方文档快速看一下怎么使用,
多去官方文档搜索, 比瞎搜索靠谱多了. 官方文档: https://docs.ansible.com/ansible/latest/user_guide/index.html
来源: https://www.cnblogs.com/keme/p/11351611.html