在物理机查看环境,[kiosk@foundation0 ~]$ cat /etc/rht
先清空当前环境,[kiosk@foundation0 ~]$ rht-clearcourse 0
再切换rh294环境,[kiosk@foundation0 ~]$ rht-setcourse rh294
验证环境是否切换成功,[kiosk@foundation0 ~]$ cat /etc/rht
每次切换环境后都先开classroom,[kiosk@foundation0 ~]$ rht-vmctl start classroom
再开启所有虚拟机all,这里的all不包含classroom,[kiosk@foundation0 ~]$ rht-vmctl start all
查看虚拟机状态,[kiosk@foundation0 ~]$ rht-vmctl status all(classroom)
彻底重置虚拟机,[kiosk@foundation0 ~]$ rht-vmctl fullreset all(classroom)
ssh有问题或ping不通就重置哪台虚拟机(reset普通重置fullreset彻底重置)。
记得拍摄快照(开机状态拍摄快照,关机状态克隆),有问题就可快速还原快照不用重置。
考试环境ssh免密和sudo提权免密都做好了的,做题环境需自配置,做题环境在所有虚拟机配置NOPASSWD:(visudo把上面的wheel注释,启用下面带NOPASSWD:的wheel)
或vim /etc/sudoers.d/student
%wheel ALL= NOPASSWD: ALL
后将此文件拷贝到其它机子上,scp /etc/sudoers.d/student root@bastion:/etc/sudoers.d/
ansible自动化运维,ansible不仅管理服务器还能管理交换机、路由器等网络设备。
ansible架构,控制节点和被控制节点,ansible软件只需在控制节点安装,被控制节点无需插件,ansible通过清单文件管理被控制节点。
ansible无需代理,控制节点通过ssh连接被控制节点,每台机子都默认安装了ssh的,所以说无需插件。
ansible通过ssh连接所管理的主机并且运行任务,将ansible模块推送到被管理机节点,模块是一段代码。
如ansible将安装ftp的模块推送到被管理机节点,这些被管理机都成功的安装了ftp就是所需状态,做完任务后这些模块会自动删除。
幂等性,在主机上多次运行同一个playbook,通过编写playbook在多台主机安装了ftp,这些就达到了特定状态了,也可以再运行一遍playbook,但不会再安装一遍。
幂等性是指当你的机器已经到了我希望的状态后就算再运行一遍playbook也不会再执行,可以安全多次的运行playbook,不会对目标主机再次修改了,因为已经修改了。
非幂等性,每次运行playbook时都以为是第一次执行,每次都会从新执行。
大部分模块都是幂等性的,可以安全多次的运行。
控制节点,必须是linux操作系统,被管理节点,可以是任意系统。
控制节点安装ansible软件,[student@workstation ~]$ sudo yum install ansible -y 被控制节点不用安装任何插件
在workstation的student用户为什么能用sudo,因为将student用户加入了wheel组,可id student查看用户信息。
[student@workstation ~]$ ansible --version,查看版本信息,有配置文件信息和python版本信息
ansible有三大文件,inventory清单文件、ansible.cfg配置文件、playbook脚本文件。
inventory清单文件:保存被控制节点信息。
静态清单,管理员手工将被控制节点信息写入该文件,适用小规模IT架构
动态清单,适合大型的IT架构,通过脚本自己解析出主机信息后填入文件中,也适合灵活性(像云服务器购买后被销毁了再次购买ip会变的,其ip是随机分配的)
管理大项目,hosts中用all或'*'代表所有主机,大部分动态清单文件用python写的。
1、列表形式:一个ip或主机名独占一行
servera
serverb
2、主机组形式:[主机组名称]
[web]
serverc
3、连续范围用冒号形式:[start:end]
server[a:d]
4、主机组的从属组,prod组属于webservers主机组
[webservers:children]
prod
默认清单文件不使用(/etc/ansible/hosts),在工作项目目录新建清单文件inventory,后在配置文件中[defaults]指向新清单文件inventory。
新建清单文件如,sudo vim /home/student/project/inventory
[dev]
servera
[prod]
server[c:d]
[webservers:children]
prod
查看清单文件是否有相应主机,配置文件中[defaults]指向新清单文件了,列出的是新清单文件中主机。
ansible servera --list-hosts 查看清单文件的servera
ansible db --list-hosts 查看清单文件db组的主机
ansible all --list-hosts 查看清单文件中所有主机
可在执行命令时使用-i参数指向新清单文件
ansible db --list-hosts -i /home/student/project/inventory
默认配置文件不使用(/etc/ansible/ansible.cfg),在工作项目目录新建配置文件ansible.cfg(系统会优先检测工作项目目录中配置文件),自建配置文件可复制默认配置文件里面内容做参考。
/etc是全局的所有用户都能读取到,每个用户家目录下的项目目录好处是分割项目,一个管理节点可以管理很多ansible项目,用每个用户家目录下的项目目录来区分。
[defaults]
inventory = 新清单文件的位置
remote_user = 远程登录受管节点的用户名
ask_pass = false ssh是否需要密码,设置false后还要ssh设置免密登入才会不需要密码
roles_path = 新角色目录位置
[privilege_escalation]
become = true 是否需要提权为root(授予root权限,像安装软件、新建用户等动作只有root能操作)
become_method = sudo 用sudo方式提权,真正提权要在visudo设置,像root ALL=(ALL) ALL意思是root用户在任何位置能执行任何命令(或将用户加到wheel组)
become_user = root 提权成root
become_ask_pass = false sudo提权时是否需要密码,真正实现以root权限运行命令不要密码,在visudo的%wheel配置NOPASSWD
先从默认配置文件(/etc/ansible/ansible.cfg)把提权部分复制出来,
[privilege_escalation]
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
新建配置文件如,sudo vim /home/student/ansible/ansible.cfg
[defaults]
inventory=/home/student/ansible/inventory
remote_user=student
roles_path=/home/student/ansible/roles
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
在工作项目目录运行临时命令,ansible 主机名称 -m 模块名称 -a '模块参数' 参数用单引号括起来
[student@workstation ansible]$ ansible all -m ping
[student@workstation ansible]$ ansible servera -m user -a 'name=user01 uid=1234 state=present' 创建用户
[student@workstation ansible]$ ansible servera -m user -a 'name=user01 uid=1234 state=absent' 删除用户
在工作项目目录用ansible-doc获取帮助,查看命令在ansible中用法,最后面有举例说明的examples
[student@workstation ansible]$ ansible-doc user
在工作项目目录中手工收集事实变量
[student@workstation ansible]$ ansible servera -m setup
playbook脚本(yaml格式),文件名以.yml结尾,在工作项目目录里创建playbook脚本。
playbook由至少一个play(yaml格式脚本)组成,playbook按照顺序从上往下执行,playbook是需要使用yaml语言来编写,文件名称结尾必须为.yml。
任何playbook都是由三个 --- 开头,以三个...结尾,其中结尾默认不写。
playbook是由至少一个play组成,每个play由3个元素组成分别是:
1 name:定义playbook的名称(play名称)
2 hosts:给哪些受管主机节点执行
3 tasks:任务列表,里面是模块名和模块
(模块名的name前面加横线-,- name,一组任务列表,列表要加横线)
相同级别的元素,必须有相同的缩进,子元素的缩进距离一定大于父元素
遇到横线-和冒号:,其后面就空一格(只能用空格缩进不能用tab键来缩进)
在家目录的工作项目目录创建配置文件ansible.cfg和清单文件inventory和playbook脚本
cd /home/student/project
创建playbook如,vim user.yml
---
- name: create user
hosts: servera
tasks:
- name: user01
user:
name: user01
state: present
执行playbook,执行过程加-v输出详情,-vv越多越详细。
$ ansible-playbook user.yml 是幂等性,只会第一次执行修改成功,后面多次执行都不会修改。
生成做题环境的playbook-basic项目目录,[student@workstation ~]$ lab playbook-basic start
cd /home/student/playbook-basic vim site.yml
---
- name: apache
hosts: web
tasks:
- name: install apache
yum:
name: httpd
state: present
- name: cp file
copy:
src: files/index.html
dest: /var/www/html/index.html
- name: start apache
service:
name: httpd
state: started
enabled: true
执行脚本,$ ansible-playbook site.yml
测试,$ curl http://serverc
变量作用范围越小,优先级越高。
使用vars关键字来定义变量,使用”{{ }}”来调用变量。
变量要写在tasks前面,真正执行的任务是tasks里面的内容,后面的tasks要引用前面的变量。
也可通过vars_files关键字来调用其他外部的变量文件(格式为yml)。
不引用外部变量写法:
vim install.yml
---
- name: install
hosts: servera
vars:
pkg: vsftpd
tasks:
- name: install ftp
yum:
name: "{{ pkg }}"
state: present
引用外部变量文件写法:
vim pkg.yml
pkg: vsftpd
变量引用另一个play中变量:
vim install.yml
---
- name: install
hosts: serverb
vars_files: pkg.yml
tasks:
- name: install ftp
yum:
name: "{{ pkg }}"
state: present
主机变量和主机组变量:
通过在项目目录中,创建host_vars 目录来定义主机变量;通过创建group_vars目录来定义主机组变量。
host_vars和group_vars目录要在工作项目目录中。
1 主机变量: 进入host_vars目录中创建一个和该主机名称一样的变量文件(同名文件,这里文件名不用以.yml结尾,这里不是yml格式),并往该文件中为这个主机定义变量和变量值。
2 主机组变量:进入group_vars目录,创建一个和该组名称一样的变量文件,并往该文件中为这个主机组定义变量和变量值。
register模块,保存命令的执行结果到某个变量中,再使用debug模块,去调试变量。
---
- name: install
hosts: serverc
tasks:
- name: install ftp
yum:
name: vsftpd
state: present
register: rhce
- name: debug
debug:
var: rhce
手工收集事实变量,在工作项目目录执行$ ansible servera -m setup |grep hostname
vim debug.yml
---
- name: debug
hosts: servera
tasks:
- name: debug
debug:
msg: my pc name is "{{ ansible_facts['hostname'] }}"
在ansible.cfg配置文件的[defaults]用log_path参数来增加日志,如log_path: /var/log
debug:
var: 调试变量信息
debug:
msg: 消息输出,类似echo
执行命令ansible-playbook时加-v 输出详情信息,v越多输出的详情信息越多。
加密文件,可用ansible-vault来创建、编辑、查看、加密、解密文件。
创建加密文件,ansible-vault create mpp.yml 交互式输入密码
先将密码写在vault-pass文件中再用--vault-password-file进行调用,
ansible-vault create --vault-password-file=vault-pass mpp.yml
查看加密文件,ansible-vault view filename 交互式输入密码
编辑已有的加密文件,ansible-vault edit filename 交互式输入密码
加密现有文件,ansible-vault encrypt filename ,可加--output=新文件名,即加密重命名文件 交互式输入密码
解密现有文件,ansible-vault decrypt filename ,可加--output=新文件名,即解密重命名文件 交互式输入密码
更改加密文件的密码,ansible-vault rekey filename 交互式先提示输入旧密码再输入新密码
把要改的密码放到文件newpass中,ansible-vault rekey --new-vault-password-file newpass filename
运行加密playbook,ansible-playbook --ask-vault-pass mpp.yml
ansible事实变量,在受管节点中检索出来的软硬件信息,这些信息都可用做变量。
当运行playbook时,在执行第一个play时,默认系统使用setup模块来收集事实变量(TASK [Gathering Facts] )
手工收集事实变量,在工作项目目录执行$ ansible servera -m setup
如何运用事实变量:
1、先用临时命令手工收集事实变量,在工作项目目录执行$ ansible db -m setup
收集后需转换为事实变量格式。
2、在playbook中使用刚才收集到的事实变量,使用的是转换为事实变量格式的。
注意,如何转换为事实变量格式,短主机名hostname,长主机名fqdn
遇到ansible开头的先转换为ansible_facts,然后将后续的字符串(后面的内容)都写入到[' ']中,
遇到子项时单独写成[' '],[' ']也可以用.代替
魔法变量:
1、groups:列出清单中所有主机或主机组
2、hostvars:从当前主机去检索其它主机的变量值
循环语句,loop
vim debug.yml loop循环列表里面内容是列表形式,列表前面要加横线-
---
- name: debug
hosts: servera
tasks:
- name: debug
debug:
msg: "{{ item }}"
loop:
- one
- two
条件判断when,vim debug.yml
---
- name: debug
hosts: servera
vars:
rhce: true
tasks:
- name: echo haha
debug:
msg: "haha"
when: rhce
注意when条件判断的变量,这里不是用事实变量的转换格式。
---
- name: debug
hosts: servera
tasks:
- name: echo haha
debug:
msg: "haha"
when: ansible_hostname == "servera"
block rescue always
block运行成功,不会运行rescue,而是直接运行always
block运行失败,会先运行rescue,再运行always
在受管节点创建文件或目录,jinja2模板
file模块,跟文件相关的,ansible-doc file 到最后面查看案例example
copy模块,src dest
vim test.yml
---
- name: test
hosts: servera
tasks:
- name: touch file
file:
path: /var/mpp
state: touch
- name: cp
copy:
src: /etc/passwd
dest: /var
- name: remoce file
file:
path: /var/mpp
state: absent
- name: create dir
file:
path: /var/dir01
state: directory
使用jinja2模板部署自定义文件,jinja2模板语法,jinja2文件以.j2结尾。
{% 表达式 %}
{{ 变量 }}
{# 注释 #}
jinja2模板需要在playbook中使用,使用template模块部署jinja2模板到受管节点。
template模块(不能用copy模块代替),src源(jinja2文件),dest目标(受管节点)
for循环的jinja2模板
{% for开头 %}
语句
{% endfor %} 结尾
{% for host in groups['all'] %}
{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }}
{{ hostvars[host]['ansible_facts']['fqdn'] }}
{{ hostvars[host]['ansible_facts']['hostname'] }}
{% endfor %}
if语句的jinja2模板
{% if 条件 %}
语句
{% endif %} 结尾
当finished变量值为true时,才会将result变量的值放入已部署的文件。
{% if finished %}
{{ result }}
{% endif %}
魔法变量:
1、groups:列出清单中所有主机或主机组
2、hostvars:从当前主机去检索其它主机的变量值
在工作项目目录中编写jinja2文件。
vim test.j2
my hostname is {{ ansible_facts['fqdn'] }}
在工作项目目录中playbook中用template模块引用jinja2文件。
vim test.yml
---
- name: test
hosts: servera
tasks:
- name: jinja2
template:
src: test.j2
dest: /etc/mytest
利用角色简化playbook
角色(roles),为了简化工作,模板,类似镜像。
角色的3个来源,红帽软件提供、自定义角色、互联网第三方提供。
角色的结构:任何角色都由这8个目录组成。
变量目录:defaults 和 vars vars的优先级高于defaults
可使用的外部文件:files
元数据目录:meta
处理程序目录:handlers
jinja2模板目录:templates
测试目录:test
角色需要执行的主任务目录:tasks (重点)
这些目录中大部分都有main.yml文件,定义内容都是在对应目录的main.yml文件中定义的。
通过在playbook中使用roles关键字来调用角色,在playbook中的roles后面设置的变量优先级高于defaults和vars
pre_tasks:角色之前执行的任务,post_tasks:角色之后执行的任务。
1、利用红帽软件提供的角色,rhel-system-roles软件包提供若干可使用的角色,在workstation的工作项目目录安装,$ sudo yum install rhel-system-roles -y
安装软件包后角色默认存放在/usr/share/ansible/roles目录中(用rhel开头的角色),系统会从默认角色路径找角色,但一般会把角色放在自定义的项目目录中,但ansible不知道你的项目目录中有角色,得在ansible.cfg配置文件的[defaults]用roles_path来指向角色新路径。
在ansible.cfg配置文件的[defaults]用roles_path=/home/student/project/roles指向新的角色目录,
然后从默认角色目录/usr/share/ansible/roles复制想要的角色目录(用rhel开头的角色)(可一次性全部复制过来)。
使用时间同步角色rhel-system-roles.timesync,任何一个角色都有个README.md文件(角色是目录)
$ cd /usr/share/ansible/roles
$ cp -r rhel-system-roles.timesync /home/student/project/roles
$ cd /home/student/project/roles/rhel-system-roles.timesync
$ vim README.md 找到并复制下面内容
- hosts: targets
vars:
timesync_ntp_servers:
- hostname: 要同步的ntp服务器的主机名
iburst: yes 打开快速同步
上述这些变量是保存在角色里面的,后面在playbook中要用到这些变量。
角色里面有tasks目录,在playbook中就不用写tasks了
$ vim timesync.yml
---
- name: time
hosts: all
vars:
timesync_ntp_servers:
- hostname: classroom.example.com
iburst: yes
roles:
- rhel-system-roles.timesync
$ ansible-playbook timesync.yml
时间同步过程的这个错误可忽略,Could not find the requested service timemaster: host
将主机selinux变成强制模式,selinux角色rhel-system-roles.selinux,任何一个角色都有个README.md文件(角色是目录)
$ cd /usr/share/ansible/roles
$ cp -r rhel-system-roles.selinux /home/student/project/roles
$ cd /home/student/project/roles/rhel-system-roles.selinux
$ vim README.md 找到找到并复制下面内容
selinux_state: enforcing
上述这些变量是保存在角色里面的,后面在playbook中要用到这些变量。
角色里面有tasks目录,在playbook中就不用写tasks了
$ vim selinux.yml
---
- name: selinux
hosts: all
vars:
selinux_state: enforcing
roles:
- rhel-system-roles.selinux
$ ansible-playbook selinux.yml
1、先安装,$ sudo yum install rhel-system-roles -y
2、复制角色到项目目录的roles,$ cp -r /usr/share/ansible/roles/rhel-system-roles.selinux /home/student/project/roles
3、在ansible.cfg中,使用roles_path指向新角色目录/home/student/project/roles
4、编写playbook并执行,可以参考README.md文件
角色名前加横线-,-代表列表,同一个元素同一个级别才能叫列表。
2、自定义角色,在工作项目目录中roles目录中定义。
第一步,初始化角色目录结构,初始化目录结构体而不是mkdir创建其目录结构体
$ ansible-galaxy init 自定义角色名
第二步,定义角色的内容
定义一个名为myroles的角色,该角色可以实现获取web主机组中所有主机的hostname,并将这些hostname放入到/tmp/hostname文件中。
$ ansible-galaxy init myroles
$ cd myroles/templates
$ vim test.j2
my name is {{ ansible_facts.hostname }}
$ cd myroles/tasks 注意角色不是playbook,name和hosts是在playbook中写的
vim main.yml
- template:
src: templates/test.j2
dest: /tmp/hostname
第三步,在playbook中使用自定义的角色
退到工作项目目录后,$ vim hostname.yml
---
- name: test
hosts: '*'
roles:
- myroles
在工作项目目录执行,$ ansible-playbook hostname.yml
虽说只用到了templates和tasks目录,但多余的目录不建议删。
3、互联网第三方提供,https://galaxy.ansible.com/ 有上千个ansible角色,可从此网站下载所需ansible角色。
$ cd /home/student/project/
$ ansible-galaxy list 列出角色 (能列出来是因为配置文件中用roles_path来指向角色新路径)
下载并安装第三方角色,ansible-galaxy install 在安装时必须在项目目录下安装,而不是项目目录下的roles目录安装。
选项,-p 指定安装到哪个目录,一般指向项目目录下的roles目录,
-r 根据应答文件来安装角色,
把要安装的角色先写在roles/requirements.yml应答文件中,
应答文件语法:
- src: 指定角色来源,nginx:1.18
version: 角色版本,1.18
name: 重命名角色名称,webnginx
scm: 指定git仓库(不是从git仓库下载的不用加scm属性),git
$ ansible-galaxy install -r roles/requirements.yml -p roles/
能用$ ansible-galaxy list 列出角色说明安装成功
$ ansible-galaxy remove 角色名 可删除任何角色
在workstation生成做题环境,$ lab role-galaxy start,先将配置文件的roles_path的注释取消掉,
$ vim roles/requirements.yml
- src: git@workstation.lab.example.com:student/bash_env
version: master
name: student.bash_env
scm: git
退到项目目录安装,$ ansible-galaxy install -r roles/requirements.yml -p roles/
playbook脚本省略了。
更换版本为dev,不先删除角色会提示此角色已存在,需--force强制安装
使用ansible管理软件包,yum模块,state状态有present安装,absent卸载,latest更新
更新所有,yum update
- name: update all packages
yum:
name: '*'
state: latest
整个组安装软件包,yum group install "Development Tools"
- name: install Development Tools
yum:
name: '@Development Tools'
state: present
关于安装软件包的模块(了解)
windows:win_package
debian、ubuntu:apt
centos、rhel:yum和dnf
使用ansible配置yum仓库,yum_repository模块
yum_repository模块用于构建yum仓库配置文件
file: yum源文件名.repo
name: [仓库名]
description: 名称
gbgcheck: 是否需要密钥,每个软件包在发布时都会用自己的私钥对软件包做签名,为了验证签名,可以导入公钥去做校验。
$ vim test.yml
---
- name: tst
hosts: servera
tasks:
- name: yum_repository
yum_repository:
file: testrhce
name: test
description: example_test
baseurl: http://www.baidu.com
enabled: yes
gpgcheck: no
state: present
验证,[student@servera yum.repos.d]$ cat testrhce.repo
[test]
baseurl = http://www.baidu.com
enabled = 1
gpgcheck = 0
name = example_test
rpm_key模块: 导入公钥
rpm_key:
key: http://...
state: present
管理用户,user模块
group: 主要组
groups: 附加组,用了附加组要加append(-a G)append: 追加
$ vim te.yml
---
- name: create user
hosts: servera
tasks:
- name: user
user:
name: mpp
state: present
shell: /bin/bash
comment: hello
管理用户组,group模块
$ vim te.yml
---
- name: create group
hosts: servera
tasks:
- name: group
group:
name: g1
state: present
gid: 2222
cron模块,周期性计划任务,分时日月周,crontab -u 指定用户
---
- name: create cron
hosts: servera
tasks:
- name: cron
cron:
name: "test crontab"
user: "root"
minute: 45
hour: 10
job: "echo hello >> 1.txt"
使用systemd和service模块管理服务,建议使用service模块,ansible-doc service 发现state有stopped started enabled等。
shell和command模块都没有幂等性,不建议生产环境使用,一般用于查询(了解)
---
- name: start ftp
hosts: servera
tasks:
- name: service
service:
name: vsftpd
state: started
防火墙,firewalld模块,$ ansible-doc firewalld
- name: firewalld
firewalld:
service: http 加的是协议,不是带d的httpd进程名,也可用端口port: 80/tcp
permanent: yes
immediate: yes 立即生效
state: enabled
使用ansible的模块配置存储分区
例如创建一个10G的新分区
- name: new 10GB partition
parted:
device: /dev/vdb
number: 1
state: present
part_end: 2GB
创建vg
- name: create vg
lvg:
vg: vg1
pvs: /dev/vdb1
pesize: 8 PE大小
创建lv
- name: create lv
lvol:
lv: lv1
vg: vg1
size: 1g
force: yes
filesystem模块,格式化文件系统
- name: filesystem
filesystem:
dev: /dev/vg1/lv1
fstype: xfs
mount模块,挂载,支持在/etc/fstab上配置挂载点
- name: creae dir
file:
path: /data
state: directory
- name: mount
mount:
path: /data
src: /dev/vg1/lv1
fstype: xfs
state: present 写入到/etc/fstab永久挂载
执行playbook后用mount -a刷新下,才能df -h查看到挂载信息