Ansible运维

配置主机

主机名 IP地址 角色
Control 10.0.17.200 控制节点(manager)
Node1 10.0.17.201 控制节点 (test)
Node2 10.0.17.202 控制节点 (proxy)
Node3 10.0.17.203 控制节点 (web1)
Node4 10.0.17.204 控制节点 (web2)
Node5 10.0.17.205 控制节点 (database)

ubuntu最小化安装
源:https://mirrors.aliyun.com/ubuntu/
网卡nat
ip:10.0.17.0/24
dns:114.114.114.114

修改主机名
hostnamectl set-hostname control

更改源地址方法
vi /etc/apt/sources.list.d/ubuntu.sources
添加
Types: deb
URIs: https://mirrors.aliyun.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg


添加本地ISO源
mount /dev/cdrom /mnt
vi /etc/apt/sources.list
添加
deb file:///mnt/cdrom noble main restricted


如果使用ISO镜像
mount ubuntu.iso /mnt
vi /etc/fstab
/dev/cdrom    /mnt   iso9660   defaults 0   0

vi /etc/apt/sources.list
添加
deb file:///mnt noble main restricted



安装vim
apt install -y vim
安装bash-completion
apt-get install bash-completion



查看网卡信息
ip a s
ens32

更改网卡信息
vi /etc/netplan/50-cloud-init.yaml
network:
    ethernets:
        ens32:
            addresses:
            - 10.0.17.200/24
            nameservers:
                addresses:
                - 114.114.114.114
                search: []
            routes:
            -   to: default
                via: 10.0.17.2
    version: 2


netplan apply

配置SSH秘钥

ssh-keygen -f /root/.ssh/id_rsa -N ''

for i in node1 node2 node3 node4 node5 ; do ssh-copy-id $i; done;

root@control:~# for i in node1 node2 node3 node4 nodee5 
> do
> ssh-copy-id $i
> done

安装ansible

apt-get install -y  ansible

配置ansible

mkdir /etc/ansible

cp /usr/lib/python3/dist-packages/ansible_collections/grafana/grafana/examples/ansible.cfg /etc/ansible/ansible.cfg

配置文件查找顺序
1.ANSIBLE_CONFIG变量定义的配置文件
2.检查当前目录下的./ansible.cfg
3.用户家目录下的~/ansible.cfg
4.检查/etc/ansible/ansible.cfg

标准主配置文件ansible.cfg

mkdir	~/ansible
vi ~/ansible/ansible.cfg


[defaults]
inventory =~/ansible/hosts #主机清单配置文件
#forks =5  #ssh并发数量

创建主机列表文件

vi ~/ansible/hosts

[test]   #定义主机组(名称任意)
node1    #定义组中主机
[proxy]
node2
[webserver]
node[3:4]
[database]
node5
[cluster:children]   #嵌套组(children为关键字)
webserver
database

测试ansible环境与配置是否正常

cd ~/ansible/
ansible all --list-hosts
查看所有主机列表

调用ping模块
ansible node1 -m ping
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}


ansible node1,node2 -m ping
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
node2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}



ansible webserver -m ping
node3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
node4 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

ansible ad-hoc命令行

格式:
ansible 主机集合 -m 模块名 -a "参数"
其他选项:-k使用密码远程 -i制定主机列表文件

ansible node1 -m ping
ansible node1,node2 -m ping
ansible webserver -m ping
默认模块command
ansible all -m command -a 'uptime'
ansible all -m command -a 'uname -a'
ansible all -m command -a 'pwd'
ansible all -m command -a 'time'
ansible all -m command -a 'cat /etc/netplan/50-cloud-init.yaml'
ansible all -m command -a 'ip a s'
查看ansible文档
ansible-doc -l
统计命令数量
ansible-doc -l | wc -l

查看apt模块
ansible-doc -l | grep apt

查看apt文档
ansible-doc apt

ansible commmand模块

1.command模块命令不启动shell,直接ssh执行
2.command不支持bash特性,管道和重定向不支持
3.所有调用shell的功能都无法使用

ansible all -m command -a 'ps | wc -l' 
#无法使用

ansible shell模块

不可使用shell模块执行交互命令如vim,top等

ansible all -m shell -a 'ps aux | wc -l'

ansible all -m shell -a 'touch /tmp/123.txt'


ansible all -m shell -a "ssh-keygen -f ~/.ssh/id_rsa -N ' ' creates=~/.ssh/id_rsa"
#creates=文件名:文件存在,则不执行shell命令

ansible apt模块

安装vim
ansible node1,node2 -m apt -a "name=vim state=present"
卸载vim
ansible node1,node2 -m apt -a "name=vim state=absent"
更新
ansible node1,node2 -m apt -a "name=vim state=latest"

ansible script模块

安装apache2


vi test.sh
apt install -y apache2
systemclt start apache2

ansible node2,node3 -m script -a "./test.sh"

ansible node2,node3 -m shell -a "systemctl status apache2"

ansible file模块

创建文件,目录,链接;修改权限与属性

创建file.txt文件
ansible test -m file -a "path=/tmp/file.txt state=touch"
创建mydir文件夹
ansible test -m file -a "path=/tmp/mydir state=directory"
修改file 所有者,,权限
ansible test -m file -a "path=/tmp/file.txt owner=sshd group=adm mode=777"
删除file.txt文件
ansible test -m file -a "path=/tmp/file.txt state=absent"
删除mydir目录
ansible test -m file -a "path=/tmp/mydir state=absent"/etc.hosts文件创建链接文件/tmp/host.txt
ansible test -m file -a "src=/etc/hosts path=/tmp/host.txt state=link"

ansible copy模块

AAA写入a3.txt
echo AAA>~/a3.txt
拷贝a3.txt到test组/root目录下
ansible test -m copy -a "src=~/a3.txt dest=/root"
拷贝a3.txt到test组/root目录下更名为3a.txt
ansible test -m copy -a "src=~/a3.txt dest=/root/3a.txt"
拷贝new.txt到test组 添加内容hello world test
ansible test -m copy -a "content='hello the world\n test' dest=/root/new.txt"

ansible fetch模块

远程主机日志拷贝到control主机

ansible test -m fetch -a "src=/etc/hostname dest=~/"
#将远程主机hostname文件下载到本地home目录

ansible lineinfile|replace模块

ansible test -m lineinfile -a "path=/etc/issue line='hello world'"
#在/etc/issue文件中添加一行内容hello world,默认添加到最后
ansible test -m lineinfile -a "path=/etc/issue line='hello world'"
#基于幂等原则,重复执行,不会创建多行内容



ansible test -m replace -a "path=/etc/issue.net regexp=Ubuntu replace='Ubuntu Ocean'"
#将issue.net内Ubuntu 替换为Ubuntu Ocean

ansible user模块

ansible test -m user -a "name=tuser1"
#创建test组中的所有主机并创建系统账户tuser1

ansible test -m user -a "name=tuser2 uid=1010 group=adm groups=daemon,root home=/home/tuser2"
#创建账户并设置对应的账户属性

ansible test -m user -a "name=tuser2 password={{'root'|password_hash('sha512')}}"
#修改账户密码


ansible test -m user -a "name=tuser1 groups=root,daemon"
#更改tuser1账户的附加组
ansible test -m user -a "name=tuser1 state=absent"
#删除tuser1
ansible test -m user -a "name=tuser2 state=absent remove=true"
#删除涂色r账户同时删除家目录,邮箱

ansible 批量更改源

#查看ubuntu linux版本
uname -a 
#查看release
cat /etc/lsb-release


#脚本
vim ~/ansible/ansible_playbook/update_apt_source.sh

#!/bin/bash
mv /etc/apt/sources.list /etc/apt/sources.list.bak
SYS_VERSION=$(lsb_release -c | grep -o "\s.*")
cat >> /etc/apt/sources.list << EOF
deb http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $SYS_VERSION-proposed main restricted universe multiverse
EOF
apt update


#ansible playbook
vim update_apt_source.yml

- hosts: k8s_nodes1
  become: true
  vars:
    docker_version: 18.09.2
  tasks:
    - name: copy update_apt_source.sh
      copy:
        src: "~/ansible/ansible_playbook/update_apt_source.sh"
        dest: '/etc/apt'
        owner: root
        group: root
        mode: 0777
    - name: update apt source.list
      shell: /etc/apt/update_apt_source.sh

#ansible 分发
ansible-playbook update_apt_source.yml

ansible apt_repository模块 更新apt源

ansible test -m apt_repository -a "filename=myapt repo='deb file:///dev/cdrom noble main restricted' state='present'"
#ISO挂载安装源
ansible test -m apt_repository -a "filename=ustc repo='
deb https://mirrors.ustc.edu.cn/ubuntu/ noble main restricted universe multiverse\n
deb-src https://mirrors.ustc.edu.cn/ubuntu/ noble main restricted universe multiverse\n
deb https://mirrors.ustc.edu.cn/ubuntu/ noble-updates main restricted universe multiverse\n
deb-src https://mirrors.ustc.edu.cn/ubuntu/ noble-updates main restricted universe multiverse\n
deb https://mirrors.ustc.edu.cn/ubuntu/ noble-backports main restricted universe multiverse\n
deb-src https://mirrors.ustc.edu.cn/ubuntu/ noble-backports main restricted universe multiverse\n
deb https://mirrors.ustc.edu.cn/ubuntu/ noble-security main restricted universe multiverse\n
deb-src https://mirrors.ustc.edu.cn/ubuntu/ noble-security main restricted universe multiverse\n
deb https://mirrors.ustc.edu.cn/ubuntu/ noble-proposed main restricted universe multiverse\n
deb-src https://mirrors.ustc.edu.cn/ubuntu/ noble-proposed main restricted universe multiverse' 
state='present'"


#删除apt源
ansible test -m apt_repository -a "filename=myapt  state='absent'"

ansible service模块

#重启
ansible test -m service -a "name=apache2 state=restarted"
#开启
ansible test -m service -a "name=apache2 state=started"
#停止
ansible test -m service -a "name=apache2 state=stopped"
#重载
ansible test -m service -a "name=apache2 state=reloaded"
#开机启动
ansible test -m service -a "name=apache2 enabled=yes"

ansible 逻辑卷相关模块

ansible-doc parted

state:present(创建)|absent(删除)



#node1新加硬盘分区
ssh node1
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary 1 50%
parted /dev/sdb mkpart primary 50% 100%
lsblk

#安装lvm2软件
ansible test -m apt -a "name=lvm2"
ansible test -m apt -a "name=lvm2 state=present"


ansible test -m lvg -a "vg=myvg pvs=/dev/sdb1"
#创建名为myvg的卷组,该卷组由/dev/sdb1组成
ansible test -m lvg -a "vg=myvg pvs=/dev/sdb1,/dev/sdb2"
#修改卷组大小
ssh node1
vgs
pvs


#创建逻辑卷
#lvg模块:创建,删除卷组(VG),修改卷组大小
#state:present(创建)|absent(删除)
#安装lvm2软件
ansible test -m apt -a "name=lvm2 state=present"

ansible test -m lvg -a "vg=myvg pvs=/dev/sdb1"
#创建名为myvg的卷组,该卷组由/dev/sdb1组成

ansible test -m lvg -a "vg=myvg pvs=/dev/sdb1,/dev/sdb2"
#修改卷组大小



#lvol模块:创建,删除逻辑卷(LV),修改逻辑卷大小
#state:present(创建)|absent(删除)
ansible test -m lvol -a "lv=mylv vg=myvg size=0.5G"
#使用myvg这个卷组创建一个名称为mylv的逻辑卷
ansible test -m lvol -a "lv=mylv vg=myvg size=0.8G"
#修改LV逻辑卷大小
ansible test -m lvol -a "lv=mylv vg=myvg state=absent force=yes"
#删除逻辑卷
ansible test -m lvg -a "vg=myvg state=absent"
删除卷组myvg



#磁盘分区
ansible-doc -l |grep parted
ansible-doc parted

#分区格式化
ansible-doc -l |grep filesystem
ansible-doc filesystem

sudo提权

基本流程
1.管理员授权(修改/etc/sudoers文件)
2.普通用户以sudo的形式执行命令
3.通过sudo -l查看授权情况

修改/etc/sudoers的方法

1.
visudo(带语法检查,默认没有颜色提示)
2.
vim /etc/sudoers(不带语法检查,默认由颜色提示)



用户或组   主机列表=(提权身份)  [NOPASSWD]:命令列表
命令需要写绝对路径
root    ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL
%sudo   ALL=(ALL:ALL) ALL



node1
useradd testuser
passwd testuser


su testuser	
vi /etc/passwd
testuser:x:1012:1012::/home/testuser:/bin/bash


管理员授权
visudo
修改文件
vi /etc/sudoers
testuser ALL=(root) NOPASSWD:/usr/bin/systemctl

systemctl restart apache2
systemctl status apache2

sudo -l 查看权限
ansible修改主机
创建用户alice 密码123456 shell=bash
ansible all -m user -a "name=alice password={{'123456'|password_hash('sha512')}} shell=/bin/bash"

使用NOPASSWORD开启无密码验证
ansible all -m lineinfile -a "path=/etc/sudoers line='alice ALL=(ALL) NOPASSWD:ALL'"
#NOPASSWD:ALL赋予所有权限

ssh alice@node1
ssh alice@node1
sudo systemctl restart apache2

修改~/ansible/ansible.cfg
修改sudo相关配置

[defaults]
inventory =~/ansible/hosts
#forks =5
remote_user = alice    #以alice用户远程被管理主机
[privilege_escalation]
become = True   #是否需要切换用户
become_method = sudo    #如何切换用户
become_user = root      #切换成什么用户
become_ask_pass = False #sudo是否需要输入密码


使用alice远程被管理主机,提前配置ssh秘钥

ansible all -m shell -a "chown alice -R /home/alice"
ansible all -m shell -a "chgrp alice -R /home/alice"


for i in node1 node2 node3 node4 node5
do
	ssh-copy-id alice@$i
done

ansible all -m command -a "who"

inventory配置


cat hosts

[test]   #定义主机组(名称任意)
node1    #定义组中主机
[proxy]
node2
[webserver]
node[3:4]
[database]
node5
[cluster:children]   #嵌套组(children为关键字)
webserver
database

#可添加变量 空格隔开
#自定义端口
ansible_ssh_port=
#自定义远程连接账户名
ansible_ssh_user=
#自定义远程连接密码
ansible_ssh_pass=
#自定义远程连接密钥
ansible_ssh_private_key_file=

Playbook

YAML

1.“#”代表注释,一般第一行为三个横杠
2.键值对使用“:“表示,数组使用”一“表示
3.缩进必须由两个或以上空格组成
4.相同层级的缩进必须对齐
5.全文不可以使用tab键
6.区分大小写、扩展名为yml或者yaml
7.跨行数据需要使用>或者|(|会保留换行符)

YAML格式的键值对数据
1.key和value之间使用":“分隔
“小明”: “男”
“小明”:
“男”
2.”: "后面必须有空格
3.缩进代表层级关系(缩进用两个空格)

YAML格式的数组数据
短横线和空格表示
1.纯数组

- "周一"
- "周二"
- "周三"
- "周四"

2.键值对和数组

"诗人":
	  - "李白"
	  - "杜甫"
	  - "白居易"
"诗人":  ["李白","杜甫","白居易"]

综合示例

-“诗人”:
       - 唐代:
              - “李白"
              - “杜甫"
       - 宋代:
              - “苏轼"
              - “李清照"

--- #跨行文本(计算机理解为一行)
自我介绍:>
字太白,号青莲居士,
唐代诗人,祖籍陇西郡,
今甘肃省平凉市

--- #跨行文本(计算机理解为多行)
自我介绍:|
字太白,号青莲居士,
唐代诗人,祖籍陇西郡,
今甘肃省平凉市

--- #一张发票
发票编号: 34843
日期: 2028-12-12
商品: 
 - 商品编号: BL394D
   描述: 足球
   价格: 100
 - 商品编号: BL4438H
   描述: 棒球
   价格: 200
税费: 10.00
总价: 310.00
备注: >
 本次采购商品均
 属于球类运动商品.

---#错误日志
时间: 2028-10-01 15:01:42
用户: ed
错误信息: 
 - 文件: nginx.conf
   行号: 23
   错误编码:0x3D5FF1"
 -文件: test.php
  行号: 12
  错误代码:0xA4C51E"
警告信息: |
 你有两个错误信息需要查看.
 一条是配置文件错误,
 一条是脚本语法错误.
 具体内容参考错误信息


   #冒号后面要有空格

Playbook语法格式

1.playbook采用YAML格式编写
2.playbook文件中由一个或多个play组成
3.每个play中可以包含:
√ hosts(主机)、tasks(任务)
√ variables(变量)、roles(角色)、handlers等元素组成
4.使用ansible-playbook命令运行playbook剧本

playbook

vi ~/ansible/test.yaml

---
- hosts: all
  tasks:
    - name: This is my first playbppk
      ping: 

ansible-playbook test.yaml



vi ~/ansible/test2.yaml

---
- hosts: all
  tasks:
    - name: This is my first playbook
      ping: 
    - name: Run a shell command
      shell: find / -name passwd 
    - name: Run a shell command
      shell: touch ~/shell.txt

ansible-playbook test2.yaml -f 5
-f自定义并发数量

ansible playbook用户案例

vi /~ansible/test_add_user.yaml


---
- hosts: webserver
  tasks: 
   - name: Add the user 'johnd'
     user: 
      name: johnd
      uid: 1040
      group: daemon
      password: "{{'123' | password_hash('sha512')}}"

ansible-playbook test_add_user.yaml



vi user_james.yaml

---
 - hosts: webserver
   tasks: 
     - name: Add the user 'james' with a bash shell, appending the group 'admins' and 'developers' to the user's groups
       ansible.builtin.user:
        name: james
        shell: /bin/bash
        groups: bin,daemon
        append: yes
        password: "{{'123' | password_hash('sha512')}}"
ansible-playbook user_james.yaml




vi del_james.yaml

---
 - hosts: webserver
   tasks: 
     - name: Add the user 'james' with a bash shell, appending the group 'admins' and 'developers' to the user's groups
       ansible.builtin.user:
        name: james
        state: absent
        
ansible-playbook del_james.yaml

ansible playbook 使用vdb创建卷组和逻辑卷

#删除分区
parted /dev/sdb rm 1
parted /dev/sdb rm 2


touch lvm.yaml

---
- hosts: test
  tasks:
    - name: Create a new primary partition with a size of 0.5GiB
      parted:
       device: /dev/sdb
       number: 1
       state: present
       part_end: 50%
    - name: Create a new primary partition with a size of 0.5GiB
      parted:
       device: /dev/sdb
       number: 2
       state: present
       part_start: 50%
       part_end: 100%
    - name: Create a volume group on top of /dev/sdb1
      lvg:
       vg: my_vg
       pvs: /dev/sdb1
    - name: Create a logical volume of 0.5G
      lvol:
       vg: my_vg
       lv: my_lv
       size: 0.4G

ansible-playbook lvm.yaml

ansible playbook 使用apt安装软件


vi apt_bash-completion.yaml

---
 - hosts: all
   tasks:
    - name: Install bash-completion
      ansible.builtin.apt:
       name: bash-completion
       state: present

ansible-playbook apt_bash-completion.yaml

ansible playbook 使用ansible_faces采集被管理设备的系统信息

所有手机的信息都被保存在变量中
每次执行playbook默认第一个任务就是Gathering Facts
使用setup模块可以查看收集到的facts信息

ansible test -m setup


ansible test -m setup -a "filter=ansible_mem*"
ansible test -m setup -a "filter=ansible_all_ipv4_addresses*"
ansible test -m setup -a "filter=ansible_bios_version*"
ansible test -m setup -a "filter=ansible_memtotal_mb*"
ansible test -m setup -a "filter=ansible_hostname*"
ansible test -m setup -a "filter=ansible_devices.sda.partitions.sda2.size"



vi debug.yaml

---
- hosts: test
  tasks: 
   - debug:
      var: ansible_all_ipv4_addresses
   - debug:
      msg: "主机名称为:{{ ansible_hostname }}"
   - debug:
      var: ansible_devices.sda.partitions.sda1.size
   - debug:
      msg: "总内存大小:{{ ansible_memtotal_mb }}mb"

ansible-playbook debug.yaml

ansible 定义变量

Inventory变量
Host Facts变量
Playbook变量
变量文件

Inventory变量(在主机清单配置文件中定义变量)


vi ~/ansible/hosts

[test]   
node1    myvar1="hello the world" myvar2="content"
[proxy]
node2
[webserver]
node[3:4]
[webserver:vars]
yourname="jacob"
[database]
node5
[cluster:children]   #嵌套组(children为关键字)
webserver
database

vi playbook/inventory.yaml

---
- hosts: test
  tasks: 
   - name: create a file with var.
     shell: echo "{{ myvar1 }}" > /tmp/"{{ myvar2 }}"
- hosts: webserver
  tasks:
   - name: create a user with var.
     user: 
      name: "{{ yourname }}" 


ansible-playbook playbook/inventory.yaml

Host Facts变量(可以直接调用ansible手机的系统信息)


vi playbook/facts_var.yaml

---
- hosts: test
  tasks:
    - name: Use facts info
      copy:
       content: "{{ ansible_hostname}}:{{ ansible_bios_version }}"
       dest: /tmp/facts.txt

ansible-playbook playbook/facts_var.yaml

Playbook变量


vi playbook/playbook_var.yaml

---
- hosts: test
  vars: 
   iname: heal
   ipass: "123456"
  tasks:
    - name: Use variables create user.
      user:
       name: "{{iname}}"
       password: "{{ipass | password_hash('sha512')}}"


ansible-playbook playbook/playbook_var.yaml

定义变量文件

vi playbook/file_var.yaml


---
- hosts: test
  vars_files: variables.yaml
  tasks:
    - name: create user
      user:
        name: "{{ iname }}"
        password: "{{ ipass | password_hash('sha512')}}"


ansible-playbook playbook/file_var.yaml

执行ansible-playbook命令时使用-e参数定义变量

vi playbook/command_var.yaml


---
- hosts: test
  tasks:
    - name: create user
      user:
        name: "{{ iname }}"
        password: "{{ ipass | password_hash('sha512')}}"

ansible-playbook playbook/command_var.yaml -e iname="beth" -e ipass="123456"

ansible 模块应用

firewall模块 配置防火墙


vi ansible/playbook/firewall.yaml

---
- hosts: test
  tasks:
    - name: install firewall
      apt: 
        name: firewalld
        state: present
    - name: run firewalld
      service:
        name: firewalld
        state: started
        enabled: yes
    - name: set firewalld rule
      firewalld:
        port: 80/tcp
        permanent: true
        immediate: true
        state: enabled


ansible-playbook playbook/firewall.yaml

template模块 拷贝不同内容文件给不同主机

拷贝index.html内容给各自主机,且内容为各自主机ip

vi template/index.html

Welcome to {{ ansible_hostname }} on {{ ansible_ens32.ipv4.address}}


vi template/template.yaml

---
- hosts: webserver
  tasks: 
   - name: use tepmlate copy index.html to webserver.
     template:
       src: ~/ansible/template/index.html
       dest: /var/www/html/index.html

ansible-playbook template/template.yaml


给webserver主机拷贝文件,每个文件内容不同

vi template/source.j2
{{ welcome }}{{ iname }}

vi template/template_2.yaml

---
- hosts: webserver
  vars:
    welcome: 'hello'
    iname: 'jack'
  tasks:
  - name: use template copy a file to remote host.
    template:
      src: ~/ansible/template/source.j2
      dest: /tmp/


ansible-playbook template/template_2.yaml

ansible error处理机制

vi error/error.yaml

---
- hosts: test
  tasks:
    - name: start a service that does not exise.
      service:
        name: hehe
        state: started
      ignore_errors: true
    - name: touch a file
      file:
       path: /tmp/serivce.txt
       state: touch


ansible-playbook error/error.yaml

忽略全局错误

---
- hosts: test
  ignore_errors: true
  tasks:
    - name: start a service that does not exise.
      service:
        name: hehe
        state: started
    - name: touch a file
      file:
       path: /tmp/serivce.txt
       state: touch

ansible hanlders处理机制

当某个任务需要依赖其他任务怎么办?

√可以通过handlers定义一组任务
√仅当某个任务触发(notify)handlers时才执行相应的任务
√如果有多个notify触发执行handlers任务,也仅执行一次
√ 仅当任务的执行状态为changed时handlers任务才执行
√ handlers任务在所有其他任务都执行后才执行


通过nofify触发执行handlers任务
关键词notify与name平级  handlers与tasks平级
cat ~/ansible/handlers.yml

---
- hosts: test
  tasks:
  - name: create directory. #多次执行playbook该任务状态不再是changed
    file:
     path: /tmp/parents/subdir/
     state: directory
    notify: touch file  #notify后面名称必须和handlers中的任务名称一致
  handlers:
  - name: touch file
    file:
     path: /tmp/parents/subdir/new.txt
     state: touch

ansible-playbook handlers/handlers.yaml

执行file创建文件夹成功返回changed之后触发hanlders创建文件new.txt

ansible when条件判断

when可以定义判断条件,条件为真时才执行某个任务

常见条件操作符如下:

√ ==、!=、>、>=、<、<=

多个条件可以使用and或or分割

when表达式中调用变量不要使用{{}}

条件操作符如下:==、!=、>、>=、<、<=

远程主机剩余内存不足700M则关闭NetworkManager服务

vi playbook/when.yaml

---
- hosts: test
  tasks:
  - name: check memory size.
    service:
     name: apache2
     state: stopped
    when: ansible_memfree_mb < 700


判断操作系统是RedHat8则创建测试文件

√>支持多行输入,不保留换行符

cat ~/ansible/playbook/when_2.yml


---
- hosts: test
  tasks:
   - name: touch a file
     file:
       path: /tmp/when.txt
       state: touch
     when: >
       ansible_distribution == "Ubuntu"
       and
       ansible_distribution_major_version == "24"


ansible-playbook playbook/when_2.yaml
   

ansible block任务块

block任务块

使用block可以将多个任务合并为一个组

[root@control ansible]# cat -/ansible/playbook/block_1.yml

---
- hosts: test
  tasks:
  - name: define a group of tasks.
    block:
     - name: install apache2
       apt:
         name: apache2
         state: present
     - name: start apache2
       service:
         name: apache2
         state: started
    when: ansible_distribution == "Ubuntu"

ansible-playbook playbook/block_1.yaml

rescue定义block任务执行失败时要执行的其他任务

always定义无论block任务是否成功,都要执行的任务


[root@control ansible]# cat -/ansible/playbook/block_2.yml

---
- hosts: test
  tasks:
   - block:
      - name: touch a file test1.txt
        file:
           path: /tmp/test1.txt #如果改为/tmp/xyz/test1.xt就无法创建成功
           state: touch
     rescue:
      - name: touch a file test2.txt
        file:
           path: /tmp/test2.txt
           state: touch
     always:
      - name: touch a file test3.txt
        file:
           path: /tmp/test3.txt
           state: touch


ansible-playbook playbook/block_2.yaml






vi playbook/block_2_2.yaml

---
- hosts: test
  tasks:
   - block:
      - name: touch a file test1.txt
        file:
           path: /tmp/xyz/test1.txt
           state: touch
     rescue:
      - name: touch a file test2.txt
        file:
           path: /tmp/test2.txt
           state: touch
     always:
      - name: touch a file test3.txt
        file:
           path: /tmp/test3.txt
           state: touch


ansible-playbook playbook/block_2.yaml

ansible loop循环

很多任务都在用相同的模块?使用loop循环避免重复

cat ~/ansible/playbook/simple_loop.yml

---
- hosts: test
  tasks:
   - name: mkdir multi directory.
     file:
       path: /tmp/{{item}}  #注意,item是关键字
       state: directory
     loop:     #定义item
       - School
       - Legend
       - Life

[root@control ansiblel# vi playbook/complex_loop.yml

---
- hosts: test
  tasks:
    - name: create multi users.
      user:
       name: "{{ item.iname }}"
       password: "{{ item.ipass | password_hash('sha512')}}"
      loop:
       - { iname: 'term', ipass: '123456'}
       - { iname: 'amy', ipass: '654321'}
~                                               


ansible-playbook playbook/complex_loop.yml

ansible-vault加密

Ansible有时需要访问一些敏感数据,如密码、Key等

使用ansible-vault可以加密和解密数据

√ encrypt(加密)、decrypt(解密)、view(查看)

[root@control ansible]# echo 123456 > data.txt#新建测试文件

[root@control ansible]# ansible-vault encrypt data.txt #加密文件

[root@control ansible]# cat data.txt

[root@control ansible]# ansible-vault view data.txt #查看加密文件

ansible-vault rekey可以修改加密的密码

[root@control ansible]# ansible-vault encrypt data.txt  #加密文件,密码111

New Vault password: 111

Confirm New Vault password:111

[root@control ansible]# ansible-vault rekey data.txt  #修改密码

Vault password:<旧密码>

New Vault password:<新密码>

Confirm New Vault password:<确认新密码>

加密、解密每次都输入密码很麻烦,可以将密码写入文件

[root@controlansiblel#echo"Im secret data">data.txt  #需要加密的敏感数据

[root@control ansible]# echo 123456 > pass.txt #加密的密码

[root@control ansible]# ansible-vault encrypt--vault-id=pass.txt data.txt

[root@control ansible]# cat data.txt

[root@control ansible]# ansible-vault decrypt --vault-id=pass.txt data.txt

[root@control ansible]# cat data.txt

Ansible Roles基础

在实际生产环境中,为了实现不同的功能,我们会编写大量的playbook文件
而且,每个playbook还可能会调用其他文件(如变量文件)
对于海量的、无规律的文件,管理起来非常痛苦!
Ansible从1.2版本开始支持Roles
Roles是管理ansible文件的一种规范(目录结构)
√ Roles会按照标准的规范,自动到特定的目录和文件中读取数据

Roles规范的目录结构

defualts/main.yml:定义变量的缺省值,优先级较低
files目录:存储静态文件的目录
handlers/main.yml:定义handlers
meta/main.yml:写作者、版本等描述信息README.md:整个角色(role)的描述信息
tasks/main.yml:定义任务的地方
templates目录:存放动态数据文件的地方(模板文件)
vars/main.yml:定义变量,优先级高

role应用

创建Role

ansible-galaxy命令可以创建、管理自己的roles

[root@control ansible]# mkdir ~/ansible/roles

[root@control ansible]# ansible-galaxy init ~/ansible/roles/issue

#创建一个Role,该Role的目的是使用模板修改远程主机的/etc/issue文件

[root@control ansible]# tree ~/ansible/roles/issue/

/root/ansible/roles/issue/
├── README.md      #写作者、版本等描述信息README.md:整个角色(role)的描述信息
├── defaults
│   └── main.yml   #定义变量的缺省值,优先级较低
├── files          #存储静态文件的目录
├── handlers
│   └── main.yml   #定义handlers
├── meta
│   └── main.yml
├── tasks
│   └── main.yml   #定义任务的地方
├── templates      #存放动态数据文件的地方(模板文件)
├── tests
│   ├── inventory  
│   └── test.yml
└── vars
    └── main.yml   #定义变量,优先级高


#查看目录结构,如果没有tree命令则需要使用apt安装该软件

修改Role

定义issue文件的模板文件

[root@control ansible]# cat ~/ansible/roles/issue/templates/issue.j2

This is the system {{ansible_hostname}}
Today's date is:{{ansible_date_time.date}}
Contact to {{ admin }}

·定义变量文件

[root@control ansible]# cat ~/ansible/roles/issue/vars/main.yml

---
# vars file for /root/ansible/roles/issue
admin: noz@noziroh.cn

修改任务文件;任务文件中不需要tasks关键词

√Role的各个文件之间相互调用不需要写路径

[root@control ansible]# vi ~/ansible/roles/issue/tasks/main.yml


---
#tasks file for /root/ansible/roles/issue
- name: delever issue file
  template:   
    src: issue.j2
    dest: /etc/issue

Playbook中调用Role

方法一:在role相同目录下创建一个playbook调用

方法二:在ansible.cfg设置roles_path=路径

[root@control ansible]# vi ~/ansible/ansible.cfg
[defaults]
remote_user = root
inventory = ~/ansible/hosts
roles_path = ~/ansible/roles
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False






vi ansible/issue.yml

---
- hosts: test
  roles:
   - issue
   - role2  #支持加载多个role

ansible-playbook issue.yml

ansible-galaxy

Ansible Galaxy是官方提供的一个共享roles的平台

√ 公共Roles仓库(https://galaxy.ansible.com)

[root@control ansible]# ansible-galaxy search 'httpd'

#联网搜索roles

[root@control ansible]# ansible-galaxy info acandid.httpd

#查看roles基本信息

[root@control ansible]# ansible-galaxy install acandid.httpd -p ~/ansible/roles/

#下载roles到特定的目录

[root@control ansible]# ansible-galaxy list -p roles/

#列出本地有哪些roles

下载Roles的方法:

√ 使用ansible-galaxy instal或者编写requirements.yml文件

[root@control ansible]# cat ~/ansible/roles/requirements.yml

#格式一:直接从Ansible Galaxy官网下载

- src: acandid.apache2

#格式二:从某个git服务器下载- src: http://gitlab.com/xxx/xxx.git scm: git

- src: http://gitlab.com/xxx/xxx.git
  scm: git 
  version:56e00a54
  name: nginx-acme

#格式三:下载tar包,支持http、https、file

- src:http://example.com/myrole.tar
  name: myrole

[root@control ansible]# ansible-galaxy install-r roles/requirements.yml-p roles

你可能感兴趣的:(ansible,运维)