自动化管理前置条件-OpenSSH
1.1 SSH服务概述
1. SSH服务-openssh,远程链接
服务端: openssh-server
客户端: openssh-client
1.2 OpenSSH vs Telnet
对比OpenSSH和Telnet服务 | 共同点 | 区别 |
---|---|---|
OpenSSH | 远程连接 | 连接时候数据加密 |
Telnet | 远程连接 | 连接时候数据未加密(明文) |
1.3 OpenSSH服务端
1)服务器端配置文件详解
配置文件 | ||
---|---|---|
性能优化 | UseDNS no | 是否开启DNS反向解析(ip — 域名),这个选项默认开启,会导致远程连接变慢 |
GSSAPIAuthentication yes | 是否开启GSSAPI认证,默认开启,开启后导致远程链接变慢 | |
安全配置 | Port 22 | 配置ssh服务端 端口号, |
PermitRootLogin yes | 是否准许root远程登陆 | |
ListenAddress 0.0.0.0 | 配置用户只能通过哪个ip访问进来 | |
PasswordAuthentication yes | 是否准许通过密码登录 |
1.4 OpenSSH客户端命令
1)概述
OpenSSH客户端核心命令 | |
---|---|
scp | 远程传输命令 |
ssh | 命令行远程连接工具 |
sftp | ftp工具 |
2)scp
scp -r -P 22 /etc/ 0.0.0.0:/tmp
scp -r 递归传递
scp -P 22 指定端口
3) ssh
ssh -p 22 root@0.0.0.0
ssh -p 22 指定端口
4) sftp
sftp root@0.0.0.0
ftp: 文件传输协议,21端口
sftp命令: 上传: put 下载: get 查看本地目录: lls 查看远程目录: ls
l代表local的意思
1.5 OpenSSH密钥认证
目标: 让linux系统间(1台到其他所有)远程连接时不需要密码连接
1)使用
环境准备 | ||
---|---|---|
master | 批量管理服务,可以连接其他机器,存放密钥对 | |
node1 | 被管理机器 | |
node2 | 被管理机器 |
1. 创建密钥对
[root@master ~]# 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:lhRaAqg5G8GPmPHro/7hUZowq1JqeBqY3mc6XpTMh78 root@master
The key's randomart image is:
+---[RSA 2048]----+
|. .... o |
|o.. + . |
|.Bo . . |
|B...o o. . |
| * . B .S |
|o.* = o. |
|== = . . |
|*o*.+o . |
|B*oB= E |
+----[SHA256]-----+
2. 分发密钥(公钥)
[root@master .ssh]# ssh-copy-id -i id_rsa.pub root@192.168.100.5
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub"
The authenticity of host '192.168.100.5 (192.168.100.5)' can't be established.
ECDSA key fingerprint is SHA256:KNSLW20zHFX1/Ds5+3LbKzjAfZ7cMvVDqAgylyEs78s.
ECDSA key fingerprint is MD5:b9:44:65:fe:a0:9f:74:c1:88:5a:0f:d9:0f:86:ec:e5.
Are you sure you want to continue connecting (yes/no)? 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
root@192.168.100.5's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.100.5'"
and check to make sure that only the key(s) you wanted were added.
3. 测试
[root@master .ssh]# ssh root@192.168.100.5
Last login: Tue Jan 30 21:29:23 2024 from k8s-master
[root@node1 ~]# hostname
node1
1.6 OpenSSH一键创建分发
1. 一键创建密钥对
ssh-keygen -f ~/.ssh/id_rsa -P ''
# -f 指定存放位置 -P 指定密码 ‘’ 代表为空
2. 一键分发密钥
-0 StrictHostKeyChecking=no 分发密钥的时候关闭主机验证功能,临时
sshpass 替我们在ssh命令在需要提供密码的时候使用
sshpss -p密码 ssh-copy-id -i ~/.ssh/id_rsa.pub -0 StrictHostKeyChecking=no root@0.0.0.0
[root@master .ssh]# sshpass ssh root@192.168.100.5 hostname
node1
2)一键化脚本实现
#!/bin/bash
ssh-keygen -f ~/.ssh/id_rsa -P ''
for ip in 5 6
do
sshpass -p123456 ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@192.168.100.$ip
done
if [ $? -eq 0 ];then
for ip in 5 6
do
ssh root@192.168.100.$ip $@
done
else
echo '分发密钥失败'
fi
Ansible 自动化批量管理工具
1. Ansible 的安装
yum -y install ansible
2. Ansible 配置主机清单
[root@master ~]# cat /etc/ansible/hosts
[test]
192.168.100.5
192.168.100.6
3. Ansible第一次测试
ansible test -m ping
# 测试 test主机分组下主机是否能通
[root@master ~]# ansible test -m ping
192.168.100.6 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.100.5 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
4. Ansible配置文件
/etc/ansible/ansible.cfg # ansible的配置文件
/etc/ansible/hosts # ansible的主机清单
5. Ansible主机清单
[root@master ~]# cat /etc/ansible/hosts
[test] #[组的名字]
192.168.100.5
192.168.100.6
[web]
192.168.100.7 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1' # 指定用户密码和端口,未做免密
# 子组:test和web合并成data组
[data:children]
test
web
6.Ansible核心模块
6.1 模块概述
# 命令和脚本模块
command模块 默认的模块,执行简单命令
shell模块 执行命令,支持特殊符号
script模块 分发脚本并执行
file 创建目录,文件,软连接
copy 远程分发文件,修改权限,所有者,备份
6.2 查询帮助
通过命令: ansible-doc -s command
6.3 Ansible-命令与脚本类模块
1)command
ansible all -m command -a '命令'
仅支持简单命令,不支持特殊符号和管道
这个模块是默认模块
2)shell模块
# 与command模块类似,但是其支持特殊符号,执行脚本
3)script模块
传输脚本到被管理端并执行脚本
ansible test -m script -a '/xxx.sh'
6.4 Ansiible-文件与目录类模块
1)file模块
file模块: 管理文件或目录,软链接
选项:
path:路径(目录,文件),必须要写
src:源文件一般用于创建软链接
state: 状态(模式),state=touch 创建文件 state=absent 删除
2)copy模块
远程传输模块
选项:
src: 源路径
dest:目标路径
backup: backup=yes ,则会在覆盖前备份
mode: 修改权限
owner: 修改用户
group: 修改所属组
6.5Ansible-服务管理和系统管理模块
1)systemd
启动、关闭、重启服务
选项:
name: 用于指定服务名称
enabled: 控制服务的开机自启动 =yes、=no
state: 表示服务的开、关、重启, state=started 开启 state=stopped 关闭 state=reloaded 重读配置文件 state= restarted 重启
daemon-reload yes 是否重新加载对应服务的管理配置文件
2)mount模块
fstype: 指定文件系统
src: 源地址
path: 挂载点
state: mounted: 挂载并修改/etc/fstab remounted: 重新挂载 present:仅修改/etc/fstab不挂载 absent: 卸载并修改/etc/fstab unmounted: 卸载不修改/etc/fstab
3)cron模块
定时任务模块
name: 定时任务名字
minute: 分钟
hour: 小时
day: 日期
month: 月份
week: 周几
job: 指定命令或脚本 job= “/sbin/ntpdate ntp1.aliyun.com &> /dev/null "
state: present 添加定时任务 absent 删除
6.6 Ansible-软件包管理模块
yum_repository 管理yum源
yum yum命令
get_url 类似wget
1)yum源配置管理模块
name: yum源中的名字 [epel]
description yum源的注释说明 name='xxxx'
baseurl yum源中的下载地址 baseurl=xxxxxxxx
enabled 是否启用这个源, yes\no enabled=1
gpgcheck 是否启动gpgcheck功能 yes\no gpgcheck=0
file 指定yum源的文件,自动添加 .repo,默认与模块名字一致
2)yum模块
通过yum命令安装软件
name: 指定软件包名称
state: installed : 安装 removed: 删除 latest:安装或更新
3)get_url模块
url: 指定下载的地址
dest: 指定下载到那个目录
validate_certs: no 用于对https连接下载使用
6.7 用户管理模块
group 创建组模块
user 创建用户模块
1)user模块
name: 用户名
uid: 指定uid
group: 指定组
shell: 指定命令解释器
create_home 是否创建家目录 yes\no
state: present 添加 absent 删除
2)group模块
name: 指定组名
gid: 指定组id
state: present 添加 absent 删除
7.Ansible-playbook
7.1 概述
通过编写剧本指定主机执行相关任务操作
ad-hoc ans命令运行对应模块和选项
playbook 通过文件执行,类似于脚本
剧本格式为yaml或yml
剧本中所有内容都要对齐
对齐的时候不能使用 tab键
只能使用空格,2个空格
案例01
---
- hosts: all
tasks:
- name: add cron sync time
cron:
name: "sync time by yzs666 20240219"
minute: "*/2"
job: "/sbin/ntpdate ntp1.aliyun.com &> /dev/null"
state: present
# 执行: ansible-playbook xxx.yml
案例02-批量下载安装zabbix-agent2-6.0客户端并启动
---
- hosts: all
tasks:
- name: touch directory
file:
path: /server/tools
state: directory
- name: dowload zabbix_agent2
get_url:
validate_certs: no
url: https://mirrors.tuna.tsinghua.edu.cn/zabbix/zabbix/6.0/rhel/7/x86_64/zabbix-agent2-6.0.0-1.el7.x86_64.rpm
dest: /server/tools/
- name: install zabbix_agent2
yum:
name: /server/tools/zabbix-agent2-6.0.0-1.el7.x86_64.rpm
state: installed
- name: start zabbix_agent2 service
systemd:
name: zabbix-agent2
enabled: yes
state: started
7.2 剧本命令参数
ansible-playbook
-i 指定主机清单文件
-C 模拟运行剧本文件,看是否有问题
--syntax-check 仅检查剧本格式语法是否有问题
7.3 剧本变量
变量的变量分类
命令行创建 临时使用
变量文件: vars_file 某一个主机使用,较少用
主机组公用变量文件: group_vars 应用范围广泛
ansible内置变量(facts变量) 收集主机的基本信息,ip地址,主机名。。。。
register变量 实现命令行$()或``功能
7.4变量详解
1)在剧本中定义变量,vars_file,group_vars
在剧本中定义变量
---
- hosts: all
vars:
tool_name: nginx
user_name: nginx
tasks:
- name: 安装nginx
yum:
name: {{tool_name}}
state: installed
- name: add user
user:
name: {{user_name}}
state: present
shell: /bin/bash
create_home: yes
把变量存放到一个文件中,剧本比较大的时候
[root@master playbook]# cat 04_bianl.yml
---
- hosts: all
vars_files: ./vars.yml
tasks:
- name: 01.mkdir
file:
path: "{{dir_name}}"
state: directory
- name: 02.touch
file:
path: "{{dir_name}}/{{file_name}}"
state: touch
[root@master playbook]# cat vars.yml
dir_name: /data/
file_name: yzs955.txt
创建一个变量文件,给某个组共用
用法: 在剧本目录下创建一个group_vars目录,目录下创建已主机组命名的目录存放变量问价: vars.yml
group_vars/ 目录
web/vars.yml 存放web组的变量
db/vars.yml 存放db组的变量
data/vars.yml
all/vars.yml 所有主机共用的变量
2)ansible-facts变量
ansible内置变量,执行剧本,有个默认任务(task),收集每个主机的基本信息
# 查看 ansible facts变量内容
ansible -i hosts web -m setup
# 常用fact变量
ansible_hostname: 主机名
ansible_memtotal_mb: 内存大小
ansible_processor_vcpus: cpu数量
ansible_default_ipv4.address: 默认的网卡ip
ansible_distribution: 系统发行的名称
ansible_date_time.date: 当前时间
# 关闭facts用来提速剧本执行速度
gather_facts: no
3) ansible-register变量
实现命令行$()或``功能
register: 变量名
---
- hosts: all
gather_facts: no
tasks:
- name: hostname
shell: hostname
register: hostname
- name: print
debug:
msg: "{{ hostname }}"
# 输出结果
ok: [192.168.100.6] => {
"msg": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"cmd": "hostname",
"delta": "0:00:00.004697",
"end": "2024-02-21 14:02:37.969856",
"failed": false,
"rc": 0, #命令返回值
"start": "2024-02-21 14:02:37.965159",
"stderr": "", # 错误信息
"stderr_lines": [],
"stdout": "node2", # 命令的结果输出
"stdout_lines": [
"node2"
]
}
}
register: 变量名
变量名.stdout # 取出正常输出信息
变量名.rc # 取出返回值
---
- hosts: all
gather_facts: no
tasks:
- name: hostname
shell: hostname
register: hostname
- name: print
debug:
msg: "{{ hostname.stdout }}"
- name: add dir
file:
path: /data/{{hostname.stdout}}
state: directory
8. Ansible-进阶-剧本调试方法
8.1 概述
debug模块
tags 标签
忽略错误
8.2 debug模块
选项:
msg: 相当于echo命令,配合着register使用
8.3 tags标签
一般用于调试剧本,给剧本的每个task设置标签,运行剧本的时候可以运行指定标签,运行剧本的时候排除某些标签
---
- hosts: all
tasks:
- name: touch directory
file:
path: /server/tools
state: directory
tags:
- add_directory
- name: dowload zabbix_agent2
get_url:
validate_certs: no
url: https://mirrors.tuna.tsinghua.edu.cn/zabbix/zabbix/6.0/rhel/7/x86_64/zabbix-agent2-6.0.0-1.el7.x86_64.rpm
dest: /server/tools/
tags:
- dowload
--list-tags
--skip-tags # 跳过某个tags
-t # 运行指定的tags
# 运行指定的标签,多个标签用逗号分隔
[root@master playbook]# ansible-playbook -i hosts 07_tags.yml -t start
PLAY [all] *********************************************************************************************************************************************************************************
TASK [start zabbix_agent2 service] *********************************************************************************************************************************************************
ok: [192.168.100.5]
ok: [192.168.100.6]
PLAY RECAP *********************************************************************************************************************************************************************************
192.168.100.5 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.6 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# 排除某些标签
[root@master playbook]# ansible-playbook -i hosts --skip-tags add_directory,dowload,install 07_tags.yml
PLAY [all] *********************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************
ok: [192.168.100.6]
ok: [192.168.100.5]
TASK [start zabbix_agent2 service] *********************************************************************************************************************************************************
ok: [192.168.100.6]
ok: [192.168.100.5]
PLAY RECAP *********************************************************************************************************************************************************************************
192.168.100.5 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.6 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
8.4 忽略错误
ignore-errors: yes,用于运行剧本时即使某个模块出现错误,也不要中断剧本的运行
---
- hosts: all
tasks:
- name: touch directory
file:
path: /server/tools
state: directory
ignore_errors: yes
tags:
- add_directory
9. Ansible-进阶-进阶应用
include
handler
when判断
循环
9.1 include功能
include 把一个人物分成多个剧本来实现,在总的文件中通过 include_tasks: 引用子剧本文件
子剧本文件只需要写taskb
9.2 handler功能
handler: 触发器(满足条件后即触发)
应用场景: 配置文件发生变化,再去进行其他操作
---
- hosts: all
tasks:
- name: config
copy:
src: ./1.txt
dest: /opt/1.txt
notify: # 埋下钩子
- restart sshd
handlers: # 与tasks平级
- name: restart sshd
systemd:
name: sshd
enabled: yes
state: restarted
9.3 when判断
when是ansible中的条件语句,用来实现对与某个模块满足或不满足条件下的不同操作
---
- hosts: all
tasks:
- name: config
copy:
src: ./1.txt
dest: /opt/1.txt
backup: yes
when: ( ansible_hostname is match("node|client")) # match 类似于sql语句中的 like
9.4 循环
批量启动或者重启服务
---
- hosts: all
gather_facts: no
tasks:
- name: restart service
systemd:
name: "{{item}}" # item 是循环的默认变量,代指with——items下的值
state: restarted
with_items:
- sshd
- network
---
- hosts: all
tasks:
- name: add users
user:
name: "{{item.name}}" # item.name对应{}中的name
uid: "{{item.uid}}"
with_items:
- {name: "yzs",uid: "12306"} # key 对应value的方式做多个变量,name和uid非固定名称
- {name: "yzs01",uid: "12307"}
9.5 Jinja2模板
经常用在配置文件中,让配置文件中包含变量
template模块在传输的时候解析配置文件中的变量(ansible),配置文件格式改为: xxx.j2
# 配置文件要以.j2结尾
# 分发文件的时候使用 template模块
---
- hosts: all
tasks:
- name: hostname
template:
src: ./1.j2
dest: /opt/1.txt
# [root@master playbook]# ansible -i hosts all -a 'cat /opt/1.txt'
# 192.168.100.6 | CHANGED | rc=0 >>
# node2 is me
# 192.168.100.5 | CHANGED | rc=0 >>
# node1 is me
9.6 roles
规范剧本的目录,本质规定几个专用的目录
roles/
top.yml
nfs-server/ # 剧本要部署的服务
files/ # 配置文件存储目录
templates/ # jinja2模板
tasks/main.yml # tasks模块下的内容
handlers/main.yml # 存放触发器
[root@master roles]# tree -F
.
|-- nfs-server/
| |-- files/
| |-- handlers/
| | `-- main.yml
| |-- tasks/
| | `-- main.yml
| `-- templates/
| `-- exports.j2
`-- top.yml
9.7Galaxy
ansible官方的roles集合
ansible-galaxy install geerlingguy.nginx
cd /root/.ansible/roles/
9.8vault
加密文件
# 给文件加密
ansible-vault encrypt hosts
New Vault password:
Confirm New Vault password:
Encryption successful
[root@master playbook]# cat hosts
$ANSIBLE_VAULT;1.1;AES256
65393432613738356465396331353663666131336164376362313765373330396235363730313862
6439323638333961396164666262626462616166346164620a393266386236383436343539356138
37633236323864373961346438386335396665383932633839323936623230336664316135323134
6234343366663134610a613863633737396362626335373630353539363865633930366335346265
31393362653233653333636433313036383438666366396362356337633164383065613664373063
66333231353861393933393733386331653361303237333833346362613630303966393838396537
306631326466353366653564336630636165
# 要使用hosts文件需要加上选项: --ask-vault-pass
[root@master playbook]# ansible --ask-vault-pass -i hosts all -a 'ls /home'
Vault password:
192.168.100.6 | CHANGED | rc=0 >>
192.168.100.5 | CHANGED | rc=0 >>
# 解密
[root@master playbook]# ansible-vault decrypt hosts
Vault password:
Decryption successful
[root@master playbook]# cat hosts
[web]
192.168.100.5
[db]
192.168.100.6
[data:children]
web
db
10. Ansible-进阶-优化
/etc/ansible/ansible.cfg
inventory = /etc/ansible/hosts #指定默认的主机清单
forks = 5 #并发数量,可以增加数量获取更快的批量管理的效率
sudo_user = root #配置下被管理端具有sudo权限的用户
host_key_checking = False #关闭新主机连接时提示的主机验证
log_path = /var/log/ansible.log #ansible的日志,默认没有开启
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s #连接的保持时间
pipelining = False #jia'su