运维
快来分享你的内容吧~
- 06-05 00:50·运维工程师
- 06-04 23:54·运维工程师Python 技能树(云原生预备 / 运维自动化方向) 核心原则 优先掌握能直接写脚本的知识点 每个知识点都要能产出可运行的代码片段 后续补上工程证据规范(README、测试、日志)查看全文foollisher:关于计算机导论CS50{X>P>SQL+Cyber}462分享
- WireGurad 搭建服务端与客户端、客户端与客户端不能通讯的问题问题描述关于WireGuard通过docker安装,客户端之间不能互ping的相关问题具体疑问【问题背景】家中有一台闲置的台式电脑,想自己搭建一个 NAS,并通过公网远程访问。当前方案如下:1. 购买一台云服务器作为 WireGuard 服务端2. 家中的台式电脑作为 WireGuard 客户端3. 通过云服务器进行中转,实现访问家庭内网设备目标是通过 WireGuard 打通云服务器与家庭内网,...查看全文编程导航小智:你这个问题非常典型,而且目标很清晰——不是单纯“能连上”,而是要构建一个可生产、可扩展、安全稳定的多云+家庭混合组网基础设施。咱们先直击核心:当前 ping 不通的根本原因,90% 是 WireGuard 的 "AllowedIPs" + 路由/转发配置没对齐,尤其在 Docker 环境下,容易漏掉关键环节。***✅ 快速定位问题(三步检查法)1. 服务端是否开启了 IP 转发?(Docker 容
- centos7上coturn服务启动后无法访问的故障处理提问背景我正在开发webrtc的视频通话功能,建立P2P的连接需要搭建stun/turn服务器,于是我在阿里云centos7服务器上利用coturn在3478端口启动了该服务,但是在测试时发现服务不可用。尝试解决一开始,我以为是端口未开放的问题,于是我在安全组设置了入方向和出方向的端口对全部流量进行全部开放,并且关闭了防火墙的限制,但是依然没有用。详细信息启动命令/usr/local/turnse...查看全文编程导航小智:从你的描述和日志来看,STUN/TURN服务已经启动并监听端口,但客户端连接后出现"allocation timeout"的问题。咱们来分析关键点:主要问题定位1. 配置问题: - "listening-ip"应该设为内网IP(172.18.61.183)是正确的 - 但"external-ip"配置需要特别注意:阿里云ECS有弹性公网IP时,应该配置双IP格式:external-ip=4
- 2025-11-09·运维开发时间倒回到那天,得知自己专转本考试失败后,人生感觉完了。———— 计算机专业,带专学历,诶哥们,你说这扯不扯 你都大专学历了,这offer我要干嘛呢,送你得了。工作后的感想就是 动不动就会来了个大的让你感觉人生完蛋了,但是人生该咋样还是咋样,该吃吃该喝喝,总会过去的。那个时候,真感觉完蛋了,啥技术项目都不会,也没系统地学习过编程,直到现在都是个半吊子水平,只不过 我必须坦诚地说,我运气很好,第一份查看全文编程导航_小y:加油,zzbu。刚毕业前几年,大专学历的确会有一定影响,不过专精运维方向也是有机会慢慢往上走的。可以后续搜一搜自动化运维、运维开发、云服务运维这几个方向,再针对招聘要求来学习,也是有机会发展的还不错,万事开头难,只要开始就一切都有机会!23812分享
- 2025-10-31·运维工程师查看全文简历或者职业方向的疑惑,求大佬们给点建议,跪谢!!! 23届,双非民办。 下面有两个版本的运维岗简历,一个是基础版,另一个是用AI优化和精简过的版本。 让我有些困惑的是,我在运维方向的技能并不是特别扎实(啥都接触但是啥都不精),但目前还是从事这方面的工作。...编程导航_小y:感觉版本 2 的简历会好一点,可以把自我介绍改为【个人优势】:https://www.codefather.cn/essay/1965277751000743937已经有两年运维经验,不太合适转 Java ,可以从自动化运维或者运维开发发展,搜一下 Boss 直聘上的岗位要求,针对性去学习422分享
Linux 基础技能树 (云原生预备 / 运维自动化方向)26-06-04(为期3-4月)
# Linux 基础技能树 v2.1 ## 云原生预备 / 运维自动化方向 ## 0. 核心原则 - 每个命令都要亲手敲过。 - 优先掌握能排查问题、写脚本、做自动化的命令。 - 不追求一次性背全命令参数,只掌握高频选项。 - 所有破坏性命令必须在测试目录、WSL、虚拟机或临时容器中练习。 - Linux 学习要和 Python 自动化结合: - `subprocess` - `pathlib` - `logging` - `requests` - `json` - `csv` - `pytest` --- # 第一层:P0 基础命令与文件操作 这一层是第一轮必须掌握的 Linux 基础。 目标: ```text 会看文件 会查目录 会改权限 会查磁盘 会读帮助 会用 grep/find 会理解路径和权限 ``` --- ## 1. 文件与目录管理 P0 必须掌握: - [ ] `pwd`:查看当前目录 - [ ] `ls`:查看目录内容 - [ ] `ls -l` - [ ] `ls -a` - [ ] `ls -h` - [ ] `ls -t` - [ ] `cd`:切换目录 - [ ] `mkdir`:创建目录 - [ ] `mkdir -p` - [ ] `touch`:创建空文件 / 更新时间戳 - [ ] `cp`:复制文件或目录 - [ ] `cp -r` - [ ] `cp -i` - [ ] `cp -u` - [ ] `mv`:移动 / 重命名 - [ ] `rm`:删除文件 - [ ] `rm -i` - [ ] `rm -r` - [ ] `rm -f` - [ ] `file`:查看文件类型 - [ ] `stat`:查看文件元数据、权限、时间、inode 暂时了解: - [ ] `rmdir`:删除空目录 高风险提醒: ```text rm -rf 很危险。 第一阶段只在测试目录里练习。 不要对 /、/home、/etc、系统目录执行递归删除。 ``` --- ## 2. 文件查看与文本搜索 P0 必须掌握: - [ ] `cat`:查看小文件 - [ ] `head`:查看文件开头 - [ ] `head -n` - [ ] `tail`:查看文件结尾 - [ ] `tail -n` - [ ] `tail -f` - [ ] `less`:分页查看大文件 - [ ] `grep`:搜索文本 - [ ] `grep -i` - [ ] `grep -v` - [ ] `grep -r` - [ ] `grep -n` - [ ] `grep -A` - [ ] `grep -B` - [ ] `grep -C` - [ ] `find`:查找文件 - [ ] 按名称查找 - [ ] 按类型查找 - [ ] 按大小查找 - [ ] 按时间查找 可以后置: - [ ] `tac` - [ ] `more` - [ ] `find -exec` 高级用法 基础正则: - [ ] `.`:任意字符 - [ ] `*`:重复 - [ ] `^`:行首 - [ ] `$`:行尾 - [ ] `[]`:字符集合 - [ ] `.*`:任意长度内容 --- ## 3. 文本处理三件套 P0 / P1 **P0 必须掌握:** - [ ] `grep`:筛选行 - [ ] `wc`:统计行数、字数、字符数 - [ ] `wc -l` - [ ] `sort`:排序 - [ ] `uniq`:去重 - [ ] `uniq -c` - [ ] `awk` 基础列提取 - [ ] `awk '{print $1}'` - [ ] `awk '{print $2}'` - [ ] `awk '{print $NF}'` **P1 第二轮掌握:** - [ ] `awk` 条件过滤 - [ ] `awk '$9 >= 500'` - [ ] `awk -F',' '{print $1}'` - [ ] `sed`:文本替换和流编辑 - [ ] `sed 's/old/new/g'` - [ ] `cut`:按分隔符截取字段 目标能力: ```text 能从日志里筛出 ERROR 能统计错误次数 能找 Top IP 能按字段提取信息 能把结果输出成报告 ``` --- ## 4. 文件编辑器 P0 至少会一个。 推荐先学: - [ ] `nano`:简单编辑文件 然后最低限度掌握 `vim`: - [ ] `vim file` - [ ] `i`:进入编辑模式 - [ ] `Esc`:退出编辑模式 - [ ] `:wq`:保存退出 - [ ] `:q!`:不保存退出 - [ ] `/keyword`:搜索 - [ ] `dd`:删除一行 目标: ```text 能在服务器或 WSL 里修改配置文件。 不需要成为 Vim 高手。 ``` --- ## 5. 权限与所有者 P0 必须掌握: - [ ] `chmod`:修改权限 - [ ] 数字模式:`755`、`644` - [ ] 符号模式:`u+x` - [ ] `chown`:修改所有者和组 - [ ] `sudo`:以管理员权限执行命令 需要理解: - [ ] owner / group / others - [ ] read / write / execute - [ ] 目录的执行权限含义 - [ ] 为什么脚本没有执行权限会报错 了解即可: - [ ] `umask` - [ ] `visudo` 概念 高风险提醒: ```text chmod -R 和 chown -R 很危险。 不要随意对系统目录递归修改权限。 不要直接乱改 /etc/sudoers。 ``` --- ## 6. 磁盘与文件系统 P0 必须掌握: - [ ] `df -h`:查看磁盘空间 - [ ] `df -i`:查看 inode - [ ] `du -sh`:查看目录大小 - [ ] `du --max-depth=1`:查看一级目录大小 - [ ] `ln -s`:创建软链接 了解即可: - [ ] 硬链接概念 - [ ] `lsblk`:查看块设备 - [ ] `mount` / `umount`:挂载概念 目标能力: ```text 能判断磁盘是否满 能判断 inode 是否耗尽 能找出哪个目录占空间最大 能理解软链接是什么 ``` --- ## 7. 帮助与命令定位 P0 必须掌握: - [ ] `man` - [ ] `command --help` - [ ] `which` - [ ] `type` 了解: - [ ] `whereis` - [ ] `info` 需要知道: ```text man 5 passwd man 1 ls man 8 systemctl ``` 目标: ```text 遇到不会的命令,能自己查基本用法。 ``` --- # 第二层:P0 / P1 系统操作、管道与脚本基础 这一层是从“会敲命令”进入“能排障、能写脚本”的关键。 --- ## 8. 输入输出、重定向与管道 P0 必须掌握: - [ ] `>`:覆盖输出到文件 - [ ] `>>`:追加输出到文件 - [ ] `<`:从文件读取输入 - [ ] `2>`:重定向 stderr - [ ] `&>`:同时重定向 stdout 和 stderr - [ ] `|`:管道 - [ ] `tee`:同时输出到屏幕和文件 必须理解: - [ ] stdin - [ ] stdout - [ ] stderr - [ ] exit code - [ ] `$?` **P1 掌握:** - [ ] `xargs`:把标准输入转成命令参数 安全练习: - [ ] `find . -name '*.log' | xargs wc -l` - [ ] (了解但谨慎)`find . -name '*.tmp' -print0 | xargs -0 rm` 高风险提醒: ```text xargs 配合 rm 使用前,必须先把 rm 换成 echo 检查目标文件。 ``` 目标能力: ```text 能把多个命令串起来。 能把命令结果保存成证据。 能区分正常输出和错误输出。 ``` --- ## 9. 进程管理 P0 必须掌握: - [ ] `ps aux` - [ ] `ps -ef` - [ ] `top` - [ ] `kill` - [ ] `kill -15` - [ ] `kill -9` - [ ] `pgrep` - [ ] `pkill` P1 掌握: - [ ] `htop` - [ ] `jobs` - [ ] `fg` - [ ] `bg` - [ ] `&` - [ ] `nohup` - [ ] `tmux` 了解: - [ ] `screen` - [ ] `killall` 必须理解: - [ ] PID - [ ] parent process - [ ] foreground / background - [ ] signal - [ ] SIGTERM vs SIGKILL 目标能力: ```text 能判断进程是否存在。 能找到高 CPU / 高内存进程。 能正常停止进程。 能解释 kill -15 和 kill -9 的区别。 ``` --- ## 10. 系统资源观察 P0 / P1 P0 必须掌握: - [ ] `free -h`:查看内存 - [ ] `uptime`:查看运行时间和 load average - [ ] `top`:查看 CPU / 内存占用 P1 掌握: - [ ] `vmstat` - [ ] `iostat` 目标能力: ```text 能初步判断 CPU、内存、负载是否异常。 ``` --- ## 11. 网络基础 P0 必须掌握: - [ ] `curl` - [ ] `curl -I` - [ ] `curl -X` - [ ] `curl -d` - [ ] `curl -H` - [ ] `curl -o` - [ ] `curl -v` - [ ] `ping` - [ ] `ss` - [ ] `ss -tulnp` - [ ] `lsof` - [ ] `lsof -i :PORT` - [ ] `dig` - [ ] `ip` - [ ] `ip addr` - [ ] `ip link` - [ ] `ip route` - [ ] `hostname` - [ ] `uname` P1 掌握: - [ ] `wget` - [ ] `traceroute` 或 `tracepath` - [ ] `nslookup` 目标能力: ```text 能判断服务是否监听端口。 能判断端口被哪个进程占用。 能用 curl 测试 HTTP/API。 能用 dig 排查 DNS。 能查看本机 IP 和路由。 ``` --- ## 12. 用户与组 P1 第一轮不必太深入。 需要掌握: - [ ] `whoami` - [ ] `id` - [ ] `who` - [ ] `w` - [ ] `passwd` 了解: - [ ] `useradd` - [ ] `userdel` - [ ] `groupadd` - [ ] `groupdel` - [ ] `/etc/passwd` - [ ] `/etc/group` - [ ] `/etc/sudoers` 高风险提醒: ```text userdel / groupdel 不要在真实主机随意练习。 ``` --- ## 13. 软件包管理 P0 / P1 Ubuntu / Debian 必须掌握: - [ ] `apt update` - [ ] `apt install` - [ ] `apt remove` - [ ] `apt search` - [ ] `apt list --installed` 了解: - [ ] `dnf` - [ ] `yum` - [ ] `./configure` - [ ] `make` - [ ] `make install` 目标能力: ```text 能安装基础工具。 能判断命令缺失时该安装什么包。 ``` --- ## 14. 压缩与归档 P0 必须掌握: - [ ] `tar -czvf` - [ ] `tar -xzvf` - [ ] `gzip` - [ ] `gunzip` - [ ] `zip` - [ ] `unzip` 了解: - [ ] `tar -cjvf` - [ ] `tar -xjvf` 目标能力: ```text 能打包日志。 能解压项目包。 能备份目录。 ``` --- ## 15. 计划任务 P1 掌握: - [ ] cron 表达式 - [ ] 分 - [ ] 时 - [ ] 日 - [ ] 月 - [ ] 周 - [ ] `crontab -e` - [ ] `crontab -l` 谨慎: - [ ] `crontab -r` 了解: - [ ] systemd timer 高风险提醒: ```text crontab -r 会删除当前用户所有 cron 任务。 练习前先 crontab -l 备份。 ``` --- ## 16. 环境变量与 Shell 配置 P0 必须掌握: - [ ] `env` - [ ] `export` - [ ] `echo $PATH` - [ ] `PATH` - [ ] `HOME` - [ ] `LANG` - [ ] `alias` 了解: - [ ] `set` - [ ] `~/.bashrc` - [ ] `~/.profile` - [ ] `/etc/profile` 目标能力: ```text 能解释环境变量是什么。 能解释为什么程序需要 DATABASE_URL。 能理解为什么命令找不到。 ``` --- ## 17. 服务管理与日志 P0 / P1 **P0 必须掌握:** - [ ] `systemctl status <service>` - [ ] `systemctl start <service>` - [ ] `systemctl stop <service>` - [ ] `systemctl restart <service>` - [ ] `journalctl -u <service>` - [ ] `journalctl -u <service> -f` **P1 掌握:** - [ ] `systemctl enable` - [ ] `systemctl disable` - [ ] `journalctl -xe` - [ ] `journalctl --since` 了解: - [ ] systemd unit 文件 - [ ] service unit 基础结构 **WSL 提醒:** - WSL2 较新版本支持启用 systemd,但不一定默认开启。 - 如果 `systemctl` / `journalctl` 报错,不一定是你学错了。 - 可以选择: 1. 启用 WSL systemd 后再练 systemctl; 2. 使用 `service` 命令做基础服务练习; 3. 用 Docker Desktop / Docker 容器练服务启动与日志; 4. 后续在 Linux VM 或云服务器中补真实 systemd 体验。 --- ## 18. Shell 脚本基础 P0 / P1 **P0 必须掌握:** - [ ] `#!/bin/bash` - [ ] 变量赋值:`var=value` - [ ] 变量引用:`$var` - [ ] 安全引用:`"$var"` - [ ] 特殊变量: - [ ] `$0` - [ ] `$1` - [ ] `$#` - [ ] `$@` - [ ] `$?` - [ ] `$$` - [ ] 条件测试: - [ ] `-f` - [ ] `-d` - [ ] `-x` - [ ] `-eq` - [ ] `-ne` - [ ] `-lt` - [ ] `=` - [ ] `!=` - [ ] `-z` - [ ] `if / then / elif / else / fi` - [ ] `for` - [ ] `while` - [ ] `case` - [ ] `exit` **P1 掌握:** - [ ] 函数定义与调用 - [ ] `set -e` - [ ] `set -u` - [ ] `set -o pipefail` - [ ] `shellcheck` 了解 目标能力: ```text 能写一个接收参数、检查文件、输出结果、返回 exit code 的脚本。 ``` --- # 第三层:P1 / P2 自动化运维场景 这一层不要求一开始全部掌握。 等 Python 基础和 Linux P0 掌握后,再逐步做。 --- ## 19. 日志分析 P1 必须练习: - [ ] 使用 `grep` 搜索 ERROR / WARN - [ ] 使用 `tail -f` 实时跟踪日志 - [ ] 使用 `grep -A/-B/-C` 查看上下文 - [ ] 使用 `awk` 提取字段 - [ ] 使用 `sort | uniq -c | sort -nr` 统计 Top 项 - [ ] 使用 `wc -l` 统计错误行数 可以后置: - [ ] `grep --line-buffered` - [ ] 将分析结果通过 webhook / 邮件发送 第一阶段建议只做: ```text 把分析结果写入文件。 不要一开始折腾邮件告警。 ``` --- ## 20. 系统监控与告警 P1 练习目标: - [ ] 检查 CPU - [ ] 检查内存 - [ ] 检查磁盘 - [ ] 检查 inode - [ ] 检查进程数 - [ ] 检查指定进程是否存在 - [ ] 检查指定端口是否监听 结合: - [ ] cron 定期执行 - [ ] 输出日志文件 - [ ] 超过阈值返回非 0 exit code - [ ] Python 使用 `subprocess` 调用脚本并处理结果 --- ## 21. 文件备份与同步 P1 掌握: - [ ] `rsync` 本地同步 - [ ] `rsync` 远程同步 - [ ] `tar + cron` 定时备份 - [ ] 增量备份思路 了解: - [ ] 备份保留周期 - [ ] 备份恢复验证 目标: ```text 不只是备份,还要能恢复。 ``` --- ## 22. 远程管理 P1 掌握: - [ ] `ssh` - [ ] `ssh-keygen` - [ ] `ssh-copy-id` - [ ] `scp` - [ ] `rsync over SSH` - [ ] `~/.ssh/config` 目标能力: ```text 能用密钥登录远程主机。 能传文件。 能同步目录。 能配置常用 SSH Host。 ``` --- ## 23. 网络排查实例 P1 必须能完成: - [ ] 用 `ping` 判断基础连通性 - [ ] 用 `dig` 判断 DNS 解析 - [ ] 用 `ss` 判断端口监听 - [ ] 用 `lsof` 判断端口占用进程 - [ ] 用 `curl` 判断 HTTP 可达性 - [ ] 用 `curl -v` 区分连接失败、TLS 问题、HTTP 错误 - [ ] 用 `ip addr` / `ip route` 查看本机网络状态 目标能力: ```text 能区分: DNS 失败 连接失败 端口未监听 服务返回 4xx / 5xx 请求超时 ``` --- ## 24. 服务管理排查 P1 必须能完成: - [ ] `systemctl status <service>` - [ ] `journalctl -u <service> -f` - [ ] 找到服务启动失败原因 - [ ] 找到配置文件错误 - [ ] 找到端口占用问题 - [ ] 重启服务并验证 - [ ] 判断服务是否开机自启 --- # 第四层:云原生前置 Linux 概念 P1 / P2 这一层主要是为 Docker、Kubernetes、SRE 打基础。 现在不要求深学,但要知道概念。 --- ## 25. 云原生前置概念 P1 必须理解: - [ ] process / PID - [ ] parent process - [ ] signal - [ ] SIGTERM - [ ] SIGKILL - [ ] stdout - [ ] stderr - [ ] stdin - [ ] exit code - [ ] environment variables - [ ] file descriptor - [ ] port - [ ] socket - [ ] listen - [ ] DNS - [ ] `/etc/hosts` - [ ] `/etc/resolv.conf` 目标: ```text 能解释一个服务如何启动、监听端口、输出日志、接收信号、退出并返回状态码。 ``` --- ## 26. 容器前置概念 P2 了解即可: - [ ] namespace - [ ] cgroups - [ ] mount namespace - [ ] network namespace - [ ] PID namespace - [ ] resource limits - [ ] container stdout/stderr 日志模型 学习时机: - 第一轮 Linux 学习只需知道名字和大概用途。 - 学 Docker 前重新复习。 - 学 Kubernetes requests / limits、Pod 网络、日志模型时再深入。 目标: ```text 知道 Docker / Kubernetes 不是魔法。 它们依赖 Linux 的进程、网络、文件系统、namespace、cgroups 等机制。 ``` --- # 第五层:高风险命令清单 这些命令要特别小心。 ## 27. 高风险命令 谨慎练习: - [ ] `rm -rf` - [ ] `chmod -R` - [ ] `chown -R` - [ ] `userdel` - [ ] `groupdel` - [ ] `crontab -r` - [ ] `systemctl disable` - [ ] `kill -9` - [ ] `dd` - [ ] `mkfs` 当前阶段不建议练: - [ ] `dd` - [ ] `mkfs` 原则: ```text 破坏性命令只在测试目录、临时容器、虚拟机里练。 不要对真实系统目录、真实数据目录、重要家目录操作。 ``` --- # 第一轮验收标准 学完 P0 后,你应该能完成下面这些任务。 ## A. 文件与权限 你应该能: - [ ] 创建一个目录结构 - [ ] 创建多个文件 - [ ] 查找某个文件 - [ ] 查看文件大小 - [ ] 查看文件类型 - [ ] 查看文件元数据 - [ ] 修改脚本为可执行 - [ ] 解释 `755` 和 `644` --- ## B. 日志查看 你应该能: - [ ] 查看日志最后 50 行 - [ ] 实时跟踪日志 - [ ] 搜索 `ERROR` - [ ] 显示 `ERROR` 前后 3 行 - [ ] 统计 `ERROR` 出现次数 - [ ] 把结果写入文件 --- ## C. 进程排查 你应该能: - [ ] 查看当前进程 - [ ] 找到某个 Python 进程 - [ ] 判断 CPU / 内存占用 - [ ] 正常停止进程 - [ ] 解释 `kill -15` - [ ] 解释 `kill -9` --- ## D. 端口排查 你应该能: - [ ] 查看 `8000` 端口是否监听 - [ ] 找到哪个进程占用 `8000` - [ ] 用 `curl` 请求本地服务 - [ ] 解释 HTTP status code - [ ] 判断是服务没启动、端口没监听,还是 HTTP 返回错误 --- ## E. DNS / 网络排查 你应该能: - [ ] 用 `dig` 查询域名 - [ ] 用 `curl` 判断 API 是否可达 - [ ] 区分 DNS 失败、连接失败、HTTP 500 - [ ] 查看本机 IP 地址 - [ ] 查看路由 --- ## F. 磁盘排查 你应该能: - [ ] 查看磁盘是否满 - [ ] 查看 inode 是否满 - [ ] 找出哪个目录占空间最大 - [ ] 知道磁盘满会导致哪些服务问题 --- ## G. Bash 脚本验收 你应该能写一个 Bash 脚本,完成: ```text 1. 接收一个目录参数 2. 检查目录是否存在 3. 统计其中 .log 文件数量 4. 搜索 ERROR 行数 5. 输出结果 6. 如果 ERROR 数量大于 0,返回非 0 exit code ``` --- ## H. Python + subprocess 运维自动化验收 你应该能写一个 Python 脚本,完成: ```text 1. 使用 subprocess 调用 df -h 2. 捕获 stdout / stderr 3. 检查 returncode 4. 解析磁盘使用率 5. 当某个挂载点使用率 > 80% 时打印 WARNING 6. 命令失败时输出错误信息 ``` 最低实现目标: ```text python disk_check.py ``` 输出示例: ```text OK: / usage is 42% WARNING: /mnt/data usage is 86% ``` 要点: - `subprocess.run` - `capture_output=True` - `text=True` - `returncode` - `stdout` - `stderr` - 简单字符串解析 - 基础异常处理 --- # 与 Python 并行的 8 周学习顺序 ## 第 1-2 周 Python 主线: ```text CS50P 基础语法 变量 字符串 list / dict if / for / while 函数 ``` Linux 并行任务: ```text 文件目录 文件查看 权限 帮助文档 磁盘基础 ``` 重点命令: ```text pwd, ls, cd, mkdir, touch, cp, mv, rm cat, head, tail, less, grep chmod, chown, df, du, man ``` --- ## 第 3-4 周 Python 主线: ```text 文件读写 异常处理 模块 JSON / CSV ``` Linux 并行任务: ```text grep / find 管道 重定向 进程 系统资源 ``` 重点命令: ```text find, grep, wc, sort, uniq >, >>, 2>, |, tee ps, top, kill, free, uptime ``` --- ## 第 5-6 周 Python 主线: ```text argparse logging requests pytest pathlib ``` Linux 并行任务: ```text 网络 环境变量 压缩 软件包 cron 入门 ``` 重点命令: ```text curl, ss, lsof, dig, ip env, export, echo $PATH tar, gzip, unzip apt, crontab ``` --- ## 第 7-8 周 Python 主线: ```text Python 小工具雏形 HTTP health checker log analyzer disk checker ``` Linux 并行任务: ```text Bash 脚本 systemctl journalctl ssh 基础 ``` 重点命令: ```text bash script systemctl status journalctl -u ssh, scp ``` --- ## 第 9 周以后 进入 Python + Linux 结合阶段: ```text HTTP health checker log analyzer disk usage reporter port checker service status checker simple incident note generator ``` 每个小工具开始加入: ```text README how to run sample input/output basic error handling run log known limitations ``` --- # 最终定位 这份 v2.1 技能树是针对“云原生预备 / 运维自动化”方向设计的: ```text Linux 基础 + 运维自动化入口 + 云原生前置概念 + Python 自动化结合点 + 排障能力预备 ``` 第一轮不要追求全打勾。 第一轮只要把 **P0** 掌握到能做到 **A~H 验收标准**,就合格。 做到这个程度,就可以进入 Python 运维小工具阶段,为 Docker、K8s、监控、CI/CD 打下坚实基础。
Python 技能树(云原生预备 / 运维自动化方向)26-06-04(为期3-4个月)
--- # Python 技能树(云原生预备 / 运维自动化方向) ## 0. 核心原则 - 优先掌握**能直接写脚本**的知识点 - 每个知识点都要能产出可运行的代码片段 - 后续补上工程证据规范(README、测试、日志) --- ## 第一层:语言基础(必须扎实) ### 0. Python 运行环境 - [ ] 版本区别(只用 Python 3) - [ ] 交互式与脚本运行 - [ ] 默认 UTF-8 编码 ### 1. 变量与运算符 - [ ] 命名规则(下划线命名,PEP8) - [ ] 多变量赋值、交换赋值 - [ ] 算术运算符 `+ - * / // % **` - [ ] 比较运算符 `> < >= <= == !=` - [ ] 赋值运算符 `+= -=` 等 - [ ] 逻辑运算符 `and or not` - [ ] 成员运算符 `in / not in` - [ ] 身份运算符 `is / is not`(了解与 `==` 区别) ### 2. 标准数据类型 - [ ] **Number**:int, float, bool(complex 不学) - [ ] **String**:定义、不可变、切片、转义、原始字符串 `r''` - [ ] **List**:可变、增删改查、排序、列表推导式 - [ ] **Tuple**:不可变、单元素逗号、索引 - [ ] **Dictionary**:key-value、增删改查、遍历 - [ ] **Set**:去重、基本运算(交集并集差集) - [ ] **None**:空值判断 ### 3. 字符串专项 - [ ] 基础运算:`+` 拼接、`*` 重复 - [ ] 内置方法:`split`, `strip`, `upper/lower`, `replace`, `join`, `find`, `startswith` - [ ] 格式化输出:f-string 为主(`f"Hello {name}"`),了解 `%` 和 `.format()` ### 4. 流程控制 - [ ] `if / elif / else` - [ ] 三元表达式 `a if cond else b` - [ ] `while` 循环 - [ ] `for` 循环(遍历可迭代对象) - [ ] `break`, `continue`, `pass` ### 5. 函数与作用域 - [ ] 定义函数 `def`,返回值 `return` - [ ] 参数:位置、关键字、默认值 - [ ] 不定长参数 `*args`(元组)、`**kwargs`(字典) - [ ] 变量作用域:局部、全局(`global`) - [ ] 文档注释(docstring) ### 6. 模块与包 - [ ] 导入方式 `import`, `from ... import ...` - [ ] `__name__ == '__main__'` 入口判断 - [ ] 自定义模块、`__init__.py` 概念 ### 7. 文件操作 - [ ] 打开文件 `open(路径, 模式, encoding)` - [ ] 模式:`r` / `w` / `a` / `b` / `r+` - [ ] 读取:`read()`, `readline()`, `readlines()` - [ ] 写入:`write()` - [ ] 关闭文件 `close()` - [ ] `with` 上下文管理器(自动关闭) ### 8. 异常处理 - [ ] `try / except / else / finally` - [ ] 捕获具体异常类型 - [ ] `raise` 主动抛出异常 ### 9. 面向对象(基础) - [ ] 类与实例 `class`, `__init__`, `self` - [ ] 实例属性、实例方法 - [ ] 简单封装(单下划线 `_` 约定) - [ ] (可选)继承基本语法,了解 `super()` - [ ] (不要求)多态、抽象类 --- ## 第二层:脚本工具能力(运维自动化必备) ### 10. 正则表达式(基础) - [ ] `re.search` / `re.match` / `re.findall` - [ ] 分组 `group()` - [ ] 常用模式:`\d` 数字、`\w` 单词、`\s` 空白、`.` 任意字符 - [ ] 数量词 `+ * ? {n,m}` ### 11. 时间处理 - [ ] `datetime` 模块:`datetime.now`, `datetime.strptime`, `datetime.strftime` - [ ] `time` 模块:`time.sleep`, `time.time` - [ ] 计算耗时(开始结束时间差) ### 12. 路径与系统接口 - [ ] `pathlib`:`Path`, `cwd`, `mkdir`, `glob`, `read_text`, `write_text` - [ ] `os` 模块:`os.getcwd`, `os.listdir`, `os.path`(或直接用 pathlib) - [ ] `sys`:`sys.argv` 命令行参数,`sys.exit` 退出码 ### 13. 命令行参数解析 - [ ] `argparse`(推荐)或 `typer`(更简洁) - [ ] 必需参数、可选参数、标志位 - [ ] `--help` 自动生成 ### 14. 日志记录 - [ ] `logging` 模块:`basicConfig`, `debug/info/warning/error` - [ ] 输出到文件和控制台 - [ ] 不同级别的作用 ### 15. 数据格式处理 - [ ] `json`:`json.loads`, `json.dumps`, 读写 `.json` 文件 - [ ] `csv`:读取和写入 CSV 文件 - [ ] (可选)`yaml` 基本加载(需安装 PyYAML) ### 16. 执行系统命令 - [ ] `subprocess` 模块:`subprocess.run()` - [ ] 获取 stdout, stderr, returncode - [ ] 安全使用(避免 shell=True 注入风险) ### 17. HTTP 请求(requests) - [ ] `requests.get()`, `requests.post()` - [ ] 设置 `timeout`, `headers`, `params` - [ ] 异常处理:`ConnectionError`, `Timeout`, `HTTPError` - [ ] 重试策略基础(结合循环或 `urllib3.Retry`) ### 18. 虚拟环境与依赖管理 - [ ] `venv` 创建隔离环境 - [ ] 激活/退出虚拟环境 - [ ] `pip install` 安装包 - [ ] `pip freeze > requirements.txt` - [ ] `pip install -r requirements.txt` ### 19. 测试基础 - [ ] `pytest` 基本用法 - [ ] 断言 `assert` - [ ] 运行测试,查看结果 ### 20. 迭代器与生成器(概念级) - [ ] 可迭代对象(能用 `for` 的都是) - [ ] 生成器:惰性求值,用 `yield` 写简单生成器(可选) - [ ] 理解“不要一次性读大文件”思想 ### 21. 多线程与并发(基础) - [ ] `threading.Thread`:`start()`, `join()` - [ ] 线程锁 `Lock` 防止资源竞争(简单了解) - [ ] 更推荐:`concurrent.futures.ThreadPoolExecutor` 实现 I/O 并发 - [ ] 注意:多线程适合网络请求、文件读写等 I/O 密集型任务 --- ## 第三层:运维自动化项目能力(综合运用) ### 22. 典型项目清单(至少完成2-3个) - [ ] 日志分析 CLI(读文件,正则提取,统计错误率,输出 JSON/CSV) - [ ] HTTP 健康检查工具(并发检查 URL 列表,超时重试,记录日志) - [ ] 文件批处理工具(批量重命名、移动、按日期归档) - [ ] 配置检查工具(读取 YAML/JSON,验证必要字段) - [ ] 端口/服务检测工具(`socket` 连接测试,进程是否存在) ### 23. 脚本工程规范(逐步建立) - [ ] 每个项目有 `README.md`(目的、用法、示例、局限性) - [ ] 使用 `argparse` 或 `typer` 提供友好命令行接口 - [ ] 日志输出到文件,保留 `run.log` - [ ] 关键函数有 `pytest` 测试(至少 3 个用例) - [ ] 异常处理返回非零退出码(`sys.exit(1)`) - [ ] 依赖写在 `requirements.txt`,使用 `venv` 隔离 --- ## 附录:不建议学习的内容(现阶段) - [ ] complex 复数 - [ ] 深拷贝细节(遇到再查) - [ ] 装饰器高级用法(看懂简单 `@` 即可) - [ ] 继承与多态深度设计 - [ ] 爬虫框架(Scrapy) - [ ] 数据分析库(numpy, pandas) - [ ] GUI(tkinter, PyQt) - [ ] asyncio 异步编程(后续按需) --- **使用说明**:可将此清单作为学习检查表,每完成一项打勾。第二层的 10–21 是对原清单的重要补充,务必掌握。完成第二层后,即可尝试第三层的项目,积累证据。
WireGurad 搭建服务端与客户端、客户端与客户端不能通讯的问题
### 问题描述 关于WireGuard通过docker安装,客户端之间不能互ping的相关问题 ### 具体疑问 **【问题背景】** 家中有一台闲置的台式电脑,想自己搭建一个 NAS,并通过公网远程访问。 当前方案如下: 1. 购买一台云服务器作为 WireGuard 服务端 2. 家中的台式电脑作为 WireGuard 客户端 3. 通过云服务器进行中转,实现访问家庭内网设备 目标是通过 WireGuard 打通云服务器与家庭内网,实现远程访问家中电脑(作为 NAS 使用)。 目前 WireGuard 服务端已经启动成功,管理页面显示客户端在线,并且有上下行流量。 【当前网络规划】 云服务器(服务端)IP:10.8.0.1 客户端1:10.8.0.2 客户端2:10.8.0.3 【当前问题】 - 云服务器 10.8.0.1 无法 ping 通 10.8.0.2和10.8.0.3 - 客户端 10.8.0.2 / 10.8.0.3 无法 ping 通 10.8.0.1 - 上行、下行均有流量 但是三者之间始终无法互相 ping 通。 - WireGuard 管理页面显示:  ### 目标: 【需求说明】 希望通过 VPN 的方式,实现公网可以直接代理访问家中闲置的台式机,使其能够作为一台可远程访问的 NAS 或内部服务器使用。 理想效果是: 1)通过公网 IP 即可访问家中台式机 2)无需依赖第三方穿透平台 3)网络结构稳定、安全、可长期运行 **【进一步规划】** 1. 如果方案成熟,希望未来可以升级为企业级架构,实现: 2. 华为云服务器与阿里云服务器之间的专线式互联 3. 多云环境之间的安全组网 4. 家庭网络与云服务器统一纳入同一个虚拟内网 5. 支持后续扩展多节点、多区域部署 **【核心目标】** 搭建一套: 稳定 可扩展 支持多云互联 安全性较高 的 VPN 组网方案。
centos7上coturn服务启动后无法访问的故障处理
### 提问背景 我正在开发webrtc的视频通话功能,建立P2P的连接需要搭建stun/turn服务器,于是我在阿里云centos7服务器上利用coturn在3478端口启动了该服务,但是在测试时发现服务不可用。   ### 尝试解决 ##### 一开始,我以为是端口未开放的问题,于是我在安全组设置了入方向和出方向的端口对全部流量进行全部开放,并且关闭了防火墙的限制,但是依然没有用。 ### 详细信息 启动命令 ```js /usr/local/turnserver/bin/turnserver -v -r 47.94.53.126 -a -o -c /usr/local/turnserver/share/examples/turnserver/etc/turnserver.conf ``` 具体配置 ```js listening-port=3478 listening-ip=172.18.61.183 tls-listening-port=5349 # TLS 加密端口 cert=/ssl/cert.pem pkey=/ssl/cert.key external-ip=47.94.53.126 user=user:654321 realm=47.94.53.126 lt-cred-mech relay-ip=0.0.0.0 # 至于为什么配置relay-ip=0.0.0.0 ?? # 因为我尝试填写了内网ip或外网IP,但都无效 min-port=49152 max-port=65535 verbose log-file=/var/log/turnserver.log ``` 部分日志 ```js 696: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 696: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 706: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 706: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 716: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 716: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 726: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 726: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 736: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 736: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 743: session 001000000000000010: refreshed, realm=<47.94.53.126>, username=<user>, lifetime=0 743: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet REFRESH processed, success 743: session 001000000000000011: refreshed, realm=<47.94.53.126>, username=<user>, lifetime=0 743: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet REFRESH processed, success 744: session 001000000000000010: usage: realm=<47.94.53.126>, username=<user>, rp=22, rb=1160, sp=22, sb=1888 744: session 001000000000000010: closed (2nd stage), user <user> realm <47.94.53.126> origin <>, local 172.18.61.183:3478, remote 36.112.200.70:30675, reason: allocation timeout 744: session 001000000000000010: delete: realm=<47.94.53.126>, username=<user> 744: session 001000000000000010: peer 172.17.0.1 deleted 744: session 001000000000000010: peer 36.112.200.70 deleted 744: session 001000000000000010: peer 10.24.68.63 deleted 744: session 001000000000000010: peer 47.94.53.126 deleted 744: session 001000000000000011: usage: realm=<47.94.53.126>, username=<user>, rp=22, rb=1160, sp=22, sb=1888 744: session 001000000000000011: closed (2nd stage), user <user> realm <47.94.53.126> origin <>, local 172.18.61.183:3478, remote 36.112.200.70:30676, reason: allocation timeout 744: session 001000000000000011: delete: realm=<47.94.53.126>, username=<user> 744: session 001000000000000011: peer 172.17.0.1 deleted 744: session 001000000000000011: peer 36.112.200.70 deleted 744: session 001000000000000011: peer 10.24.68.63 deleted 744: session 001000000000000011: peer 47.94.53.126 deleted ``` 使用lsof命令查看端口信息 ```js [root@iZ2zeh5hzhg0kgjwdxkm9cZ ~]# lsof -i :3478 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME turnserve 27441 root 17u IPv4 25694475 0t0 TCP iZ2zeh5hzhg0kgjwdxkm9cZ:stun (LISTEN) turnserve 27441 root 20u IPv4 25693882 0t0 TCP iZ2zeh5hzhg0kgjwdxkm9cZ:stun (LISTEN) turnserve 27441 root 22u IPv4 25693885 0t0 UDP iZ2zeh5hzhg0kgjwdxkm9cZ:stun turnserve 27441 root 23u IPv4 25693886 0t0 UDP iZ2zeh5hzhg0kgjwdxkm9cZ:stun ```
【大专学历】起起伏伏的两年运维路
时间倒回到那天,得知自己专转本考试失败后,人生感觉完了。———— 计算机专业,带专学历,诶哥们,你说这扯不扯 你都大专学历了,这offer我要干嘛呢,送你得了。 工作后的感想就是 动不动就会来了个大的让你感觉人生完蛋了,但是人生该咋样还是咋样,该吃吃该喝喝,总会过去的。 那个时候,真感觉完蛋了,啥技术项目都不会,也没系统地学习过编程,直到现在都是个半吊子水平,只不过 我必须坦诚地说,我运气很好,第一份工作,家里直接帮我安排了,我叔叔在南京干it这一块混了个经理水平,找几个负责人喝了喝酒,就把我丢到无锡的某司干it去了。但是,因为经济不好,+ 把我塞进去的老板跟他爹关系不好,老板愿意丢我进来混,老板他爹不愿意啊 —— 公司不是有it了 又招一个,不浪费钱吗 ? 所以实际上也就呆了三个月就给我干滚蛋了,但是起码啊,有三个月的经验和履历了,再包装包装,说自己干了半年,再吹吹牛 我又实习过半年,就这样,我混到第二家公司干系统运维去了。 说是系统运维,实际上和第一家公司一样,搞搞桌面,网络,服务器因为是传统制造业,也没那么多的需求和迭代,经理自己一个人都能搞定了。 ———————— **https://www.bilibili.com/video/BV1nx4y1v7FV/?spm_id_from=333.337.search-card.all.click** 这期课程含金量还是挺高的,因为如果是像我这样小地方做做运维来讲,基本上就是这些内容。这期视频底下也有我的评论:“如果能掌握到 UP主说得这些内容,再略懂一点交换机的基础排障、配置的思路和命令,基本上小公司(像是乙方给国企单位啊医院 之类干活的)的网络运维,完全没问题了。日常网络这一块基本就是这样,如果是甲方内部的it运维,这些玩意甚至不用特别懂 基本上也能开混开摆了,当然都懂一些肯定更好。” 真实工作当中就这样,网络运维的方向 因此呢 网络这一块的薪资待遇,如果不是去大的集成商、代理商和运营商的公司,基本上小地方 也就五六千的水平吧,因为需要掌握的排障技能就这么些。 “自己刚踏入社会的职业发展大概就这么定型了。 像我们这种小地方的话,如果你是去小公司做网络运维,那么弱电和监控,基本上是躲不掉的,毕竟这种维保的活就这些。 在稍微大点的公司内部的话,基本上 桌面维护的活也是躲不掉的,打印机和电脑故障问题 ———— 没办法,运维是这样的,身兼数职。 像是这一个视频的作者,他是不推荐学生,刚毕业的应届生做运维这一行的 他认为这一行只适合养老和躺平 确实是这样的 干过运维这一行的都知道他为什么会这么说。 但 这个世界也很真实,我就属于那种开发也没卷出来的 不是我选择了运维,而是运维收留了我,就我这专科学历,不是运维 要么就是去做测试 要么就是告别IT行业里的技术岗位转行了。 再加上,运维这一行只是上下限都大得厉害 像我这种水平、阶段和段位的工程师,确实也就是 别人眼中的‘网管啊’、‘机房管理员’什么的,但厉害的运维,还是有点发展前景的 就是得有自驱力、得能自学。 而且运维这行,跟网工也一样,也吃平台 平台高,发展得自然而然就能好;在大公司干运维 和小公司干运维区别确实会差很多,小公司乙方的运维 很多也确实就是到别的机房里去拧拧螺丝、上上架设备 调试设备是另一批厂商派来的人;大点公司就看公司有多大了 不同级别、规模的公司都是不一样的。 其他倒是没啥好说的,毕竟生活嘛 我这也才刚毕业没多久、水货一个 多多学习,其他的交给天意和缘分。” 这是刚毕业后,一年的时候,自己写的文章,那个时候,自己还是有点意气风发的。实际上自己上班也没咋学,公司上市失败,资金链出了很严重的问题,来了一个新执行董事对着公司大刀阔斧的改革,最大的变动就是人员架构的调整,能开的基本上都开干净了,也没我的一席之地了,就这么滚蛋了。 去上海两三个月没搞明白上海,所以还是回了无锡。目前有个offer已经走到老板那里的流程了,老板点头就有班上了,希望一切顺利吧。无锡并不是it岗位多的地方,目前自己也还小 23岁 只想混混日子 来鱼皮的编程导航也快一年了,教程更新了那么多,很惭愧 大多数都没咋看,又看了鱼皮最新的一期讲自己创业历程的视频,只能说我是一个被鱼皮大大所打动的那么一个混子,因为鱼皮的执行力很强,又很卷很能折腾,做了那么多事,再回头看过来自己 基本上也没学啥,日子就那么浑浑噩噩地过,想跟着鱼皮跟着编程导航的大家一起好好学了。 自己也没头绪也不知道未来用不用得到,也都无所谓 一眨眼自己都是两年经验的it了,再努努力,就三年经验了,自己要是真懂点技术,随便包装包装点项目,配合上ai的加持,自己也更有信心了 未来说不定也能做做其他的方向就是了。 编程导航的大家,都很努力啊。 作为编程导航的一员 自己也得努力起来了。
简历或者职业方向的疑惑,求大佬们给点建议,跪谢!!! 23届,双非民办。 下面有两个版本的运维岗简历,一个是基础版,另一个是用AI优化和精简过的版本。 让我有些困惑的是,我在运维方向的技能并不是特别扎实(啥都接触但是啥都不精),但目前还是从事这方面的工作。 现在有几个岗位机会,都是驻场运维相关的岗位(比如监狱的运维岗、很多都是跟政府相关的运维岗,技术要求没那么高),但我其实并不太想继续往这个方向发展。 之前我也在学习Java,想转向Java后端开发岗位,但发现相关岗位大多要求有几年工作经验,所以比较难找到合适的机会。 目前我在河南,除了郑州,其他小城市也不太好找相关岗位。对自动化比较感兴趣,日常也会用Python写一些自动化软件。 是继续走运维方向,还是尝试转向Java后端开发或者是Python方向? 我最开始找工作就是想做后端开发,但没找到合适的岗位,只能先做运维,一边做一边学,后来因为项目问题,跑路了现在休息一个月了。 大家对我的简历或者职业方向有什么建议? 非常感谢大家!!!!!@编程导航_小y @程序员鱼皮 @
白嫖 GitHub 当流水线
# 前言 前段时间,笔者有个桌面端产品进入了快速迭代期,更新频率突然高了起来。 每次发版,我都得当“人肉流水线”: 1. 先在 Windows 电脑上跑一遍构建,打个 .exe 包。 1. 然后再滚到 Mac 电脑上,再跑一遍,打个.dmg 包。 1. 最后再吭哧吭哧手动传到服务器。 频繁更新几次后,我逐渐感到不对劲了:<span style="color: red;font-size: 18px">“都什么年代了,还在这儿玩‘纯手工’?”</span> 作为一个有追求的开发者,我意识到这样下去不行,**至少**也得引入**自动化构建,** 不然每次构建十几二十分钟就浪费了。 我第一个想到的,就是 GitHub Actions。 # 为什么是 GitHub Actions ? 众所周知,GitHub 是赛博大善人。 在**任何仓库内都提供了强大的自动化构建功能**,它能够直接提供多种系统的虚拟机作为运行环境,而且笔者的项目代码正好托管在 GitHub 上,这简直是最佳选择!  更重要的是,这个功能对公开和私有仓库都非常友好:**对公开仓库是免费的,私有仓库也配有 2000 分钟的免费时长限额(帐号共享)。**  它直接提供了三种系统的虚拟机:**Ubuntu、windows、macOS**。 这非常适合我的需求(Windows 和 macOS 打包)。  # 别急着抄,先搞懂这 3 个“灵魂”配置 光会复制粘贴AI代码是不够的,你炼丹不得知道丹方的作用吗?代码也是,你最好知道每个重要配置项是什么作用的。 ## 重点 1:strategy: matrix (并行构建) ```YML strategy: fail-fast: false matrix: os: [macos-latest, windows-latest] ``` 这是节省 Actions 资源的重要配置,因为 GitHub 是按虚拟机运行时间来计费的。 <span style="color: red;font-size: 18px">matrix: { os: [...] }</span>:这是官方提供的“矩阵构建”。GitHub 看到这个,会同时启动两台虚拟机(一台 Mac,一台 Win),并行跑下面的所有 steps。 <span style="color: red;font-size: 18px">fail-fast: false</span>:“防翻车”配置。 默认是 true,意思是一旦 Mac 挂了,Windows 也会被“连坐”干掉。改成 false 后,Mac 翻车了,Windows 照样跑它的,互不干扰。 ## 重点 2:actions/cache@v4 (提速核心) ```YML - name: Cache npm and node_modules (macOS) if: matrix.os == 'macos-latest' uses: actions/cache@v4 with: path: | ~/.npm node_modules key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json', 'bun.lock', 'bun.lockb') }} restore-keys: | ${{ runner.os }}-npm- ``` <span style="color: red;font-size: 18px">GitHub 虚拟机每次运行 Action 都是全新的</span>,npm install 能慢死人。 actions/cache@v4 就是官方提供的缓存包,能把 node_modules 和 npm 缓存(~/.npm)打包存起来。 key 是“钥匙”,用 lock 文件 的哈希值生成。 下次跑,如果 key 就一样,直接把缓存解压出来,npm ci 就能直接读缓存了 ⚡ ## 重点 3:Upload Artifact (分包上传) ```YML - name: Upload macOS ARM64 artifact if: matrix.os == 'macos-latest' uses: actions/upload-artifact@v4 with: name: macos-arm64-dmg path: dist/electron/*-arm64.dmg ``` 这是 Electron 项目的刚需。Mac 现在必须分 arm64(M 芯片)和 x64(Intel)。 我们用 path 通配符 \*-arm64.dmg 来精确匹配,把它们分成不同的产物(Artifacts)上传,方便单独下载。 # 放一下笔者目前在用的配置 说实话,这玩意儿的配置项又多又杂。AI 写的也不一定好使,都得微调。(不过如果你对配置项很熟,可以在第一次 prompt 的时候就描述清楚关键词,这样后面改的工作量就少些) 笔者这里直接把我在用的 **YAML 贴出来**。这套配置改过几版,目前基本能用,**集成了“并行构建”、“防翻车”、“缓存提速”、“分包上传”**等玩意儿。 ```yml # 1. 'name': 这个 Action 在 GitHub UI 上显示的名字 name: 跨平台构建(macOS + Windows) # 2. 'on': 触发这个 Action 的事件 on: # 2.0 自动触发:当 package.json 或任何锁文件变更时,在 main 分支上触发 push: branches: - master # 确保这是你要构建代码的分支 paths: - 'package.json' - 'bun.lock' # 2.1 'workflow_dispatch': 允许你"手动"在 GitHub 网页上点按钮触发 workflow_dispatch: # 2.1.1 'inputs': 定义手动触发时可以输入的参数 inputs: # 2.1.1.1 'build_message': 定义一个叫 "build_message" 的输入框 build_message: # 'description': 输入框旁边的提示文字 description: "构建说明(可选)" # 'required': 是否必须填写 (false = 不必须) required: false # 'default': 留空时的默认值 default: "手动触发跨平台构建" # 3. 'jobs': 定义这个 Action 要跑的所有"任务" (可以有多个 job) jobs: # 3.1 'build': 定义一个叫 "build" 的 job build: # 3.2 'strategy': 定义这个 job 的"策略" (比如并行、矩阵) strategy: # 3.2.1 'fail-fast': 关键配置!false = "防翻车" # 意思是,一个平台(Mac)挂了,另一个(Win)继续跑,别"连坐" fail-fast: false # 3.2.2 'matrix': "矩阵",核心。让 job 并行跑多次 matrix: # 3.2.2.1 'os': 定义一个叫 'os' 的变量,它有两个值 os: [macos-latest, windows-latest] # 这会导致 job 跑两次 # 3.3 'runs-on': 指定 job 跑在哪台虚拟机上 # '${{ matrix.os }}' 会动态读取矩阵里的值 (第一次是 macos, 第二次是 windows) runs-on: ${{ matrix.os }} # 3.4 'steps': 这个 job 要执行的"步骤" (按顺序执行) steps: # 3.4.1 'name': 步骤 1: "拉取代码" (UI上显示的名字) - name: Checkout code # 'uses': 使用一个"现成的" Action 插件 (来自市场) uses: actions/checkout@v4 # v4 是版本号 # 3.4.2 'name': 步骤 2: "安装 Node.js 环境" - name: Setup Node.js # 'uses': 使用安装 Node.js 的插件 uses: actions/setup-node@v4 # 'with': 传给这个插件的参数 with: # 'node-version': 指定 Node.js 的版本号 (锁死版本是好习惯) node-version: "20" # --- 缓存 node_modules (注释行,方便阅读) --- # 3.4.3 'name': 步骤 3: "缓存 (Mac)" (提速核心) - name: Cache npm and node_modules (macOS) # 'if': 条件判断,只在 'os' 变量是 'macos-latest' 时才跑这一步 if: matrix.os == 'macos-latest' # 'uses': 使用缓存插件 uses: actions/cache@v4 with: # 'path': 要缓存的"路径" (Mac的npm缓存在 ~/.npm) path: | ~/.npm node_modules # 'key': 缓存的"钥匙" (用系统名+lock文件哈希值) key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} # 'restore-keys': "备用钥匙",key 没命中时,会尝试捞最近的缓存 restore-keys: | ${{ runner.os }}-npm- # 3.4.4 'name': 步骤 4: "缓存 (Windows)" - name: Cache npm and node_modules (Windows) # 'if': 只在 Windows 虚拟机上跑 if: matrix.os == 'windows-latest' uses: actions/cache@v4 with: # 'path': Windows 的 npm 缓存路径不一样,得分开写 path: | ~\AppData\Roaming\npm-cache node_modules # 'key': 钥匙 (同上) key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} # 'restore-keys': 备用钥匙 (同上) restore-keys: | ${{ runner.os }}-npm- # 3.4.5 'name': 步骤 5: "显示构建信息" (打日志,方便追溯) - name: Show build info # 'run': 自己跑 shell 命令 run: | echo "🚀 触发平台 - ${{ matrix.os }}" echo "📝 构建说明: ${{ github.event.inputs.build_message }}" # 读取手动输入的 'build_message' # 'shell': 指定用哪个 shell 跑 (bash 通用性好) shell: bash # 3.4.6 'name': 步骤 6: "创建 .env 文件" (如果构建需要) - name: Create .env file (if needed) run: echo "NODE_ENV=production" > .env shell: bash # --- 使用 npm ci (注释行) --- # 3.4.7 'name': 步骤 7: "安装依赖" (专业姿势) - name: Install dependencies (npm) run: | # 'if': 检查 lock 文件在不在 if [ -f "package-lock.json" ]; then # 'npm ci': 严格按 lock 文件安装 (CI环境首选,防灵异事件) npm ci --include=dev # '--include=dev' 顺便装 devDependencies else # 'npm install': 备用方案 npm install fi shell: bash # 3.4.8 'name': 步骤 8: "执行构建" - name: Build application # 'run': 跑 package.json 里的 "build:ci" 脚本 run: npm run build:ci # 'env': 注入"环境变量" env: NODE_ENV: production # 告诉脚本,这是生产环境 CI: true # 告诉脚本,这是在 CI 里跑的 # --- 检查构建产物 (注释行) --- # 3.4.9 'name': 步骤 9: "检查产物 (Mac)" (Debug神器) - name: List build output and check sizes (macOS) if: matrix.os == 'macos-latest' run: | # 'ls': 看看 'dist/electron' 目录里有啥 (|| echo... 是为了防止目录不存在时报错) echo "=== Build output (dist/electron) ===" ls -la dist/electron/ || echo "dist/electron/ not found" # 'find': 找找有没有超过 500MB 的"胖"文件 (防止把不该打的打进去了) find dist/ -type f -size +500M -exec ls -lh {} \; 2>/dev/null || echo "No oversized files found" shell: bash # 3.4.10 'name': 步骤 10: "检查产物 (Windows)" - name: List build output and check sizes (Windows) if: matrix.os == 'windows-latest' run: | echo "=== Build output (dist/electron) ===" ls -la dist/electron/ || echo "dist/electron/ not found" find dist/ -type f -size +500M -exec ls -lh {} \; 2>/dev/null || echo "No oversized files found" shell: bash # --- 分包上传 (注释行) --- # 3.4.11 'name': 步骤 11: "上传 Mac ARM64 包" (Electron 刚需) - name: Upload macOS ARM64 artifact if: matrix.os == 'macos-latest' # 'uses': 使用"上传产物"插件 uses: actions/upload-artifact@v4 with: # 'name': 上传后,在 UI 上显示的名字 (M 芯片) name: macos-arm64-dmg # 'path': 要上传的文件的路径 (用通配符 *) path: dist/electron/*-arm64.dmg # 'retention-days': 产物保留 7 天 (别占人家便宜太久) retention-days: 7 # 3.4.12 'name': 步骤 12: "上传 Mac Intel 包" - name: Upload macOS Intel artifact if: matrix.os == 'macos-latest' uses: actions/upload-artifact@v4 with: # 'name': Intel 芯片的包 name: macos-intel-dmg path: dist/electron/*-x64.dmg retention-days: 7 # 3.4.13 'name': 步骤 13: "上传 Windows 包" - name: Upload Windows artifacts if: matrix.os == 'windows-latest' uses: actions/upload-artifact@v4 with: # 'name': Windows 的安装包 name: windows-setup path: | dist/electron/*.exe dist/electron/*.exe.blockmap # blockmap 是增量更新用的,顺便传 retention-days: 7 ``` 也可以看官方的[快速启动教程](https://docs.github.com/en/actions/get-started/quickstart) # 最后 从“人肉流水线”到“一键触发”,其实就是一份 YAML 文件的距离。 对于有频繁构建烦恼、又不想掏钱买高额虚拟机的开发者来说,GitHub Actions 绝对是“赛博大善人”。 你可能会说,这 YAML 一百多行,谁记得住? <span style="color: red;font-size: 18px">你不需要记住。</span> 在 AI 时代,你只需要知道**“我需要一个带缓存、能防翻车、可以并行跑 Mac 和 Win 的 CI”**,然后把这个需求丢给 AI,让它给你出第一版配置。 我们的工作,已经从“埋头写”变成了“Review(审查)”。 理解上面那几个“灵魂”配置项,你就能轻松审查 AI 给你的 YAML 到底靠不靠谱。 快去试试吧,别再浪费时间“手动打包”啦!
长沙神漫文化运维
一面: 1,安装win11系统步骤? 2,配置电脑的型号 3,显卡了解哪些? 4,文件打开乱码怎么处理? 5,了解哪些建模工具? 6,谈谈你对这个岗位的想法? 7,是否了解ad域搭建? 主管面: 纯聊天,啥也没问,就介绍公司最近要上线的动漫项目。我这岗位就两个人,我偏向硬件。 有点儿桌面运维的感觉
合胜科技桌面运维
win11安装的过程? win10和win11的区别? 加入驱动掉了该怎么解决? 了解过哪些网络协议? 网络连不上怎么解决? 如果客户很急,你该怎么去面对解决? 自己工作中遇到的最大的困难,并如何解决的?
运维系统故障恢复--系统引导文件出错
## 系统引导文件出错 使用情况:系统因为我的误操作,系统重启或服务器登陆时导致系统不能启动,或某些应用不能启动。开机引导不起来了,我们怎样去恢复它,使系统可以正常使用。 **注意:** 进行故障修复时它就不可能通过什么通过Xshell远程工具去做到的,你需要登录到本地,也可以外地远程本地。 **具体步骤如下:** ### 1、模拟故障。 /boot/grub2/grub.cfg (此文件为引导配置文件)破坏此文件,模拟故障。 **关键命令: echo “invalid configuration”>/boot/grub2/grub.cfg** (把引导文件内容修改为“invalid configuration”) 破坏文件两种方式第一种改名,找不到文件。第二种,我把里面文件内容全替换掉。记得把这个文件备份一下子,并且在操作前加快照。 ### 2、使用安装光盘启动 模拟故障完关机,再次开机我们发现开机引导界面没了,我们该怎么办呢? 1.进入固件将光盘调整为第一位 2.选择troubleshooting ---rescue a centos 输入1(光盘文件系统把Linux硬盘的文件系统呢,变成光盘中的一个目录)从故障排错到救援模式 chroot /mnt/sysimage此地址存放我们原来的系统, 进入救援模式我们可以看见系统提示原来的文件系统被放在此目录下了。 3.使用chroot命令将根目录从光盘文件系统变为原来的硬盘文件系统。 关键命令: 进入根目录cd / 替换目录 chroot /mnt/sysimage/ 4..重新生成新的引导文件,并将引导文件变为正确的引导文件。 第一种情况:引导文件有备份,直接使用备份恢复 第二种情况:无备份,重新生成再输入文件 关键命令: **grub2-mkconfig -o /boot/grub2/grub.cfg** grub2-mkconfig是一个用于生成GRUB的工具.会扫描系统中已经安装的操作系统,内核等相关信息然后生成对应的GURB配置信息。后面表示输出到后面文件地址 5.exit 6.reboot(记得关闭光盘链接,不行的话就固件改顺序)
