跳至内容

博客列表

Docker--- Nodejs

目标:Docker 建立 Nodejs 镜像并跑一个 Nodejs 容器 Troubleshooting Record [devops@lb01 ~]$ sudo docker build -t nginx-image . [+] Building 0.1s (1/1) FINISHED docker:default => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 2B 0.0s ERROR: failed to build: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory 需要先创建一个文件/文件夹 [devops@lb01 ~]$ docker build -t nginx-image ./docker/nginx-image ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock 没有权限访问 socket 文件:/var/run/docker.sock 检查sock文件权限:660 / 666 将当前用户加入docker组:sudo usermod -aG docker $USER;然后退出重登。 [devops@lb01 ~/docker]$ docker build -t nginx-image . [+] Building 0.0s (1/1) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 2B 0.0s ERROR: failed to build: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory 显示没有文件/文件夹 尝试用文件夹建立dockerfile 发现仍然报错,显示文件不存在搜索后发现是dockerfile没有提前建立的关系,于是先建立Dockerfile文件在项目下,再次docker build -t my-nodejs就没有报错了 docker images

更多 →

April 15, 2026

yum 进阶

探究yum源的混乱 更换yum源核心逻辑:注释metalink;更换国内的baseurl 解决方案:源于yum错乱,为了尽快解决最好的办法就是删除原来错乱的配置重新配置官方的yum源 配置yum的目的: 直接跨海访问国外会有极高的延迟和丢包率,从而使用国内的镜像加速,本质上是切换到了 地理位置更近、带宽更高的镜像站 高可用:国内大厂的镜像站有极高的负载均衡,保证 7X24 小时不中断 版本一致性:使用私有的企业内部私有源保证服务器安装的 软件版本一致 /etc/yum.repos.d/ 文件拆解: 核心系统源(BaseOS, AppStream): rocky.repo 包含 linux内核,li,cp,ssh等操作系统生存必须的基础包 必须改!!! 官方拓展源 ( Extras, Plus): rocky-extras.repo 包含官方支持但不属于核心系统的插件 建议改 第三方社区源( EPEL ): epel.repo 由 Federa 社区维护,提供很多红帽系官方不带的工具 必须改 repo 文件示例: [epel] # 仓库 ID name=Extra Packages for Enterprise Linux 9 # 仓库名称 # metalink=https://mirrors... # 自动寻找最快节点的地址(通常由于网络问题失效) baseurl=https://mirrors.aliyun.com/epel/9/Everything/x86_64/ # 真正的下载地址 enabled=1 # 是否启用(1为启用) gpgcheck=1 # 是否校验签名(为了安全,必须为1) gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9 # 校验用的公钥 Yum 源案例实践:

更多 →

April 11, 2026

自动发送天气预报

接收方:钉钉 发送方:和风天气 API_HOST, WEBHOOK, API_KEY都在和风官方开发者后台里/头像首页 平台:Github托管代码 代码及解释(直接放在main分支): import requests import json # ================= 配置区 ================= API_HOST = 'p34y3kvamv.re.qweatherapi.com' # 你的控制台设置里 DINGTALK_WEBHOOK = 自己的 WEATHER_API_KEY = 自己的 CITY_ID = 天气api城市id #城市代码可自行查询当地天气代码 # ========================================== def get_weather(): """获取和风天气数据""" url = f'https://{API_HOST}/v7/weather/3d?location={CITY_ID}' # 新版推荐将API KEY放在请求头中 headers = { 'X-QW-Api-Key': WEATHER_API_KEY } try: response = requests.get(url, headers=headers).json() if response['code'] == '200': today = response['daily'][0] date = today['fxDate'] temp_max = today['tempMax'] temp_min = today['tempMin'] text_day = today['textDay'] wind_dir = today['windDirDay'] uv_index = today['uvIndex'] # 注意:正文中必须包含你在钉钉里设置的“自定义关键词”(如:天气) msg = f"""### 🌤️ 今日天气预报 **日期**:{date} **白天天气**:{text_day} **温度**:{temp_min}℃ ~ {temp_max}℃ **风向**:{wind_dir} **紫外线指数**:{uv_index} 祝你今天有个好心情! """ return msg else: print(f"获取天气失败,错误码:{response['code']}") return None except Exception as e: print(f"请求发生异常: {e}") return None def send_to_dingtalk(msg_text): """发送 Markdown消息到钉钉 """ headers = {'Content-Type': 'application/json'} data = { "msgtype": "markdown", "markdown": { "title": "今日天气", "text": msg_text } } response = requests.post(DINGTALK_WEBHOOK, headers=headers, data=json.dumps(data)) print("钉钉返回结果:", response.text) if __name__ == '__main__': weather_info = get_weather() if weather_info: send_to_dingtalk(weather_info) 把yml文件放在workflows下: 代码: name: Daily Weather Bot on: schedule: - cron: '30 23 * * *' # 注意:这里是UTC时间!UTC的23:30相当于北京时间早上7:30。2000次最大/月 workflow_dispatch: # 允许手动点击运行 jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip pip install requests - name: Run script run: python weather_bot.py #脚本名字 完成后每天7点半即可接收到钉钉消息!!!

更多 →

March 31, 2026

钉钉自动巡检告警--完全版

钉钉自动巡检告警: 注意:钉钉机器人有使用频率限制:每个机器人最多20条/min 注意:配置前安装好相应库 功能:自动检测并定时发送hostname,datetime,cpu,mem,disk,服务状态;Zabbix面板链接可自行添加 文本格式:Markdown 代码及解释: import psutil import socket import requests import json from datetime import datetime #配置区================================================== WEBHOOK_URL = "你的钉钉群机器人token" #设置合理告警阈值: THRESHOLD_CPU = 80 #CPU THRESHOLD_MEM = 85 #内存 THRESHOLD_DISK = 90 #磁盘 #======================================================= def get_sys_info(): """获取系统基础信息""" # 获取主机名和当前时间(格式自定义) hostname = socket.gethostname() now_time = datetime.now().strftime("%Y-%m-%d %H-%M-%S") # 1.CPU 使用率(采样1次/s): cpu_usage = psutil.cpu_percent(interval=1) # 2.MEM 使用率: mem = psutil.virtual_memory() mem_usage = mem.percent # 3.DISK 使用率: disk = psutil.disk_usage('/') disk_usage = disk.percent return hostname, now_time, cpu_usage, mem_usage, disk_usage def check_service(service_name): """检查特定进程(服务)是否在运行""" # 遍历当前所有进程名: for proc in psutil.process_iter(['name']): if service_name.lower() in proc.info['name'].lower(): return "✔️ 该服务正在运行中。" return "❌️ 该服务已经停止!" def send_markdown_msg(hostname, now_time, cpu, mem, disk, nginx_status): """发送 MarkDown 格式告警""" #根据状态判断标题颜色(若有异常则提醒): status_title = "🤚 系统巡检正常" if cpu > THRESHOLD_CPU or mem > THRESHOLD_MEM or disk > THRESHOLD_DISK or "❌️" in nginx_status: status_title = "🤦🏻‍♂️ 系统告警:检测到异常" # Markdown 内容 markdown_content = f"""### {status_title} **主机名称**: {hostname} **巡检时间**: {now_time} --- - **CPU 使用率**:{cpu}% {'⚠️' if cpu > THRESHOLD_CPU else ''} - **内存 使用率**:{mem}% {'⚠️' if mem > THRESHOLD_MEM else ''} - **磁盘 使用率**:{disk}% {'⚠️' if disk > THRESHOLD_DISK else ''} - **Nginx服务**: {nginx_status} --- [点击查看Zabbix监控看板](http://Zabbix地址) """ data = { "msgtype": "markdown", "markdown": { "title": "服务器巡检报告", "text": markdown_content } } headers = {"Content-Type": "application/json"} try: res = requests.post(WEBHOOK_URL, data=json.dumps(data), headers=headers) print(f"发送状态:{res.text}") except Exception as e: print(f"发送失败:{e}") if __name__ == "__main__": #执行巡检 h, t, c, m, d = get_sys_info() #可换成其他进程名 n_status = check_service("nginx") #发送报告 send_markdown_msg(h, t, c, m, d, n_status) 推荐:Emoji状态表情可自行复制进去。 函数及库的使用 1. 库的调用 psutil: 专门用来读取 CPU、内存、进程等硬件和系统信息。 socket: 用来获取 hostname(主机名),这在管理几十台服务器时非常重要,否则你不知道是哪台机器出的问题。 datetime: 获取当前时间,所有的运维报告必须带时间戳。

更多 →

March 31, 2026

钉钉自动巡检告警--磁盘空间

钉钉自动巡检告警–Disk: 注意:在虚拟环境中要提前 pip 安装相应的库 注意:钉钉机器人有使用频率限制:每个机器人最多20条/min 建议采用Python虚拟环境避免冲突 #新建文件夹: mkdir /to/your/myPython touch /to/your/myPython/DingDing.py #激活venv环境,使命令行前出现venv标志 python3 -m venv venv #在所在文件目录执行 source venv/bin/activate #执行脚本 python3 /to/your/myPython/DingDing.py #取消venv deactivate 脚本代码及解释: import requests import json import psutil import socket #自己的token,在 钉钉自建群 ==》机器人 ==》 自定义机器人 ==》查看token ==》 安全策略带关键词,如"告警" WEBHOOK_URL = "你的token" def send_dingtalk_msg(content): """发送钉钉告警的核心函数""" headers = {"Content-Type": "application/json"} #构建消息体(必须包含关键词"告警") data = { "msgtype": "text", "text": { "content": f"【服务器自动巡检告警】\n{content}" } } try: response = requests.post(WEBHOOK_URL, data=json.dumps(data), headers=headers) result =response.json() if response.status_code == 200: print("钉钉消息发送成功!!!") else: print(f"发送失败,错误码:{response.status_code}") except Exception as e: print(f"网络请求出错:{e}") def check_disk_usage(): """检查磁盘使用率""" hostname = socket.gethostname() disk_info = psutil.disk_usage('/') percent = disk_info.percent print(f"当前磁盘使用率:{percent}") #设置一个合理的磁盘空间"报警值" if percent > 80: msg = f"主机名:{hostname}\n状态:磁盘空间不足\n当前使用率:{percent}%\n请及时清理日志或扩容!!!" send_dingtalk_msg(msg) else: print("磁盘状态正常") if __name__ == "__main__": check_disk_usage() 设置crontab定时脚本: #编辑脚本 crontab -e #添加: 0 * * * * /to/your/venv/bin/python /to/your/DingDing.py #完成后会出现新安装的提示 #如果想要测试的话还是直接用: python3 /to/your/DingDing.py

更多 →

March 31, 2026

SSH安全密钥设置

==SSH开放高位端口以及免密钥匙登录== 极度重要提示:在进行以下操作时,请务必全程保持当前 SSH 连接不断开! 所有的测试请在新开的终端窗口中进行。如果配置有误,你可以使用未断开的原窗口进行修改挽救,否则你可能会被彻底锁在服务器外面。 以下是完整的操作步骤: 第一步:确保你已经配置好了密钥登录 在禁用密码登录之前,你必须确保密钥登录已经可以成功使用。 如果你在本地还没有生成过密钥,请在本地电脑终端执行: ssh-keygen -t ed25519 -C "your_email@example.com" 将公钥上传到服务器(把 user 和 ip 换成你的服务器账号和IP): ssh-copy-id user@ip 测试密钥登录:新开一个终端,输入 ssh user@ip,如果不需要输入密码就能直接登入,说明密钥配置成功。 第二步:修改 SSH 配置文件 在服务器上,使用你熟悉的编辑器(如 vim 或 nano)编辑 sshd 服务器端配置文件:

更多 →

March 21, 2026

Docker简单配置

Docker配置命令: # 1)先清理冲突包 dnf remove y podmandocker podman runc # 2)安装仓库管理工具 dnf y install dnfpluginscore # 3)添加 Docker 官方 RHEL 仓库 dnf configmanager addrepo https://download.docker.com/linux/rhel/dockerce.repo # 4)安装 Docker dnf y install dockerce dockercecli containerd.io dockerbuildxplugin dockercomposeplugin # 5)启动并设置开机自启 systemctl enable now docker # 6) 验证 docker version docker info 这条路径和 Docker 官方给 RHEL 8/9/10 的安装方式一致;Rocky 的官方文档也给出了相同的仓库地址和安装包组合。 # 阶段 1:认识镜像 docker search nginx docker pull nginx docker images # 阶段 2:跑第一个容器 docker run d name mynginx p 80:80 nginx docker ps docker logs f mynginx docker exec it mynginx bash # 阶段 3:理解生命周期 docker stop mynginx docker start mynginx docker rm f mynginx # 阶段 4:练习镜像管理 docker image inspect nginx docker image save nginx > nginx.tar docker image load i nginx.tar docker rmi nginx 报错点(环境被污染):

更多 →

March 20, 2026

FTP办公挂载文件夹

搭建服务器的FTP文件夹挂载在win上 简单介绍: FTP(VSFTP) 类unix系统使用的FTP服务器软件 安全,高速,稳定 vim /etc/services 查端口 20 传数据;21 传指令 FTP会话通道: 20数据通道:正文 21控制通道:敲门,输密码,发指令 主动模式: C随机开高位端口&发给S,Server通过20端口与Client连接&发数据 被动模式(passive): 相对的 S开放随机高位端口&发给C,然后等待Client连接 配置实现: dnf install vsftpd y systemctl start vsftpd systemctl status vsftpd firewallcmd permanent addservice=ftp firewallcmd reload vim /etc/vsftpd/vsftpd.conf local_enables=YES write_enables=YES setenforce 0 大功告成!!!最后: win 下资源管理器输入: ftp://虚拟机IP

更多 →

March 20, 2026

Python自动下载整个网站的漫画

实现源码: import requests import os import bs4 def download_comics(): url = 'https://xkcd.com/3216/' floder_name = 'xkcd_comics' os.makedirs(floder_name, exist_ok=True) count = 0 while not url.endswith('#') and count < 5: print(f"正在访问网页: {url}") headers = {'UserAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'} res = requests.get(url, headers=headers) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, 'html.parser') comic_elem = soup.select('#comic img') if comic_elem == []: print("未在该页面找到图片!!!") else: comic_url = 'https:' + comic_elem[0].get('src') print(f'下载图片:{comic_url}') res = requests.get(comic_url, headers=headers) res.raise_for_status() image_name = os.path.basename(comic_url) image_path = os.path.join(floder_name, image_name) with open(image_path, 'wb') as image_file: for chunk in res.iter_content(100000): image_file.write(chunk) prev_link = soup.select('a[rel="prev"]')[0] url = 'https://xkcd.com' + prev_link.get('href') count += 1 print("所有漫画下载完毕!!请看xkcd_comics文件夹") if __name__ == '__main__': download_comics() 注意:处于网络问题可能有访问不了的情况!

更多 →

March 20, 2026

《Nginx 恶意攻击 IP 自动分析与封禁拦截器》

背景:Nginx 服务器遭到恶意爬虫的疯狂扫描,/var/log/nginx/error.log 文件瞬间暴增了上万行。 如果手动去找是哪些 IP 在攻击,然后一条条加进防火墙,费时费力 解决方案:通过Python自动化脚本运用 os 和 re库来自动化提取恶意IP;并放入Shell脚本中,根据实际情况决定是否执行脚本 操作:检查下列代码(有解释);并根据自身实际情况修改,将py代码与自身想要检索的日志放在同一个目录下 代码与逻辑: import re import os #============配置区============= LOG_FILE = 'error.log' OUTPUT_FILE = 'ban_ips.sh' THERESHOLD = 50 #报警阈值 WHERELIST = ['192.168.1.6', '10.0.0.6'] #白名单 #============================== def main(): ip_Regex = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ip_Counts = {} #空字典当“计数器” print(f"正在分析日志文件: {LOG_FILE}") if not os.path.exists(LOG_FILE): print("找不到日志文件,请检查路径。") return with open(LOG_FILE, 'r', encoding='utf-8', errors='ignore') as file: for line in file: match = ip_Regex.search(line) if match: ip = match.group() if ip in WHERELIST: continue if ip in ip_Counts: ip_Counts[ip] += 1 else: ip_Counts[ip] = 1 malicious_ips = [] for ip, count in ip_Counts.items(): if count >= THERESHOLD: malicious_ips.append(ip) print(f"发现恶意IP {ip} 攻击了 {count} 次!!!") if malicious_ips: with open(OUTPUT_FILE, 'w', encoding='utf-8') as out_file: out_file.write("#!/bin/bash\n") out_file.write("# 自动生成的防火墙封禁脚本\n\n") for ip in malicious_ips: cmd = f"firewall-cmd --permanent --add-rich-rule='rule family=\"ipv4\" source address=\"{ip}\" drop' \n " out_file.write(cmd) out_file.write("\nfirewall-cmd --reload\n") out_file.write(f"echo '所有恶意ip已经被写入文件{OUTPUT_FILE}'\n") print(f"\n 已经生成封禁IP脚本{OUTPUT_FILE}") print(f" 您只需要执行:bash {OUTPUT_FILE} 即可封禁恶意IP") else: print("\n 日志很干净没有发现恶意IP") if __name__ == '__main__': main() 执行结果如下: 终端中: [root@SERVER nginx]# python3 ./ips_blocker.py 正在分析日志文件: error.log 发现恶意IP 141.101.69.127 攻击了 896 次!!! 发现恶意IP 172.71.126.94 攻击了 583 次!!! 已经生成封禁IP脚本ban_ips.sh 您只需要执行:bash ban_ips.sh 即可封禁恶意IP Shell脚本中: #!/bin/bash 自动生成的防火墙封禁脚本 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="141.101.69.127" drop' firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="172.71.126.94" drop' firewall-cmd --reload echo '所有恶意ip已经被写入文件ban_ips.sh'

更多 →

March 19, 2026