写在前面:618买的小米电子书到了,当初没买kindle是因为这个价位的只有kindle青春版,但是配置明显比小米低,分辨率和内存,其他的不说了。用它看三体感觉超棒。但是三体这部小说一开始我感觉还不错,但是对于三体人描写我觉得它减分了,为啥子三体人和人类的认知类似呢,感觉作者没跳出人类的认知,我觉得三体人可以更加特别。
ansible all -m setup -a 'filter="*distribution*"' # 查看系统的版本
absible-galaxy 其他命令
absible-galaxy 跟github命令一样
ansible-galaxy list xx 查看本地是否安装
ansible-galaxy remove 删除
默认 下载到 .ansible/roles/
ansible-playbook 命令
下面是剧本的yml 文件,口代表空格
--- # 整个playbook 开始 不写也没事
-口hosts:口all
remote_user:口root # 以rot用户身份执行
# 最好再空一行
tasks:
-口name:口叫啥都行
command:口hostname # 这个command是模块名
执行:
ansible-platbook -C 上面的yml文件名 # 先检查一遍
ansible-playbook 上面的yml文件名 # 再执行
ansible-playbook websrvs file.yml --limit xx # 这个xx是websrvs中一台,或者一部分
ansible-playbook file.yml -- list-tasks # 任务列表
---
- hosts: all
remote_user: root
tasks: # 注意tasks缩进
- name: create file
file: name=chenxi state=touch
ansible-vault 命令
ansible-valut encrypt xxx # 将剧本的yml文件加密,要记住输入的密码
# 加密过的剧本执行 ansible-playbook xxx 会失败
ansible-valut decrypt xxx # 将加密过的剧本解密
ansible-valut create xx.yml # 直接创建加密的剧本
ansible-valut rekey xx.yml # 修改密码,前提时知道密码
ansible-valut view xx.yml # 查看加密的文件内容,要输入密码
absible-valut edit xx.yml # 编辑
Yaml语法:
--- 代表文档开始, ... 代表文档结束
缩进是统一的,不能空格和tab混用
一个name一个task
列表:其所有元素,-开头 - Apple
字典:name:xx,{name: xx, xxx}
例如:
spouse:
name: xxx
age: 37
gender: male
chiledren:
- name: xx
age:17
- name: 17
age: 13
核心元素
Hosts: 执行远程主机的列表
Tasks: 任务集合
Varniables 内置变量或自定义变量在playbook中调用
Templates 模板
Handlers和notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行。
tags: 标签,指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分。
ansible-playbook -t tagsname xx.yml
Hosts:
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行任务的任务主机,预先定义在主机清单中。
eg.
---
- hosts: all
remote_user: root
tasks:
- name: 随便叫啥
file: name=/data/newfile stae=touch # 建立空的文件
- name: create new user
user: name=test2
- name: install package
yum: name=httpd
- name: copy file
copy: src=xx dest=xx
- name: statr service
service: name=httpd state=started enabled=yes # 后面这个是否开机自启
...
执行 ansible-playbook -C xxx 在执行 ansible-playbook xxx
如果其中一部分任务执行错误,为了接着执行它下面的命令,可以设置忽略错误。这样将会忽略它的错误。
- name: install package
yum: name=httped
ignore_errors: True
下面比较重要
handlers和notify结合使用触发条件
handlers: 是tasks列表,这些tasks和前述的tasks没有本质不同,用于关注的资源发生变化时,才会采取一定操作。
notify:此action可用于每个play的最后被触发,这样可避免多次有改变发生时,每次都执行指定操作,仅在所有的变化发生之后一次性地执行指定操作。在notify中列出的操作成为handle,也即notify中调用handler中的操作。
---
- hosts: all
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
- name: copy xxx
copy: src=files/httpd.conf dest=/etc/httpd/conf backup=yes # 如果目标目录已经有同名文件,backup会进行备份
notify: restart service # 可以绑定多个
- name: start service
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restarted
...
tags 可以指定执行单个的任务
tasks:
- name: create
file: name=tttt state=touch
notify: restart service # 可以绑定多个
tags: inshttpd
ansible-playbook -t inshttpd xx,yml # 执行单个任务
ansible-playbook --list-tags # 查看所有标签
playbook使用变量
变量来源:
- 在/etc/ansible/hosts 中定义,普通变量:主机组中主机单独定义,优先级高于公共白变量。公共组变量:针对主机组中所有主机定义统一变量。
- 通过命令指定变量,优先级最高。 ansible-playbook -e 变量=xxx
- 在playbook中定义。
- 单独的yml文件中。
- 在role中定义。
① 通过外部命令
---
- hosts: all
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }}
- name: start service
service: name={{ pkname }} state=started enabled=yes
...
ansible-playbook -e 'pkname=xx,下一个变量'
②直接通过playbook内部指定
---
- hosts: all
remote_user: root
vars: # 通过vars指定变量
- pkname= xxx
tasks:
- name: install package
yum: name={{ pkname }}
- name: start service
service: name={{ pkname }} state=started enabled=yes
...
③在/etc/ansible/hosts 配置文件里添加配置
普通变量
[websrvs]
192.168.30.201 http_port=81
或者这样配置,公共组变量
[websrvs:vars]
nodename=www
ooo=xxx
使用时
tasks:
- name: sethostname
hostname: name=www.{{ http_port }}.xx.xx
④ 这个是最常用的,创建个文件来存放变量
vars.yml
var1:htpd
var2:vsftpf
test.yml
---
- hosts: all
remote_user: root
vars_files:
- vars.yml # 指定变量路径
tasks:
- name: istall package
yum: name={{ var1 }}
- name: create file
file: name=/xxx/xxx state=touch
...
jinja模板 只能用于ansible-playbook
下面是个例子,
新建个ansible文件夹,在里面创建个templates文件夹,和yml文件同级别。这样playbook的yml文件默认情况下就可以找到模板
实测只要模板文件和paly-book在同一级别就可以,不用非得在templats文件里。
template这个标签就是将带有变量的文件复制到远程主机。
执行 cp /etc/nginx/ngnix.conf templates/nginx_conf.j2
然后件nginx_conf.j2的部分内容替换成变量,变量的来源还是上面说的那几个。
xx.yml
---
- hosts: all
remote_user: root
tasks:
- name: install package
yum: name=nginx
- name: copy template
template: stc=nginx.conf.j2 dest=/etc/nginx/nginx.conf
# 就是把模板的内容 dest就是复制到远程主机的位置
notify: restart service
- name: start sercvice
service: name=nginx state=nginx state=started enabled=yes
handlers:
- name: restart service
service: name=nginx state=restarted
...
下面就是模板的一些用法。
when: 只用条件符合才执行
---
- hosts: all
remote_user: root
tasks:
- name: xxxx
command: /sbin/shutdown -h now
when: ansible_os_family == "ReadHat" # 当when为true时才执行这个tasks
notify: xxx
迭代:
---
- hosts: all
remote_user: root
tasks:
- name: create file
file: name={{ item }} state=touch # 写法都是固定的
when: ansible_distributon_major_version == "7"
with_items: # 固定的
- file1
- file2
- file3
...
也可以这样写,将with_items写成个字典
---
- hosts: all
remote_user: root
tasks:
- name: xxxx
users: name={{ itme.name }} group={{ item.group }} state=present
with_item:
- {name: "xxx", group: "xxx"}
- {name: "xxx", group: "xxx"}
...
for循环 模板里的
{% for vhsot in nginx_vhosts %}
serve{
listen {{ vhost.listen }}
}
{% endfor %}
eg.
playbook test.yml
---
- hosts: all
remote_user: root
vars:
ports:
- 81
- 82
tasks:
- name: xxxx
template: src=conf.j2 dest=for2.conf
...
模板文件 conf.j2
{% for port in ports %}
server{
listen {{ port }}
}
{% endfor %}
然后执行ansible-playbook test.yml 就会发现目标主机出现了for2.conf的文件。
再或者这样写:
---
- hosts: all
remote_user: root
vars:
ports:
- listen_port: 81
- listen_port: 82
tasks:
- name: xxxx
template: src=for1.conf.j2 dest=for2.conf
...
{% for port in ports %}
server{
listen {{ port.listen_port }}
}
{% endfor %}
if 用法
我没试过 不知道后面的is defind 是不是要必须写。
{% if p.name is defind %}