Linux之Ansible自动化运维(一) - 教程

一、Ansible 工具的概念和实战

1.Ansible软件概念

Ansible是一款开源、免费的自动化工具软件,主要用于批量管理Unix、Linux服务器,具体对服务器操作:执行命令、修改配置文件、性能调优、系统上线和下线、任务计划的管理等

2.Ansible软件特点

  • 基于Python语言去开发的,简洁,高效率
  • 无需在客户端机器部署Agent机器
  • 通过SSH协议远程登录客户端对其管理
  • 批量执行的指令可以写成Playbook剧本(类似SHELL脚本)
  • 可以支持二次开发,能够跟自动化运维平台整合
  • 可以使用普通用户去管理客户端,支持sudo提权

3.Ansible工作原理

  • 通过Ansible自动化运维工具管理客户端,需提前将客户端主机名或IP地址写入本地/etc/ansible/hosts主机清单文件中,没有被写入的客户端是不能被管理的
  • 批量执行的指令或任务可以写成Playbook剧本(类似shell脚本),剧本文件无需拷贝至客户端上,在ansible管理端主动推送剧本中的命令让客户端机器去运行
  • Ansible是基于SSH协议去远程连接客户端(客户端一定开启SShd服务)并且管理端会调用自带的模块或者第三方插件管理,不同模块实现的功能需求各不相同

二、Ansible自动化工具实战

  • 配置文件修改

基于OpenEuler22.x操作系统部署一套Ansible软件gongju7,采用Yum、RPM方式安装,部署方法 和指令如下

提前将客户端的IP地址或主机名写入到ansible管理端/etc/ansible/hosts主机清单文件中(可以创建分组)

for i in $(seq 128 130);do echo 192.168.101.$i ;done >> /etc/ansible/hosts

基于ansible工具去管理客户端需要调用各自的模块去操作,常见模块:command命令、shell(linux指令,shell命令)、copy(拷贝文件或目录)、file(创建文件)、user(管理用户和组)、cron(任务计划)、yum(安装、卸载软件)、script(脚本管理)、setup(获取系统信息)

使用客户端192.168.101.6作为客户端,让客户端执行"df -h"命令去查看磁盘的使用情况,具体命令如下:

  • 公私钥免密登录

默认通过ansible管理客户端需要输入用户名、密码,下面是对免秘钥登录操作

## 在ansible机器使用ssh-keygen
ssh-keygen
##查看秘钥对文件
ls -l
## 拷贝公钥文件
ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.101.6
## 在客户端查看公钥文件内容
cat /root/.ssh/authorized_keys

公钥情况都一致

设置免密钥之后再次执行客户端192.168.101.6命令“”df -h”(不使用-k选项密码登录)

  • ansible基础使用

-i选项和-m选项(默认都有)可省略不写

并发执行查看三台机器磁盘情况命令

ansible all -a "df -h" -f 100(每隔100台机器并行一次)

在ansible配置文件设置如下配置即可忽略警告

ansible_python_interpreter = /usr/bin/python3
interpreter_python = /usr/bin/python3

# 串行执行

for i in $(seq 5 7);do echo -e "\033[31m192.168.$i | CHANGED | rc=0 ##\033[0m" ;ssh -l root 192.168.101.$i "df -h" ;done

  • ansible模块化使用

  • shell模块

shell模块使用正则查看进程情况

ansible all -m shell -a "ps -ef | grep -aiE sshd"

  • 通过shell模块使用yum 
ansible all -m shell -a "yum -y install ntpdate"

  • yum 模块

## 安装yum模块
ansible 192.168.101.5 -m yum -a "name=screen,lrzsz,ntpdate state=install"
### 安装httpd工具
ansible 192.168.101.6 -m yum -a "name=httpd state=latest"

  • ping模块

192.168.101.5 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.101.6 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.101.7 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.101.7 port 22: No route to host",
"unreachable": true
}
  • user模块

## 创建user用户
[root@localhost ~]# ansible deepseek -m user -a "name=jfedu state=present home=/home/jfedu shell=/sbin/nologin"
192.168.101.6 | CHANGED => {
"changed": true,
"comment": "",
"create_home": true,
"group": 1000,
"home": "/home/jfedu",
"name": "jfedu",
"shell": "/sbin/nologin",
"state": "present",
"system": false,
"uid": 1000
}
192.168.101.7 | CHANGED => {
"changed": true,
"comment": "",
"create_home": true,
"group": 1000,
"home": "/home/jfedu",
"name": "jfedu",
"shell": "/sbin/nologin",
"state": "present",
"system": false,
"uid": 1000
}
n/nologin"

  • copy模块

不检测ssh远程连接秘钥

参数目录

使用copy模块,拷贝文件内容

[root@localhost ~]# ansible deepseek -m copy -a "content='good evening' dest=/usr/share/nginx/html/index.html"
192.168.101.7 | CHANGED => {
"changed": true,
"checksum": "d09bfa96b41c338eed41ea3ee2e5218340dfb313",
"dest": "/usr/share/nginx/html/index.html",
"gid": 0,
"group": "root",
"md5sum": "0fa14c6f02392c5bcaaaa979552de664",
"mode": "0644",
"owner": "root",
"size": 12,
"src": "/root/.ansible/tmp/ansible-tmp-1755692096.9817061-4999-90484632827178/source",
"state": "file",
"uid": 0
}
192.168.101.6 | CHANGED => {
"changed": true,
"checksum": "d09bfa96b41c338eed41ea3ee2e5218340dfb313",
"dest": "/usr/share/nginx/html/index.html",
"gid": 0,
"group": "root",
"md5sum": "0fa14c6f02392c5bcaaaa979552de664",
"mode": "0644",
"owner": "root",
"size": 12,
"src": "/root/.ansible/tmp/ansible-tmp-1755692096.95608-4997-183015220025852/source",
"state": "file",
"uid": 0
}
[root@localhost ~]# ansible deepseek -m shell -a "cat /usr/share/nginx/html/index.html"
192.168.101.7 | CHANGED | rc=0 >>
good evening
192.168.101.6 | CHANGED | rc=0 >>
good evening
## 使用backup选项对原文件进行备份
[root@localhost ~]# ansible deepseek -m copy -a "content='hallo' dest=/usr/share/nginx/html/index.html backup=yes "
  • cron模块

常见参数:

ame                                       任务计划名称;
cron_file                                    替换客户端该用户的任务计划的文件;
minute                                    分( 0-59 ,* ,*/2 );
hour                                      时( 0-23 ,* ,*/2 );
day                                       日( 1-31 ,* ,*/2 );
month                                    月( 1-12 ,* ,*/2 );
weekday                                  周( 0-6 或 1-7 ,* );
job                                       任何计划执行的命令,state要等于present;
backup                                    是否备份之前的任务计划;
user                                       新建任务计划的用户;
state                                       指定任务计划present、absent。

自定义实现ntp实现时间同步

## 添加定时任务
[root@localhost ~]# ansible all -m cron -a "minute=0 hour=0 day=* month=* weekday=* name='Ntpdate server for sync time' job='pool.ntp.org'"
192.168.101.5 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"Ntpdate server for sync time"
]
}
192.168.101.7 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"Ntpdate server for sync time"
]
}
192.168.101.6 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"Ntpdate server for sync time"
]
}
[root@localhost ~]# cat /var/spool/cron/root
#Ansible: Ntpdate server for sync time
0 0 * * * pool.ntp.org
## 删除定时任务
[root@localhost ~]# ansible all -m cron -a "minute=0 hour=0 day=* month=* weekday=* name='Ntpdate server for sync time' state=absent job='pool.ntp.org'"
192.168.101.5 | CHANGED => {
"changed": true,
"envs": [],
"jobs": []
}
192.168.101.7 | CHANGED => {
"changed": true,
"envs": [],
"jobs": []
}
192.168.101.6 | CHANGED => {
"changed": true,
"envs": [],
"jobs": []
}
[root@localhost ~]# cat /var/spool/cron/root
[root@localhost ~]#

  • synchronize模块

常见参数模块内容

compress                           开启压缩,默认为开启;
archive                                是否采用归档模式同步,保证源和目标文件属性一致;
checksum                          是否效验;
dirs                                   以非递归的方式传输目录;
links                                  同步链接文件;
recursive                               是否递归yes/no;
rsync_opts                             使用rsync 的参数;
copy_links                             同步的时候是否复制连接;
delete                                 删除源中没有而目标存在的文件;
src                          源目录及文件;
dest                                      目标目录及文件;
dest_port                               目标接受的端口;
rsync_path                             服务的路径,指定 rsync 命令来在远程服务器上运行;
rsync_timeout                           指定rsync操作的IP超时时间;
set_remote_user                      设置远程用户名;
--exclude=.log                           忽略同步.log结尾的文件;
mode

  • 模块练习
## 远程拷贝目录(增量拷贝)
[root@localhost ~]# ansible 192.168.101.7 -m synchronize -a "src=/root/ dest=/root/"
192.168.101.7 | CHANGED => {
"changed": true,
"cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=>%i %n%L /root/ 192.168.101.7:/root/",
}
## 删除源目标目录重复文件
[root@localhost ~]# ansible 192.168.101.7 -m synchronize -a "src=/root/ dest=/root delete=yes"
192.168.101.7 | CHANGED => {
"changed": true,
"cmd": "/usr/bin/rsync --delay-updates -F --compress --delete-after --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=>%i %n%L /root/ 192.168.101.7:/root rsync_opts=--no-motd,--exclude=*.log"
}
## 排除.log以外其他文件
[root@localhost ~]# ansible 192.168.101.7 -m synchronize -a "src=/root/ dest=/root delete=yes rsync_opts=--no-motd,--exclude=*.log"
192.168.101.7 | CHANGED => {
"changed": true,
"cmd": "/usr/bin/rsync --delay-updates -F --compress --delete-after --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --no-motd --exclude=*.log --out-format=>%i %n%L /root/ 192.168.101.7:/root",
"msg": ".d..t...... .ansible/tmp/\ncd+++++++++ .ansible/tmp/ansible-local-86444xxrtdv1/\ncd+++++++++ .ansible/tmp/ansible-local-86444xxrtdv1/ansiballz_cache/\n
  • service模块

[root@localhost ~]# ansible 192.168.101.6 -m service -a "name=httpd state=restarted"
192.168.101.6 | CHANGED => {
"changed": true,
"name": "httpd",
"state": "started",
"status": {
"ActiveEnterTimestamp": "n/a",
"ActiveEnterTimestampMonotonic": "0",
"ActiveExitTimestamp": "n/a",
"ActiveExitTimestampMonotonic": "0",
"ActiveState": "inactive",
"After": "nss-lookup.target network.target system.slice -.mount tmp.mount basic.target httpd-init.service remote-fs.target systemd-journald.socket sysinit.target systemd-tmpfiles-setup.service",
"AllowIsolate": "no",
"AssertResult": "no",
"AssertTimestamp": "n/a",
}
[root@localhost ~]# ansible 192.168.101.6 -m shell -a "ps -ef | grep httpd"
192.168.101.6 | CHANGED | rc=0 >>
root       27375       1  0 23:19 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache     27376   27375  0 23:19 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache     27377   27375  0 23:19 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache     27378   27375  0 23:19 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache     27379   27375  0 23:19 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root       28560   28559  0 23:21 pts/1    00:00:00 /bin/sh -c ps -ef | grep httpd
root       28562   28560  0 23:21 pts/1    00:00:00 grep httpd

三、实战ollama部署大模型框架

  • 设置模型分组

[nginx]
192.168.101.5
[deepseek]
192.168.101.6
192.168.101.7
  • 准备ollama-linux-amd64.tgz的linux安装包(拷贝ollama包至其他文件)

[root@localhost ~]# ls
anaconda-ks.cfg
install_panel.sh
ollama-linux-amd64.tgz
[root@localhost ~]# ansible deepseek -m copy -a "src=/root/ollama-linux-amd64.tgz dest=/usr/src owner=root group=root mode=644"
  • 创建文件目录存放压缩目录

## 创建文件夹
[root@localhost ~]# ansible deepseek -m file -a "path=/usr/local/ollama/ state=directory mode=755"
192.168.101.7 | CHANGED => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/usr/local/ollama/",
"size": 4096,
"state": "directory",
"uid": 0
}
192.168.101.6 | CHANGED => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/usr/local/ollama/",
"size": 4096,
"state": "directory",
"uid": 0
}
## 查看文件夹是否存在
[root@localhost ~]#  ansible deepseek -m shell -a "ls -ld /usr/local/ollama/"
192.168.101.6 | CHANGED | rc=0 >>
drwxr-xr-x 2 root root 4096 Aug 20 19:44 /usr/local/ollama/
192.168.101.7 | CHANGED | rc=0 >>
drwxr-xr-x 2 root root 4096 Aug 18 03:53 /usr/local/ollama/
  • 解压压缩包到指定目录

[root@localhost ~]#  ansible deepseek -m shell -a "tar nux-amd64.tgz -C /usr/local/ollama"
192.168.101.6 | CHANGED | rc=0 >>
192.168.101.7 | CHANGED | rc=0 >>

  • 写入环境变量,启动大模型工具

## 加入环境变量
[root@localhost ~]# ansible deepseek -m shell -a  "echo 'export PATH=\$PATH:/usr/local/ollama/bin/' >>/etc/profile"
192.168.101.6 | CHANGED | rc=0 >>
192.168.101.7 | CHANGED | rc=0 >>
## 生效ollama组件
[root@localhost ~]# ansible deepseek -m shell -a  "source /etc/profile; ollama serve &"
192.168.101.6 | CHANGED | rc=0 >>
## 查询端口时未生效
[root@localhost ollama]# ss -tnlp|grep 11434
[root@localhost ~]# ansible deepseek -m shell -a  "ps -ef | grep ollama"
192.168.101.6 | CHANGED | rc=0 >>
root        6476    6475  0 20:04 pts/1    00:00:00 /bin/sh -c ps -ef | grep ollama
root        6478    6476  0 20:04 pts/1    00:00:00 grep ollama
192.168.101.7 | CHANGED | rc=0 >>
root       15152   15151  0 04:13 pts/0    00:00:00 /bin/sh -c ps -ef | grep ollama
root       15154   15152  0 04:13 pts/0    00:00:00 grep ollama
## 启动ollama程序
ansible deepseek -m shell -a "/usr/local/ollama/bin/ollama serve"
[root@localhost ollama]# source /etc/profile;ollama pull deepseek-r1:1.5b
  • 查看deepseek安装情况

[root@localhost ollama]# ollama ls | grep -aiE deepseek
deepseek-r1:1.5b    e0979632db5a    1.1 GB    6 minutes ago
## 运行大模型
ollama run deepseek-r1:1.5b
  • deepseek嵌套deepseekUI模型(放在.7机器上)

## 安装ftp(文件大于4G)
yum -y install vsftpd
## 安装ftp服务
service vsftpd restart
## 创建用户
useradd adm2
passwd adm2
## 上传UI界面文件(如图)
cd /home/adm2/
## 安装docker
yum -y install docker
## 运行UI
docker run -itd -p 3000:8080 -e HF_ENDPOINT=https://hf-mirror.com -e OLLAMA_BASE_URL=http://172.17.0.1:11434 -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:latest
## 重启docker
service docker restart
## 加载UI工具
docker load -i open-webui.tar
  • windows登录ftp服务

  • 自定义ollama服务

cat>/etc/systemd/system/ollama.service<
    posted @ 2025-08-24 21:20  yfceshi  阅读(47)  评论(0)    收藏  举报