Ansible入门教程
1、环境准备
1.1、准备主机
这里使用3台主机做为演示
# IP地址:192.168.10.15 【控制机】 hostnamectl set-hostname ansible-control # IP地址:192.168.10.14 hostnamectl set-hostname nfs1 # IP地址:192.168.10.13 hostnamectl set-hostname web1
1.2、时间同步服务端
# 安装软件包 yum install chrony -y # 修改如下配置 vi /etc/chrony.conf makestep 10 -1 allow local stratum 10 systemctl enable chronyd systemctl start chronyd # 带星表示同步成功 chronyc sources -v # 查看是否同步成功 [root@k8s-master ~]# timedatectl Local time: Tue 2023-01-03 13:40:23 CST Universal time: Tue 2023-01-03 05:40:23 UTC RTC time: Tue 2023-01-03 05:40:23 Time zone: Asia/Shanghai (CST, +0800) NTP enabled: yes NTP synchronized: yes RTC in local TZ: no DST active: n/a
1.3、安装python
1.3.1、下载软件
https://www.python.org/ftp/python/3.10.10/Python-3.10.10.tgz
1.3.2、安装依赖包
yum install gcc gcc-c++ glibc-devel glibc zlib-devel zlib sqlite-devel readline-devel bzip2-devel libffi-devel -y
1.3.3、安装openssl-3.0.8【根据python版本选择】
# 下载openssl wget --no-check-certificate https://www.openssl.org/source/openssl-3.0.8.tar.gz # 安装perl和所需要的模板块 yum install perl perl-CPAN -y # 进入perl环境 perl -MCPAN -e shell # 往perl安装此模板 cpan[1]> install IPC/Cmd.pm # 解压安装 tar xvf openssl-3.0.8.tar.gz && cd openssl-3.0.8 && ./config --prefix=/usr/local/openssl-3.0.8 && make && make install
1.3.4、安装openssl-1.1.1【此python版本使用这教程】
# 下载openssl wget --no-check-certificate https://www.openssl.org/source/openssl-1.1.1t.tar.gz # 安装perl和所需要的模板块 yum install perl # 解压安装 wget --no-check-certificate https://www.openssl.org/source/openssl-1.1.1t.tar.gz && ./config --prefix=/usr/local/openssl-1.1.1 && make && make install
# 创建软链接,方便管理 ln -s /usr/local/openssl-1.1.1 /usr/local/openssl # 增加动态链接库 echo " /usr/local/openssl/lib" >>/etc/ld.so.conf ldconfig -v # 更换openssl mv /usr/bin/openssl /usr/bin/openssl.old ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
1.3.5、安装Python软件
tar xvf Python-3.10.10.tgz && cd Python-3.10.10 && ./configure --prefix=/usr/local/Python-3.10.10 --with-openssl=/usr/local/openssl && make && make install 注意事项: Python2 在编译安装时,可以通过参数 --enable-unicode=ucs2 或 --enable-unicode=ucs4,分别用于指定使用2个字节,4个字节表示一个unicode字符。 Python3 无需进行选择,默认使用ucs4。 # 查看当前Python中表示unicode字符串时占用的空间 import sys print(sys.maxunicode) #如果值是 65535 ,表示使用ucs4标准,即:2个字节表示 #如果值是 1114111 ,表示使用ucs4标准,即:4个字节表示
1.3.6、
cat >/etc/ld.so.conf.d/Python-3.10.10.conf <<'EOF' /usr/local/Python-3.10.10/lib/ EOF ldconfig
1.3.7、配置环境变量
ln -s /usr/local/Python-3.10.10/bin/python3 /usr/bin/python3 ln -s /usr/local/Python-3.10.10/bin/pip3 /usr/bin/pip3
1.4、安装ansible
1.4.1、安装
# 创建副本 python3 -m venv ansible-env # 加载该环境 source ansible-env/bin/activate # 安装ansible python3 -m pip install --upgrade pip python3 -m pip install ansible # 检查安装的版本 [root@ansible-control bin]# pip list Package Version ------------ ------- ansible 7.2.0 ansible-core 2.14.2 cffi 1.15.1 cryptography 39.0.1 Jinja2 3.1.2 MarkupSafe 2.1.2 packaging 23.0 pip 23.0.1 pycparser 2.21 PyYAML 6.0 resolvelib 0.8.1
1.4.2、创建配置目录、配置主机组
# 创建配置文件目录 mkdir /etc/ansible/ # 使用密码登陆 cat > /etc/ansible/hosts << 'EOF' [web1] 192.168.10.13 ansible_ssh_user=root ansible_ssh_pass='root1234' [nfs1] 192.168.10.14 ansible_ssh_user=root ansible_ssh_pass='root1234' EOF
1.4.3、检查是否加载配置成功
(ansible-env) [root@ansible-control ~]# ansible all --list-hosts hosts (2): 192.168.10.13 192.168.10.14
1.4.4、ping所有主机是否是通
yum install sshpass -y (ansible-env) [root@ansible-control ~]# ansible all -m ping 192.168.10.14 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 192.168.10.13 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
1.4.5、ansible常用命令参数
[root@ansible-control ~]# ansible --version ansible [core 2.14.2] # 配置文件位置 config file = /etc/ansible/ansible.cfg # 模板搜索位置 configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/Python-3.10.10/ansible-env/lib/python3.10/site-packages/ansible ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections executable location = /usr/local/Python-3.10.10/ansible-env/bin/ansible python version = 3.10.10 (main, Feb 19 2023, 21:10:13) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] (/usr/local/Python-3.10.10/ansible-env/bin/python3) jinja version = 3.1.2 libyaml = True # 常用的命令 [root@ansible-control ~]# ansible --help # 模板参数 #使用的模块参数,模块的具体动作参数 -a MODULE_ARGS, --args MODULE_ARGS The action's options in space separated k=v format: -a 'opt1=val1 opt2=val2' or a json string: -a '{"opt1": "val1", "opt2": "val2"}' #提示输入ssh密码,而不使用基于ssh的密钥认证#模拟执行测试,但不会真的执行 -k, --ask-pass ask for connection password # 指定主机清单文件 -i INVENTORY # 模拟执行测试 -C, --check don't make any changes; instead, try to predict some of the changes that may occur # 模板名字 (default=command) -m MODULE_NAME, --module-name MODULE_NAME #执行命令的超时 -T TIMEOUT, --timeout TIMEOUT #显示详细信息 -v, --verbose 包含插件日志 -vvvvvv. 正常日志 -vvv debug -vvvv
1.4.6、普通用户需要配置提权的方法
# 普通用户需要配置提权的方法 [root@ansible-control ~]# cat /etc/ansible/ansible.cfg [privilege_escalation] become_ask_pass=False become_method=sudo become_user=root
1.4.7、配置子组
[root@ansible-control ~]# cat /etc/ansible/hosts [web1] 192.168.10.13 [nfs1] 192.168.10.14 [webnfs:children] web1 nfs1
2、ansible认证方式
# 关闭key检查 cat >> /etc/ansible/ansible.cfg << 'EOF' [defaults] # (boolean) Set this to "False" if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host host_key_checking=False EOF
2.1、基于主机密码认证
2.1.2、配置方法
# 旧版本配置 ansible_ssh_user ansible_ssh_pass ansible_ssh_port # 旧版本配置 ansible_user ansible_password ansible_port # 新版兼容旧版的配置,配置如下: cat >/etc/ansible/hosts <<'EOF' [web1] 192.168.10.13 ansible_ssh_user=root ansible_ssh_pass='root1234' ansible_ssh_port=22 [nfs1] 192.168.10.14 ansible_user=root ansible_password='root1234' ansible_port=22 EOF
2.1.2、测试验证
(ansible-env) [root@ansible-control ~]# ansible all -m ping 192.168.10.14 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 192.168.10.13 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
2.2、基于公密钥-免密认证
2.2.1、配置方法
[root@ansible-control ~]# cat /etc/ansible/hosts [web1] 192.168.10.13 [nfs1] 192.168.10.14
2.2.2、配置免密登陆
# 在ansible控制主机创建的密钥文件 [root@ansible-control ~]# ssh-keygen -t rsa -b 2048 # 将公钥复制到免密登陆的主机节点 [root@ansible-control ~]# ssh-copy-id root@192.168.10.13 # 需要输入登陆密码 [root@ansible-control ~]# ssh-copy-id root@192.168.10.14 # 需要输入登陆密码
2.2.3、测试验证
(ansible-env) [root@ansible-control ~]# ansible all -m ping 192.168.10.14 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 192.168.10.13 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
3、Ansible查询帮忙
3.1、查询模板使用方法
[root@ansible-control ~]# ansible-doc -s ping - name: Try to connect to host, verify a usable python and return `pong' on success ping: data: # Data to return for the `ping' return value. If this parameter is set to `crash', the module will cause an exception.
3.2、查询所有模板
[root@ansible-control ~]# ansible-doc -l amazon.aws.autoscaling_group Create or delete AWS AutoScaling Groups (ASGs) amazon.aws.autoscaling_group_info Gather information about EC2 Auto Scaling Groups (ASGs) in AWS amazon.aws.aws_az_info Gather information about availability zones in AWS
...
4、模块
4.1、command
此模块是不支持管道符过滤,一般使用shell模块
4.1.1、给远程主机创建文件、查看、删除
# 创建文件 [root@ansible-control ~]# ansible nfs1 -m command -a 'touch /root/test.txt' 192.168.10.14 | CHANGED | rc=0 >> # 查看是否创建成功 [root@ansible-control ~]# ansible nfs1 -m command -a 'ls -l /root' 192.168.10.14 | CHANGED | rc=0 >> -rw-r--r-- 1 root root 0 Feb 23 11:46 test.txt # 删除文件 [root@ansible-control ~]# ansible nfs1 -m command -a 'rm -f /root/test.txt' 192.168.10.14 | CHANGED | rc=0 >> # 查看是否删除成功 [root@ansible-control ~]# ansible nfs1 -m command -a 'ls -l /root' 192.168.10.14 | CHANGED | rc=0 >> total 0
4.2、shell
支持复杂语法,如管道符、过滤等
4.2.1、查ens33网卡的子网掩码信息
[root@ansible-control ~]# ansible nfs1 -m shell -a "ifconfig ens33 | grep netmask" 192.168.10.14 | CHANGED | rc=0 >> inet 192.168.10.14 netmask 255.255.255.0 broadcast 192.168.10.255
4.3、script
4.3.1、调用nfs1组安装wget脚本
mkdir /opt/script cat > /opt/script/install_wget.sh <<'EOF' #!/bin/bash yum install wget -y EOF # 把控制机的脚本,发往被控制主机运行脚本 ansible nfs1 -m script -a '/opt/script/install_wget.sh'
4.4、yum
4.4.1、参数介绍
name= # rpm名字 state= # 安装(`present' or `installed', `latest'), 删除 (`absent' or `removed') enablerepo= # 指定仓库安装 disablerepo= # 禁用指定仓库安装 list= # 查询rpm包信息 download_only=true # 仅下载软件包,不安装
exclude # 排除安装的包
4.4.2、安装
ansible web1 -m yum -a 'name=wget state=present'
4.4.3、安装rpm包
ansible web1 -m yum -a 'name=https://repo.zabbix.com/zabbix/6.2/rhel/7/x86_64/zabbix-agent2-6.2.1-1.el7.x86_64.rpm state=installed'
4.4.4、更新
ansible web1 -m yum -a 'name=wget state=latest'
4.4.5、删除
ansible web1 -m yum -a 'name=wget state=removed'
4.4.6、查询
ansible web1 -m yum -a 'list=wget'
4.4.7、指定仓库安装
ansible web1 -m yum -a 'name=epel-release state=installed' ansible web1 -m yum -a "list=ansible enablerepo=epel"
4.5、copy
4.5.1、参数介绍
src # 推送数据的源文件信息
dest # 推送数据的目标路径
backup # 对推送传输过去的文件,进行备份
content # 直接批量在被管理端文件中添加内容
group # 将本地文件推送到远端,指定文件属组信息
owner # 将本地文件推送到远端,指定文件属主信息
mode # 将本地文件推送到远端,指定文件权限信息
4.5.2、复制文件
ansible nfs1 -m copy -a "src=/etc/hosts dest=/tmp/test.txt"
4.5.3、复制文件并且备份
# 如果文件内容变化则,备份文件 ansible nfs1 -m copy -a "src=/etc/hosts dest=/tmp/test.txt backup=yes"
4.5.4、content内容写入硬盘
ansible nfs1 -m copy -a "content=hello dest=/tmp/test.txt"
4.5.5、复制文件并且设置权限
ansible nfs1 -m copy -a "src=/etc/hosts dest=/tmp/test.txt owner=nobody group=nobody mode=600"
4.6、file
4.6.1、参数介绍
path # 文件路径 state # 删除"absent"、目录"directory"、文件"file"、硬链接"hard"、软链接"link"、创建文件"touch" owner # 所属者 recurse # 递归操作 state=directory group # 组 mode # 权
4.6.2、创建目录
ansible nfs1 -m file -a "path=/tmp/1/2/3 state=directory"
4.6.3、创建文件
ansible nfs1 -m file -a "path=/tmp/touch.txt state=touch"
4.6.4、创建目录并且修改权限
# 注意:如目录存在,则只修改权限 # 只修改目录权限,不会修改目录里面文件的权限 ansible nfs1 -m file -a "path=/tmp/nfs/ state=directory owner=nobody" # 目录权限以及目录所有文件的权限 ansible nfs1 -m file -a "path=/tmp/nfs/ state=directory owner=nobody recurse=true"
4.7、get_url
4.7.1、参数介绍
作用:下载HTTP, HTTPS, FTP的文件
url # 下载地址
dest # 保存的位置
checksum # md5校验
4.7.2、下载文件
ansible nfs1 -m get_url -a "url=https://repo.zabbix.com/zabbix/6.2/rhel/7/x86_64/zabbix-release-6.2-3.el7.noarch.rpm dest=/tmp validate_certs=false"
4.8、yum_repository
4.8.1、参数介绍
作用:配置yum仓库 name # yum源名字 baseurl # yum的地址 file # 指定yum配置文件的路径和名称。 enable yes/no # 是否开启yum源 state # absent(删除)/present(安装,默认)
4.8.2、给控制主机配置zabbix源
ansible nfs1 -m yum_repository -a 'name=zabbix description="php repo" baseurl=http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/ enabled=yes state=present'
4.9、service
4.9.1、参数介绍
作用:管理服务的启动与停止,开机自启动
name # 服务名字
state
started # 启动服务
stopped # 停止服务
restarted # 重启服务
reloaded # 重新加载服务
enabled # 开机自启动
4.9.2、启动&开启开机自启动
ansible nfs1 -m service -a 'name=crond state=started enabled=yes
4.9.3、停止&关闭开机自启动
ansible nfs1 -m service -a 'name=crond state=stopped enabled=no'
4.9.4、重启
ansible nfs1 -m service -a 'name=crond state=restarted'
4.9.5、重新加载
ansible nfs1 -m service -a 'name=crond state=reloaded'
4.10、group
4.10.1、参数介绍
作用:创建系统的组
name # 指定创建的组名
gid # 指定组的gid
state
absent # 删除远端的主机的组
present # 创建远端的主机的组
4.10.2、创建组
ansible nfs1 -m group -a 'name=nfs gid=1200'
4.11、user
4.11.1、参数介绍
创建用户 uid # 指定用户ID group # 指定用户组的名称 groups # 指定用户组的名移,可以指定多个 password # 用户的密码(记得单引号括起来) shell # 指定用户的登陆shell create_home # 是否创建家目录
4.11.2、创建nfs用户指定组并且不创建家目录
ansible nfs1 -m user -a 'name=nfs uid=1200 group=1200 shell=/sbin/nologin create_home=no'
4.11.3、删除nfs用户
ansible nfs1 -m user -a 'name=nfs state=absent'
4.11.4、创建用户并且生成密钥对
ansible nfs1 -m user -a 'name=nfs uid=1200 group=nfs generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa'
4.11.5、创建用户并且设置密码
# 设置密码 [root@ansible-control ~]# ansible localhost -m debug -a "msg={{ '123456' | password_hash('md5','salt') }}" [DEPRECATION WARNING]: Encryption using the Python crypt module is deprecated. The Python crypt module is deprecated and will be removed from Python 3.13. Install the passlib library for continued encryption functionality. This feature will be removed in version 2.17. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. localhost | SUCCESS => { "msg": "$1$salt$638tR8bROOvPnPklDQ9Vf/" } # 创建用户 ansible nfs1 -m user -a 'name=nfs password="$1$salt$638tR8bROOvPnPklDQ9Vf/" shell=/bin/bash create_home=yes shell=/bin/bash'
4.12、cron
4.12.1、参数介绍
name # 任务名字 state # [删除 absent, 增加 present] job # 命令 minute # 分钟 hour # 小时 day # 每天 month # 月 weekday # 每周几 disabled # 禁用定时任务
# 安装ntpdate工具,定时同步时间,用于演示
ansible nfs1 -m yum -a 'name=ntpdate state=present'
4.12.2、增加定时任务
ansible nfs1 -m cron -a 'name=time ntpdate sync state=present minute=*/1 job=/usr/sbin/ntpdate ntp5.aliyun.com 2>&1 > /dev/null" [root@ansible-control ~]# ansible nfs1 -m command -a 'crontab -l' 192.168.10.14 | CHANGED | rc=0 >> #Ansible: time ntpdate sync */1 * * * * /usr/sbin/ntpdate ntp5.aliyun.com 2>&1 > /dev/null
4.12.3、删除定时任务
ansible nfs1 -m cron -a "name='time ntpdate sync' state=absent"
4.12.4、注释定时任务
ansible nfs1 -m cron -a "name='time ntpdate sync' disabled=yes minute=*/1 job='/usr/sbin/ntpdate ntp5.aliyun.com 2>&1 > /dev/null'" (ansible-env) [root@ansible-control ~]# ansible nfs1 -m command -a 'crontab -l' 192.168.10.14 | CHANGED | rc=0 >> #Ansible: time ntpdate sync #*/1 * * * * /usr/sbin/ntpdate ntp5.aliyun.com 2>&1 > /dev/null
4.13、mount
4.13.1、参数介绍
作用:挂载硬盘,支持设置开机自动挂的功能 src # 挂载哪个硬盘 path # 挂载路径 fstype # 文件系统类型 state present # 开机挂载,仅将挂载配置写入/etc/fstab mounted # 挂载设备,并将配置写入/etc/fstab unmounted # 卸裁设备,不会清除/etc/fstab写入的配置 absent # 卸载设备,会清理/etc/fstab写入的配置
4.13.2、挂载nfs的实践
# 安装nfs服务 ansible nfs1 -m yum -a 'name=nfs-utils state=present' # 创建共享的目录 ansible nfs1 -m file -a 'path=/data state=directory' # 配置共享的目录 ansible nfs1 -m copy -a 'content="/data 192.168.10.0/24(rw,sync,no_all_squash)" dest=/etc/exports' # 启动nfs服务【两个命令都是一样作用,选择其一即可】 ansible nfs1 -m systemd -a 'name=nfs state=started enabled=yes' ansible nfs1 -m service -a 'name=nfs state=started enabled=yes' # 将nfs挂载至web服务器上 ansible web1 -m mount -a 'src=192.168.10.14:/data path=/data fstype=nfs state=mounted' # 卸载nfs,不会删除开机自启动 ansible web1 -m mount -a 'src=192.168.10.14:/data path=/data fstype=nfs state=unmounted' # 完整卸载nfs ansible web1 -m mount -a 'src=192.168.10.14:/data path=/data fstype=nfs state=absent'
4.14、firewalld
4.14.1、参数介绍
作用:firewalld防火墙的配置
service # 指定开放或关闭的服务名称
port # 指定开放或关闭的端口
masquerade # 开启地址伪装
immediate # 临时生效
permanent # 是否添加永久生效
state # 开启或是关闭
zone # 指定配置某个区域
rich_rule # 配置富规则
source # 指定来源IP
4.14.2、放行指定的端口与服务
# 开启firewalld服务 ansible web1 -m systemd -a 'name=firewalld state=started' # 放行http服务 ansible web1 -m firewalld -a 'service=http immediate=yes permanent=yes state=enabled' # 放行8080-8090的端口 ansible web1 -m firewalld -a 'port=8080-8090/tcp immediate=yes permanent=yes state=enabled'
4.15、selinux
4.15.1、开启
ansible web1 -m selinux -a 'state=enforcing'
4.15.2、关闭
ansible web1 -m selinux -a 'state=disabled'
4.16、iptables
4.16.1、安装iptables
# 安装iptables systemctl disable firewalld systemctl stop firewalld yum install iptables-services systemctl start iptables
4.16.2、放行80端口的配置
[root@ansible-control ~]# ansible web1 -m iptables -a 'action=insert table=filter chain=INPUT protocol=tcp source=192.168.10.0/24 destination_port=80 jump=ACCEPT state=present' 192.168.10.13 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "chain": "INPUT", "chain_management": false, "changed": true, "flush": false, "ip_version": "ipv4", "rule": "-p tcp -s 192.168.10.0/24 -j ACCEPT --destination-port 80", "state": "present", "table": "filter" } # 增加 state=present
# 删除 state=absent
# 插入规则
action=insert
# 追加规则
action=append
4.14.17、实践安装nginx
# 1、配置nginx yum源 ansible web1 -m yum_repository -a 'name=nginx description="nginx repo" baseurl=http://nginx.org/packages/centos/7/x86_64/ enabled=no gpgkey=https://nginx.org/keys/nginx_signing.key gpgcheck=true state=present' # 2、安装nginx ansible web1 -m yum -a 'name=nginx state=present enablerepo=nginx' # 3、修改html内容 ansible web1 -m copy -a 'content="hello test nginx" dest=/usr/share/nginx/html/index.html backup=yes' # 4、启动nginx服务 ansible web1 -m systemd -a 'name=nginx state=started enabled=yes' # 5、放开80端口 ansible web1 -m iptables -a 'action=insert table=filter chain=INPUT protocol=tcp source=192.168.10.0/24 destination_port=80 jump=ACCEPT state=present'
5、ansible-playbook
5.1、playbook入门语法介绍
5.1.1、yaml语法的介绍
缩进:YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用tabs
冒号:以冒号结尾的除外,其他所有冒号后面所有必须有空格。
短横线:表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表。
5.1.2、playbook常用关键字的介绍
host # 对哪些主机进行操作
remote_user # 我要使用什么用户执行
tasks # 具体执行什么任务
5.2、playbook入门示例
5.2.1、查询所有主机名
# 1、Ad-hoc[点对点模板]的语法 ansible all -m command -a 'hostname' # 2、创建存放playbook的文件目录 mkdir /opt/playbook && cd /opt/playbook # 3、编写playbook cat > query_hostname.yaml <<'EOF' --- - name: query all hostname hosts: all remote_user: root tasks: - name: execute hostname commond command: hostname EOF # 4、检查playbook语法是否正确 ansible-playbook query_hostname.yaml -C
5.2.2、创建一个文件的示例
# 1、Ad-hoc[点对点模板]的语法 ansible all -m file -a 'name=/tmp/test_all.txt state=touch' # 2、创建一个文件的playbook cat > create_file.yaml << 'EOF' --- - name: touch file hosts: all remote_user: root vars: file_name: cyc_test tasks: - name: exe file mod file: name=/tmp/{{file_name}} state=touch EOF # 3、执行或调试测试 ansible-playbook create_file.yaml -C ansible-playbook create_file.yaml
5.3、nfs-playbook实践
5.3.1、安装nfs
# 创建nfs配置文件 cat > exports.0225 <<'EOF' /data 192.168.10.0/24(rw,sync,no_all_squash) EOF # 编写安装nfs的playbook cat > nfs_install.yaml <<'EOF' --- - name: install nfs package hosts: nfs1,web1 remote_user: root tasks: - name: install nfs server yum: name=nfs-utils,rpcbind state=installed - name: configure nfs server hosts: nfs1 remote_user: root tasks: - name: configure nfs1 copy: src=./exports.0225 dest=/etc/exports - name: create share directory file: path=/data state=directory owner=nfsnobody group=nfsnobody recurse=yes - name: start rpcbind server systemd: name=rpcbind state=started enabled=yes - name: start nfs server systemd: name=nfs state=started enabled=yes - name: mount nfs dir hosts: nfs1,web1 remote_user: root tasks: - name: mount dir mount: src=192.168.10.14:/data path=/mnt/nfs_data fstype=nfs state=mounted EOF # 查看是否挂载成功 [root@ansible-control playbook]# ansible all -m command -a 'tail -1 /etc/fstab' 192.168.10.14 | CHANGED | rc=0 >> 192.168.10.14:/data /mnt/nfs_data nfs defaults 0 0 192.168.10.13 | CHANGED | rc=0 >> 192.168.10.14:/data /mnt/nfs_data nfs defaults 0 0
5.3.2、卸载nfs
cat > nfs_uninstall.yaml <<'EOF' --- - name: unmount nfs dir hosts: nfs1,web1 remote_user: root tasks: - name: unmount dir mount: src=192.168.10.14:/data path=/mnt/nfs_data fstype=nfs state=absent - name: configure nfs server hosts: nfs1 remote_user: root tasks: - name: delete exports file: path=/etc/exports state=absent - name: delete directory file: path=/data state=absent - name: stop nfs server systemd: name=nfs state=stopped enabled=no - name: stop rpcbind server systemd: name=rpcbind state=stopped enabled=no - name: uninstall nfs package hosts: nfs1,web1 remote_user: root
tasks: - name: uninstall nfs server yum: name=nfs-utils,rpcbind state=absent EOF
5.3.3、安装nfs【notify、handler】
cat > nfs_notify_install.ymal << 'EOF' --- - name: install nfs package hosts: nfs1,web1 remote_user: root tasks: - name: install nfs server yum: name: nfs-utils,rpcbind state: installed - name: configure nfs server hosts: nfs1 remote_user: root tasks: - name: configure nfs1 copy: src: ./exports.0225 dest: /etc/exports backup: yes - name: create share directory file: path: /data state: directory owner: nfsnobody group: nfsnobody recurse: yes - name: start rpcbind server systemd: name: rpcbind state: started enabled: yes - name: start nfs server systemd: name: nfs state: started enabled: yes - name: mount nfs dir hosts: nfs1,web1 remote_user: root vars: umount_path: /opt/nfs_data mount_path: /opt/nfs_share tasks: - name: mount dir mount: src: 192.168.10.14:/data path: "{{mount_path}}" fstype: nfs state: mounted notify: - nfs absent - nfs mounted handlers: - name: nfs absent mount: src: 192.168.10.14:/data path: "{{umount_path}}" fstype: nfs state: absent - name: nfs mounted mount: src: 192.168.10.14:/data path: "{{mount_path}}" fstype: nfs state: mounted EOF
5.4、nginx-playbook实践
5.4.1、安装nginx playbook
cat > www.conf << 'EOF' server { listen 80; server_name ansible.test.com; location / { root /usr/share/nginx/html; index index.html; } } EOF cat > nginx_install.yaml << 'EOF' --- - name: install nginx hosts: web1 remote_user: root tasks: - name: configure nginx repo yum_repository: name: nginx description: "nginx repo" enabled: no baseurl: http://nginx.org/packages/centos/7/x86_64/ gpgkey: https://nginx.org/keys/nginx_signing.key gpgcheck: true state: present - name: install nginx yum: name: nginx state: present enablerepo: nginx - name: edit index.html copy: content: "playbook install show" dest: /usr/share/nginx/html/index.html backup: yes - name: config nginx copy: src: ./www.conf dest: /etc/nginx/conf.d/default.conf backup: yes - name: start nginx service systemd: name: nginx state: started enabled: yes - name: pass 80 port iptables: action: insert table: filter chain: INPUT protocol: tcp source: 192.168.10.0/24 destination_port: 80 jump: ACCEPT state: present EOF
5.4.2、安装nginx playbook【notify、handler】
notify # 监听文件是否变化,变化则执行handlers里面对应的任务 handlers cat > www.conf << 'EOF' server { listen 80; server_name ansible.test.com; location / { root /usr/share/nginx/html; index index.html; } } EOF cat nginx_install.yaml --- - name: install nginx hosts: web1 remote_user: root tasks: - name: configure nginx repo yum_repository: name: nginx description: "nginx repo" enabled: no baseurl: http://nginx.org/packages/centos/7/x86_64/ gpgkey: https://nginx.org/keys/nginx_signing.key gpgcheck: true state: present - name: install nginx yum: name: nginx state: present enablerepo: nginx - name: edit index.html copy: content: "playbook install show notify" dest: /usr/share/nginx/html/index.html backup: yes notify: Restart Nginx - name: config nginx copy: src: ./www.conf dest: /etc/nginx/conf.d/default.conf backup: yes notify: Restart Nginx - name: start nginx service systemd: name: nginx state: started enabled: yes - name: pass 80 port iptables: action: insert table: filter chain: INPUT protocol: tcp source: 192.168.10.0/24 destination_port: 80 jump: ACCEPT state: present handlers: - name: Restart Nginx systemd: name: nginx state: restarted
5.5、ansible变量
5.5.1、ymal文件内定义变量
cat > var_ymal.yaml << 'EOF' --- - hosts: nfs1,web1 vars: - nc_pkg: nc - nmap_pkg: nmap tasks: - name: Install nc nmap pkg yum: name: - "{{nc_pkg}}" - "{{nmap_pkg}}" state: present EOF
5.5.2、外部ymal文件内定义变量
cat > vars.yaml << 'EOF' nc_pkg: nc nmap_pkg: nmap EOF cat > var_ymal.yaml << 'EOF' --- - hosts: nfs1,web1 vars_files: ./vars.yaml tasks: - name: Install nc nmap pkg yum: name: - "{{nc_pkg}}" - "{{nmap_pkg}}" state: present EOF
5.5.3、从/etc/ansible/hosts定义变量
cat > /etc/ansible/hosts << 'EOF' [web1] 192.168.10.13 [nfs1] 192.168.10.14 [webnfs:children] web1 nfs1 [webnfs:vars] nc_pkg=nc nmap_pkg=nmap EOF cat > var_ymal.yaml << 'EOF' --- - hosts: nfs1,web1 tasks: - name: Install nc nmap pkg yum: name: - "{{nc_pkg}}" - "{{nmap_pkg}}" state: present EOF
5.5.4、按组和主机名定义变量
host_vars # 文件名就是/etc/ansible/hosts里面定义的主机名 group_vars # 这里的文件名就是/etc/ansible/hosts里面定义的组名 mkdir group_vars cat > group_vars/webnfs << 'EOF' nc_pkg: nc nmap_pkg: nmap EOF cat > /etc/ansible/hosts << 'EOF' [web1] 192.168.10.13 [nfs1] 192.168.10.14 [webnfs:children] web1 nfs1 [webnfs:vars] nc_pkg=nc nmap_pkg=nmap EOF cat > var_ymal.yaml << 'EOF' --- - hosts: nfs1,web1 tasks: - name: Install nc nmap pkg yum: name: - "{{nc_pkg}}" - "{{nmap_pkg}}" state: present EOF
5.5.5、注册变量,自定义显示内容
cat > register.yaml <<'EOF' --- - hosts: all tasks: - name: shell: hostname register: run_status - name: get run status debug: msg: "status:{{run_status.rc}} result:{{run_status.stdout}}" EOF
5.5.6、facts变量
# Facts介绍 Ansible facts是在被管理主机上通过ansible自动采集发现的变量。 facts包含每台特定的主机信息。比如被控端主机的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等。 facts使用场景: 1、通过facts检查CPU,来生成对应的Nginx配置文件。 2、通过facts检查主机名信息,来生成不同的Zabbix配置文件。 3、通过act检索的内存情况来自定义mysql的配置文件。 # 查看主机的详细信息 ansible nfs1 -m setup # 获取采集信息 cat > facts.yaml <<'EOF' --- - hosts: nfs1 tasks: - name: show varibales ansible facts debug: msg: - "IP地址:{{ansible_default_ipv4.address}}" - "CPU物理核数:{{ansible_processor_cores}}" - "总内存:{{ansible_memtotal_mb}}MB" EOF # 关闭采集信息 - hosts: nfs1 gather_facts: no tasks: ... # filter用法 ansible nfs1 -m setup -a 'filter="ens33"' ansible nfs1 -m setup -a 'filter="*ens33*"'
5.6、Task控制
5.6.1、when语法介绍
when使用and或or多条件判断的语法 # OR when: ( ansible_hostname is match("web*") or ansible_hostname is match("nfs*") ) # AND when: ( ansible_hostname is match("web*") and ansible_hostname is match("nfs*") ) when: - ansible_hostname is match("web*") - ansible_hostname is match("nfs*")
5.6.2、when实战1-根据不同操作系统安装相同的软件包
# 根据不同操作系统,安装相同的软件包 cat > when_system.yaml << 'EOF' --- - hosts: web1 tasks: - name: Centos install httpd yum: name: - httpd state: present when: ( ansible_distribution == "CentOS" ) - name: ubuntu install httpd yum: name: - httpd2 state: present when: ( ansible_distribution == "Ubuntu" ) EOF
5.6.3、when实战2-根据判断主机名配置nginx yum源
cat > when_nginx.yaml << 'EOF' --- - name: install nginx hosts: all remote_user: root tasks: - name: configure nginx repo yum_repository: name: nginx description: "nginx repo" enabled: no baseurl: http://nginx.org/packages/centos/7/x86_64/ gpgkey: https://nginx.org/keys/nginx_signing.key gpgcheck: true state: present when: ( ansible_hostname is match("web*") ) EOF
5.6.4、when实战3-判断httpd服务没有开启则重启服务
cat > when_is_active.yaml <<'EOF' - hosts: web1 tasks: - name: Check Http Server command: systemctl is-active httpd ignore_errors: yes register: check_httpd - name: debug outprint debug: var=check_httpd - name: Httpd Restart systemd: name: httpd state: restarted when: ( check_httpd.rc != 0 ) EOF
5.6.5、loop实战1-使用循环启动多个服务【with_items】
cat > 01_loop.yaml <<'EOF' - hosts: web1 tasks: - name: restart httpd crond sshd server service: name: "{{ item }}" state: restarted enabled: yes with_items: - httpd - crond - sshd EOF
5.6.6、loop实战2-使用自定义变量名的方式循环重启服务【vars】
cat > 02_loop_var.yaml <<'EOF' - hosts: web1 tasks: - name: install wget lrzsz pkg yum: name: "{{ pkg_name }}" state: present vars: pkg_name: - wget - lrzsz EOF
5.6.7、loop实战3-使用字典循环方式创建多个用户【with_items】
cat > 03_create_user_loop.yaml <<'EOF' - hosts: web1 tasks: - name: create many user user: name: "{{ item.name }}" groups: "{{ item.groups }}" state: present with_items: - { name: 'test01',groups: 2000 } - { name: 'test02',groups: 2000 } EOF
5.6.8、tags实战1-使用标签控制运行流程
# 语法介绍 --list-tags # 查询yaml标签的数量 -t # 指定运行的标签 --skip-tags # 忽略运行标签 # 标签示例 cat > nfs_tags.yaml << 'EOF' - hosts: nfs1 remote_user: root tasks: - name: install nfs server yum: name: nfs-utils state: present tags: - install_nfs - install_nfs_server - name: server nfs server service: name: nfs-server state: started enabled: yes tags: start_nfs_server EOF
5.6.9、include实战1-文件复用
# 作用:实现配置文件分离,方便管理 # 主配置文件 cat > main.yaml << 'EOF' - hosts: all remote_user: root tasks: - include_tasks: create_file_01.yaml - include_tasks: create_file_02.yaml EOF # create_file_01.yaml cat > create_file_01.yaml <<'EOF' - name: create file 01 file: path: /root/file_01.txt state: touch EOF # create_file_02.yaml cat > create_file_02.yaml <<'EOF' - name: create file 02 file: path: /root/file_02.txt state: touch EOF
5.6.10、ignore_errros实战1-忽略错误
cat > test_ignore_errors.yaml <'EOF' - hosts: all tasks: - name: Ignore False command: /bin/false ignore_errors: yes - name: touch new file file: path: /root/ignore.txt state: touch EOF
5.7、JinJa2-模板
5.7.1、语法
{{ 名称 }} # 变量使用名称 {% for i in EXPR %}...{% endfor %} # 作为循环表达式 {% if EXPR %}...[% elif %}...{% endif%} # 作为条件判断 {# COMMENT #} # 表示注释
5.7.2、template实战1-替换数据分发到其它节点
# 模板文件 cat > motd.j2 << 'EOF' hostname: {{ ansible_hostname }} total_memory is: {{ ansible_memtotal_mb }} MB EOF # 编写playbook cat > cat jinja2_01.yaml << 'EOF' - hosts: web1 tasks: - name: copy template file /etc/motd template: src: ./motd.j2 dest: /etc/motd EOF # 运行结果 [root@ansible-control jinja2]# ansible web1 -m command -a 'cat /etc/motd' 192.168.10.13 | CHANGED | rc=0 >> hostname: web1 total_memory is: 1819 MB
5.7.3、template实战2-使用for替换nginx模板
cat > jinja2_nginx.yaml << 'EOF' - hosts: web1 vars: - server_name: ansible.test.org - http_port: 80 tasks: - name: www.conf template: src: www.j2 dest: /etc/nginx/conf.d/www.conf backup: yes EOF cat > www.j2 << 'EOF' upstream {{ server_name }} { {% for i in range(7,10) %} server 192.168.10.{{i}}:{{http_port}}} weight=1 max_fails=3 fail_timeout=30; {% endfor %} } server { listen {{http_port}}; server_name {{server_name}}; location / { proxy_pass http:://{{server_name}}; proxy_set_header Host $host; proxy_set_header X_Forwarded_For; } } EOF
5.8、Roles
5.8.1、roles介绍
按目录划分模块
5.8.2、实战1-打印hell
# 创建目录 mkdir base/basic/{tasks,templates,handlers,files,group_vars} -p && cd base # 创建目录 mkdir base/basic/{tasks,templates,handlers,files,group_vars} -p && cd base # 主入口 cat > run.yaml << 'EOF' - hosts: all roles: - role: basic EOF # task任务 cat > basic/tasks/main.yaml << 'EOF' - name: print hello debug: msg: "Hello Roles" EOF # 目录结构base
│
├── ── group_vars
│
├── basic
│ ├── files
│ ├── handlers
│ ├── tasks
│ │ └── main.yaml
│ └── templates
└── run.yaml
6、playbook-项目
6.1、基础环境配置
# 入口 cat > run.yaml <<'EOF' - hosts: all roles: - role: basic EOF # 目录结构
mkdir -p base/basic/{files,tasks,templates,handlers}
mkdir -p base/{group_vars} tree /opt/playbook/base
├── base
│ ├── basic
│ │ ├── files
│ │ ├── handlers
│ │ ├── tasks
│ │ │ └── main.yaml
│ │ └── templates
│ ├── group_vars
│ │ └── all
cat > basic/tasks/main.yaml << 'EOF' - name: set base yum repo yum_repository: name: CentOS-Base baseurl: http://mirrors.aliyun.com/centos/7.9.2009/os/x86_64/ description: "Base repo" enabled: yes gpgkey: http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 gpgcheck: true state: present - name: epel yum repo yum_repository: name: epel baseurl: http://mirrors.aliyun.com/epel/7/x86_64/ description: "epel repo" enabled: no gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 gpgcheck: false state: present - name: zabbix yum repo yum_repository: name: zabbix baseurl: http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/ description: "zabbix repo" enabled: no state: present - name: configure nginx repo yum_repository: name: nginx description: "nginx repo" enabled: no baseurl: http://nginx.org/packages/centos/7/x86_64/ gpgkey: https://nginx.org/keys/nginx_signing.key gpgcheck: true state: present - name: configure nginx repo yum_repository: name: php description: "php repo" enabled: no baseurl: https://us-east.repo.webtatic.com/yum/el7/x86_64/ state: present - name: install base software yum: name: - tree - vim - lrzsz - unzip - psmisc - net-tools - nc - nmap - ntpdate state: present - name: stop firewalld systemd: name: firewalld state: stopped enabled: no - name: disable selinux selinux: state: disabled - name: groupadd group: name: www_nginx gid: 2000 - name: useradd user: name: www_nginx group: www_nginx shell: /sbin/nologin create_home: no - name: config sync time cron: name: ali sync time minute: "*/2" job: "/sbin/ntpdate ntp1.aliyum.com &>/dev/null" EOF
6.2、playbook-nginx安装
# 创建新目录 mkdir -p base/nginx/{files,tasks,templates,handlers} mkdir -p base/{group_vars} # 复制nginx 配置文件 scp root@192.168.10.13:/etc/nginx/nginx.conf /opt/playbook/base/nginx/templates/ # 目前只把下面两个值设置为变量 cat base/nginx/templates/nginx.conf.j2 ... user {{ user }}; worker_processes {{ ansible_processor_vcpus }}; ... # 设置变量 cat > base/group_vars/all << 'EOF' user: www_nginx EOF # 运行入口 cat > base/run.yaml <<'EOF' - hosts: all roles: - role: basic - hosts: web1 roles: - role: nginx EOF # 定义运行任务 cat > base/nginx/tasks/main.yaml <<'EOF' - name: install nginx yum: name: nginx state: present enablerepo: "nginx" - name: copy configure nginx file template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf backup: yes notify: - restart nginx - name: start nginx systemd: name: nginx state: started enabled: yes EOF # 定义handlers cat > base/nginx/handlers/main.yaml << 'EOF' - name: restart nginx systemd: name: nginx state: reloaded EOF