由于网站业务上线,需要运维人员在短时间内完成几百台服务器部署,工作包括:系统安装、系统初始化、软件安装与配置、性能监控等
所以需要利用脚本与第三方工具或自行开发的工具在最少的人工干预下,实现证业务系统快速上线以及7*24小时高效稳定的运行
不通方式的运维要求
各个阶段 | 运维规模(台) | 运维效率 | 技能要求 |
---|---|---|---|
纯手工 | <50 | 低 | 一般 |
脚本与文档 | 50–100 | 一般 | 高 |
运维工具 | 100–500 | 高 | 一般 |
脚本+运维工具 | > 500 | 最高 | 高 |
监控运维(7x24运维值班、故障处理)
应用运维(业务熟悉、服务部署、业务部署、版本管理、灰度发布、应用监控)
安全运维(整体的安全方案、规范、漏洞检测、安全防护等)
系统运维(架构层面的分布式缓存、分布式文件系统、日志收集、环境规划(测试、开发、生产)、架构设计、性能优化)
基础服务运维(包含运维开发)(内部DNS、负载均衡、系统监控、资产管理、运维平台)
基础设施运维(系统初始化、网络维护、负责设备上下架、巡检、报修、硬件监控)
Ansible是一种基于python开发、分布式、无客户端、轻量级、采用YAML配置语言的常用自动运维化工具
Ansible 的名称来自科幻小说《安德的游戏》中跨越时空的即时通信工具,使用它可以在相距数光年的距离,远程实时控制前线的舰队战斗
缺点:对于几千台、上万台机器的操作,还不清楚性能、效率情况如何,需要进一步了解
角色 | 主机名 | IP |
---|---|---|
控制机 | server.example.com | 192.168.48.130 |
被管理节点 | node1.example.com | 192.168.48.131 |
被管理节点 | node2.example.com | 192.168.48.132 |
# server端操作
[root@server ~]# nmcli connection modify ens160 ipv4.addresses 192.168.48.130/24 ipv4.gateway 192.168.48.2 ipv4.dns 114.114.114.114 ipv4.method manual
[root@server ~]# nmcli c reload
[root@server ~]# nmcli c up ens160
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)
# node1端操作
[root@node1 ~]# nmcli connection modify ens160 ipv4.addresses 192.168.48.131/24 ipv4.gateway 192.168.48.2 ipv4.dns 114.114.114.114 ipv4.method manual
[root@node1 ~]# nmcli connection reload
[root@node1 ~]# nmcli connection up ens160
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)
# node2操作
[root@node2 ~]# nmcli connection modify ens160 ipv4.addresses 192.168.48.132/24 ipv4.gateway 192.168.48.2 ipv4.dns 114.114.114.114 ipv4.method manual
[root@node2 ~]# nmcli c reload
[root@node2 ~]# nmcli c up ens160
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)
# server操作
[root@server ~]# hostnamectl set-hostname server.example.com
[root@server ~]# reboot
# node1操作
[root@node1 ~]# hostnamectl set-hostname node1.example.com
[root@node1 ~]# reboot
# node2操作
[root@node2 ~]# hostnamectl set-hostname node2.example.com
[root@node2 ~]# reboot
# server端操作
[root@server ~]# vim /etc/hosts
# 删除原有内容,输入以下内容
127.0.0.1 server.example.com
192.168.48.130 server.example.com
192.168.48.131 node1.example.com
192.168.48.132 node2.example.com
# node1端操作
[root@node1 ~]# vim /etc/hosts
# 删除原有内容,输入以下内容
127.0.0.1 node1.example.com
192.168.48.130 server.example.com
192.168.48.131 node1.example.com
192.168.48.132 node2.example.com
# node2端操作
[root@node2 ~]# vim /etc/hosts
# 删除原有内容,输入以下内容
127.0.0.1 node2.example.com
192.168.48.130 server.example.com
192.168.48.131 node1.example.com
192.168.48.132 node2.example.com
# server端操作
[root@server ~]# ssh-keygen -t rsa # 之后一路回车
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:PJ8WjFa3sQDoMmi9GYUpuAuff79Wt9g64bMolE9yucA [email protected]
The key's randomart image is:
+---[RSA 3072]----+
| . o .. |
|. . o o . |
| . + o o o |
|o o = .. + o + |
|.+ . B .S.o o |
|. o o E.+ooo. |
| . . * ++= . |
| . o +o= o |
| . ++.o= |
+----[SHA256]-----+
[root@server ~]# ssh-copy-id node1.example.com # server端向node1分发密钥
The authenticity of host 'node1.example.com (192.168.48.131)' can't be established.
ED25519 key fingerprint is SHA256:K7nvJFkfIh+p9YytEGR44wLbTfpB0Y52oVou0UdG6nc.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes # 输入yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: # 输入登录密码123456
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'node1.example.com'"
and check to make sure that only the key(s) you wanted were added.
[root@server ~]# ssh-copy-id node2.example.com # 向node2分发密钥,过程同上
# 测试
[root@server ~]# ssh node1.example.com # server端远程登录到node1端
Activate the web console with: systemctl enable --now cockpit.socket
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Sat May 13 15:48:01 2023
[root@node1 ~]# exit # 已成功,注销
注销
Connection to node1.example.com closed.
[root@server ~]# ssh node2.example.com # # server端远程登录到node2端
Activate the web console with: systemctl enable --now cockpit.socket
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Sat May 13 15:48:12 2023
[root@node2 ~]# exit # 已成功,注销后回到server端
注销
Connection to node2.example.com closed.
[root@server ~]#
[root@server ~]# setenforce 0
[root@server ~]# systemctl stop firewalld
……
[root@server ~]# yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
[root@server yum.repos.d]# yum makecache
[root@server ~]# yum list | grep ansible # 查看可以安装的软件包名及版本号
[root@server ~]# yum install ansible.noarch # 安装ansible
[root@server ~]# ansible --version # 通过查看版本检索安装是否成功
[root@server ~]# vim /etc/ansible/hosts # 设置管理机的主机清单,输入受空机
node1.example.com
node2.example.com
[root@server ~]# ansible all -m ping # 测试受控机是否能管理
# 设置本地yum源
[root@server ~]# mount /dev/sr0 /media/ # 挂载光盘
mount: /media: WARNING: source write-protected, mounted read-only.
[root@server ~]# cd /etc/yum.repos.d/ # 进入yum配置目录
[root@server yum.repos.d]# ls
CentOS-9-Stream.repo
[root@server yum.repos.d]# mv CentOS-9-Stream.repo CentOS-9-Stream.repo.back # 将已存在的yum配置文件备份并改扩展名,使其失效,该步骤可选
[root@server yum.repos.d]# vim dvd.repo # 编写本地yum配置文件,输入以下内容:
[baseos]
name=from dvd
baseurl=file:///media/BaseOS
enabled=1
gpgcheck=0
[appstream]
name=from dvd
baseurl=file:///media/AppStream
enabled=1
gpgcheck=0
[root@server yum.repos.d]# yum clean all # 清除缓存
13 文件已删除
[root@server yum.repos.d]# yum makecache # 新建缓存
[root@server yum.repos.d]# yum list | grep ansible # 查看安装包
[root@server yum.repos.d]# yum install ansible-core.x86_64 -y
[root@server yum.repos.d]# ansible --version # 测试
静态主机清单可以通过文本文件定义
动态主机清单可以根据需要通过脚本或其他程序生成
[root@server ~]# vim /etc/ansible/hosts
node1.example.com
node2.example.com
[root@server ~]# ansible all --list-hosts
hosts (2):
node1.example.com
node2.example.com
[root@server ~]# ansible all -m ping
node2.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
node1.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
[组名]
一行一个ip地址或主机名
[root@server ~]# vim /etc/ansible/hosts
[dev]
node1.example.com
[test]
node2.example.com
[root@server ~]# ansible-inventory --graph
@all:
|--@ungrouped: # 未分组的主机,当前无
|--@dev:
| |--node1.example.com
|--@test:
| |--node2.example.com
[root@server ~]# ansible ungrouped --list-hosts # 查看未分组的主机信息
[WARNING]: No hosts matched, nothing to do # 当前无未分组
hosts (0):
[root@server ~]# ansible dev -m ping # dev为组名
node1.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
[root@server ~]# ansible test -m ping
node2.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
[root@server ~]# vim /etc/ansible/hosts
192.168.48.[130:135]
[root@server ~]# ansible all --list-hosts # 查看
hosts (6):
192.168.48.130
192.168.48.131
192.168.48.132
192.168.48.133
192.168.48.134
192.168.48.135
# 分组
[root@server ~]# vim /etc/ansible/hosts
192.168.48.141
192.168.48.142
[dev]
192.168.48.[130:132]
[test]
192.168.48.[133:135]
[prod]
192.168.48.[135:140]
[root@server ~]# ansible-inventory --graph # 分组查看
@all:
|--@ungrouped: # 未分组
| |--192.168.48.141
| |--192.168.48.142
|--@dev: # dev组
| |--192.168.48.130
| |--192.168.48.131
| |--192.168.48.132
|--@test: # test组
| |--192.168.48.133
| |--192.168.48.134
| |--192.168.48.135
|--@prod: # prod组
| |--192.168.48.135
| |--192.168.48.136
| |--192.168.48.137
| |--192.168.48.138
| |--192.168.48.139
| |--192.168.48.140
[子组1]
主机列表
[子组2]
主机列表
[子组3]
主机列表
[父组:children] # children关键字表示父组包含子组1字组2
[子组1名]
[子组2名]
……
[Dev_A]
192.168.48.[130:133]
[Dev_B]
192.168.48.[134:136]
[Dev:children]
Dev_A
Dev_B
[Test]
192.168.48.[137:139]
[Prod]
192.168.48.[140:144]
[Openlab:children]
Test
Prod
[root@server ~]# ansible-inventory --graph
@all:
|--@ungrouped:
|--@Dev:
| |--@Dev_A:
| | |--192.168.48.130
| | |--192.168.48.131
| | |--192.168.48.132
| | |--192.168.48.133
| |--@Dev_B:
| | |--192.168.48.134
| | |--192.168.48.135
| | |--192.168.48.136
|--@Openlab:
| |--@Test:
| | |--192.168.48.137
| | |--192.168.48.138
| | |--192.168.48.139
| |--@Prod:
| | |--192.168.48.140
| | |--192.168.48.141
| | |--192.168.48.142
| | |--192.168.48.143
| | |--192.168.48.144
[root@server ~]# vim /root/inv
[web]
node1.example.com
node2.example.com
# 格式:
ansible all -i 自定义主机清单名 --list-hosts
[root@server ~]# ansible all -i /root/inv --list-hosts
hosts (2):
node1.example.com
node2.example.com
[root@server ~]# vim /etc/ansible/hosts
192.168.48.254
[web]
192.168.48.[130:133]
[http]
192.168.48.[134:135]
[ftp]
192.168.48.[136:139]
[dns]
192.168.48.[140:145]
[mail]
192.168.48.[143:146]
[root@server ~]# ansible all --list-hosts
[root@server ~]# ansible 'dns' --list-hosts
hosts (6):
192.168.48.140
192.168.48.141
192.168.48.142
192.168.48.143
192.168.48.144
192.168.48.145
[root@server ~]# ansible 'mail' --list-hosts
hosts (4):
192.168.48.143
192.168.48.144
192.168.48.145
192.168.48.146
[root@server ~]# ansible 'dns:&mail' --list-hosts # & 表示交集
hosts (3):
192.168.48.143
192.168.48.144
192.168.48.145
[root@server ~]# ansible 'dns:!mail' --list-hosts # !表示补集,即属于A组但不属于B组
[root@server ~]# ansible '!dns:mail' --list-hosts # 不属于A组但属于B组
hosts (1):
192.168.48.146
[root@server ~]# ansible 'ftp:mail' --list-hosts # 并集
hosts (8):
192.168.48.136
192.168.48.137
192.168.48.138
192.168.48.139
192.168.48.143
192.168.48.144
192.168.48.145
192.168.48.146
[root@server ~]# ansible 'web:ftp:mail' --list-hosts
Ansible提供两种方式去完成任务,一是ad-hoc命令,一是写Ansible playbook(剧本)
Ad-hoc命令:即交互式临时命令,是一种单条命令,命令不需要特别保存下来,执行后即结束,可以用于执行简单的临时命令,相当于shell命令
Ansible playbook:更适合解决复杂或需固化下来的任务,相当于Linux系统的Shell Scripts
ansible 主机或组 -m 模块名 -a '模块参数' -i 清单文件
-k 手动输入SSH协议密码
-i 指定主机清单文件
-m 指定要使用的模块名
-M 指定要使用的模块路径
-S 使用su命令
-T 设置SSH协议连接超时时间
-a 设置传递给模块的参数
--version 查看版本信息
-h 帮助信息
有1000+,需要使用帮助文档来查询、记忆、理解
ansible-doc 模块名称
ansible-doc ping # 示例
ansible-doc -l
# 创建主机清单
[root@server ~]# vim /etc/ansible/hosts
node1.example.com
node2.example.com
[root@server ~]# ansible all -m ping
[root@server ~]# ansible all -m yum -a "name=httpd state=installed"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: apr-util-bdb-1.6.1-20.el9.x86_64",
"Installed: httpd-filesystem-2.4.53-11.el9.noarch",
"Installed: apr-util-openssl-1.6.1-20.el9.x86_64",
"Installed: httpd-core-2.4.53-11.el9.x86_64",
"Installed: httpd-tools-2.4.53-11.el9.x86_64",
"Installed: mod_http2-1.15.19-4.el9.x86_64",
"Installed: centos-logos-httpd-90.4-1.el9.noarch",
"Installed: httpd-2.4.53-11.el9.x86_64",
"Installed: apr-1.7.0-11.el9.x86_64",
"Installed: mod_lua-2.4.53-11.el9.x86_64",
"Installed: apr-util-1.6.1-20.el9.x86_64"
]
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: apr-util-bdb-1.6.1-20.el9.x86_64",
"Installed: httpd-filesystem-2.4.53-11.el9.noarch",
"Installed: apr-util-openssl-1.6.1-20.el9.x86_64",
"Installed: httpd-core-2.4.53-11.el9.x86_64",
"Installed: httpd-tools-2.4.53-11.el9.x86_64",
"Installed: mod_http2-1.15.19-4.el9.x86_64",
"Installed: centos-logos-httpd-90.4-1.el9.noarch",
"Installed: httpd-2.4.53-11.el9.x86_64",
"Installed: apr-1.7.0-11.el9.x86_64",
"Installed: mod_lua-2.4.53-11.el9.x86_64",
"Installed: apr-util-1.6.1-20.el9.x86_64"
]
}
[root@server ~]# ansible all -a 'df -h'
[root@server ~]# ansible all -a 'date'