2025-03-15    2025-03-15    4991 字  10 分钟

一、Ansible 是如何运作的?

一台机器充当主控端(Control Machine),其他机器充当被控节点(node Machine)。

二、如何安装Ansible?

一般我们在主控节点安装Ansiable即可。被管理节点(Ansible 管理的机器)不需要安装 Ansible,但需要 Python 来运行 Ansible 生成的 Python 代码。 主控节点及被控节点系统环境:ubuntu22.04 (预装Python 3.10.12)

ansible-core与python版本对照表: https://docs.ansible.org.cn/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix

本次试验版本:Ansible 2.17.9、所有节点提前安装Python 3.10.12(编译安装见Python)

三、主控端安装Ansiable

主控端使用ubuntu22.04 jammy 版本

1
2
3
4
5
UBUNTU_CODENAME=jammy
wget -O- "https://keyserver.ubuntu.com/pks/lookup?fingerprint=on&op=get&search=0x6125E2A8C77F2818FB7BD15B93C4A3FD7BB9C367" | sudo gpg --dearmour -o /usr/share/keyrings/ansible-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/ansible-archive-keyring.gpg] https://launchpad.proxy.ustclug.org/ansible/ansible/ubuntu $UBUNTU_CODENAME main" | sudo tee /etc/apt/sources.list.d/ansible.list

sudo apt update && sudo apt install ansible

四、定义主机清单

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# ssh-key(可选,免密码)	
	ssh-keygen
	ssh-copy-id	IP地址	# 推送公钥

# 我们现在ansible控制机上主机名解析 
tail /etc/hosts 
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 
192.168.200.5 master
192.168.200.2 node1

vim  /etc/ansible/hosts  
[webserver]			# 增加主机组
node1

# 因为考虑到安全问题,会有主机秘钥的检查,但如果在内网非常信任的服务器就没必要了. 
sed -i 's/# *StrictHostKeyChecking *ask/StrictHostKeyChecking no/g' /etc/ssh/ssh_config
去掉(yes/no)的询问

# systemctl restart sshd

[root@master ~]# ansible webserver -m ping  -o	# 并不是真的ping,只是检查客户端的22号端口是否在提供工作. 
# -o 简介输出 
# -k 输入密码
# -m 指定模块
SSH password: 
node1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3.10"},"changed": false,"ping": "pong","warnings": ["Platform linux on host node1 is using the discovered Python interpreter at /usr/bin/python3.10, but future installation of another Python interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information."]}

# 增加用户名 密码
vim /etc/ansible/hosts
[webserver]
node1  ansible_ssh_user='root' ansible_ssh_pass='flying' # 此处可以加上ansible本机,也可以不加
master ansible_ssh_user='root' ansible_ssh_pass='flying'
node2  ansible_user='root' ansible_ssh_pass='flying'
# 此处如果有node3,node4可以这样写
# node[2:5] ansible_ssh_user='root' ansible_ssh_pass='flying'
# 如果默认端口sshd端口不一样需要修改,需要指定端口
# node2 ansible_ssh_user='root' ansible_ssh_pass='flying' ansible_ssh_port='2222'

root@master:~# ansible webserver -m ping  -o
node1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3.10"},"changed": false,"ping": "pong","warnings": ["Platform linux on host node1 is using the discovered Python interpreter at /usr/bin/python3.10, but future installation of another Python interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information."]}

# 免密成功

# 自定义主机列表
vim /opt/hosts
[webserver]
node1
[webserver:vars]
ansible_ssh_user='root'
ansible_ssh_pass='flying'

[root@node1 ~]# ansible -i /opt/hostlist webserver -m ping -o
node2 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
master | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}

Ansible模块(Ad-Hoc)

1
ad hoc 临时的点对点模式,在ansible中只需要快速执行一条简单的命令,不需要保存起来,对于负载的命令则为playbook剧本,剧本就是ad hoc 的集合。

Shell模块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# shell模块
# 执行远程命令 
# 获取主机名
root@master:~# ansible webserver -m shell -a 'hostname' -o -f 3
node1 | CHANGED | rc=0 | (stdout) node1
# -f  指定线程数,默认为5

# 查询系统负载
root@master:~# ansible webserver -m shell -a "uptime" -o
node1 | CHANGED | rc=0 | (stdout)  15:22:21 up 29 min,  2 users,  load average: 0.05, 0.01, 0.00
# -a  单条指令
root@master:~# ansible webserver -m shell -a 'date' -o
node1 | CHANGED | rc=0 | (stdout) 2025年 03月 13日 星期四 15:22:41 CST

root@master:~# ansible-doc -l
# A10、华为、docker、EC2、aws等等广大厂商设备都可以使用ansible配置

Yum模块(centos7中有,ubuntu中用apt模块。)

1
2
3
4
5
6
# yum模块 
# ansible-doc yum 
[root@node1 ~]# ansible webserver -m yum -a 'name=httpd state=latest' 
[root@node1 ~]# ansible webserver -m shell -a 'yum -y install httpd' 
[root@node1 ~]# ansible webserver -m yum -a 'name=git state=latest' 软件包管理 
[root@node1 ~]# ansible webserver -m yum -a 'name='*' state=latest'

Apt 模块

1
2
3
# apt模块 
# ansible-doc apt
root@master:~# ansible all -m apt -a 'name=apache2 state=latest' 

Copy 模块

1
2
3
4
5
# copy模块
# 帮助  ansible-doc copy
root@master:~# ansible all -m copy -a 'src=/root/index.html dest=/tmp/index.html owner=root group=bin mode=777'

root@master:~# ansible all -m copy -a 'src=/root/index.html dest=/tmp/index.html owner=root group=bin mode=777 backup=yes'

用户模块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 用户模块
# 帮助  ansible-doc user
root@master:~# ansible webserver -m user -a 'name=you-men state=present'		# 创建用户

root@master:~# ansible all -m shell -a 'id you-men' -o
node1 | CHANGED | rc=0 | (stdout) uid=1001(you-men) gid=1001(you-men) groups=1001(you-men)

root@master:~#  ansible webserver -m user -a 'name=you-men state=absent'		# 删除用户

root@master:~# echo 'flying' |openssl passwd -1 -stdin
$1$qMNVI9Ce$wrrPlN3Zge1riXZxX4d9x1
root@master:~# ansible webserver -m user -a 'name=you-men password="$1$qMNVI9Ce$wrrPlN3Zge1riXZxX4d9x1"'
# 修改密码

root@master:~# ssh [email protected]
Warning: Permanently added '192.168.200.6' (ED25519) to the list of known hosts.
[email protected]'s password: 
[you-men@master ~]$ 
-----------------------------------------------------------

root@master:~# ansible webserver -m user -a 'name=you-men shell=/sbin/nologin append=yes'	# 修改shell
root@master:~# ssh [email protected]
[email protected]'s password: 


This account is currently not available.
Connection to 192.168.200.6 closed.
# 只需要将shell修改为/bin/bash即可恢复正常用户

服务模块

1
2
3
4
5
6
7
8
9
# 帮助  ansible-doc service
root@master:~# ansible webserver -m service -a 'name=nginx state=started enabled=yes'		# 启动服务并设置开机自启动
root@master:~# ansible webserver -m shell -a 'curl -I http://localhost:80'

root@master:~# ansible webserver -m service -a 'name=nginx state=stopped'		# 停止服务

root@master:~# ansible webserver -m service -a 'name=nginx state=restarted' 	# 重启服务

root@master:~# ansible webserver -m service -a 'name=nginx state=started enabled=no'	# 开机不启动

文件模块

1
2
3
4
5
# 帮助 ansible-doc file 
root@master:~# ansible webserver -m file -a 'path=/tmp/88.txt mode=777 state=touch' # 创建文件 
root@master:~# ansible webserver -m file -a 'path=/tmp/99.txt mode=777 state=directory' # 创建目录 
root@master:~# ansible webserver -m shell -a 'ls -l /tmp/88.txt' -o
node1 | CHANGED | rc=0 | (stdout) -rwxrwxrwx 1 root root 0  3月 13 16:19 /tmp/88.txt

解压模块

1
2
3
4
5
6
7
8
root@master:~# ansible all -m get_url -a "url=http://nginx.org/download/nginx-1.17.4.tar.gz dest=/root mode=0440 force=yes"
# 下载文件到指定目录

root@master:~# ansible all -m unarchive -a "src=/root/nginx-1.17.4.tar.gz dest=/tmp mode=0755 copy=yes"
# 解压ansible管理机上的压缩文件到远程主机

root@master:~# ansible all -m unarchive -a "src=/root/nginx-1.17.4.tar.gz dest=/root mode=0755 copy=no"
# 解压远程主机上的文件到目录

收集模块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 帮助  ansible-doc setup
root@master:~# ansible webserver -m setup 	# 查询所有信息

root@master:~# ansible webserver -m setup -a 'filter=ansible_all_ipv4_addresses' -o 
node1 | SUCCESS => {"ansible_facts": {"ansible_all_ipv4_addresses": ["10.0.2.15","192.168.200.6"],"discovered_interpreter_python": "/usr/bin/python3.10"},"changed": false,"warnings": ["Platform linux on host node1 is using the discovered Python interpreter at /usr/bin/python3.10, but future installation of another Python interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information."]}



root@master:~# ansible webserver -m setup -a 'filter=ansible_processor_cores' -o		# 收集cpu数量,可以设置nginx启动的线程数
node1 | SUCCESS => {"ansible_facts": {"ansible_processor_cores": 2,"discovered_interpreter_python": "/usr/bin/python3.10"},"changed": false,"warnings": ["Platform linux on host node1 is using the discovered Python interpreter at /usr/bin/python3.10, but future installation of another Python interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information."]}

Playbook

1
2
3
4
5
# 语法的注意事项
# yaml语言使用空格进行分割,不可以使用tab键,否则会报错
# yaml语言通常是---开始的,也可以不写

# playbook是由一个或多个'play'组成的列表,play的主要功能在于将事先归并于一组的主机装扮成事先通过ansible中的task定义好的角色,从根本上来讲,所谓task无非是调用ansible的一个module,将多个play组织在一个playbook中,即可以让他们联合起来按实现编排的机制完成某一个任务.

apache Demo(centos7)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# 清除环境
[root@node1 ~]# ansible all -m yum -a 'name=httpd state=absent'

# 编写apache安装启动修改配置文件全套动作的剧本
[root@node1 ~]# mkdir /apache
[root@node1 ~]# cd /apache
[root@node1 apache]# cp /etc/httpd/conf/httpd.conf .
[root@node1 apache]# grep '^Listen' httpd.conf
Listen 8080


[root@node1 apache]# cat apache.yaml   # 名字自定义
---
- hosts: webserver
  tasks:								 #  这个任务是主机,不能加-,是隶属关系
  - name: Install Apache Package		 #  自定义task下面一个任务的名字
    yum: name=httpd state=present

  - name: Copy Apache Conf
    copy: src=/apache/httpd.conf  dest=/etc/httpd/conf/conf/httpd.conf

  - name: ensure apache is running
    service: name=httpd state=started enabled=yes

[root@node1 apache]# ansible-playbook apache.yaml --syntax-check
										  # 检查是否有语法错误
playbook: apache.yaml
[root@node1 apache]# echo $?
0

# 列出任务列表
[root@node1 apache]# ansible-playbook apache.yaml --list-task
playbook: apache.yaml
  play #1 (webserver): webserver	TAGS: []
    tasks:
      Install Apache Package	TAGS: []
      Copy Apache Conf	TAGS: []
      ensure apache is running	TAGS: []

[root@node1 apache]# ansible-playbook apache.yaml --list-hosts
playbook: apache.yaml		#  列出执行任务的主机列表
  play #1 (webserver): webserver	TAGS: []
    pattern: [u'webserver']
    hosts (3):
      node1
      node2
      master

[root@node1 apache]# cat apache.yaml 
---
- hosts: webserver
  tasks:
  - name: Install Apache Package
    yum: name=httpd state=present

  - name: Copy Apache Conf
    copy: src=/apache/httpd.conf  dest=/etc/httpd/conf/httpd.conf

  - name: ensure apache is running
    service: name=httpd state=started enabled=yes

  handlers:	# 当配置文件发生更改之后,处理器需要被触发从而产生一个事件,重新加载进程,handlers和tasks是并列关系.
  - name: Restart Apache Service
    service: name=httpd state=restarted

# 如果服务原来就是启动的,那个修改配置文件之后的再次启动是不生效的,所以需要有一个触发器,一旦修改了配置文件,那个就触发重启服务的操作:

[root@node1 apache]# ansible-playbook apache.yaml 
		#  执行时会先搜集任务信息
PLAY [webserver] ***************************************************************************

TASK [Gathering Facts] *********************************************************************
ok: [node1]
ok: [node2]
ok: [master]

TASK [Install Apache Package] **************************************************************
ok: [node1]
changed: [node2]
changed: [master]

TASK [Copy Apache Conf] ********************************************************************
fatal: [node1]: FAILED! => {"changed": false, "checksum": "1fb15fc07df5cace0db41401584e59bcb72ecc04", "msg": "Destination directory /etc/httpd/conf/conf does not exist"}
fatal: [node2]: FAILED! => {"changed": false, "checksum": "1fb15fc07df5cace0db41401584e59bcb72ecc04", "msg": "Destination directory /etc/httpd/conf/conf does not exist"}
fatal: [master]: FAILED! => {"changed": false, "checksum": "1fb15fc07df5cace0db41401584e59bcb72ecc04", "msg": "Destination directory /etc/httpd/conf/conf does not exist"}

PLAY RECAP *********************************************************************************
master                     : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
node1                      : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
node2                      : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   


[root@node1 apache]# ansible webserver -m shell -a 'ss -antp |grep :8080'

Apache2 Demo(ubuntu22.04)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
root@master:/tmp/apache# pwd 
/tmp/apache
root@master:/tmp/apache# tree .
.
├── apache2.yaml
├── index.html
└── vhost.tpl

0 directories, 3 files

# index.html 自定义主页,vhost.tpl 自定义模板。
# apache2.yaml 定义剧本。
root@master:/tmp/apache# cat apache2.yaml 
---
- hosts: webserver
  become: true
  vars:
    doc_root: /var/www/example
  tasks:
    - name: Update apt
      apt:
        update_cache: yes
    - name: Install Apache Package
      apt:
        name: apache2
        state: present
    - name: Create custom document root
      file:
        path: "{{ doc_root }}"
        state: directory
        owner: www-data
        group: www-data
    - name: Set up HTML file
      copy:
        src: index.html
        dest: "{{ doc_root }}/index.html"
        owner: www-data
        group: www-data
        mode: 0644
    - name: Set up Apache virtual host file
      template:
        src: vhost.tpl
        dest: /etc/apache2/sites-available/000-default.conf
      notify: restart apache   # 通过notify触发
    - name: Ensure apache is running
      service:
        name: apache2
        state: started
        enabled: yes
  handlers:
    - name: restart apache
      service: 
        name: apache2
        state: restarted   

#hosts: all
#Playbook 开始时指定应该应用于清单中的所有主机(hosts: all)。也可以将 Playbook 的执行限制为特定主机或主机组。这个选项可以在执行时被覆盖。
#become: true
#become: true 部分告诉 Ansible 在执行此 Playbook 中的所有任务时使用特权升级(sudo)。这个选项可以在任务级别上被覆盖。
#vars
#定义一个变量 doc_root,稍后在任务中使用。这个部分可以包含多个变量。
#tasks
#定义实际任务的部分。第一个任务更新 apt 缓存,第二个任务安装 apache2 软件包。
#第三个任务使用内置模块 file 创建一个目录作为我们的文档根目录。这个模块可以用来管理文件和目录。
#第四个任务使用模块 copy 将本地文件复制到远程服务器。我们正在复制一个简单的 HTML 文件,作为由 Apache 托管的网站。
#handlers
#最后,我们有 handlers 部分,声明了服务。我们定义了 restart apache 处理程序,它在第四个任务中被通知,那里应用了 Apache 模板。

Role角色扮演

1
2
# roles实在ansible中,playbooks的目录组织结构。
# 将代码或文件进行模块化,成为roles的文件目录组织结构,易读,代码可重用,层次清晰.

通过role远程部署Nginx

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
root@master:~# mkdir /role
root@master:~# cd /role
root@master:/tmp/role# mkdir nginx/{files,handlers,vars,tasks,templates} -p
root@master:/tmp/role# touch nginx/{tasks,handlers,vars}/main.yaml
root@master:/tmp/role# touch /tmp/role/site.yaml
root@master:/tmp/role# echo welcome to nginx > /tmp/role/nginx/index.html
root@master:/tmp/role# tree .
.
├── nginx
│   ├── files
│   │   └── nginx.repo
│   ├── handlers
│   │   └── main.yaml
│   ├── index.html
│   ├── tasks
│   │   └── main.yaml
│   ├── templates
│   │   └── nginx.conf.j2
│   └── vars
│       └── main.yaml
└── site.yaml

6 directories, 7 files

# 将每一个功能分离出来定义成角色更有条理性
# site.yaml: 是一个习惯性的命名方式,存放在那个主机用那个角色
# vars:	用于存放变量,这个变量是用在整个角色中的,如果没有变量,此目录不需要创建.
# templates: ansible的jinja2模板就是template模板,该模板和copy模板作用基本一样,都是把某个文件复制到远端主机上,但是区别在于template模板可以获取变量的值,而copy则是原封不动的把文件内容复制过去.
# files: 存放一些配置文件,源,包,不需要传参的文件
# handlers: 运行任务后的触发动作
# tasks: 运行任务列表

# ansible机器准备nginx源(ubuntu 系统不需要!!!)
cat /etc/yum.repos.d/nginx.repo 
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

root@master:/tmp/role# cp /etc/yum.repos.d/nginx.repo  /role/nginx/files/

root@master:/tmp/role# yum -y install nginx

root@master:/tmp/role# cp /etc/nginx/nginx.conf /role/nginx/templates/nginx.conf.j2		# j2是一个Jinja模板文件

root@master:/tmp/role# ls
nginx  site.yaml
root@master:/tmp/role# cat site.yaml 
---
- hosts: webserver
  roles:
  - nginx		# 此处的nginx对应/tmp/role/nginx,相当于一个角色,可以再来php,mysql,这样就条理很清晰

# 写tasks角色中的yaml文件
root@master:/tmp/role# cat nginx/tasks/main.yaml 
---
- name: Install Nginx
  apt:
    name: nginx
    state: present
    update_cache: yes

- name: Copy Nginx configuration
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify:
    - Restart Nginx

- name: Copy Nginx configuration
  template:
    src: default.conf.j2
    dest: /etc/nginx/conf.d/default.conf
  notify:
    - Restart Nginx

- name: Copy index.html
  copy:
    src: index.html
    dest: /var/www/html/index.html
- name: ensure nginx running
  service:
    name: nginx
    state: started
    enabled: yes
- debug:
    msg: "Nginx configuration updated and handler notified."



# 写handlers角色中的yaml文件
root@master:/tmp/role# cat nginx/handlers/main.yaml 
---
- name: Restart Nginx
  service: 
    name: nginx 
    state: restarted

# 写vars角色中定义变量
root@master:/tmp/role# cat nginx/vars/main.yaml 
worker_connections: 10240
ports: 80

# 演ansible的剧本
root@master:/tmp/role#  ansible-playbook site.yaml	# 注意路径

# 检测剧本是否成功
root@master:/tmp/role# ansible webserver -m shell -a 'ss -antp |grep nginx' -o
node1 | CHANGED | rc=0 | (stdout) LISTEN 0      511          0.0.0.0:80         0.0.0.0:*     users:(("nginx",pid=14054,fd=6),("nginx",pid=14053,fd=6))



root@master:/tmp/role# ansible webserver -m shell -a 'cat /usr/share/nginx/html/index.html' -o
node1 | CHANGED | rc=0 | (stdout) <!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href="http://nginx.org/">nginx.org</a>.<br/>\nCommercial support is available at\n<a href="http://nginx.com/">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>

# 修改nginx的端口,检查handlers重启nginx的效果.需要重新下发指令。
[root@node1 role]# cat nginx/vars/main.yaml 
worker_connections: 10240
ports: 80

root@master:/tmp/role# ansible webserver -m shell -a 'ss -antp |grep nginx' -o 
node1 | CHANGED | rc=0 | (stdout) LISTEN    0      511          0.0.0.0:80          0.0.0.0:*     users:(("nginx",pid=17025,fd=6),("nginx",pid=17024,fd=6),("nginx",pid=17023,fd=6))

Valut管理敏感资料

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Vault:
# 加密已存在host明文主机清单档案
root@master:~# ansible-vault encrypt /etc/ansible/hosts 
New Vault password: 
Confirm New Vault password: 
Encryption successful
# 建立加密档案
root@master:~# ansible-vault create foo.yml
# 编辑加密档案
root@master:~# ansible-vault edit foo.yml 
Vault password: 

root@master:~# ansible-vault rekey foo.yml 
Vault password: 
New Vault password: 
Confirm New Vault password: 
Rekey successful		# 更换加密金匙

root@master:~# ansible-vault decrypt /etc/ansible/hosts # 解密
# 检视已加密的档案内容
root@master:~# ansible-vault view foo.yml 
Vault password: 
you-men

# 此时哪怕使用root用户访问也是乱码
root@master:~# cat /etc/ansible/hosts |head -5
$ANSIBLE_VAULT;1.1;AES256
34346531613430326665616466346366636138633038333765633731366531306539386331363261
3834613435373234663136323239626438663738313234340a336365666536396565306133373337
37633430393966636665306434316235383138326134393336373966646266316139316363376436
6364323261303464620a346434343630333263303935343134306232386636383938363232656163
# 编辑加密后的主机清单文件
root@master:~# ansible-vault edit /etc/ansible/hosts --ask-vault-pass
Vault password: 

# 使用加密文件运行任务
root@master:~# ansible webserver -i /etc/ansible/hosts -m ping	
# 如果不输入加密密码是无法运行的
# 只有指定密码
root@master:~# ansible -i /etc/ansible/hosts webserver -m ping --ask-vault-pass -o
Vault password: 
node1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3.10"},"changed": false,"ping": "pong","warnings": ["Platform linux on host node1 is using the discovered Python interpreter at /usr/bin/python3.10, but future installation of another Python interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information."]}




手动输入金钥 (密码) 解密
执行 Playbook 并搭配 --ask-vault-pass 参数手动输入密码。
$ ansible-playbook hello_world.yml --ask-vault-pass
或通过 ansible.cfg 启用 ask_vault_pass,其预设值为 false。
设定 ansible.cfg。
$ vi ansible.cfg
[defaults]
ask_vault_pass = true
执行 Playbook。
$ ansible-playbook hello_world.yml

透过金钥 (密码) 档解密
建立密码档:此例用的密码为 bGpvxx。
$ echo 'bGpvxx' > secret.txt
执行 Playbook 并搭配 --vault-password-file 参数指定金钥路径。
$ ansible-playbook hello_world.yml --vault-password-file secret.txt
或于 ansible.cfg 里新增 vault_password_file 参数,并指定金钥路径。
$ vi ansible.cfg
[defaults]
vault_password_file = secret.txt

如何让不同用户登录不同的主机?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 在主机清单里设置
[webservers`]
you-men.com  ansible_port=5000   ansible_user=alice  ansible_pass=123456
flying.com   ansible_port=5001   ansible_user=bob   ansible_pass=654321

# 判断主机地址为192.168.200.6的主机,关闭该主机
- hosts: webserver
  tasks:
  - name: "shut down 192.168.200.6 system"
    command: /usr/sbin/init 0
    when: ansible_all_ipv4_addresses == "49.233.69.195"
# 循环创建多个用户
- hosts: webserver
  tasks:
  - name: add several users
    user: name={{ item }} state=present groups=wheel
    with_items:
       - you-men
       -  you-men