在 Docker Compose 中为项目启用 IPv6 并可通过 IPv6 可访问

需求:在 Docker 环境下启用 IPv6,使基于 nginx 的容器服务可通过 IPv6 访问。 为网络启用 IPv6 添加 enable_ipv6: true 并配置 ipam。 设置子网前缀为 fd00:abcd::/64。 networks: my-network: driver: bridge enable_ipv6: true ipam: driver: default config: - subnet: "fd00:abcd::/64" 在项目前端的 nginx 配置中,增加 IPv6 监听: listen 80; listen [::]:80 ipv6only=on; enable_ipv6: true + ipam.subnet:告诉 Docker 网络为容器分配 IPv6 地址并(可选)使用指定前缀。 nginx 增加 listen [::]:80:容器内 nginx 需要监听 IPv6 地址,否则即使容器有 IPv6 也无法响应 IPv6 请求。 配置 Docker Engine 必须在 Docker 引擎启用 IPv6,否则容器不会拿到 IPv6 地址。在 /etc/docker/daemon.json 中加入: ...

发布于2026-01-28  ·  Kerolt

RockyLinux启用EPEL软件仓库

epel-release 是一个 RPM 软件包,用于在基于 Red Hat 的 Linux 发行版(如 RHEL、CentOS、Rocky Linux、AlmaLinux 和 Oracle Linux)上启用 EPEL(Extra Packages for Enterprise Linux) 软件仓库。 EPEL 是一个由 Fedora 项目维护的社区驱动的额外软件包仓库,提供不在标准 RHEL 或其衍生发行版基础仓库中的高质量开源软件包。 通常安装方法如下: sudo dnf install epel-release -y sudo dnf makecache

发布于2026-01-26  ·  Kerolt

利用eBPF与perf_event记录系统调用栈

perf_event_open perf 原理图:https://plantegg.github.io/2021/05/16/Perf_IPC%E4%BB%A5%E5%8F%8ACPU%E5%88%A9%E7%94%A8%E7%8E%87/ 在用户态中触发 sys_perf_event_open 系统调用,内核陷入中断以后会调用 perf_event_open 来处理。在用户态,我们可以用如下的代码来使用: #include <linux/perf_event.h> #include <sys/syscall.h> #include <unistd.h> int64_t perf_event_open(struct perf_event_attr* hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags) -> { return syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); } 以文件描述符为中心的“测量单元” 在 Linux 中,“一切皆文件”。当调用 perf_event_open 时,内核创建了一个独立的测量实例。 每个文件描述符代表一个监控任务(1 fd == 1 Event,比如“监控 CPU 0 的指令执行数”)。 同时,可以把多个 fd 绑在一起,即为事件分组 (Group): 例如你想计算“每条指令的缓存未命中率”,你需要同时测量“指令数”和“缓存未命中数”。将它们分组可以确保这两个事件在硬件上是同时开始、同时结束的,从而保证比例的准确性。 状态控制:ioctl 与 prctl 事件创建后,并不一定立即开始工作,你可以像控制开关一样控制它。 ioctl (Input/Output Control):这是最常用的方式,直接针对某个 fd 进行操作。 ioctl(fd, PERF_EVENT_IOC_ENABLE):打开开关。 ioctl(fd, PERF_EVENT_IOC_DISABLE):关闭开关。 prctl (Process Control):这是针对当前进程及其所有事件的操作。 如果你有 10 个测量事件,不需要一个个 ioctl,可以用 prctl 一次性全部启用或禁用。 “保持存在”的意义:禁用事件只是让计数器停止,它不会销毁数据。这允许你在程序运行的特定片段(比如只在某个核心算法执行期间)开启监控。 ...

发布于2026-01-23  ·  Kerolt

CMake与Conan协同工作理解

背景 最近根据 【eBPF 入门实践教程十二:使用 eBPF 程序 profile 进行性能分析】 这篇文章,写了一个性能分析的小工具。不过文章中的实现是 rust,但我还不怎么熟悉 rust,因而打算参考其代码使用 c++ 来实现相同的功能。项目地址:profiler。 rust 中使用 cargo 就能非常方便的管理依赖与构建项目,c++ 中我使用 CMake 来构建项目,Conan 来管理依赖。在使用期间,我对于这二者的协同工作原理感到好奇,因此有了这篇笔记。 文中的出现的“依赖”、“包”、“库”等名词都是指代同一个概念,只是不同的说法而已~ CMake 查找依赖 在 CMake 中查找和管理项目依赖,主要是通过内置的 find_package 命令完成,其会在系统中寻找指定的库。 find_package(<PackageName> [version] [REQUIRED] [COMPONENTS components...]) PackageName: 库的名称(区分大小写,如 OpenCV、Qt5)。 REQUIRED: 如果找不到该库,CMake 会直接报错并停止配置。 COMPONENTS: 查找库中的特定模块(例如 Qt5 里的 Widgets)。 CMake 有两种查找库的逻辑: Module 模式 (查找 Find<PackageName>.cmake) CMake 预置了一系列脚本(在 /usr/share/cmake/Modules 下)。它会寻找名为 FindGSL.cmake 这样的文件。 适用场景: 较老或不直接支持 CMake 的库(如 CURL, ZLIB)。 Config 模式 (查找 <PackageName>Config.cmake 或 <lower-case-pkg>-config.cmake) 这是现代库推荐的方式。库在安装时会自带一个配置文件。 适用场景: OpenCV, Qt, Protobuf 等现代库。 查找路径: 库的安装路径、CMAKE_PREFIX_PATH 或环境变量。 CMAKE_PREFIX_PATH 当在 CMake 中使用 find_package、find_library 或 find_path 等指令去寻找一个外部库时,CMake 并不知道这个库安装在哪里。CMAKE_PREFIX_PATH 就是用来告诉 CMake 去这些目录下找找看。 ...

发布于2026-01-22  ·  Kerolt

如何在CMake工程中使用Rust库blazesym

在 【eBPF 入门实践教程十二:使用 eBPF 程序 profile 进行性能分析】 这篇文章中, profiler 工具的实现是使用了 rust 编写的 blazesym 库,而我现在打算使用 C++ 实现,还好这个库提供了 C API,但是需要我们将这个 Rust 库的构建集成到 CMake 中。 Corrosion 可将 Rust 集成到现有 CMake 项目中,它是一个 CMake 工具链,旨在让 CMake 像对待原生 C++ 子项目一样对待 Rust 的 Cargo 项目。Corrosion 将手动调用 cargo build,处理复杂的跨平台路径、构建配置(Debug/Release)以及繁琐的链接参数这些过程完全自动化了。 Corrosion 的核心功能 Corrosion 的工作原理是在 CMake 层面为 Cargo 包装了一层“外壳”,其主要功能包括: 自动处理构建类型:CMake 的 Release 或 Debug 模式会自动映射到 Cargo 的 --release 或默认模式。 目标导入:将 Rust 的 staticlib 或 cdylib 导入为标准的 CMake 目标(Targets),你可以直接对它们使用 target_link_libraries。 跨平台交叉编译:它能自动将 CMake 的交叉编译设置(如 Android, iOS, 嵌入式等)传递给 Rust 的目标三元组(Target Triple)。 多包支持:支持 Cargo 工作区(Workspaces)和单个 Crate。 项目结构 在我的项目 profiler 中使用 Corrosion 时,项目布局如下: ...

发布于2026-01-22  ·  Kerolt

C++对Rust中Result的简单模仿

注意! 以下代码需要支持 C++23 的编译器 这里利用 std::expected 和 std::unexpected 进行模仿: #include <print> #include <string> #include <expected> template <typename E = std::string> using Err = std::unexpected<E>; template <typename T, typename E = std::string> using Result = std::expected<T, E>; struct Inner { int a, b; }; struct X { Inner* i_; X(Inner* i) { std::println("X()"); i_ = i; } ~X() { std::println("~X() delete inner obj"); delete i_; } }; auto foo(bool flag) -> Result<X> { if (!flag) { return Err<>("Flag is false!"); } Inner* i = new Inner(); i->a = 1; i->b = 2; return Result<X>{i}; } int main() { std::println("main--1"); { std::println("main--2"); auto x = foo(true); std::println("main--3"); } { std::println("main--4"); auto x = foo(false); std::println("Error message is: {}", x.error()); std::println("main--5"); } std::println("main--6"); } 输出为: ...

发布于2026-01-20  ·  Kerolt

【个性化】个人装机配置

1、Windhawk 通过一些插件来改善体验。 其中“Disable grouping on the taskbar”非常有用,可以让一个应用开多个窗口时任务栏图标不会堆叠,而是每个窗口一个图标。 2、右键扩展 关闭右键扩展: reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve taskkill /f /im explorer.exe & start explorer.exe 如果想要恢复右键扩展: reg delete "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}" /f taskkill /f /im explorer.exe & start explorer.exe 3、ContextMenuManager 链接:https://github.com/BluePointLilac/ContextMenuManager 右键菜单内容管理工具。 4、Dism++ Windows 系统清理、配置项调整。 5、用户名调整为英文 简单来说就是重命名一个目录 + 更新一个对应的注册表项。 具体看知乎的文章:https://zhuanlan.zhihu.com/p/509804656 6、修改默认目录名为英文 系统路径内的目录不仅有图标还显示中文名称,但是打开路径的时候显示的却是英文,如何修改呢? (1)显示受保护的操作系统文件 先要显示受保护的操作系统文件,设置完成之后将会看到 desktop.ini 文件( desktop.ini 在每个目录内都有一个),如果没看到,就要勾选“查看”->“显示”->“隐藏的项目”。 (2)编辑 desktop.ini 如果要设置哪个目录的别名就找到哪个目录内的 desktop.ini 文件,并编辑下图红框中的内容: 将 LocalizedResourceName 最后的数字修改为想要的目录名称,设置完成之后保存 刷新就 OK 了,设置完成注意要 隐藏受保护的操作系统文件。 好像不同版本后面的数字不同,在修改前记得保存。 7、用户目录下创建数据盘的目录软连接 这样做的目的是我个人想要让用户目录和 Linux 中的 home 目录比较一致,但软件、图片、文档我又不想保存在 C 盘,而是用软连接连接到数据盘(例如 D 盘)。 ...

发布于2026-01-06  ·  Kerolt

【Nginx】location与proxy_pass配置中的斜杠差异

Nginx 作为反向代理服务器,需要精确匹配客户端请求路径,并将请求转发到后端服务。在这个过程中: location 指令:决定哪些请求会被当前配置块处理 proxy_pass 指令:决定如何将请求转发到后端 而斜杠在这两个指令中的不同位置,会改变 Nginx 的匹配逻辑和路径传递行为,配置不当可能导致 404 错误、路径污染或安全风险。 1、Location 配置:/api/vs /api 的核心差异 1.1 语法对比 配置 匹配模式 精确要求 示例匹配结果 location /api/ 前缀匹配(带斜杠) 必须以 /api/ 开头 /api/user✅ /api❌ /api-test❌ location /api 前缀匹配(无斜杠) 以 /api 开头即可 /api/user✅ /api✅ /api-test✅ 1.2 语义解释 /api/:表示一个 " 目录 " 路径,Nginx 会将其视为完整的路径段,只匹配以 /api/ 开头的请求。这种配置更精确,避免了意外匹配。 /api:表示一个 " 前缀字符串 “,匹配所有以 /api 开头的请求,包括 /api 本身、/api/xxx 以及 /api-anything。这种配置更宽泛,可能产生误匹配。 1.3 实际场景分析 场景 1:API 接口路由(推荐使用 /api/) # 推荐配置:精确匹配API目录 location /api/ { proxy_pass http://backend; # 只处理/api/下的所有请求,不会误匹配/api-test } # 不推荐:可能误匹配其他路径 location /api { # 会匹配/api、/api/、/api-test、/api-v2等 # 如果后端没有/api-test接口,可能返回404或错误数据 } 场景 2:静态资源目录(必须使用 /xxx/) ...

发布于2026-01-05  ·  Kerolt

uv包安装网络超时解决

$ uv add numpy pandas torch scikit-learn matplotlib Resolved 45 packages in 21ms × Failed to download `nvidia-cufft-cu12==11.3.3.83` ├─▶ Failed to fetch: │ `https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl` ├─▶ Request failed after 3 retries ├─▶ error sending request for url │ (https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl) ╰─▶ operation timed out help: If you want to add the package regardless of the failed resolution, provide the `--frozen` flag to skip locking and syncing. 这个错误是因为 uv 在尝试从官方源下载 NVIDIA 的 CUDA 组件包(nvidia-cufft-cu12)时网络超时了。 ...

发布于2025-12-12  ·  Kerolt

Linux修改IP

首先确定网络是用什么工具管理: $ systemctl is-active NetworkManager active 说明 网络由 NetworkManager 管理,这种情况修改 IP 通常使用 nmcli: 修改静态 IP 看当前连接名 nmcli connection show 输出类似: NAME UUID TYPE DEVICE Wired connection 1 2d3e1f6a-4e87-4a76-8f23-2f459c8c112b ethernet enp60s0 这里的 NAME(如 Wired connection 1)就是连接名,后面命令要用到。 修改为静态 IP 假设你想把 IP 设置为: IP:192.168.1.100/24 网关:192.168.1.1 DNS:8.8.8.8, 1.1.1.1 执行: sudo nmcli con mod "Wired connection 1" ipv4.addresses 192.168.1.100/24 sudo nmcli con mod "Wired connection 1" ipv4.gateway 192.168.1.1 sudo nmcli con mod "Wired connection 1" ipv4.dns "8.8.8.8,1.1.1.1" sudo nmcli con mod "Wired connection 1" ipv4.method manual 注意 "Wired connection 1" 需要替换为你自己的连接名。 如果名字里有空格,必须加引号。 ...

发布于2025-11-09  ·  Kerolt