普通视图

发现新文章,点击刷新页面。
昨天以前Solitudes

安利一下我最近写的两个caddy插件

2025年5月7日 22:07

我个人 Caddy 粉哈,习惯 Caddy 一梭子,从我历史博客中就可以看出来。最近写了两个 Caddy 的插件,geocngfw.

源码及镜像

源码 ysicing/dockerfiles#caddy

以下是我构建好的镜像,可以根据自己的环境拉取

  • ysicing/caddy2
  • ghcr.io/ysicing/caddy2
  • registry.cn-beijing.aliyuncs.com/k7scn/caddy2
  • ccr.ccs.tencentyun.com/k7scn/caddy2

源码构建

需要 go 环境了

go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
xcaddy build \
    --with github.com/caddyserver/jsonc-adapter \
    --with github.com/caddy-dns/cloudflare \
    --with github.com/caddy-dns/tencentcloud \
    --with github.com/caddy-dns/alidns \
    --with github.com/ysicing/caddy2-geocn \
    --with github.com/ysicing/caddy2-gfw \
    --with github.com/mholt/caddy-dynamicdns \
    --with github.com/mholt/caddy-events-exec \
    --with github.com/WeidiDeng/caddy-cloudflare-ip \
    --with github.com/xcaddyplugins/caddy-trusted-cloudfront \
    --with github.com/mholt/caddy-l4 \
    --with github.com/mholt/caddy-webdav \
    --with github.com/mholt/caddy-ratelimit

插件 geocn

  • 源码:https://github.com/ysicing/caddy2-geocn
  • 用途:识别来源 ip 是否为中国 ip,我的大部分服务都开启了这个,只针对大陆放行,甚至部分服务只针对部分省市(误判比较大,后续有需要也可以开源 😄)
@china {
		geocn 
	}
	file_server @china {
		root ./docker/example/deny
	}

上面是默认参考,正常情况下不需要调整,GeoIP 数据源来自 Hackl0us/GeoIP2-CN,支持自定义

geocn {
 georemote 你的自定义地址
}

插件 gfw

{
    order gfw before respond
}

:80 {
    gfw {
        # 基本规则配置
        block_rule ip:1.2.3.4
        block_rule url:/admin
        block_rule ua:curl
        block_rule_file /path/to/rules.txt
        ttl 24h

        # 额外安全检测(默认关闭)
        enable_extra true
    }
}

目前是所有实例共享黑名单的,命中就 1 天黑名单直接返回 403,之前想的是命中后触发 hook 执行 iptables 封禁 ip,但是容器跑的好像不太方便。

最后

大家对 Caddy 插件有什么的需求或者想法么?


轻松部署 Alist + MinIO,打造你的专属私人网盘

2025年5月6日 20:49

还在为网盘限速、空间不足而焦虑?想要一个安全、快速、完全掌控的私人网盘?今天带你一步步用 Alist 结合 MinIO,快速搭建一个高性能的私人云存储,文件管理从此自由无忧!

部署非常简单,也很适合内网私有化部署。另外这也是一个开源项目,社区灵活度特别高,对接的存储类型非常丰富,但是本文还是着重写写对接 minio。今天的音频调了几版,目前这版相关好点

什么是 Alist 和 MinIO?

  • Alist:一款开源免费的目录列表程序,支持挂载多种存储(如本地存储、云盘、对象存储等),提供简洁美观的界面,支持文件预览、下载、分享等功能。简单来说,它是你文件管理的“超级中枢”。
  • MinIO:一个高性能、分布式的对象存储服务,兼容 S3 协议,适合搭建私有云存储。相比第三方网盘,MinIO 让你完全掌控数据,安全又高效。

通过 Alist + MinIO 的组合,你可以轻松打造一个私有网盘,享受无限存储空间和极速访问体验!

Alist + MinIO 的优势

  • 多存储支持:Alist 支持 MinIO、本地存储、OneDrive、阿里云盘等多种存储方式,灵活扩展。
  • 简洁易用:Alist 界面美观直观,操作简单。
  • 高性能:MinIO 提供企业级的对象存储性能,适合大文件存储和高速访问。
  • 安全可靠:数据存储在你自己的服务器上,隐私有保障。
  • 开源免费:Alist 和 MinIO 均为开源项目,自由使用,社区活跃。

部署步骤:Alist + MinIO 一键搞定

以下以 Docker 部署为例,带你快速搭建 Alist 和 MinIO 的组合。这里就跳过 MinIO 部署相关了,之前也讲过,可以查看我之前写的文章:

准备工作

  • 准备好 MinIO 的账号即可,有存储视频资源最好不过

镜像

根据实际情况来,默认 aio 镜像已经包含本地存储缩略图 ffmpeg 和离线下载 aria2, 后面需要用的上

  • xhofe/alist:main-aio
  • 国内镜像 ccr.ccs.tencentyun.com/k7scn/alist:main-aio

创建 docker compose 文件

  • docker-compose.yml
services:
  alist:
    image: xhofe/alist:main-aio
    # image: ccr.ccs.tencentyun.com/k7scn/alist:main-aio
    container_name: alist
    ports:
      - "5244:5244"
    volumes:
      - /data/alist:/opt/alist/data # 应用程序持久化数据
      - /data/share:/opt/share # 本地存储,可选
    environment:
      - TZ=Asia/Shanghai
      - ALIST_ADMIN_PASSWORD=goxee7dieXeihu9uochoo6iquaighail
    restart: always

ALIST_ADMIN_PASSWORD 支持自定义密码,很早之前我提交的 PR😂,估计也就我一个人这么用。

启动容器

docker compose up -d

配置 caddy

caddy 配置比较简单

alist.ysicing.eu.org {
  reverse_proxy 100.90.80.2:5244
}

访问 alist

访问 Alist:在浏览器输入 http://你的服务器IP:5244 或者 caddy域名,进入 Alist 界面。

默认用户名是 admin, 密码是你配置的 ALIST_ADMIN_PASSWORD 值信息

挂载 MinIO 存储

登录 Alist,点击 管理 > 存储 > 添加

选择存储类型为对象存储

填写以下信息:

  • 挂载路径:自定义,例如 /minio。
  • Endpoint:http://minio 域名地址:9000。
  • Bucket:填写你在 MinIO 创建的存储桶名称,例如 ja。
  • Access Key 和 Secret Key:填入 MinIO 控制台生成的密钥。
  • 强制路径样式:默认勾选
  • 地区:默认留空

保存配置后,返回 Alist 主页,即可看到挂载的 MinIO 存储

可以上面的操作后就可以通过 Alist 浏览、分享 MinIO 中的文件,支持在线预览、下载等功能。

其他

官方文档

总结

通过 Alist 和 MinIO 的组合,你可以轻松搭建一个功能强大、安全可靠的私人网盘,告别存储焦虑!无论是个人文件管理还是团队协作,这个方案都能满足你的需求。快动手试试吧!


私有化部署无名杀卡牌游戏

2025年5月5日 19:52

部署非常简单,非常适合收藏,内网私有化部署。另外这是一个开源项目,灵活度比较高。

项目地址

https://github.com/libnoname/noname

镜像

可以根据自己的网络情况选择对应的镜像下载,镜像比较大, 大概 3.5G 左右。

  • hsiaoshun/noname
  • ccr.ccs.tencentyun.com/k7scn/noname

部署 compose

services:
  noname:
    image: hsiaoshun/noname
    # image: ccr.ccs.tencentyun.com/k7scn/noname
    container_name: noname
    ports:
      - '6080:80'
    restart: always

端口配置

  • 80 游戏本体网页版入口
  • 8080 WS 协议,联机大厅服务(客户端使用)

caddy 代理

示例,不建议公网跑,对带宽有点要求

sgs.ysicing.eu.org {
reverse_proxy 100.90.80.2:6080
}

联机大厅配置说明

目前只支持 windows 和安卓

注意: 结尾的/不能省略, 如果没有证书就是 ws,有证书就是 wss

其他

如果有更多兴趣的话,可以看看无名杀懒人包。


Debian常用初始化流程

2025年5月5日 14:50


在搭建 k3s 轻量级 Kubernetes 集群时,Debian 系统因其稳定性和灵活性成为首选。然而,Debian 默认配置可能无法满足 k3s 的需求,需要通过初始化优化系统设置。本文将分享一套针对 k3s 环境的 Debian 初始化方案,涵盖基础包安装、系统配置和防火墙规则,仅供参考。

安装基础包

以下命令安装 k3s 集群所需的基础工具,保持系统轻量:

export DEBIAN_FRONTEND=noninteractive
apt update -qq
apt remove -y -qq ufw lxd lxd-client lxcfs lxc-common
apt install --no-install-recommends --no-install-suggests -y -qq nfs-common iptables conntrack jq socat bash-completion open-iscsi rsync ipset ipvsadm htop net-tools wget psmisc git curl nload ebtables ethtool procps

配置系统

配置 ssh

修改 ssh 端口,设置密钥登录,禁用密码登录。这些比较常见,这里就不细说了。

更新内核

之前好像也写过,通常我都是使用最新内核,仅供参考.(通常也会踩坑比较多)

curl https://c.ysicing.net/oss/scripts/debian-upcore.sh | bash
# 或者
apt install -t bookworm-backports linux-image-amd64 -y

配置 system 相关

调整 Systemd 的资源限制和日志设置

mkdir -pv /etc/systemd/system.conf.d
cat > /etc/systemd/system.conf.d/30-k8s-ulimits.conf <<EOF
[Manager]
DefaultLimitCORE=infinity
DefaultLimitNOFILE=100000
DefaultLimitNPROC=100000
EOF

mkdir -pv /etc/systemd/journald.conf.d /var/log/journal

cat > /etc/systemd/journald.conf.d/95-k3s-journald.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 最大占用空间 2G
SystemMaxUse=2G
# 单日志文件最大 100M
SystemMaxFileSize=100M
# 日志保存时间 1 周
MaxRetentionSec=1week
# 禁止转发
ForwardToSyslog=no
ForwardToWall=no
EOF

systemctl daemon-reload
systemctl restart systemd-journald

cat > /etc/modules-load.d/10-k3s-modules.conf <<EOF
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF

systemctl daemon-reload
systemctl restart systemd-modules-load

配置防火墙规则

提示:8.8.8.8 为示例白名单 IP,请替换为实际 IP,搭配rc.local

  • /data/scripts/iprule.sh
#!/bin/bash
iptables -I INPUT -s 8.8.8.8 -j ACCEPT
iptables -I INPUT -p udp -j ACCEPT
iptables -I INPUT -i lo -j ACCEPT
iptables -I INPUT -i tailscale0 -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT -s 10.0.0.0/8 -j ACCEPT
iptables -I INPUT -s 172.16.0.0/12 -j ACCEPT
iptables -I INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -I INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A INPUT -p icmp -j DROP
iptables -A OUTPUT -j ACCEPT
iptables -A INPUT -j DROP

防火墙规则没考虑使用 iptables-save 等保存恢复,而是每次开启时重新配置。

总结

通过以上步骤,我们完成了一套针对 k3s 环境的 Debian 系统初始化,优化了网络、资源限制和安全性。你可以直接使用以下脚本一键初始化

curl https://c.ysicing.net/oss/scripts/init.sh

Debian 双栈网络时开启 IPv4 优先(音频版)

2025年5月3日 23:32

PS: 用 AI 生成的图老是不合法微信封面的比例,放到文尾。本文也提供音频版, 欢迎订阅我的微信公众号。

在如今的网络世界,IPv6 正在逐渐普及,但 IPv4 依然是许多场景的“老大哥”。如果你用的是 Debian 系统,并且身处 IPv4 和 IPv6 共存的双栈网络环境,可能会发现系统默认优先使用 IPv6——这在某些情况下并不理想,比如某些服务只支持 IPv4,或者 IPv6 连接不稳定。今天,我们就来聊聊如何在 Debian 上实现 IPv4 优先,甚至在需要时完全禁用 IPv6。跟着这篇教程,轻松搞定网络配置!

为什么需要调整网络优先级?

先来点背景知识:双栈网络指的是设备同时支持 IPv4 和 IPv6 协议栈。现代操作系统(如 Debian)和浏览器通常默认优先使用 IPv6,只有当 IPv6 连接失败时才会“退而求其次”用 IPv4。这听起来很智能,但在实际场景中可能会遇到问题:

  • 服务兼容性:某些老旧服务或内网应用只支持 IPv4,IPv6 优先可能导致连接失败
  • 网络性能:部分网络环境下,IPv6 的延迟或稳定性不如 IPv4
  • 特殊需求:比如开发测试时,你可能希望强制使用某一种协议

所以学会调整 IPv4 和 IPv6 的优先级,或者在极端情况下禁用 IPv6,是每个 Debian 用户的“进阶技能”。下面,我们一步步教你搞定!

让 IPv4 优先:修改 gai.conf 文件

Debian 系统中,/etc/gai.conf 文件控制了 getaddrinfo 函数的行为,这个函数决定了系统如何选择 IPv4 或 IPv6 地址。默认情况下,IPv6 优先,但我们可以通过简单修改让 IPv4 站到“C 位”。

修改步骤

打开终端,输入以下命令编辑 /etc/gai.conf

#precedence ::ffff:0:0/96  100

去掉 # 号,修改为:

precedence ::ffff:0:0/96  100

保存并退出。

懒人福利:如果你不想手动编辑,可以直接用这条命令一键搞定:
bash

sed -i 's/#precedence ::ffff:0:0\/96  100/precedence ::ffff:0:0\/96  100/' /etc/gai.conf

测试效果

配置完成后,用 curl 命令测试一下:

curl ip.sb

也可以使用

# 查询本机外网IPv4地址
curl 4.ipw.cn

# 查询本机外网IPv6地址
curl 6.ipw.cn

# 测试网络是IPv4还是IPv6访问优先(访问IPv4/IPv6双栈站点,如果返回IPv6地址,则IPv6访问优先)
curl test.ipw.cn

如果返回的是类似 6.6.6.6 的 IPv4 地址,恭喜你,IPv4 优先已生效!如果返回的是类似 2001:db8::2 的 IPv6 地址,检查是否正确保存了配置。

原理

::ffff:0:0/96 是 IPv4 地址在 IPv6 协议中的映射范围,设置其优先级为 100(高于默认 IPv6 的优先级),系统就会优先选择 IPv4 地址。

特殊场景:强制 IPv6 优先

有些朋友可能有“奇特”需求,比如测试 IPv6 环境或某些服务明确要求 IPv6 优先。别担心,我们也可以反向操作!

同样编辑 /etc/gai.conf, 在文件末尾添加以下两行:

label 2002::/16    1
label 2001:0::/32   1

保存退出,或者用命令一键添加:
bash

echo -e "label 2002::/16    1\nlabel 2001:0::/32   1" | sudo tee -a /etc/gai.conf

原理

2002::/162001:0::/32 是常见的 IPv6 地址段,设置它们的 label 优先级为 1,确保系统优先选择这些 IPv6 地址。IANA 目前分配的公网 IPv6 地址还未覆盖到 3000:0000::/4,所以这招基本万无一失

(这个未测试过,仅供参考)

极端情况:完全禁用 IPv6

如果你的网络环境压根不需要 IPv6,或者 IPv6 总给你添乱,可以直接禁用它。以下是禁用 IPv6 的方法,适合“断舍离”爱好者。
编辑 /etc/sysctl.conf 文件:

net.ipv6.conf.all.disable_ipv6 = 1
# 禁用eth0的ipv6
net.ipv6.conf.eth0.disable_ipv6 = 1

结语

通过简单的配置文件调整,你就可以在 Debian 双栈网络中自由掌控 IPv4 和 IPv6 的优先级,甚至彻底禁用 IPv6。无论是提升网络兼容性、优化性能,还是满足特定需求,这些技巧都能让你事半功倍!


Debian 12 解决 /etc/rc.local 开机启动问题

2025年5月3日 06:59

在 Debian 12(以及 Debian 9 及以上版本)中,/etc/rc.local 是配置开机自启动脚本的传统方式,但默认未启用,导致自定义脚本无法自动运行。本文将详细指导你在 Debian 12 上启用和配置 /etc/rc.local,步骤同样适用于 Debian 9 Stretch、10 Buster 和 11 Bullseye

问题背景:rc.local 为什么不生效?

Debian 9 起采用 systemd 作为初始化系统,传统的 /etc/rc.local 默认不生效。尽管系统内置了 rc-local,但默认处于禁用状态:

root@debian:~$ systemctl status rc-local.service
○ rc-local.service - /etc/rc.local Compatibility
     Loaded: loaded (/lib/systemd/system/rc-local.service; static)
    Drop-In: /usr/lib/systemd/system/rc-local.service.d
             └─debian.conf
     Active: inactive (dead)
       Docs: man:systemd-rc-local-generator(8)

以下是默认的 rc-local.service 配置,表明它会在 /etc/rc.local 可执行时自动拉起:

root@docker:~$ systemctl cat rc-local.service
# /lib/systemd/system/rc-local.service
#  SPDX-License-Identifier: LGPL-2.1-or-later
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

# /usr/lib/systemd/system/rc-local.service.d/debian.conf
[Unit]
# not specified by LSB, but has been behaving that way in Debian under SysV
# init and upstart
After=network-online.target

# Often contains status messages which users expect to see on the console
# during boot
[Service]
StandardOutput=journal+console
StandardError=journal+console

解决步骤:启用 /etc/rc.local

以下步骤助你快速启用 /etc/rc.local,实现开机脚本自动运行

创建 /etc/rc.local 文件

默认没有 /etc/rc.local,我们需要手工添加一个 /etc/rc.local 文件:

cat <<EOF >/etc/rc.local
#!/bin/bash
# 这是一个示例 rc.local 文件
# 在这里添加你的开机执行命令
# 示例:启动一个自定义脚本
# /path/to/your/script.sh
exit 0
EOF

设置可执行权限

确保文件具有可执行权限

chmod +x /etc/rc.local

启用并立即启动 rc-local 服务

启动 rc-local 服务,此时可能会弹出警告,可直接忽略

systemctl enable --now rc-local

检查服务状态, 状态显示 active (exited) 表示服务已运行

root@docker:~$ systemctl status rc-local.service
● rc-local.service - /etc/rc.local Compatibility
     Loaded: loaded (/lib/systemd/system/rc-local.service; static)
    Drop-In: /usr/lib/systemd/system/rc-local.service.d
             └─debian.conf
     Active: active (exited) since Fri 2025-05-02 18:21:26 EDT; 3s ago
       Docs: man:systemd-rc-local-generator(8)
    Process: 333116 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)
        CPU: 4ms

May 02 18:21:26 docker systemd[1]: Starting rc-local.service - /etc/rc.local Compatibility...
May 02 18:21:26 docker systemd[1]: Started rc-local.service - /etc/rc.local Compatibility.

添加自定义开机脚本

在 /etc/rc.local 的 exit 0 前添加命令。例如:

#!/bin/sh -e
#
# rc.local
#
# By default this script does nothing.
/data/scripts/ip.sh || true
exit 0

注意:使用绝对路径(如 /data/scripts/ip.sh),确保脚本有执行权限。|| true 可防止脚本失败影响。

测试配置

重启系统

总结

通过以上步骤,你可以在 Debian 9 及以上版本快速启用 /etc/rc.local,实现开机自动运行脚本。尽管 systemd 提供更现代的方案,rc.local 仍适合简单任务


深入浅出 MinIO:身份管理与权限配置实战

2025年5月2日 01:21

前面刚刚讲了如何搭建 MinIO,本文趁热打铁手把手教你如何配置 MinIO 权限配置。对于略懂 MinIO 的用户,配置权限可能是个挑战:如何安全地让别人读取存储内容,但不能列出所有存储桶或文件列表?或者让某个存储桶的内容可以列出? 本文将深入讲解 MinIO 的身份管理和权限配置,聚焦存储桶权限(private、public、custom)的区别和 匿名访问 的应用,通过清晰的场景示例,教你实现安全分享,同时保护数据

MinIO 身份管理基础

MinIO 的身份管理负责用户认证和授权,默认使用内置身份提供者(IDP)。核心概念包括:

  1. 用户(User)
    用户通过 Access Key(用户名)和 Secret Key(密码)访问 MinIO,可用命令行工具 mc 或 Web 控制台管理。
  2. 服务账号(Service Account)
    服务账号是为应用程序设计的专用凭证,无法登录控制台,但可通过 API 访问资源,适合自动化脚本或服务集成。
  3. 策略(Policy)
    JSON 格式的策略定义用户、服务账号或匿名访问对存储桶(Bucket)和对象(Object)的权限,基于 AWS S3 语法。
  4. 匿名访问(Anonymous Access)
    允许未认证用户(无 Access Key)通过 URL 或 API 访问特定资源,需通过存储桶权限配置。

用户组:可通过 mc admin group 批量管理用户权限,本文不展开。

我们的目标是:安全地让匿名用户或服务账号读取特定内容,限制列出存储桶或文件列表,或有选择地允许列出某个存储桶的内容。

准备工作

  1. 确保 MinIO 运行:假设 MinIO 部署在 http://localhost:9000,管理员账号为 homes4,密码为 aiy0ooCheephai0ohNahmu3Aijee6eiv
  2. 安装 mc 工具:下载 MinIO 客户端(mc),用于配置权限(支持 Windows、Mac、Linux)。
  3. 配置 mc
mc alias set homes4 http://localhost:9000 homes4 aiy0ooCheephai0ohNahmu3Aijee6eiv
Added `homes4` successfully.

准备好后,我们开始配置权限!

PS:命令行方式和可视化操作效果是一样的,下文会穿插着来,但是主要还是以可视化 web 操作为主

存储桶权限:Private、Public 和 Custom

MinIO 的存储桶权限控制匿名访问行为,分为 privatepubliccustom 三种模式,可通过 mc anonymous 命令设置。以下是它们的区别

Private(私有)

  • 定义:禁止所有匿名访问,仅允许认证用户或服务账号(有 Access Key 和策略授权)访问。
  • 适用场景:保护敏感数据,如内部文档、用户数据。
  • 效果:匿名用户访问存储桶或对象时,返回 403 Forbidden
  • 配置:mc anonymous set none homes4/web

Public(公开)

注意:风险较高,容易暴露所有文件,慎用。(我个人基本不用)

  • 定义:允许匿名用户访问,权限包括:

    • download:只读(s3:GetObject)
    • upload:只写(s3:PutObject)。
    • public:读写均可。
  • 适用场景:分享公开资源,如网站静态文件、开源软件。

  • 配置(只读):mc anonymous set download homes4/web

  • 效果:匿名用户可通过 URL(如 http://localhost:9000/web/file.jpg)读取对象,可能列出文件列表(若未限制)。

Custom(自定义)

推荐用

  • 定义:通过 JSON 策略精确控制匿名访问权限,如限制特定路径或操作。
  • 适用场景:部分公开,如只分享某个文件夹,或禁止列出文件列表。
  • 配置:见下文场景示例。
  • 效果:灵活性最高,匿名用户只能执行策略允许的操作。

存储桶权限区别总结

模式 匿名访问权限 适用场景 配置命令
Private 禁止匿名访问 敏感数据 mc anonymous set none
Public 读、写或读写(看设置) 公开资源 mc anonymous set download upload/public
Custom 自定义(JSON 策略) 部分公开、精确控制 mc anonymous set-json

实战:安全分享存储内容

通过一个最常见的场景,教你如何:

  • 让匿名用户只读特定文件,禁止列出存储桶或文件列表。

此外,还会写如何用服务账号为应用程序提供类似权限。

新建存储桶

先创建一个存储桶,默认创建的存储桶都是私有权限

root@docker:~$ mc mb homes4/cli
Bucket created successfully `homes4/cli`.
root@docker:~$ mc ls homes4
[2025-05-01 11:26:11 EDT]     0B cli/
[2025-05-01 11:23:57 EDT]     0B ddd/
[2025-05-01 10:38:53 EDT]     0B homes4/
[2025-05-01 11:29:06 EDT]     0B web/

场景:只读特定文件,禁止列出存储桶或文件列表

需求:存储桶 web 包含 public/photo.jpg 和 private/secret.pdf。想让匿名用户只读 photo.jpg,但不能列出 web 桶中 的文件列表,也不能访问其他文件或存储桶

步骤:

设为 Private(默认安全)

mc anonymous set none homes4/web

创建自定义策略:只允许匿名读取 public/photo.jpg

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": ["s3:GetObject"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::web/public/photo.jpg"],
      "Principal": "*"
    }
  ]
}
  • s3:GetObject:允许读取对象
  • Resource:精确到 photo.jpg, 例如你想某个目录读写 arn:aws:s3:::web/public/*
  • Principal: "*":表示匿名用户
  • s3:ListBucket:禁止列出文件列表

应用策略

mc anonymous set-json custom.json homes4/web

控制台可以直接编辑存储桶的 Access Policy,改成 Custom,内容和上面一致

查看策略

root@docker:~$ mc anonymous get-json homes4/web
{
 "Statement": [
  {
   "Action": [
    "s3:GetObject"
   ],
   "Effect": "Allow",
   "Principal": {
    "AWS": [
     "*"
    ]
   },
   "Resource": [
    "arn:aws:s3:::web/public/photo.jpg"
   ]
  }
 ],
 "Version": "2012-10-17"
}

效果

  • 匿名用户可通过 http://localhost:9000/web/public/photo.jpg 下载 photo.jpg。
  • 其他访问都是 403

服务账号:为应用程序配置相同权限

需求:为应用程序(如网站后端)提供只读 public/photo.jpg 的权限,类似上述场景,但通过服务账号实现

步骤:

创建用户(服务账号需绑定到用户):

密码长度需要 8-40

mc admin user add homes4 app1user app1pass

web 可视化操作,policy 那里随便选个小权限的,后面需要调整

创建服务账号:为 app1user 生成服务账号,绑定 custom.json 策略

mc admin user svcacct add homes4 app1user --access-key svc1 --secret-key svc1pass --policy custom.json

可视化操作创建服务状态,凭证信息会随机生成,且只显示一次

策略信息只能在生成 access key 后才能编辑操作

实用技巧:兼顾安全与便利

  • 优先 Custom 模式:比 public 安全,精确控制分享内容。
  • 避免 Public 模式:除非真想完全公开,否则可能暴露所有文件。
  • 检查权限:定期用 mc anonymous get-json homes4/web 确认存储桶权限
  • 随机存储桶名:用随机名,降低被猜到风险
  • 用预签名 URL 临时分享:生成带有效期的链接,过期失效:
# 分享下载链接,下载速度限制10MB/s有效期7天
mc share download --limit-download 10MB homes4/web/private/secret.pdf

总结

MinIO 的权限配置简单而灵活,用服务账号拥有某个存储桶的只读权限就行了。


超简单!5分钟用群晖搭建 MinIO + Caddy 对象存储

2025年5月1日 18:12

对象存储和 Web 服务是开发者必备工具。MinIO 凭借高性能和 S3 兼容性成为存储领域的“顶流”,Caddy 则以自动 HTTPS 和极简配置深受开发者喜爱。结合 Docker Compose,只需 5 分钟,你就能搭建一个安全、高效的对象存储服务!本文手把手教你部署 MinIO + Caddy。

前提要求

  • 群晖/大盘鸡(大硬盘 VPS):运行 MinIO 服务。
  • 大带宽机器(如腾讯云锐驰 200):运行 Caddy,代理 MinIO 服务。
  • 组网服务(如 Tailscale/EasyTier):确保内网互联互通

我的网络环境通过组网服务实现全链路打通,家里的群晖与腾讯云锐驰无缝互联,Caddy 代理内网 MinIO 服务,借助锐驰大带宽对外提供高效访问。

为啥选择 MinIO + Caddy

  • MinIO:开源、S3 兼容、支持分布式存储,轻松应对海量数据。
  • Caddy:自动 HTTPS、配置简洁,专为高并发优化,支持丰富插件。
  • Docker Compose:一键部署多容器,省时省力。

组合优势:Caddy 为 MinIO 提供安全访问和负载均衡,Docker Compose 确保部署简单,完美适配静态文件托管、API 服务或私有云存储。

5 分钟快速部署

根据需求,可选择在同一机器上部署或分布式部署。我因跨机器需求,选择分布式部署。

部署 MinIO

群晖已支持 Docker Compose,通用配置如下:

  • docker-compose.yaml
version: "3"
services:
  minio:
    image: bitnami/minio:2025
    # image: ccr.ccs.tencentyun.com/k7scn/minio:2025
    container_name: minio
    restart: always
    environment:
      - MINIO_ROOT_USER=homes4
      - MINIO_ROOT_PASSWORD=aiy0ooCheephai0ohNahmu3Aijee6eiv
      - MINIO_DEFAULT_BUCKETS=homes4
    ports:
      - '9000:9000'
      - '9001:9001'
    volumes:
      - '/volume1/docker/minio/data:/bitnami/minio/data'

注意:可能遇到目录权限问题,可运行以下命令解决:
chmod 777 /volume1/docker/minio/data -R

访问 MinIO 管理界面

在浏览器输入 http://NAS_IP:9001http://域名:9001,进入 MinIO 登录页面,使用 MINIO_ROOT_USERMINIO_ROOT_PASSWORD 登录。

安装客户端

提供 Linux/amd64 的 mc 客户端下载链接:

https://c.ysicing.net/oss/tiga/linux/amd64/mc

或从官网获取最新客户端 Install mc

部署 Caddy

  • docker-compose.yaml
services:
  caddy:
    image: ysicing/caddy2
    # image: ccr.ccs.tencentyun.com/k7scn/caddy2
    container_name: caddy
    restart: always
    # 可选host或者端口映射
    network_mode: host
    volumes:
      - '/data/caddy/cfg:/etc/caddy'
      - '/data/caddy/data:/data'
      - '/data/caddy/config:/config'
      - '/data/caddy/log:/var/log/caddy'

此 Caddy 镜像为我的定制版,内置以下常用插件:

xcaddy build \
    --with github.com/caddy-dns/cloudflare \
    --with github.com/caddy-dns/tencentcloud \
    --with github.com/caddy-dns/alidns \
    --with github.com/caddy-dns/dnspod \
    --with github.com/ysicing/caddy2-geocn \
    --with github.com/mholt/caddy-l4 \
    --with github.com/mholt/caddy-ratelimit

Caddy 配置

配置文件位于 /data/caddy/cfg,目录结构如下:

/data/caddy/cfg# tree
.
├── Caddyfile
├── load.sh
└── site
    ├── cr.caddy
    ├── dev.caddy
    ├── hub.caddy
    ├── http.caddy
    └── minio.caddy

Caddyfile 示例

(LOG) {
	log {
		output file "{args[0]}" {
			roll_size 50M
			roll_uncompressed
			roll_local_time
			roll_keep 3
			roll_keep_for 7d
		}
		format json
	}
}

(COMCFG) {
	encode zstd gzip
}

(ERR) {
	handle_errors {
    	# 异常重定向
		redir https://dxgw-{err.status_code}.caddy.local
	}
}

{
	debug
	# admin off
}

(TLS) {
tls {
  dns tencentcloud {
    secret_id AKID***
    secret_key CH85***
  }
}
}

import /etc/caddy/site/*.caddy

MinIO 配置

minio.caddy

域名 {
	import ERR
    # 如果是内网域名可以设置import TLS开启dns签发证书
    # import TLS
    import LOG "/var/log/caddy/minio.log"
	@rootPath {
		path /
	}
	handle @rootPath {
		respond "EdgeONE 451 Forbidden" 451
	}
    # 内网minio地址
    reverse_proxy 100.90.80.2:9000
}

同理,minio 控制台也是一样,通常控制台不对外开放,仅限内网访问。

minio-api.caddy

域名 {
	import ERR
    # 如果是内网域名可以设置import TLS开启dns签发证书
    # import TLS
    import LOG "/var/log/caddy/minio-api.log"
    @denied not remote_ip 192.168.1.0/24
    respond @denied "Access Denied" 403
    # 内网minio api地址
    reverse_proxy 100.90.80.2:9001
}

重新加载配置

curl "http://localhost:2019/load" -H "Content-Type: text/caddyfile" --data-binary @Caddyfile

使用 MinIO

配置 MinIO 客户端(mc)以访问服务:

# 内网
mc alias set home http://100.90.80.2:9000 homes4 aiy0ooCheephai0ohNahmu3Aijee6eiv
# 外网
mc alias set home https://域名 homes4 aiy0ooCheephai0ohNahmu3Aijee6eiv

更多场景可结合 restic,rclone,下载服务

写在最后

通过 MinIO 和 Caddy 的组合,你可以快速搭建一个高性能、安全的对象存储服务。本文提供的配置仅供参考,MinIO 还有更多玩法等待探索!


五一大盘大带宽物理服务器活动推荐

2025年4月30日 09:39

之前,也有小伙伴让我推荐几家物理服务器(后面简称杜甫), 趁着五一假期有活动,推荐两家我都在用的,各有优势,但是活动期价格会有优惠。

物语云

优点

  • 工单响应速度快
  • 有 DDoS 攻击防护
  • 大带宽流量套餐/上行限速的不限流量套餐(账单日可互换)
  • 测试不满意满足条件可退款

不足

  • 多台机器暂不支持组内网
  • 暂不支持 ipv6
  • 暂时只支持国内
  • 只支持操作系统安装

目前活动

立减优惠码 Event8259

物语云计算物理机活动:双路铂金物理机600G防护399/月起。
🎉限时立减100循环优惠码:
Event8259
※优惠码使用流程:登录账号后选择对应产品,在下单处点击“我有优惠码”之后填入。

硬件配置:
物理服务器|NVMe SSD|资源完全独享|自助管理面板
CPU:双路铂金Platinum8259CL 48核96线程
内存:128G RECC DDR4
硬盘:1TB NVMe SSD

网络规格:
以下四种网络规格可选,价格相同:
 - 浙江宁波/电信/50Mbps独享/100G防护/不限流量
 - 湖北十堰/电信/50Mbps独享/600G防护/不限流量
 - 浙江宁波/移动/50Mbps独享/10G防护/不限流量
 - 浙江宁波/电信/500Mbps流量计费/100G防护/双向2TB

优惠活动:
销售价:1150/月 优惠价:499/月
活动价:399/月,循环优惠,续费同价。

※上述产品均为独享带宽,并非“峰值”、“共享”带宽,可7x24小时随时跑满,拒绝带宽竞技场!

<服务协议与退款>
云服务器产品 24 小时内上行方向使用不超过30GB流量均支持退款,
物理服务器产品 24 小时内上行方向使用不超过100GB流量均支持退款,每用户每月最多退款 1 次。

购买链接 物语云杜甫

测评

具体可以参考 https://www.nodeseek.com/post-303956-1,带宽是可以长时间跑满的。

狗云

多年资深狗云老用户了,目前我只用他们家的 KC 杜甫、重庆联通杜甫

优点

  • 相比较其他杜甫首发优惠力度很大
  • 预购活动多
  • 香港大带宽流量套餐
  • 支持多台机器组网
  • 支持 ipv6, 掩码 /64
  • 安装系统支持种类多
  • 支持快递硬盘

缺点

  • 只支持工单响应(可以 PY 德克狗老板)
  • 杜甫 VNC 需要工单才能开,且有时间限制(每次半小时,记得不太清了)
  • 重装每小时限制一次
  • 需要实名

目前活动

预售活动

预售活动力度大些,折扣也比较高, 走 aff 成功绑定后返利一半

预售地址 二代铂金服务器预售

主要说一下网络规则,支持切换每次手续费 20, 推荐优化线路,优化线路可以附加国际线路,但是不支持附加精品线路

网络规格:
以下三种网络规格可选,价格相同:
 - 精品线路 75 Mbps, 额外附加20元/个/月
 - 优化线路  750 Mbps,额外附加15元/个/月
 - 国际线路  1000 Mbps,额外附加10元/个/月
 - 额外附加高防IP200元/个/月

五一 · 劳动节促销

活动一:
折扣码“51”,新开弹性云7折,新开经典云(特价机除外)8折。
折扣码“jian100”,新开独立服务器优惠100元。

活动二:
5月1日-5月5日,单笔充值每满100元送10元。

活动三:
5月1日-5月5日,幸运大转盘每日抽取5折码,流量,余额等奖品。

活动四:
二代铂金服务器预售:https://ds.dogyun.com/server/preorder

香港-KC物理服务器邮件硬盘添加活动将在5月10日开始接收

测评 KC

具体可以参考 https://www.nodeseek.com/post-314492-1

其他 CQA

他们家的老款绝版 CQA 月付 200 还是挺不错的,稳定的很,可以收一收。

最后

祝各位老板五一假期玩的开心。


欢迎关注我的微信公众号

沉迷塔防的乐趣:推荐Kingdom Rush系列游戏

2025年4月28日 20:41

作为一名开发者,我下班后除了写写代码、折腾技术,也喜欢通过游戏放松一下。塔防类游戏是我的最爱,尤其 Ironhide Game Studio(铁皮) 的 Kingdom Rush 系。这系列塔防游戏以扎实的玩法、精致的设计和恰到好处的挑战性,俘获了无数玩家的心。今天,我想向大家安利这个系列,希望你也能爱上它的独特魅力!

Kingdom Rush 系列简介

We make the games we'd love to play!

Steam 直达

Kingdom Rush 系列始于 2011 年的 Flash 游戏《Kingdom Rush》(早期我记得叫 皇家守卫军, 现在普遍翻译为 王国保卫战),随后推出了多款续作,覆盖 PC、移动端(iOS/Android)和主机平台,核心玩法保持一致,同时不断创新。目前包括以为五代作品(衍生品不算):

-《Kingdom Rush》(2011):初代经典,奠定系列基础。
-《Kingdom Rush: 前线》(2013):地图更复杂,敌人多样。
-《Kingdom Rush: 起源》(2014):优化塔升级,精灵主题, 节奏感比较好。
-《Kingdom Rush: 复仇》(2018):扮演反派,暗黑风格暗黑风格搭配创新塔种, 我最推荐。
-《Kingdom Rush 5: 联盟》(2024):双英雄机制,通关难度适中,兼顾新老玩家。

游戏设定在一个奇幻世界,玩家扮演指挥官,通过建造防御塔、操控英雄和使用魔法,抵御兽人、巨魔、恶魔等多样化敌人的进攻。核心玩法直观易上手:沿固定路线部署防御塔,合理分配资源,阻挡敌人前进。防御塔分为弓箭塔、兵塔、魔法塔和炮塔四类,每种塔可升级并解锁独特技能,如弓箭塔的连发箭、魔法塔的闪电链,策略性极强。
此外,系列引入了英雄系统,每位英雄拥有独特技能,例如弓箭手擅长远程狙击,骑士适合近战肉搏。玩家需操控英雄移动,堵截漏网敌人或支援薄弱防线。魔法技能(如陨石雨、援军召唤)则为战斗增添变数,关键时刻往往能逆转局势。特别值得一提的是,《复仇》的凤凰能喷射烈焰清场,《联盟》的双龙组合则带来史诗级输出,令人印象深刻。

为什么推荐 Kingdom Rush?

Kingdom Rush 系列由* Ironhide Studio* 精心打造,品质始终如一。以下是我推荐它的几大理由:

难度平衡,适合各水平玩家

关卡设计用心,普通模式新手友好,挑战模式(如老兵模式,即高难度关卡)则满足硬核玩家。敌人波次与资源分配恰到好处,既不无脑也不虐心。

高可玩性,玩法丰富多样

每作包含十余主线关卡,外加挑战关和隐藏关,内容充实。防御塔与英雄的多样组合,让每关都有新鲜玩法,重复游玩也不乏味。

碎片时间友好,单机体验纯粹

游戏无需联网,随时暂停,适合忙碌的玩家抽空玩一把。单机设计无内购压力,带来纯粹的游戏乐趣。

性价比高,物超所值

游戏在 Steam 和移动端定价多在几十元,经常打折。DLC 内容丰富,诚意十足,堪称塔防游戏的良心之作。

我的个人体验

高中时,我在 4399 平台接触到初代 Kingdom Rush,被它精致的画面和紧凑的节奏深深吸引。熬夜尝试不同防御塔组合,解锁隐藏关卡的成就感让我乐此不疲。后来,系列续作不断推出,我始终保持热情。2024 年 Kingdom Rush 5: 联盟 发布后,我迫不及待挑战老兵模式。双英雄机制让战斗更灵活,但也略微降低了通关难度。相比之下,我更偏爱《复仇》的暗黑风格和高难度设计,每次通关都充满成就感,尽管偶尔会被棘手的关卡“虐”得抓狂。

写在最后

Kingdom Rush 系列适合各类型玩家,无论是喜欢策略的硬核玩家,还是想休闲娱乐的轻度玩家,都能找到乐趣。作为技术人,我欣赏它在关卡设计和技能平衡上的用心。如果你喜欢塔防,或想找款轻松耐玩的单机游戏,不妨试试 Kingdom Rush。一旦上手,可能就停不下来!


在群晖上使用 Docker 部署 Proxmox Backup Server

2025年4月27日 20:45

在群晖上使用 Docker 部署 Proxmox Backup Server

Proxmox Backup Server(后续简称 PBS) 是 PVE 容器、虚拟机的备份解决方案,支持增量、重复数据消除备份,可以节省存储空间,同时支持加密和完整性校验。

PBS 官方提供了 iso 格式的镜像,同时社区也有开源的 Docker 镜像的部署方式,为了在群晖等 NAS 上部署方便,本文使用 Docker 的方式进行部署,项目地址:https://github.com/ayufan/pve-backup-server-dockerfiles

镜像:

  • ayufan/proxmox-backup-server:latest
  • ccr.ccs.tencentyun.com/k7scn/proxmox-backup-server:latest (国内镜像)

部署 PBS

使用 Docker 或者 Docker Compose 方式部署都可以。方便起见,统一使用 docker compose 方式部署, 不管群晖还是飞牛都适用。

安装配置 PBS

参加官方的 compose 示例,可以配置如下:

  • docker-compose.yaml
services:
  pve-backup-server:
    image: ayufan/proxmox-backup-server:latest
    # image: ccr.ccs.tencentyun.com/k7scn/proxmox-backup-server:latest
    container_name: pbs
    ports:
      - "8007:8007"
    volumes:
      - /data/pve/pbs/etc:/etc/proxmox-backup
      - /data/pve/pbs/log:/var/log/proxmox-backup
      - /data/pve/pbs//lib:/var/lib/proxmox-backup
      - /data/pve/pbs/data:/backups
    tmpfs:
      - /run
    restart: always

唯一需要关注的是

  • /data/pve/pbs/data:/backups 存储你的备份数据的,所属目录空间需要大一些

配置 PBS

在启动容器后,访问 https://<ip>:8007/ 端口即可进行登录,默认的用户名是 admin,密码是 pbspbs,选择 Proxmox Backup authentication server 进行登录,可把语言切换成中文,证书问题可忽略

配置备份存储

配置存储路径

首次登录是没有配置存储的,在 数据存储中添加数据存储,将刚才映射的 /backups 目录作为存储路径

配置用户权限

默认情况下,新用户和 API 令牌没有任何权限。给用于备份的 admin 用户添加备份路径的访问权限

获取 PBS 指纹信息

指纹用于在 PVE 中添加备份时进行认证

在 PBS 仪表盘里显示指纹备用

配置 PVE

在 PVE 的数据中心-存储中选择添加 Proxmox Backup Server,输入认证信息和指纹;Datastore 为 Proxmox Backup Server 的数据存储的名称,如 local, 相关参数都是上面步骤配置的

验证备份是否可用

在 PVE 的数据中心-备份中添加备份计划,按需添加,添加完成后选择现在运行即可开始备份

在 PBS 处验证看是否有备份数据

End

到这里 PVE 系列教程结束了,新买的杜甫应该算折腾好了,趋向于稳定了。后面会陆续写些之前工作积攒的一些小技巧,吐槽一下 Caddy 新版本 libdns 变更真是一个特别大的破坏性更新。


Proxmox VE 添加监控

2025年4月26日 20:32

Proxmox VE 添加监控

PVE 支持添加 InfluxDB 或者 Graphite 作为指标数据的存储;在添加配置后,PVE 会主动上报相关监控数据,用于记录和监控 PVE 的状态

效果图

使用 InfluxDB 和 Grafana 对 PVE 进行监控,效果如图:

本文适用 8.x 版本,仅在 PVE8.3、PVE8.4 版本测试过。

安装配置 InfluxDB

当前 PVE 版本需要使用的 InfluxDB v2 版本,使用 Flux 语法进行查询。方便操作,本次仅提供 compose 部署方式,k8s 部署也是类似比较简单。

  • docker-compose.yaml
services:
  influxdb:
    image: bitnami/influxdb:2
     # image: ccr.ccs.tencentyun.com/k7scn/influxdb:2
    container_name: influxdb
    environment:
      - INFLUXDB_ADMIN_USER_PASSWORD=Cha3ie7gahthooyeech1xohgaeyax7Gi
      - INFLUXDB_ADMIN_USER_TOKEN=Eing5yaew6ujoo9ohd3saeH6neeshei3
      - INFLUXDB_USER_ORG=proxmox
      - INFLUXDB_USER_BUCKET=proxmox
      - INFLUXDB_USER=proxmox
      - INFLUXDB_USER_PASSWORD=Ao2eeGh7aDoh2eich0zeith6viyae4er
    volumes:
      - /data/influxdb:/bitnami/influxdb
    ports:
      - '8086:8086'
      - '8088:8088'
    restart: always

密码可以使用 pwgen 工具生成, 例如:

# 生成一个32位的随机密码
pwgen 32 1
  • INFLUXDB_ADMIN_USER_TOKEN 后续上报还是 grafana 获取监控数据都使用这个配置

由于我这个 influxdb 只有 PVE 使用,故初始化组织和 Bucket 都为 proxmox

配置 PVE

登录 PVE 后,PVE 的 服务器视图 下,选择数据中心 - 指标服务器,选择添加 InfluxDB,输入相关的配置;
协议选择 HTTP,组织添加 INFLUXDB_USER_ORG 配置的值,插槽添加 INFLUXDB_USER_BUCKET 配置的 Bucket, 令牌填写 INFLUXDB_ADMIN_USER_TOKEN 配置的 Token

添加后 PVE 就会将监控指标推送到 InfluxDB 的 Bucket 中了。

登录 InfluxDB 验证配置是否正确,使用 admin 账号密码登录

配置 Grafana

启动 Grafana

在上面的 docker-compose.yaml 的基础上,添加 grafana

grafana:
    image: bitnami/grafana:11
    # image: ccr.ccs.tencentyun.com/k7scn/grafana:11
    container_name: grafana
    ports:
      - '100.90.80.15:3000:3000'
    environment:
      - 'GF_SECURITY_ADMIN_PASSWORD=joh1AhDah9quah8ruteexaeloh1Ohyuc'
    volumes:
      - /data/grafana:/opt/bitnami/grafana/data
    restart: always

配置启动 grafana

docker compose pull
docker compose up -d

添加 InfluxDB 数据源

访问 http://ip:3000/connections/datasources/new, 使用 InfluDB 作为数据源

  1. Query Language 选择 Flux
  2. URL 填写 InfluxDB 的地址,如 http://100.90.80.15:8086
  3. Auth 下的配置不需要启用,默认启动 Basic auth,去掉勾选
  4. Custom HTTP Headers 添加一个新的配置,Header 名称为 Authorization, Value 为 Token+ 配置的 Token,如 Token Eing5yaew6ujoo9ohd3saeH6neeshei3(需注意 Token 和值中间有一个空格)
  5. OrganizationDefault Bucket 填写和上面配置的值一致就行,如果没变更填 proxmox
  6. 配置完成后,点击 Save and Test,如果提示成功则表示配置正确

添加 Grafana 图表

Grafana Dashboard 中搜索 proxmox,选择支持 Flux 查询语法的图表进行添加,如添加 Proxmox Flux,根据 ID 导入 Grafana 即可看到 PVE 的监控指标

这里推荐 ID 使用 15356

访问 http://100.90.80.15:3000/dashboard/import

导入 Dashboard 后效果如下:


PVE环境折腾之配置DHCP

2025年4月23日 20:37

感觉最近售卖杜甫的 IDC 有点多,最近凑热闹买了几台杜甫(物理服务器简称),本文不会过多介绍安装 PVE,仅记录配置 dhcp

安装 PVE 环境

推荐先安装 Debian12 环境,在这个的基础上部署 PVE 环境。

  • 物语云暂时只支持系统, 配置 96 核 128G1T 存储 399 元/月,境内服务器
  • 狗云杜甫支持 PVE 环境,配置 48 核 64G1.92T 存储 450 元/月,香港 KC

Debian12 安装 PVE

推荐使用 https://github.com/oneclickvirt/pve 这个项目,基本很稳, 一键虚拟化项目。

细节这里就不多说了,更多可以参考文档

配置 DHCP

默认情况下,是没有配置 DHCP 的,不然每次创建虚拟机后还要手动配置多麻烦,也没 cloud-init

添加 NAT 网桥

如果你是按照上面的文档安装,整个流程走完 NAT 网桥默认已经配置完成了的。

示例配置文件应该如下, 具体网卡具体分析哈

# /etc/network/interfaces 仅摘选相关的部分
auto vmbr1
iface vmbr1 inet static
    address 192.168.23.1
    netmask 255.255.255.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up echo 1 > /proc/sys/net/ipv4/conf/vmbr1/proxy_arp
    post-up iptables -t nat -A POSTROUTING -s '192.168.23.0/24' -o vmbr0 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s '192.168.23.0/24' -o vmbr0 -j MASQUERADE

虚拟机网段默认使用 192.168.23.0/24, 网卡是 vmbr1

安装 DHCP 服务

安装完可能会提示报错,这是正常情况需要配置才能启动成功。

apt-get install isc-dhcp-server

配置 DHCP 服务

这里仅涉及 ipv4 部分,所以改动仅涉及 ipv4

编辑 /etc/default/isc-dhcp-server

INTERFACESv4="vmbr1" # 仅修改这里,默认为空,修改为你的NAT网卡vmbr1
INTERFACESv6=""

编辑 /etc/dhcp/dhcpd.conf

:> /etc/dhcp/dhcpd.conf

清空配置文件,重新生成

option domain-name-servers 8.8.8.8;

default-lease-time 600;
max-lease-time 7200;

ddns-update-style none;

authoritative;

log-facility local7;

subnet 192.168.23.0 netmask 255.255.255.0 {
  range 192.168.23.10 192.168.23.50;
  option subnet-mask 255.255.255.0;
  option domain-name-servers 8.8.8.8;
  option routers 192.168.23.1;
  option netbios-name-servers 192.168.23.1;
  option netbios-node-type 8;
  get-lease-hostnames true;
  use-host-decl-names true;
  default-lease-time 600;
  max-lease-time 7200;
  interface vmbr1;
}

默认分配 IP 从 192.168.23.10~192.168.23.50, 切记不要包含网关哈

service isc-dhcp-server restart

重启服务没有报错,即表示配置成功了。如果有错误配置,重启服务会失败。

PVE 导入备份

qmrestore vzdump-qemu-104-2025_04_15-14_56_54.vma.zst 100 -storage local2

其中 local2 为你的存储池

AD 部分

狗云续费、新购充值可以走我的 AFF,如果成功绑定了我的 AFF,返利 50%


欢迎关注、订阅我的微信公众号

快速部署私有微信编辑器

2025年4月22日 22:05

快速部署私有微信编辑器

之前都是在使用开源作者提供的官方演示站点, 但是最近不知道是不是网络问题,我打开站点比较慢,即使上了手段

WeChat Markdown Editor

一款高度简洁的微信 Markdown 编辑器:支持 Markdown 语法、自定义主题样式、内容管理、多图床、AI 助手等特性

项目地址: doocs/md

功能特性

  • • 支持 Markdown 所有基础语法、数学公式
  • • 提供对 Mermaid 图表的渲染和 GFM 警告块的支持
  • • 丰富的代码块高亮主题,提升代码可读性
  • • 允许自定义主题色和 CSS 样式,灵活定制展示效果
  • • 提供多图上传功能,并可自定义配置图床
  • • 便捷的文件导入、导出功能,提升工作效率
  • • 内置本地内容管理功能,支持草稿自动保存
  • • 集成主流 AI 模型(如 DeekSeek、OpenAI、通义千问),辅助内容创作

那为啥选择它,主要是我的博客系统 Solitudes 也支持它的语法,我只要写一次就可以复用。

PS: 打个广告 Solitudes 是使用 Go 编写的轻量博客引擎, 我的博客是魔改版,一直说要把改动 PR 到上游一直鸽到现在

部署

部署比较简单,官方也提供了镜像

docker 部署

执行完如下命令后,访问你的 80 端口就可以了

docker run -d -p 80:80 doocs/md:latest

k3s+caddy

下面仅供参考

---
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
  labels:
    app: wxmd
  name: wxmd
  namespace: nb-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wxmd
  updateStrategy:
    type: InPlaceIfPossible
  template:
    metadata:
      labels:
        app: wxmd
    spec:
      tolerations:
      - operator: Exists
      nodeSelector:
        node-role.kubernetes.io/china: "true"
      containers:
      - image: doocs/md
        imagePullPolicy: Always
        name: wxmd
        ports:
        - containerPort: 80
          protocol: TCP
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: wxmd
  namespace: nb-system
spec:
  selector:
    app: wxmd
  ports:
  - port: 80
    targetPort: 80

将服务部署到 china 的节点池上,并且创建 svc, 配置 caddy,直接使用 svc 的 ip 更方便

wxmd.nbds.ysicing.net {
reverse_proxy http://10.25.220.235
}

公益服务

wxmd.nbds.ysicing.net, 本文就是使用该服务完成的。本服务应该会长期提供服务,下线会提前通知的。


Cherry Studio:搭建个人知识库的完美助手!

2025年4月21日 21:15

Cherry Studio:搭建个人知识库的完美助手!

之前我曾写过一篇关于如何基于 LobeHub 部署个人知识库的文章。有朋友反馈上手难度较高,因此今天我想再推荐一款非常适合我们国人的 AI 助手——Cherry Studio

这款工具非常易于使用,现已基本完成对 LobeHub 的替代。为什么我现在选择使用它呢?我觉得主要有以下几个优点:

  • 客户端支持:兼容 macOS 和 Windows 系统,下载安装后便可直接使用,无需复杂的服务部署。
  • 数据私有化:非 SaaS 服务,数据管理更加安全。
  • 内置丰富的提示词模板(智能体),大大提高使用效率。
  • 便捷的 数据备份,让信息管理更顺畅

相较于 LobeHub,Cherry Studio 唯一不足之处在于多客户端之间的记录同步和合并。但我相信,有了 AI 的加持,这些问题在后续都将迎刃而解(这里先给大家埋个伏笔!)

总之,Cherry Studio 上手简单且功能强大。如果你在寻找一款优秀的 AI 终端应用,我毫不犹豫地推荐它,真的是 YYDS!

安装 Cherry Studio

打开 Cherry Studio 官方下载页面 https://cherry-ai.com/download,根据你的操作系统进行下载。如果是 macOS 系统,M 系列用户请下载 Apple 芯片版本。
当然,如果你有相关技术,还可以通过官方 GitHub 开源项目下载 CherryHQ/cherry-studio

下载完成后,点击进行安装,过程非常简单。安装完成后,启动 Cherry Studio,开始配置。

配置模型服务

Cherry Studio 支持主流大模型服务,配置过程也大同小异,界面上还有相关引导。

配置国产大模型

以深度求索的 DeepSeek 模型为例进行演示

在第五步这里,是验证你的大模型和 Token 配置正常,如果请求成功,则可以设置启用

配置 ollama

整体流程与上述类似,唯一的区别是 Token 地址为空;下图示范的模型是我本地经常进行测试的模型。

需要注意的一点,添加完模型后需要管理,将模型添加上,上面显示的是已经附加了的模型

配置中转大模型

在许多场景下,我们经常使用中转服务商提供的 AI 网关,以解决特殊因素导致的非必要问题。

大部分 AI 网关支持通用的 OpenAI 格式 AI 请求,因此我在这里选择 OpenAI 进行配置。

整体流程与其他模型相似,同样需要在管理页添加所需使用的模型。

设置默认模型

Cherry Studio 允许为不同对话设置不同模型,我们可以在设置中定义默认助手模型。我这里配置的是 GPT-4o-mini。主要这个模型便宜的很,日常使用没有特别大的问题。

在聊天过程中,当然也可以随时切换不同的模型。

网络搜索

强烈推荐使用搜索引擎,可以免费获取实时信息资讯,配置也相对简单。

这里简单给大家实操一下, 查询北京明天天气情况

智能体

虽说是智能体,但更多像单一 Agent 哈,只是内置了相关提词。

生成网页也是轻轻松松, 预览效果如下

图片

默认只能用硅基流动,通常不用它。可以使用 gpt-4o-image 模型生图

个人知识库

Cherry Studio 的个人知识库功能非常实用,下面是配置流程的简要说明:

点击知识库,添加一个知识库

随便添加一些文本

编辑默认助手,勾选知识库

在使用过程中,系统有时能够命中知识库的信息,效果相当不错。

数据备份

Cherry Studio 支持多种数据备份方式,我推荐使用 WebDAV。如果你有飞牛,可以直接开启 WebDAV 服务;如果没有,也可以用 Docker 部署一个 WebDAV 服务。

docker run -d -e USERNAME=test -e PASSWORD=test -v /data/webdav:/var/webdav -p 8888:80 morrisjobke/webdav

顺便提一句,我利用 AI 解决了 WebDAV 的两个问题:

  • 同类型设备备份没发区分备份文件所属机器问题 #5004
  • 备份文件保留设置 #5060,只支持清理当前设备备份数据,历史数据需要手动自行清理了

其他

关于 MCP 部分的内容,下次再分享哈。

重磅,Tailscale的Derp服务器原生支持自签发证书

2025年4月5日 21:32

重磅,Tailscale 的 Derp 服务器原生支持自签发证书

最近比较忙,鸽了很久 😄。如题的功能已经出了比较长的时间了。本篇文章简单讲讲有啥新的调整。

背景

在官方支持之前,大家普遍通过修改源码来支持的,也有不少大佬提供相关镜像。可能大家会有疑问,为啥会有这类需求?受限于部分网络环境下 LetsEncrypt 是被禁用的;还有一些场景,使用域名的方式需要 ICP 许可,跨云 IDC 会比较麻烦。

开源作者讨论 tailscale#issues/11776
相关 PR tailscale#pull/15208

新版本好处

  • • 不需要域名
  • • 不需要 ICP 许可/接入
  • • 不需要证书

新版本部署

编译或下载二进制

如果你有 Go 的环境,可以使用如下命令

go install tailscale.com/cmd/derper@latest

当然也可以使用我编译好的二进制文件

wget https://c.ysicing.net/oss/tiga/linux/amd64/derper

将相关二进制复制到 /usr/bin/derper, 并赋予执行权限

cp -a derper /usr/bin/derper
chmod +x /usr/bin/derper

手动签发 IP 证书

示例是你的 derper 公网 ip

export DERP_IP="1.1.1.1"
mkdir /etc/derper
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout /etc/derper/${DERP_IP}.key -out /etc/derper/${DERP_IP}.crt -subj "/CN=${DERP_IP}" -addext "subjectAltName=IP:${DERP_IP}"

手动启动 derper

derper --hostname="1.1.1.1"  -certmode manual -certdir /etc/derper

启动完成会提示如下信息

2025/04/05 20:00:25 Using self-signed certificate for IP address "1.1.1.1". Configure it in DERPMap using: (https://tailscale.com/s/custom-derp)
  {"Name":"custom","RegionID":900,"HostName":"1.1.1.1","CertName":"sha256-raw:970d3fae5ccd1480ad5e1017597c91f33d4bf0ef5bbeb5f54a2c20c0156ca081"}

然后可以打开浏览器访问这个网址看看,需要放行 804433478, 其中 3478 是 UDP 端口。

配置 ACL

方便显示,格式化如下:

{
    "RegionID": 910,
    "RegionCode": "yxvm",
    "RegionName": "yxvm",
    "Nodes": [
        {
            "Name": "yxvm",
            "RegionID": 910,
            "HostName": "46.x.x.x",
            "IPv4": "46.x.x.x",
            "CertName":"sha256-raw:8a81f6658a7e1830fbaf363b72427f975d1f033d1616bf603cec3defa7e52391",
            "InsecureForTests": true 
        }
    ]
}

保存之后,使用 tailscale netcheck 测试

* DERP latency:
        - yxvm: 118.8ms (yxvm)

总结

如果你之前就使用自签证书的话,更新一下二进制就行

离线私有化环境部署deepseek之ollama模型缓存

2025年2月14日 16:48

离线私有化环境部署 deepseek 之 ollama 模型缓存

在某些特殊的环境下,导致我们使用 ollama 模型存在各种各样的问题。最常见的就是拉取不了或者拉取速度很慢。基于这点,想到了如何去镜像缓存这些。

应用场景

方便给离线环境下的用户部署私有大模型体验。

ollama 与 oci

可以跳过这部分记录早期我的探索,得出目前不支持通用 OCI 方式。

从上面 ollama 拉取模型来看,是不是很眼熟,和我们经常拉取容器镜像是不是很相似。深入研究后发现,有着容器镜像的模型名称、分层存储结构,其中 manifest 保存 layer 列表,blob 存储二进制文件。那灵机一动是不是,可以存镜像的 registry 是不是也可以存 model。

搭建镜像服务

services:
  registry:
    image: registry:latest
    container_name: registry
    restart: always
    ports:
      - "5000:5000"
    environment:
      TZ: Asia/Shanghai

基于官方的 registry 镜像跑了一个镜像仓库来模拟,将上面的文件保存为 docker-compose.yaml

运行起来

docker compose pull
docker compose up -d

下载 deepseek-r1 小模型

# 下载deepseek最小模型验证
ollama pull deepseek-r1:1.5b
# 重命名
ollama cp deepseek-r1:1.5b 127.0.0.1:5000/ollama/deepseek-r1:1.5b

推送到本地镜像仓库

ollama push 127.0.0.1:5000/ollama/deepseek-r1:1.5b --insecure

推送很成功,给人一种万事俱备,只等下载了

验证下载

ollama pull 100.90.80.29:5001/ollama/deepseek-r1:1.5b --insecure
pulling manifest
pulling aabd4debf0c8...   0% ▕                                                                                                                                                                                    ▏    0 B/1.1 GB
Error: http: no Location header in response

下载提示这个,去搜了一下这个报错,也有人反馈这个问题,解决也可以参考这个 ollama#7474

根据核心开发者的反馈,我大概总结了一下:

尚未公开使用 OCI 规范,因为我们正在对其进行重大修改,以确保未来的灵活性。

其实到这里使用 oci 的方式行不通了。另外官方也没有透露如何搭建私有化模型仓库。

基于 caddy+ollama 部署镜像缓存加速

主要参考了大佬 ollama 模型缓存这篇博客,有兴趣的可以看看作者的逆向分析。这里主要讲一下如何快速搭建模型缓存。

镜像版本

使用这个镜像,可能有丢丢麻烦,但是也还好,需要套两层 caddy,一个是镜像内置的 caddy,一个是外部的 caddy 代理服务。

services:
  ollama-registry:
    image: wbuntu/ollama-registry:v0.1
    container_name: ollama-registry
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - '/data/ollama-models:/data'

将上面的文件保存为 docker-compose.yaml, 执行

docker compose pull
docker compose up -d

配置 caddy 服务

ai-models.china.12306.work {
    import LOG "/var/log/caddy/ai-models.log"
	reverse_proxy 127.0.0.1:8080
}

到这里基本模型缓存服务就搭建完了,但是使用需要满足以下几点需求

  1. 首先需要 ollama-registry 服务缓存相关模型
  2. 其次才能通过 ollama-registry 拉取模型
# 通过ollama-registry缓存qwen2.5的模型
docker exec ollama-registry ollama pull qwen2.5:latest
# 其他服务器下载模型
ollama pull ai-models.china.12306.work/library/qwen2.5:latest

非镜像版本

要求部署了 ollama 和 caddy,方便操作 caddy 部署用户使用 root,避免权限问题.(默认情况,两者都已经跑起来了), 主要是配置 caddy。

其实就是将镜像里的 caddy 独立出来了,Caddyfile 示例如下:

ai-models.china.12306.work {
 	import LOG "/var/log/caddy/ai-models.log"
	# root directory 
	root * /root/.ollama/models

	# match blob request
	@blobRequests path_regexp blob /v2/([^/]+)/([^/]+)/blobs/sha256:(.+)
	# rewrite blob request
	rewrite @blobRequests /blobs/sha256-{re.blob.3}
	# add Location header on response
	header @blobRequests {
		Location {uri}
	}

	# match manifest request
	@manifestRequests {
		path_regexp manifest /v2/([^/]+)/([^/]+)/manifests/(.+)
	}
	# rewrite manifest request
	rewrite @manifestRequests /manifests/registry.ollama.ai/{re.manifest.1}/{re.manifest.2}/{re.manifest.3}
	# add Content-Type header on response
	header @manifestRequests {
		Content-Type application/vnd.docker.distribution.manifest.v2+json
	}

	# static file server
	file_server browse
}

其他

目前,我已经缓存了 5 个通用大模式供大家下载, 如果大家还有其他模型需要加速,可以私信我。

ai-models.china.12306.work/library/qwen2.5:latest
ai-models.china.12306.work/library/qwen2.5-coder:latest
ai-models.china.12306.work/library/deepseek-r1:1.5b
ai-models.china.12306.work/library/deepseek-r1:7b
ai-models.china.12306.work/library/deepseek-r1:8b

附录

离线私有化环境部署deepseek之ollama模型缓存

2025年2月11日 22:23

离线私有化环境部署 deepseek 之 ollama 模型缓存

在某些特殊的环境下,导致我们使用 ollama 模型存在各种各样的问题。最常见的就是拉取不了或者拉取速度很慢。基于这点,想到了如何去镜像缓存这些。

应用场景

方便给离线环境下的用户部署私有大模型体验。

ollama 与 oci

可以跳过这部分记录早期我的探索,得出目前不支持通用 OCI 方式。

从上面 ollama 拉取模型来看,是不是很眼熟,和我们经常拉取容器镜像是不是很相似。深入研究后发现,有着容器镜像的模型名称、分层存储结构,其中 manifest 保存 layer 列表,blob 存储二进制文件。那灵机一动是不是,可以存镜像的 registry 是不是也可以存 model。

搭建镜像服务

services:
  registry:
    image: registry:latest
    container_name: registry
    restart: always
    ports:
      - "5000:5000"
    environment:
      TZ: Asia/Shanghai

基于官方的 registry 镜像跑了一个镜像仓库来模拟,将上面的文件保存为 docker-compose.yaml

运行起来

docker compose pull
docker compose up -d

下载 deepseek-r1 小模型

# 下载deepseek最小模型验证
ollama pull deepseek-r1:1.5b
# 重命名
ollama cp deepseek-r1:1.5b 127.0.0.1:5000/ollama/deepseek-r1:1.5b

推送到本地镜像仓库

ollama push 127.0.0.1:5000/ollama/deepseek-r1:1.5b --insecure

推送很成功,给人一种万事俱备,只等下载了

验证下载

ollama pull 100.90.80.29:5001/ollama/deepseek-r1:1.5b --insecure
pulling manifest
pulling aabd4debf0c8...   0% ▕                                                                                                                                                                                    ▏    0 B/1.1 GB
Error: http: no Location header in response

下载提示这个,去搜了一下这个报错,也有人反馈这个问题,解决也可以参考这个 ollama#7474

根据核心开发者的反馈,我大概总结了一下:

尚未公开使用 OCI 规范,因为我们正在对其进行重大修改,以确保未来的灵活性。

其实到这里使用 oci 的方式行不通了。另外官方也没有透露如何搭建私有化模型仓库。

基于 caddy+ollama 部署镜像缓存加速

主要参考了大佬 ollama 模型缓存这篇博客,有兴趣的可以看看作者的逆向分析。这里主要讲一下如何快速搭建模型缓存。

镜像版本

使用这个镜像,可能有丢丢麻烦,但是也还好,需要套两层 caddy,一个是镜像内置的 caddy,一个是外部的 caddy 代理服务。

services:
  ollama-registry:
    image: wbuntu/ollama-registry:v0.1
    container_name: ollama-registry
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - '/data/ollama-models:/data'

将上面的文件保存为 docker-compose.yaml, 执行

docker compose pull
docker compose up -d

配置 caddy 服务

ai-models.china.12306.work {
    import LOG "/var/log/caddy/ai-models.log"
	reverse_proxy 127.0.0.1:8080
}

到这里基本模型缓存服务就搭建完了,但是使用需要满足以下几点需求

  1. 首先需要 ollama-registry 服务缓存相关模型
  2. 其次才能通过 ollama-registry 拉取模型
# 通过ollama-registry缓存qwen2.5的模型
docker exec ollama-registry ollama pull qwen2.5:latest
# 其他服务器下载模型
ollama pull ai-models.china.12306.work/library/qwen2.5:latest

非镜像版本

要求部署了 ollama 和 caddy,方便操作 caddy 部署用户使用 root,避免权限问题.(默认情况,两者都已经跑起来了), 主要是配置 caddy。

其实就是将镜像里的 caddy 独立出来了,Caddyfile 示例如下:

ai-models.china.12306.work {
 	import LOG "/var/log/caddy/ai-models.log"
	# root directory 
	root * /root/.ollama/models

	# match blob request
	@blobRequests path_regexp blob /v2/([^/]+)/([^/]+)/blobs/sha256:(.+)
	# rewrite blob request
	rewrite @blobRequests /blobs/sha256-{re.blob.3}
	# add Location header on response
	header @blobRequests {
		Location {uri}
	}

	# match manifest request
	@manifestRequests {
		path_regexp manifest /v2/([^/]+)/([^/]+)/manifests/(.+)
	}
	# rewrite manifest request
	rewrite @manifestRequests /manifests/registry.ollama.ai/{re.manifest.1}/{re.manifest.2}/{re.manifest.3}
	# add Content-Type header on response
	header @manifestRequests {
		Content-Type application/vnd.docker.distribution.manifest.v2+json
	}

	# static file server
	file_server browse
}

其他

目前,我已经缓存了 4 个通用大模式供大家下载, 如果大家还有其他模型需要加速,可以私信我。

ai-models.china.12306.work/library/qwen2.5:latest
ai-models.china.12306.work/library/deepseek-r1:1.5b
ai-models.china.12306.work/library/deepseek-r1:7b
ai-models.china.12306.work/library/deepseek-r1:8b

附录

告别DNS劫持!手把手教你搭建私人DOH服务,上网安全提升300%

2025年2月5日 20:13

你是否经常遇到网页被劫持、广告弹窗不断?普通 DNS 正在暴露你的上网隐私!今天教你在 Linux 服务器上零成本搭建专属 DOH 服务,从此告别网络监控,访问速度还能快人一步。本文重点是避免部分场景下的恶意劫持,提供错误的解析记录

为啥要自建 DOH 服务

主要原因还是: 公共 DNS 存在响应延迟和信任风险; 其次自建服务可自定义过滤规则,拦截广告/恶意网站

环境要求

  • 非国内机器(推荐是香港或者日本, 可以考虑小阿里 claw)
  • 容器化部署(docker 或者 k3s, 如果是 k3s 更好不过了)
  • 若使用内网穿透工具 tailscale 就更好不过了
  • 环境支持 IPv6(非必须)
  • 域名及域名证书

除了第一点要求外,其他都是可选的

示例环境

  • 小阿里香港优化线路节点
  • k3s
  • caddy

搭建 DOH 服务

基于 ysicing/doh 部署的 doh 服务。这个小项目是春节期间利用 cursor 七拼八凑实现的一个小工具,使用场景主要给 mihomo 的 fallback dns 使用。

具体实现可以参考源码,刚开始实现很简单,就是基于 github.com/miekg/dns,然后加了一些奇奇怪怪的想法。

默认情况下会自动缓存解析记录 5 分钟。

k3s 部署

源码目录下,默认提供了一个名为 ds.yaml 的 yaml 文件。

这个文件主要分成了几大部分

  • tailscale k3s 集群 loadBalancer 使用 tailscale,对外暴露服务,并要求该 pod 调度到非国内 ipv6 节点,提供更加优质的双栈国际互联效果
  • ads 增强版 DaemonSet,由 kruise 驱动
  • traefik 入口ingress,了解我博客架构的都知道哈,traefik 是国内入口,由于合规要求,我使用 caddy 代替

docker 部署

使用 dockerhub 或者 ghcr 的镜像都可以的

docker run -itd -p 65001:65001 ghcr.io/ysicing/doh

caddy 配置示例

doh.pub {
	reverse_proxy 100.90.90.5
}

验证 doh 是否可用

推荐使用 q 命令

具体使用可以参考官方文档, 如果你本地安装有 go 环境,可以尝试

go install github.com/natesales/q@latest

验证 doh

下面是一个错误的显示哈,只验证 doh 功能是否正常

q www.google.com @http://127.0.0.1:65001 | nali
www.google.com [Google Web 业务] . 5m A 199.16.158.9 [美国 Twitter公司]
www.google.com [Google Web 业务] . 5m A 31.13.106.4 [瑞典]
www.google.com [Google Web 业务] . 5m A 199.16.158.182 [美国 Twitter公司]
www.google.com [Google Web 业务] . 5m A 199.59.148.229 [美国 Twitter公司]
www.google.com [Google Web 业务] . 5m AAAA 2001::1 [IANA特殊地址 Teredo隧道地址]
www.google.com [Google Web 业务] . 5m A 31.13.94.41 [爱尔兰 Facebook分公司]

其他

除此之外,还推荐nbdns, 一个聪明的 DNS 中继器,放置于 AdGuard Home 上游,可提升 DNS 解析准确性。

浅谈2025新年贺岁 · 哪吒之魔童闹海

2025年2月4日 14:22

今天抽空看了一下,还是挺不错的。如果问是否推荐看,我觉得还是值得去电影院看一场 IMAX 3D 版。
每个人都有自己的看法,这里仅代表我写这篇观感时的看法,不代表不会改变

好的地方

  • 视觉体现没得说,高燃的打斗画面
  • 细化了第一部的人物关系,迎来了第二部的大反派以及诸多配角人物

不足的地方

  • 与配角相比,第二部对主角的塑造感觉差了一丢丢,没有第一部那么明显。
  • 对于常看仙侠神话类小说的人来说,剧情有点老套(高层陷害、中层背锅、底层遭殃)

其他

  • 隐喻太多,特别是那灭魂丹
  • 申公豹 豹哥真男人
  • 结界兽真是 NB,纯纯概念神

我们还年轻,不知天高地厚

乙巳蛇年 · 祝大家身体健康,蛇行万里,吉祥如意

2025年2月4日 14:22

亲爱的朋友,新年好!2025 年是农历乙巳蛇年,在这个辞旧迎新之际,我谨代表自己向各位拜个早年!

祝大家在新的一年里:

  • 身体健康,蛇行千里,活力四射!
  • 万事如意,心想事成,梦想成真!
  • 财源滚滚,富贵吉祥,财运亨通!
  • 事业腾飞,步步高升,前程似锦!
  • 幸福美满,阖家欢乐,家庭和睦!

新的一年,让我们一起携手并进,共同创造更加辉煌的未来!

愿除旧妄生新意,端与新年日日新

乙巳蛇年 · 祝大家身体健康,蛇行万里,吉祥如意

2025年1月29日 00:19

亲爱的朋友,新年好!2025 年是农历乙巳蛇年,在这个辞旧迎新之际,我谨代表自己向各位拜个早年!

祝大家在新的一年里:

  • 身体健康,蛇行千里,活力四射!
  • 万事如意,心想事成,梦想成真!
  • 财源滚滚,富贵吉祥,财运亨通!
  • 事业腾飞,步步高升,前程似锦!
  • 幸福美满,阖家欢乐,家庭和睦!

新的一年,让我们一起携手并进,共同创造更加辉煌的未来!

愿除旧妄生新意,端与新年日日新

乙巳蛇年 · 祝大家身体健康,蛇行万里,吉祥如意

2025年1月29日 00:19

亲爱的朋友,新年好!2025 年是农历乙巳蛇年,在这个辞旧迎新之际,我谨代表自己向各位拜个早年!

祝大家在新的一年里:

  • 身体健康,蛇行千里,活力四射!
  • 万事如意,心想事成,梦想成真!
  • 财源滚滚,富贵吉祥,财运亨通!
  • 事业腾飞,步步高升,前程似锦!
  • 幸福美满,阖家欢乐,家庭和睦!

新的一年,让我们一起携手并进,共同创造更加辉煌的未来!

愿除旧妄生新意,端与新年日日新

旁路由OpenWrt与内网穿透(Tailscale、EasyTier)

2025年1月21日 20:46

旁路由 OpenWrt 与内网穿透(Tailscale、EasyTier)

近况

最近家里的旁路由坏了,这一坏感觉和外界失联了一样,这也用不了那也用不了。还好有一个群晖临时顶一顶。

群晖部署 OpenWrt

下载固件

常见固件下载地址

这里我随便选择了一个 Lean 固件

这个固件包含了我们常用的一些插件:

  • Mosdns
  • 动态 DDNS
  • UPNP 自动端口转发
  • 默认多个主题
  • 默认管理 IP: 192.168.1.251, 用户名 root,密码 password
  • 等等

解压固件并上传

默认是 gz 文件需要解压后,群晖才能识别

gunzip 01.11-openwrt-x86-64-generic-squashfs-combined-efi.img.gz

选择解压后的镜像 img 文件上传

创建 gw 虚拟机

  1. 选项导入硬盘映像

  1. 选择上传的镜像文件

  1. 调整网络,这步的作用主要是确定我们虚拟的软路由的工作模式是“全双工”或者“半双工”,全双工的优势明显,默认的是半双工,所以我们这里需要更改一下即可

PS: 由于我的环境都需要绑定 mac 地址,需要记录 mac 地址并在主路由器绑定相关 ip

  1. 其它设置这里设置自动启动为,其它保持缺省,不需要调整
  2. 分配权限,选择自己的群晖 NAS 管理员账户即可
  3. 点击“完成”创建虚拟机,然后开机
  4. 选择刚刚开机的,点击连接

  1. 出现如下的界面的时候,按电脑的“回车”键进入 OpenWRT shell

  1. 修改默认 ip, 将 “lan” 里面的 ipaddr,gateway 和 dns 更改为自己的配置
vi /etc/config/network
# 示例我的环境
config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.31.66'
	option netmask '255.255.255.0'
	option ip6assign '60'
	option gateway '192.168.31.1'
	list dns '8.8.4.4'
  1. 修改完成后保存并退出 vi,然后输入 reboot 命令重新启动 OpenWrt。
reboot
  1. 到这里基本安装就完成了,通过浏览器访问 http://192.168.31.66(具体 IP 根据自己的情况哈)

配置 OpenWrt

修改软件包源,这里默认使用腾讯云 https://mirrors.cloud.tencent.com 镜像源

点击配置 OPKG,具体如下,我这个已经是替换过后的了

配置完成,点击更新列表

开启 ssh 功能

系统-管理权,开启 ssh 登陆功能

安装 Tailscale

搜索 tailscale 安装, 我这里已经安装了。

然后 ssh 登录到 OpenWrt, 开启 tailscale

# 开启启动
/etc/init.d/tailscale enable
# 启动
/etc/init.d/tailscale start
# 获取登录链接
tailscale up --accept-dns=false

这样完事后,tailscale 是组网成功了,只能用 tailscale ping 100.90.80.66, 没法使用系统命令 ping 100.90.80.66

OpenWrt 配置 Tailscale

在 OpenWrt 上新建一个接口,协议选静态地址,设备选 tailscale0,地址为 Taliscale 管理页面上分配的地址,掩码 255.0.0.0。

防火墙区域选 lan 区域。

到这里,基本就完事,保存并应用即可

补充其他

如果你上面 tailscale up 时开启了子网路由,可以将下面内容添加加到防火墙的自定义规则当中,并重启防火墙。

iptables -I FORWARD -i tailscale0 -j ACCEPT 
iptables -I FORWARD -o tailscale0 -j ACCEPT 
iptables -t nat -I POSTROUTING -o tailscale0 -j MASQUERADE

安装 EasyTier

原理和流程同 Tailscale

可视化 UI 配置

OpenWrt 配置 EasyTier

在 OpenWrt 上新建一个接口,协议选静态地址,设备选 easytier0,地址为 Easytier 管理页面上分配的地址,掩码 255.255.255.0。

防火墙区域选 lan 区域。

到这里,基本就完事,保存并应用即可

测试

其他组网节点,使用系统 ping 测试,看看网络是否通。由于本文是事后回忆,可能有疏漏,敬请谅解

本地k3s集群常见小技巧

2025年1月19日 22:41

本地 k3s 集群常见小技巧

概述

本文主要给出一些具体的安装实践案例供大家参考,之前也写过一些 k3s 系列教程,不过本文专门针对资源不太够的情况下。

默认安装

有时候只是想用 k3s 来替代容器来部署一些应用,不需要 k8s 特别复杂的功能特性时或者是测试的机器资源不是特别充足时,可以禁用很多不需要的组件来节约服务器资源:

$ curl -sfL https://get.k3s.io | sh -s - server \
  --disable-kube-proxy \
  --disable-cloud-controller \
  --disable-network-policy \
  --disable-helm-controller \
  --disable=traefik,local-storage,metrics-server,coredns

可根据自身需求,删除部分 disable 参数来启用相关功能。

NAT 环境或者路由器上安装极简 k3s

将 k3s 安装在自家路由器或者买的 NAT 机器上,可能需要注意添加如下参数了:

--node-ip=192.168.31.163 \
  --tls-san=192.168.31.163  \
  --tls-san-security=false \

强制指定 ip,避免后续证书问题,如果你的环境 ip 不会经常变化的话,可以忽略

延长证书有效期

k3s 签发的证书默认有效期是 1 年,到期前 90 天之后 重启 k3s 才会自动续期。只能通过环境变量来处理。

配置方法是创建 /etc/systemd/system/k3s.service.env 或者 /etc/default/k3s 文件,添加如下内容:

# 3650 天 = 10 年 代码里最大就是10年,应该也足够了
CATTLE_NEW_SIGNED_CERT_EXPIRATION_DAYS=3650

具体配置需要看你的 k3s 的 service 文件了

systemctl cat k3s.service

配置完成后,手动触发证书轮转并重启 k3s 服务:

k3s certificate rotate
systemctl restart k3s

禁止驱逐

k8s 会自动检测 node 内存和存储空间,超过阈值就会触发驱逐,如果 k3s 只是单机使用,驱逐毫无意义且影响使用,这时可以禁用驱逐。

/etc/rancher/k3s/config.yaml 中添加如下配置:

kubelet-arg:
  - "eviction-hard=memory.available<1Mi,nodefs.available<1Mi" # 禁用驱逐

禁用镜像清理

当存储空间不够时 k3s 会尝试自动清理镜像来释放空间,可能导致不希望被清理的镜像被清理掉,这时可以禁用镜像清理。

/etc/rancher/k3s/config.yaml 中添加如下配置:

kubelet-arg:
  - "image-gc-high-threshold=100" # 禁用 image gc

EasyTier组网续

2025年1月16日 21:39

EasyTier 组网续

上一篇写完异地组网工具新推荐,easytier 轻松实现跨地域设备互联
, 实现了组网的基本功能,本文主要记录后续使用的一些调整

参数还是配置文件

easytier 支持通过命令行参数方式

easytier-core --ipv4 x.x.x.x --network-name xxx --network-secret yyy --peers tcp://peer_host:11010

也支持配置文件方式

easytier-core  -c ./config.toml

初步调试时使用参数很方便,后续使用配置文件就很方便了,维护起来很简单。如果不知道咋写配置文件,可以先用命令行方式将服务跑起来,然后使用如下命令获取配置文件

easytier-cli node config

当然也可以参考官方文档配置文件

这里给出两个环境下的配置文件,其中 instance_id 根据实际情况调整,需要保证每个节点不一样

家里云环境

不监听任何端口,只连接到对等节点

instance_name = "default"
instance_id = "e35ef2df-b325-47c7-9688-3d1ab7139dec"
ipv4 = "192.168.66.34"
dhcp = false
listeners = []
mapped_listeners = []
exit_nodes = []
rpc_portal = "127.0.0.1:15888"

[network_identity]
network_name = "example"
network_secret = "example"

[[peer]]
uri = "tcp://public.easytier.top:11010"

[flags]
dev_name = "easytier0"

云服务 VPS/VDS

监听 ipv4 的 11010,使用 tcp 协议

instance_name = "default"
instance_id = "c0871c03-2a55-4708-a3b9-426666f46b1c"
ipv4 = "192.168.66.15"
dhcp = false
listeners = ["tcp://0.0.0.0:32379"]
mapped_listeners = []
exit_nodes = []
rpc_portal = "127.0.0.1:15888"

[network_identity]
network_name = "example"
network_secret = "example"

[[peer]]
uri = "tcp://public.easytier.top:11010"

[flags]
dev_name = "easytier0"

ipv6 支持

示例为监听 ipv4/ipv6 的 tcp/udp, 如果有 ipv6 推荐开启 ipv6 支持

listeners = [
    "udp://0.0.0.0:32379",
    "tcp://0.0.0.0:32379",
    "tcp://[::]:32379",
    "udp://[::]:32379",
]

监听协议推荐

经过测试 wss 也不错

listeners = [
    "tcp://0.0.0.0:32379",
    "udp://0.0.0.0:32379",
    "wss://0.0.0.0:32380/pip3",
]

macOS 使用

macOS 使用大概有 3 种方式,按推荐的顺序依次介绍

plist 方式

可以手搓相关配置,也可以使用 serviceman

url -sS https://webi.sh/serviceman | sh; \
source ~/.config/envman/PATH.env

使用 serviceman 管理, 具体 ~/.config/easytier/config.toml 同家里云环境

sudo serviceman add --name easytier --system \
--workdir /var/log/easytier \
--groupname wheel --username root \
--cap-net-bind \
-- easytier-core -c ~/.config/easytier/config.toml

gui 方式

从 Github 下载自己设备对应架构的 GUI 即可

wireguard 接入

新增如下配置,wg 网段为 192.168.77.0/24, 监听端口为 11013

[vpn_portal_config]
client_cidr = "192.168.77.0/24"
wireguard_listen = "0.0.0.0:11013"

然后通过 easytier-cli vpn-portal 获取 wg 配置文件

[Interface]
PrivateKey = *****
Address = 192.168.77.你的ip/32

[Peer]
PublicKey = ****
AllowedIPs = 192.168.66.0/24,192.168.77.0/24
Endpoint = 开启wg特性节点公网ip:11013
PersistentKeepalive = 25

其实配置都一样的,只需要保证 Address 的 ip 不重复就行。但是不足的地方是没法通过 easytier-cli peer 查看相关接入节点,但是可以通过 easytier-cli vpn-portal 可以看到连接的客户端


其他阅读可以访问我的博客 Solitudes


异地组网工具新推荐,easytier轻松实现跨地域设备互联

2025年1月6日 22:01

异地组网工具新推荐,easytier 轻松实现跨地域设备互联

EasyTier 是由 Rust 和 Tokio 驱动一个简单安全去中心化的内网穿透 远程 组网方案,开源项目

优点

  • 去中心化:无需依赖中心化服务,节点平等且独立
  • 公网 IP 组网:支持利用共享的公网节点组网, 可以使用 EasyTier 公共 Peers
  • 低占用: 即使最垃圾的机器也可以跑
  • 跨平台支持
  • NAT 穿透:支持基于 UDP 的 NAT 穿透,即使在复杂的网络环境下也能建立稳定的连接
  • 子网代理(点对网):节点可以将可访问的网段作为代理暴露给 远程 子网,允许其他节点通过该节点访问这些子网
  • 智能路由:根据流量智能选择链路,减少延迟,提高吞吐量
  • TCP 支持:在 UDP 受限的情况下,通过并发 TCP 链接提供可靠的数据传输,优化性能
  • 高可用性:支持多路径和在检测到高丢包率或网络错误时切换到健康路径
  • 安全:支持利用 WireGuard 加密通信,也支持 AES-GCM 加密保护中转流量
  • IPV6 支持:支持利用 IPV6 组网

项目情况

部署

这里以手动安装和 docker 部署方式为例

手动安装部署

EasyTier 采用 rust 开发,交叉编译成二进制文件,部署极其方便简单
直接下载已经编译好的文件,安装即可,下面分几步执行

EasyTier 默认是不区分客户端还是服务端,故本次部署即是服务端又是客户端。一般情况下 开放监听端口为服务端,不开放监听端口为客户端

Linux-x86_64 适用于 Debian 系列,其它架构系统类似。默认 root 终端执行。

下载 EasyTier

mkdir -p /etc/et && cd /etc/et
wget wget https://github.com/EasyTier/EasyTier/releases/download/v2.1.1/easytier-linux-x86_64-v2.1.1.zip
# 上面没法下载,可以使用下面的链接下载
wget https://gh.dev.438250.xyz/https://github.com/EasyTier/EasyTier/releases/download/v2.1.1/easytier-linux-x86_64-v2.1.1.zip

解压

unzip easytier-linux-x86_64-v2.1.1.zip
cp -a easytier-linux-x86_64/* .
rm -rf easytier-linux-x86_64 easytier-linux-x86_64-v2.1.1.zip
chmod +x ./*
mv ./easytier-* /usr/bin/

编写配置文件

默认路径为 /etc/et/config.toml,内容如下:

instance_name = "default"
# easytier组网的ip地址
ipv4 = "192.168.66.80"
dhcp = false
exit_nodes = []
# api地址,记得改成本地监听
rpc_portal = "127.0.0.1:15888"
# 自定义 使用 32379 32380 端口作为监听发现服务 默认监听IPv4/IPv6, 服务端可以根据自己实际情况配置,可以全开,也可以为空不开listeners = [],客户端可以不开
listeners = [
    "tcp://0.0.0.0:32379",
    "udp://0.0.0.0:32379",
    "udp://[::]:32379",
    "tcp://[::]:32379",
    "wss://0.0.0.0:32380/",
    "wss://[::]:32380/",
]

# 组网凭证
[network_identity]
network_name = "xxxx"
network_secret = "xxxx"

# tcp://public.easytier.top:11010 是自定义要连的其他节点, 如果是第一个节点,可以不用配置, 这里以官方的节点为例
[[peer]]
uri = "tcp://public.easytier.top:11010"

# 其他参数
[flags]
dev_name = "easytier0"
enable_ipv6 = true

另外当服务跑起来后,也可以使用 easytier-cli node config 命令查看节点配置文件

编写启动守护文件并启动

cat > /etc/systemd/system/easytier.service <<EOF
[Unit]
Description=EasyTier
After=network.target

[Service]
Type=simple
WorkingDirectory=/etc/et
# ExecStart=/usr/bin/easytier-core -i 192.168.66.80 --network-name ysicing --network-secret ysicing -e tcp://public.easytier.top:11010 --dev-name easytier0 --rpc-portal 127.0.0.1:15888 --no-listener
ExecStart=/usr/bin/easytier-core -c /etc/et/config.toml
Restart=always
RestartSec=10
User=root
Group=root
[Install]
WantedBy=multi-user.target
EOF

可以使用配置文件,也可以使用命令行参数方式,如果节点配置都一样,推荐使用配置文件方式。

启动服务

# 开机自启并立即启动
systemctl enable easytier --now

如果使用命令行参数,每次启动后需要 reload 一下

systemctl daemon-reload
systemctl restart easytier

查询服务是否正常

执行 easytier-cli peer, 由于使用的是公共节点,所以会有节点信息

如下是我自己的组网节点

使用 docker 部署

编写 docker-compose.yml

首先创建一个目录(如 easytier),然后在该目录下创建 docker-compose.yml 文件,内容如下:

services:
  easytier:
    privileged: true
    container_name: easytier
    network_mode: host
    volumes:
      - easytier:/root
    environment:
      - TZ=Asia/Shanghai
    # 方便国内部署,我会定期同步到腾讯云容器仓库
    image: ccr.ccs.tencentyun.com/k7scn/easytier:latest
    # 凭证需要保持一致
    command: -i 192.168.66.8 --network-name ysicing --network-secret ysicing -l tcp://0.0.0.0:32379 -e tcp://public.easytier.top:11010 --dev-name easytier0 --rpc-portal 127.0.0.1:15888 # --vpn-portal wg://0.0.0.0:32380/192.168.77.0/24
    restart: always

volumes:
  easytier:
    driver: local

启动服务

docker compose pull
docker compose up -d

同理,如果需要查看节点信息,可以使用 docker exec -it easytier easytier-cli peer 命令

需要自行放行相关端口,如 32379, 32380 等

其他系统部署

Windows 部署可以参考官方文档

Windows Scoop 安装

在 PowerShell 执行下列代码以安装 Scoop

irm get.scoop.sh | iex
scoop install git
scoop install nssm
# 添加软件源
scoop bucket add moec https://github.com/laoxong/ScoopBucket
scoop install easytier
# 以服务的方式启动,也可以直接启动测试
nssm.exe install easytier_service C:\Scoop\apps\easytier\current\easytier-core.exe 你的参数
# 编辑服务
nssm edit easytier_service

示例: nssm.exe install easytier_service C:\Scoop\apps\easytier\current\easytier-core.exe -i 192.168.66.81 -e tcp://public.easytier.top:11010 --dev-name easytier0 --network-name xxxx --network-secret xxxx

注意:Windows 下需要管理员权限执行, 相关路径也需要确定,不一定是 C:\Scoop\,可能是当前用户目录下的 scoop 目录

打开 services.msc 找到 easytier_service,修改为延迟启动

其他

仅供参考,不对其安全性负责

RustDesk自建服务器简易教程

2024年10月21日 22:05

RustDesk 自建服务器简易教程

RustDesk 是一款开源的远程桌面软件,支持 Windows、Linux、MacOS 等多个平台。它的特点是简单易用,无需配置,只需下载安装即可使用。此外,RustDesk 支持自建服务器,可利用自己的服务器实现高质量的画质传输,而无需付费购买主流远程桌面软件的增值服务。本文记录了如何在 NAT 机器上搭建 RustDesk 服务器的简易步骤。(PS: 其实云主机或者组网更方便)

前提

这里列出 NAT 机器或者腾讯云轻量应用服务器

  • 都已经安装 docker 和 docker-compose

NAT

  • 明确清晰,NAT 机器是否支持 UDP,若不支持则无法部署

腾讯云轻量

  • 默认所有端口都放行(默认都是放行,后面可以根据自己实际情况放行)

其他

如果你是通过 wireguard 或者 tailscale 组网的,可以默认不设置啥

步骤

编写 docker-compose.yml

首先创建一个目录(如 rustdesk),然后在该目录下创建 docker-compose.yml 文件,内容如下:

services:
    rustdesk:
        container_name: rustdesk
        environment:
            - RELAY=${RUSTDESK_RELAY}:${RUSTDESK_HBBR}
            - ENCRYPTED_ONLY=1
        image: ccr.ccs.tencentyun.com/k7scn/rustdesk-server-s6
        ports:
            - ${HOST_IP}:${RUSTDESK_NAT}:21115
            - ${HOST_IP}:${RUSTDESK_HBBS}:21116
            - ${HOST_IP}:${RUSTDESK_HBBS}:21116/udp
            - ${HOST_IP}:${RUSTDESK_HBBR}:21117
            - ${HOST_IP}:${RUSTDESK_WEB_CLIENT_1}:21118
            - ${HOST_IP}:${RUSTDESK_WEB_CLIENT_2}:21119
        restart: always
        volumes:
            - ./data/hbbs:/data

在和 docker-compose.yml 同级目录下新建 .env 文件

RUSTDESK_RELAY="cm.example.com"
HOST_IP=""
RUSTDESK_HBBR=11055
RUSTDESK_HBBS=11056
RUSTDESK_NAT=21115
RUSTDESK_WEB_CLIENT_1=21118
RUSTDESK_WEB_CLIENT_2=21119

这里讲一下,正常情况下只需要配置

  • RUSTDESK_RELAY: 你公网链接的 ip 或者域名。如果是 NAT,通过是 NAT 服务商提供的 DDNS 域名;如果是轻量云服务器,可以是轻量云的公网 ip 或者你解析到轻量云公网 ip 的域名;组网的话等同轻量云用组网 ip 或者解析到组网 ip 到域名。该参数必须按
  • ENCRYPTED_ONLY: 默认为 1,不接受未加密的连接
  • 端口通常只设置 RUSTDESK_HBBRRUSTDESK_HBBS, 其中 RUSTDESK_HBBS 需要设置 TCP/UDP

注意如果你选择的 NAT 商家端口映射需要自行添加时,需要注意,这里我以小黄鸡为例

小黄鸡添加端口

示例添加 HBBS 端口

选择 TCP/UDP

等待添加完成同步

可能有人要问为啥不用默认端口:提高安全性,避免被轻易攻击或者阻断

其他 NAT 服务商

其他 NAT 服务商可能没小黄鸡大方,可能只给了 10 个端口,这种通过是根据内网 ip 算映射端口范围的,端口设置为映射访问内的即可。

组网情况下

可以不调整,原先是啥端口就是映射啥端口

云主机

同 NAT 方案,当然也可以不改,但是不推荐哈哈,你懂得。

由于腾讯云或其他云服务商默认会开启防火墙,因此需要在安全组中添加规则,允许 21115-21119/tcp 和 21116/udp 端口的外网访问。下图是腾讯云轻量应用服务器的防火墙配置界面:

运行 docker compose

在上述的 rustdesk 目录下,运行以下命令:

docker compose up -d

RustDesk 服务已经快乐的运行在服务器上

docker compose ps

配置客户端

根据本机的操作系统类型下载对应客户端,安装并打开,在设置中输入 ID 服务器的公网 IP 地址以及 Key,应用后即可连接到服务器。

如无特殊配置(按本文的操作),ID 服务器的公网地址默认为[NAT DDNS 域名]:11056,公网 IP 或者域名可以在服务器提供商的控制台中查看

由于我改下了默认端口,中继服务器需要自行填写, 默认为[NAT DDNS 域名]:11055.

此外,Key 的内容需要在服务器的 rustdesk/data 目录下查看,文件名为 id_ed25519.pub,将其内容复制到客户端的 Key 输入框中

填写完成后保存,应用,到主页观察下方的链接状态,如果显示就绪,则表示连接成功,即可开始远程操作

开始远程

找台 windows 机器测试一下

其他

组网情况下,就更简单了。另外组网环境下,可以跑到群晖上也是没有问题的。

相关 NAT 推荐

  • 北京地区的可以考虑 酷雪云北京移动的机器 9 折优惠码:CX7UU52JP7(季付以上可用)8 折优惠码:QU2RN5R6C6(仅限年付,S7840HS-9929 机型除外)
  • 西北地区的可以考虑 鸡仔云重庆移动的机器 优惠码: 月付-5 循环:CM-CQ-Monthly-5 年付-60 循环:CM-CQ-Annually-60

云主机

  • 各家轻量云主机活动

其他

当然,也可以花几块钱使用我提供的服务,仅供个人使用。

傻瓜式部署哪吒监控:一步一步教你轻松上手

2024年10月8日 21:17

傻瓜式部署哪吒监控:一步一步教你轻松上手

在这个信息化时代,监控系统已经成为了保障服务稳定性和性能的重要工具。今天,我们将介绍如何傻瓜式地部署哪吒监控,让你轻松上手,不再为监控问题烦恼,小白也可以轻松上手

先上几个成果预览图:

总体监控大图

链路监控大图

概览图

部署起来大概,分三大部分,其中是前两步,第三步可选

控制端 Dashboard

推荐使用 docker 部署, 方便升级和迁移

要求

  • 控制端服务器 需要公网 可被访问
  • 已安装 docker(可选)
  • 已经安装 caddy, 也可以使用 nginx、traefik 等

安装 docker

默认使用 root 用户

export DOWNLOAD_URL="https://mirrors.tuna.tsinghua.edu.cn/docker-ce"
# 如您使用 curl
curl -fsSL https://raw.githubusercontent.com/docker/docker-install/master/install.sh | sh
# 如您使用 wget
wget -O- https://raw.githubusercontent.com/docker/docker-install/master/install.sh | sh

或者执行我提供的脚本

curl https://c.ysicing.net/oss/scripts/docker.sh | bash

初始化 docker

curl https://c.ysicing.net/oss/scripts/dockerconfig.sh | bash

哪吒配置文件

创建目录

mkdir nezha
touch nezha/config.yaml

哪吒的配置文件 config.yaml, 示例如下

AvgPingCount: 2
Cover: 0
DDNS:
  AccessID: ""
  AccessSecret: ""
  Enable: false
  MaxRetries: 3
  Provider: webhook
  WebhookHeaders: ""
  WebhookMethod: POST
  WebhookRequestBody: ""
  WebhookURL: ""
Debug: false
EnableIPChangeNotification: false
EnablePlainIPInNotification: false
GRPCHost: agent.nzops.ysicing.net
GRPCPort: 5555
HTTPPort: 80
IPChangeNotificationTag: default
IgnoredIPNotification: ""
IgnoredIPNotificationServerIDs: {}
Language: zh-CN
Location: Asia/Shanghai
MaxTCPPingValue: 500
Oauth2:
  Admin: admin
  ClientID: 19507d56-xxxx
  ClientSecret: gto_xxxx
  Endpoint: https://gitea.local
  Type: gitea
ProxyGRPCPort: 0
Site:
  Brand: Monitor
  CookieName: ops-dashboard
  CustomCode: <script async src="https://umami.external.ysicing.net/script.js" data-website-id="c"></script>
  DashboardTheme: default
  Theme: default
  ViewPassword: ""
TLS: false

这里说下几个比较重要的地方

  • GRPCHost: agent 连接地址
  • Oauth2 配置的地方,我示例的是用 Gitea,由于某些因素,哪吒监控只支持 Oauth2 方式,常见使用 Github 方式

哪吒监控接入 Github、Gitlab、Gitee、Gitea 作为后台管理员账号,这里主要已常见的 Github 和我自用的 Gitea 为例。

Github 方式

登录 Github 后,打开 Oauth App

  • Application name - 随意填写。
  • Homepage URL - 填写面板的访问域名,如:"http://dashboard.example.com"(你的域名)。
  • Authorization callback URL - 填写回调地址,如:"http://dashboard.example.com/oauth2/callback"(不要忘记 /oauth2/callback)。

保存页面中的 Client ID,然后点击 “Generate a new client secret“,创建一个新的 Client Secret,新建的密钥仅会显示一次,请妥善保存。

配置文件

Oauth2:
  Admin: ysicing #你的github账号
  ClientID: 19507d56-xxxx # github clientid
  ClientSecret: gto_xxxx # github client secret
  Type: github

Gitea 方式

登录你的 Gitea 后, 访问 https://你的 gitea 域名/user/settings/applications

配置文件

Oauth2:
  Admin: ysicing #你的github账号
  ClientID: 19507d56-xxxx # github clientid
  ClientSecret: gto_xxxx # github client secret
  Endpoint: https://gitea.local
  Type: gitea

配置 compose

推荐使用这个版本, 将下面的文件保存为 docker-compose.yaml

version: "3"

services:
  nezha-dashboard:
    image: registry.cn-shanghai.aliyuncs.com/naibahq/nezha-dashboard:v0.18.2
    container_name: nezha-dashboard
    restart: always
    ports:
      - 44544:80
      - 44545:5555
    volumes:
      - ./nezha:/dashboard/data

启动 Dashboard

docker compose -f docker-compose.yaml up -d

配置 caddy 反代

示例: ops.ysicing.net 是控制 UI 域名,agent.ops.ysicing.net 是 agent 通信域名, 默认使用 caddy v2 版本

ops.ysicing.net {
        tls root@ysicing.net
		import LOG /var/log/caddy/nzops_ysicing_net.log
        reverse_proxy 10.76.0.7:44544
}

agent.ops.ysicing.net {
        tls root@ysicing.net
        import LOG /var/log/caddy/nzops_agent_ysicing_net.log
        reverse_proxy {
        to 10.76.0.7:44545
        transport http {
            versions h2c 2
        }
    }
}

具体 caddy 安装参考 caddy 部署

到这里,哪吒监控面板部署完成了

部署 Agent

服务器区域负责管理 Agent,是哪吒探针中最基础的区域,也是其他功能的基础。部署Agant前需要新增服务器
拥有相同分组的服务器会在受支持的主题中划分到一起进行显示,备注仅会在后台显示,无需担心泄露信息。

登陆控制端 Dashboard,切到管理后台

添加完成复制密钥

到需要安装 agent 的节点执行如下脚本

export NZ_URL=控制URL
export NZ_TOKEN=复制的token
curl https://c.ysicing.net/oss/scripts/nezha.sh | bash

或者使用管理后台的一键脚本

部署仪表面板

通过管理后台创建 API Token

services:
  nezha-dash:
    container_name: nezha-dash
    image: ccr.ccs.tencentyun.com/k7scn/nezha-dash
    restart: always
    environment:
      - NezhaBaseUrl="哪吒面包URL"
      - NezhaAuth=your-nezha-api-token
    ports:
      - "3000:3000"

效果可见 运维探针

Plandex 开源的AI编码引擎初体验

2024年8月31日 15:46

Plandex 开源的 AI 编码引擎初体验

再也不需要自己动手写代码了,目前还不太完善,但是基本能满足需求了。下面以私有化部署为例。

什么是 Plandex

Plandex 是一个 开源 的、基于终端的 AI 编码引擎,可借助使用 LLM 处理复杂的开发任务。

它组合多个 Agent 来完成跨多个文件的任务并对响应进行建模。分配任务时,会自动继续工作,直到确定任务完成。

应用场景

  • 现有项目添加新的特性功能
  • 编写自动化测试脚本
  • 修复 bug
  • 重构代码
  • 使用不熟悉的技术栈
  • 等等

特性

  • 版本控制, 独立的版本控制暂存区域与 git 的版本控制隔离,支持分支和 rewind 特性(rewind 简单理解记忆助手)
  • 强大的 上下文管理, 时刻保持已经加载的文件处于最新状态,且让你清楚上下文变更了什么

不足

  • 不自动执行代码
  • 自动选择上下文

模型支持

  • 推荐使用 gpt-4o-mini, 目前代码里还未集成,需要手动添加一下

其他

  • 支持多平台,语言没限制。

部署方式

仅测试过 k8s 部署版本

docker 部署

services:

  postgresql:
    image:  ccr.ccs.tencentyun.com/k7scn/postgresql:16
    container_name: postgresql
    # ports:
    #   - '5432:5432'
    volumes:
      - 'postgresql_data:/bitnami/postgresql'
    environment:
      - 'POSTGRESQL_DATABASE=plandex'
      - 'POSTGRESQL_USERNAME=plandex'
      - 'POSTGRESQL_PASSWORD=plandex'

  plandex:
    image: ccr.ccs.tencentyun.com/k7scn/app-plandex-server
    container_name: plandex
    ports:
      - '8080:8080'
    depends_on:
      - postgresql
    environment:
      - 'DATABASE_URL=postgres://plandex:plandex@postgresql:5432/plandex?sslmode=disable'
      - GOENV=development
      - PLANDEX_BASE_DIR=/data
    volumes:
      - 'plandex_data:/data

volumes:
  postgresql_data:
    driver: local
  plandex_data:
    driver: local

上面是示例 compose 文件,保存为 plandex.yaml

docker compose -f plandex.yaml down -v
docker compose -f plandex.yaml pull
docker compose -f plandex.yaml up -d
# sleep 等待一会儿, 正常不需要,需要依赖pg起来
docker compose -f plandex.yaml restart plandex

上面的 docker 部署未测试哈,也可以参考官方部署

git clone https://github.com/plandex-ai/plandex.git
cd plandex/app
cp _env .env
# edit .env to override any default environment variables
docker compose build
docker compose up

k8s 部署

手动创建 pg 相关库

CREATE USER plandex WITH PASSWORD plandex;
CREATE DATABASE plandex OWNER plandex;
GRANT ALL PRIVILEGES ON DATABASE plandex TO plandex;

将下面的 yaml 保存为 plandex.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: plandex
  namespace: nat
spec:
  storageClassName: longhorn
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
  labels:
    app: plandex
  name: plandex
  namespace: nat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: plandex
  updateStrategy:
    type: InPlaceIfPossible
  template:
    metadata:
      labels:
        app: plandex
    spec:
      tolerations:
      - operator: Exists
      nodeSelector:
        node-role.kubernetes.io/storage: "true"
      containers:
      - image: ccr.ccs.tencentyun.com/k7scn/app-plandex-server
        imagePullPolicy: Always
        name: plandex
        ports:
        - containerPort: 8080
          protocol: TCP
        env:
        - name: GOENV
          value: "development"
        - name: DATABASE_URL
          value: "postgres://plandex:plandex@10.25.25.25:5432/plandex?sslmode=disable"
        - name: PLANDEX_BASE_DIR
          value: "/data"
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
        volumeMounts:
        - mountPath: /data
          subPath: data
          name: plandex
      restartPolicy: Always
      volumes:
      - name: plandex
        persistentVolumeClaim:
          claimName: plandex
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: plandex
  name: plandex
  namespace: nat
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: plandex
  type: ClusterIP

创建部署

kubectl apply -f plandex.yaml

安装 cli

curl -sL https://plandex.ai/install.sh | bash

配置

基于自托管实验

创建账号

到这里需要,看下容器的日志,因为设置为开发者模式,验证码直接看容器日志就可以了,如果是生产模式,需要配置邮箱相关

2024/08/31 06:37:24 Received request for CreateEmailVerificationHandler
2024/08/31 06:37:24 Development mode: Verification pin is D5caxd for email i@ysicing.net
2024/08/31 06:37:24 Successfully created email verification

验证码就是 D5caxd

剩下的就没有什么了,创建组织或者加入组织,第一次肯定是新建

配置 GPT 相关环境变量

根据自己的情况配置,最好支持多模态、图片识别

export OPENAI_API_BASE=https://oneapi.i.ysicing.net/v1
export OPENAI_API_KEY=sk-gACJ1kjv6BnyoqVHDbA20eD0F0Ba442eBb0028086dA1B3C1

查看模型, 发现不支持 gpt-4o-mini

plandex models available

手动添加 gpt-4o-mini, 具体参考如下

  • 相关参数根据推荐值写就行
  • calling supportedmulti-modal 相关情况,根据自己的 API 接口灵活调整,不过我发现 Is function calling supportedAre streaming function calls supported 较多 API 中转都会报错 403,所有选择 no

这里的功能设置会影响 role 的角色的配置, 一开始可以设置 yes,调用的时候有报错在改

查看添加是否成功

plandex models available

设置默认模型

plandex set-model default

  • planner: streaming 支持
  • 其他: function calling 支持

具体角色可以参考文档 models/roles

实战

基于 CodeGPT 实践,目前 CodeGPT 不支持 DeepSeek, 新添加一个需求支持上。

下载代码

git clone https://github.com/appleboy/CodeGPT.git
cd CodeGPT

new

初始化

plandex new

加载上下文

plandex load -r .

如果有提示 Gpt-4o-mini does not support images in context 配置忽略图片

cat .plandexignore
images/
*.png

设置提词

支持多种方式:inline 模式,如下所示

  • plandex tell -f prompt.txt
  • plandex tell # vi 模式
  • inline 模式,如下所示
plandex tell "目前已经支持OpenAI和Azure, 以及Gemini。现在我想额外支持DeepSeek,其接口兼容OpenAI格式,地址为https://api.deepseek.com/v, 其可用模型有deepseek-chat和deepseek-coder,请帮我实现"

review 代码

plandex diff

或者

plandex changes

apply

接受代码,当然也可以拒绝

plandex apply

拒绝的话可以选择也可以指定文件

plandex  reject openai/openai.go

其实在 review 的时候拒绝体验最好 😂

其他命令

每次向 Plandex 发送提示或 Plandex 回复时,计划的对话都会更新。对话受版本控制,可以进行分支

plandex convo --plain

对话摘要

plandex summary

plandex log

其他问题

  • 如何修改模型参数,简单看了一下没发现,删除重新添加最快 plandex models rm gpt-4o-mini

成本

成本不是问题,模型只会越来越便宜,这只是进行了 1-2 轮,如果要想代码可用至少得跑上好几轮不止。

最后

这就是未来的趋势,我们只是高质量需求的搬运工,产品工程师

LobeChat知识库版本部署

2024年8月23日 11:26

LobeChat 知识库版本

先占坑,新版本修复了 minio 上传问题,但是后面版本又改出问题了,目前知识库还有些问题,再等等 是我的问题,已经完美支持。

docker compose 文件

services:

  postgresql:
    image: ccr.ccs.tencentyun.com/k7scn/pgvector:pg16
    container_name: postgresql
    # ports:
    #   - '5432:5432'
    volumes:
      - 'postgresql_data:/var/lib/postgresql/data'
    environment:
      - 'POSTGRES_DB=lobe'
      - 'POSTGRES_PASSWORD=lobepassw0rd'

  minio:
    image: ccr.ccs.tencentyun.com/k7scn/minio:2024
    container_name: minio
    ports:
      - '9000:9000'
      - '9001:9001'
    volumes:
      - 'minio_data:/bitnami/minio/data'
    environment:
      - 'MINIO_ROOT_USER=lobe'
      - 'MINIO_ROOT_PASSWORD=lobepassw0rd'
      - 'MINIO_DEFAULT_BUCKETS=lobe'

  lobe:
    image: ccr.ccs.tencentyun.com/k7scn/lobe-chat-database
    container_name: lobe
    ports:
      - '3210:3210'
    depends_on:
      - postgresql
      - minio
    environment:
      - 'KEY_VAULTS_SECRET=Px/trSNqJMIQ0SbOIDhIpDiNv2eUdNFf8ZUoh76g9+c=' # openssl rand -base64 32
      - 'DATABASE_URL=postgres://postgres:lobepassw0rd@postgresql:5432/lobe'
      - NEXT_AUTH_SECRET=q5JdZ9lgcOZ79vuJSYAFyOIudCX1CDlMzpnKcGN21 # openssl rand -base64 32
      - ACCESS_CODE=hhhhhh # 后续版本可能去掉
      - NEXT_AUTH_SSO_PROVIDERS=github
      - GITHUB_CLIENT_ID=xxxx # 你的github app client id
      - GITHUB_CLIENT_SECRET=xxxxx # 你的github app client secret
      - NEXTAUTH_URL=http://100.90.80.25:3210/api/auth # 不用域名访问,一定要配置,具体改成你的ip
      - S3_ACCESS_KEY_ID=lobe
      - S3_SECRET_ACCESS_KEY=lobepassw0rd
      - S3_ENDPOINT=http://100.90.80.25:9000
      - S3_BUCKET=lobe
      - S3_PUBLIC_DOMAIN=http://你的公网ip:19000/lobe # 新版本可能不需要
      - APP_URL=http://100.90.80.25:3210 

volumes:
  postgresql_data:
    driver: local
  minio_data:
    driver: local

新版本新增了知识库的支持,需要调整数据库开启向量的扩展。比较麻烦。由于我的数据不太重要,重建是最简单。

docker compose -f lobe.yaml down -v
docker compose -f lobe.yaml pull
docker compose -f lobe.yaml up -d
# sleep 等待一会儿, 正常不需要,但是我测试的时候遇到了几次
docker compose -f lobe.yaml restart lobe

目前有个比较坑的地方就是自建 minio,这个配置 S3_PUBLIC_DOMAINNEXT_PUBLIC_S3_DOMAIN, 需要配置 minio 能公网访问的地址。

minio 公网访问

这里我简单操作一下了,将 minio 转发到香港的某台机器(1.1.1.1)上,如使用 realm

[log]
level = "info"

[network]
no_tcp = false
use_udp = true
tcp_timeout = 300
udp_timeout = 30
send_proxy = false
send_proxy_version = 2
accept_proxy = false
accept_proxy_timeout = 5

# cos
[[endpoints]]
listen = "0.0.0.0:19000"
remote = "192.168.94.17:9000"

长传图片

知识库分块

上传文件

使用知识库

云原生存储Longhorn升级到1.7,支持定期或按需全量备份特性

2024年8月22日 20:36

k3s 分布式存储 Longhorn1.7 版本升级记录

抽空水一下,有兴趣的需要先阅读傻瓜式教学:部署云原生存储 Longhorn

新特性

  • 新增 cli 工具代替之前的脚本(新用户用的比较多),其他用途暂时没了解, 官方说支持故障排查, 命令行文档
  • RWX(NFS 协议)相关特性增强
    • RWX 卷快速故障转移,支持快速检测和响应 ShareManage 故障
    • 存储网络支持多次读写
  • 当卷意外分离时自动删除工作负载 pod
  • 支持定期和按需全量备份
  • 增强了副本自动均衡功能
  • 建议使用 6.7+ 内核版本

新 Bug

无法附加在 v1.5.2 和 v1.4.4 之前创建的卷

如果 Longhorn 集群包含具有以下特征的资源,请避免升级到 v1.7.0:

  • 资源名称:格式为 。<volume name>-e-<8-char random id>
  • 创建时间:集群上安装了 v1.5.2 和 v1.4.4 之前的 Longhorn 版本

运行以下命令以检查是否可以安全地将 Longhorn 集群升级到 v1.7.0:

[ $(kubectl -n longhorn-system get engines.longhorn.io -o name | grep -E '\-e\-[a-z0-9]{8}$' | wc -l) -gt 0 ] && echo "Please hold off on upgrading to v1.7.0 until v1.7.1 is available." || echo "Safe to upgrade to v1.7.0."

升级后体验感觉

自动重新平衡副本

之前手动干预比较多。调整如下参数阈值,会自动在同一节点内的另一个磁盘上重建相关副本

kubectl get settings.longhorn.io/replica-auto-balance-disk-pressure-percentage  -n longhorn-system

升级安装

相关镜像我已经同步到国内。

添加 Longhorn Helm 仓库

helm repo add longhorn https://charts.longhorn.io

更新

helm repo update

准备 values.yaml

我的环境限制,仅在存储节点运行。

global:
  nodeSelector:
    node-role.kubernetes.io/storage: "true"
  tolerations:
    - operator: Exists
      effect: NoSchedule

persistence:
  defaultClass: false
  defaultDataLocality: best-effort
  migratable: true

defaultSettings:
  createDefaultDiskLabeledNodes: true
  defaultDataPath: /data/k8s/longhorn
  defaultDataLocality: best-effort
  replicaAutoBalance: best-effort
  storageMinimalAvailablePercentage: 10
  systemManagedComponentsNodeSelector: "node-role.kubernetes.io/storage: true"
  taintToleration: ":NoSchedule"

longhornUI:
  replicas: 1

ingress:
  enabled: true
  ingressClassName: nginx
  host: lhsc.ysicing.local
  # annotations:
  #   nginx.ingress.kubernetes.io/auth-type: basic
  #   nginx.ingress.kubernetes.io/auth-secret: basic-auth

longhornManager:
  nodeSelector:
    node-role.kubernetes.io/storage: "true"
  tolerations:
    - operator: Exists
      effect: NoSchedule

longhornDriver:
  nodeSelector:
    node-role.kubernetes.io/storage: "true"
  tolerations:
    - operator: Exists
      effect: NoSchedule

image:
  longhorn:
    engine:
      repository: ccr.ccs.tencentyun.com/k7scn/longhorn-engine
    manager:
      repository: ccr.ccs.tencentyun.com/k7scn/longhorn-manager
    ui:
      repository: ccr.ccs.tencentyun.com/k7scn/longhorn-ui
    instanceManager:
      repository: ccr.ccs.tencentyun.com/k7scn/longhorn-instance-manager
    shareManager:
      repository: ccr.ccs.tencentyun.com/k7scn/longhorn-share-manager
    backingImageManager:
      repository: ccr.ccs.tencentyun.com/k7scn/backing-image-manager
    supportBundleKit:
      repository: ccr.ccs.tencentyun.com/k7scn/support-bundle-kit
  csi:
    attacher:
      repository: ccr.ccs.tencentyun.com/k7scn/csi-attacher
    provisioner:
      repository: ccr.ccs.tencentyun.com/k7scn/csi-provisioner
    nodeDriverRegistrar:
      repository: ccr.ccs.tencentyun.com/k7scn/csi-node-driver-registrar
    resizer:
      repository: ccr.ccs.tencentyun.com/k7scn/csi-resizer
    snapshotter:
      repository: ccr.ccs.tencentyun.com/k7scn/csi-snapshotter
    livenessProbe:
      repository: ccr.ccs.tencentyun.com/k7scn/livenessprobe

升级

helm upgrade -i longhorn longhorn/longhorn -n longhorn-system -f values.yaml

最近折腾的那些事之镜像站相关

2024年8月19日 20:25

最近折腾的那些事之镜像站相关

之前一段时间比较忙,也没空写写。

docker 镜像仓库

之前也维护了几个镜像站,但是最近又国际互联因素影响,体验很差,白天 基本能用,到了晚高峰基本就用不了。

h.ysicing.net
h2.ysicing.net
h3.ysicing.net

目前只能保证基本可用,无法 sla 保证

k3s 使用

编辑 /etc/rancher/k3s/registries.yaml

# cat /etc/rancher/k3s/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://h3.ysicing.net"
      - "https://h2.ysicing.net"
      - "https://h.ysicing.net"

docker 使用

编辑 /etc/docker/daemon.json

{
  "registry-mirrors": ["https://h.ysicing.net","https://h2.ysicing.net", "https://h3.ysicing.net"],
  "bip": "169.254.123.1/24",
  "max-concurrent-downloads": 10,
  "live-restore": true,
  "log-driver": "json-file",
  "log-level": "warn",
  "log-opts": {
    "max-size": "30m",
    "max-file": "3"
  },
  "storage-driver": "overlay2"
}

其他软件镜像

由我维护的开源镜像服务, 致力于提高国内用户体验,希望能对国内开源软件用户有所帮助。主要针对Debian系,暂不考虑支持其他发行版

v1 版本

历史版本mirrors.ysicing.net 纯粹基于 caddy 实现的,蛮多朋友使用的,但是实际体验一般,没有缓存机制。

v2 版本

基于 caddy+nexus 重新弄了一版 mirrors.china.12306.work,有了缓存,速度体验 ++, 目前支持多款软件如 tailscalecaddy

tailscale 镜像

echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://mirrors.china.12306.work/repository/tailscale/debian bookworm main" | tee /etc/apt/sources.list.d/tailscale.list
apt-get update
apt-get install tailscale

caddy 镜像

echo "deb [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] https://mirrors.china.12306.work/repository/caddy/stable/deb/debian any-version main" | tee /etc/apt/sources.list.d/caddy.list
apt-get update
apt-get install caddy

为什么没有我用的软件包?

因为我可能暂时用不上, 有好的想法可以邮件或通过其他途径联系我.

出手头最后一台国内廉价联通杜甫

2024年8月10日 21:55

最近消费降级又买了新 🐔,想把手头闲置的出掉

杜甫简介

狗云重庆杜甫 CQA,很长一段时间没货了,原价 400 元

  • 需求实名
  • 重庆联通, 共享带宽
    • 入 50 Mbps
    • 出 35 Mbps
  • IPv4(默认 1 个,可附加 5 个,每个 50), IPv6(/64, 可添加会员等级 +1 个 IPv6 子网数量)
  • CPU: 10C20T E5-2630 v4
  • 内存: 64G DDR4 ECC
  • 硬盘: 800G SSD
  • 月付:200
  • 年付:2000
  • 到期:2025-08-01(356 天)

上面是我日常使用情况,具体也可以参观我的哪吒监控 其中狗云 3 号就是本次出售的。

这台机器溢价 300 收的,现在原价 +Push 费用,总共 2020 出。

之前也出 出 2 台国内廉价联通杜甫

使用 Docker 部署LobeChat服务端数据库版

2024年8月9日 22:41

使用 Docker 部署 LobeChat 服务端数据库版

当前版本暂不支持 Minio 私有对象存储,即图片上传功能不可用。官方文档已经足够详细了,这里我简单部署实践一下

准备工作

支持 docker 环境即可或者 k8s 环境也行,这里简单操作, 我已经将相关镜像同步到国内。

docker compose 文件

services:

  postgresql:
    image: ccr.ccs.tencentyun.com/k7scn/postgresql:16
    container_name: postgresql
    # ports:
    #   - '5432:5432'
    volumes:
      - 'postgresql_data:/bitnami/postgresql'
    environment:
      - 'POSTGRESQL_DATABASE=lobe'
      - 'POSTGRESQL_PASSWORD=lobepassw0rd'

  minio:
    image: ccr.ccs.tencentyun.com/k7scn/minio:2024
    container_name: minio
    ports:
      - '9000:9000'
      - '9001:9001'
    volumes:
      - 'minio_data:/bitnami/minio/data'
    environment:
      - 'MINIO_ROOT_USER=lobe'
      - 'MINIO_ROOT_PASSWORD=lobepassw0rd'
      - 'MINIO_DEFAULT_BUCKETS=lobe'

  lobe:
    image: ccr.ccs.tencentyun.com/k7scn/lobe-chat-database
    container_name: lobe
    ports:
      - '3210:3210'
    depends_on:
      - postgresql
      - minio
    environment:
      - 'KEY_VAULTS_SECRET=Px/trSNqJMIQ0SbOIDhIpDiNv2eUdNFf8ZUoh76g9+c=' # openssl rand -base64 32
      - 'DATABASE_URL=postgres://postgres:lobepassw0rd@postgresql:5432/lobe'
      - NEXT_AUTH_SECRET=q5JdZ9lgcOZ79vuJSYAFyOIudCX1CDlMzpnKcGN21 # openssl rand -base64 32
      - ACCESS_CODE=hhhhhh # 后续版本可能去掉
      - NEXT_AUTH_SSO_PROVIDERS=github
      - GITHUB_CLIENT_ID=xxxx # 你的github app client id
      - GITHUB_CLIENT_SECRET=xxxxx # 你的github app client secret
      - NEXTAUTH_URL=http://100.90.80.25:3210/api/auth # 不用域名访问,一定要配置,具体改成你的ip
	  # 下述配置暂时不可用,有bug,图片上传功能有问题
      - S3_ACCESS_KEY_ID=lobe
      - S3_SECRET_ACCESS_KEY=lobepassw0rd
      - S3_ENDPOINT=http://100.90.80.25:9000
      - S3_BUCKET=lobechat
      - NEXT_PUBLIC_S3_DOMAIN=http://100.90.80.25:9000

volumes:
  postgresql_data:
    driver: local
  minio_data:
    driver: local

将上述文件保存为 lobe.yaml

配置身份验证功能

身份验证服务

从官方文档来看,我总结了一下还是 GitHub Auth 简单点, 基本没啥门槛。

配置 Github 身份验证服务

  1. 创建一个新的 Github App, 填写 Github App name、Homepage URL、Callbak URL,主要写 Callbak URL 地址要对我的示例 http://100.90.80.25:3210/api/auth/callback/github

  1. 没需求 Webhook 勾去掉

  1. 设置读取邮件地址权限及仅个人使用, 公开使用比较麻烦

  1. 创建成功后,点击「Generate a new client secret」创建客户端 Secret,并保存下来,更新 lobe.yaml 的 GITHUB_CLIENT_IDGITHUB_CLIENT_SECRET

配置对象存储

推荐自建, 但是目前功能不可用,等待官方修复, 近期会修复

使用 cloudflare 的 r2 储存上传图片提示错误#3413

启动

docker compose -f lobe.yaml up -d

中间可能 lobe 启动失败了,稍等片刻或者等 pg 启动完成后,再执行一下

docker compose -f lobe.yaml up -d

访问

访问地址 http://100.90.80.25:3210

推荐 API 中转

OpenAI 官方渠道折扣为 6.8 折,Azure 渠道折扣为 5 折 TurboAI你值得拥有,我已经体验很长时间了,很稳定。

k3s集群私有负载均衡的另一种选择Tailscale

2024年7月23日 20:45

k3s 集群私有负载均衡的另一种选择 tailscale

在阅读此文实践前需要阅读 多云组网部署 k3s 集群的另一种选择 Tailscale

要求

  • 基于 tailscale 实现 k3s 集群部署
  • 有私有负载均衡场景
  • 已经安装 helm

本文默认已经满足上述条件了。

历史选择

在 tailscale 之前,我是利用 MetalLB 实现负载均衡的,然后再由 tailscale 某个节点广播负载均衡路由的。

如今

在 tailscale v1.50 版本之后,增强了对 k8s 的支持,Kubernetes operator 诞生了,带来了很多新功能:

  • 代理访问 k8s 控制平面 API
  • 向 k8s 集群公开内部服务/k8s 集群服务暴露给内部(集群内部和集群外部互通有无,甚至是跨集群互通)
  • 打通 saas 云服务
  • 在 Kubernetes 上部署出口节点和子网路由控制器

其中 2、4 比较我用的比较多

安装部署

准备工作

  1. 编辑 ACL 策略, 新增如下配置
"tagOwners": {
		"tag:k8s-operator": [],
		"tag:k8s":          ["tag:k8s-operator"],
	},

  1. 创建 Oauth 客户端备用, 选择 Devices 读写权限,并绑定 tag:k8s-operator

点击创建后,会弹出 Client IDClient secret 记得留存一下,只会显示一次,后续步骤会使用

安装

  1. 添加到本地 Helm 存储库:https://pkgs.tailscale.com/helmcharts
helm repo add tailscale https://pkgs.tailscale.com/helmcharts
  1. 更新
helm repo update
  1. 安装
helm upgrade \
  --install \
  tailscale-operator \
  tailscale/tailscale-operator \
  --namespace=tailscale \
  --create-namespace \
  --set-string oauth.clientId=<OAauth Client ID> \
  --set-string oauth.clientSecret=<OAuth Client secret> \
  --set-string operatorConfig.image.repository=ccr.ccs.tencentyun.com/k7scn/tailscale-k8s-operator \
  --set-string proxyConfig.image.repository=ccr.ccs.tencentyun.com/k7scn/tailscale \
  --wait

如果你的环境拉取镜像没问题的话,关于镜像部分可以去掉, 目前最新版本是 v1.68.1

operatorConfig.image.repository=ccr.ccs.tencentyun.com/k7scn/tailscale-k8s-operator 
ccr.ccs.tencentyun.com/k7scn/tailscale
  1. 验证

等 pod 状态变成 ok 之后,可以在 tailscale 控制台机器里看到 tailscale-operator 节点,类似

使用

这里主要介绍 svc 负载均衡模式(即 ingress 模式)和 svc 子网路由配置,其他可以参考官网文档

负载均衡

其实这里最好的演示是 nginx-ingress-controller, 但是 bitnami 的 nginx-ingress-controller 不支持这个参数

默认已经安装好了 nginx-ingress-controller,这里我手动配置一下。

apiVersion: v1
kind: Service
metadata:
  annotations:
    meta.helm.sh/release-name: nginx-ingress-controller
    meta.helm.sh/release-namespace: kube-system
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: nginx-ingress-controller
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: nginx-ingress-controller
    app.kubernetes.io/version: 1.10.1
    helm.sh/chart: nginx-ingress-controller-11.3.8
  name: nginx-ingress-controller-lb
  namespace: kube-system
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: http
  - name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: nginx-ingress-controller
    app.kubernetes.io/name: nginx-ingress-controller
  sessionAffinity: None
  type: LoadBalancer
  loadBalancerClass: tailscale

手动配置 loadBalancerClass 值为 tailscale

apply 生效后,查看 kubectl get svc -n kube-system

查看 tailscale 命令空间

当然除了这种方式外还支持给 Service 添加注解,更多详细请阅读官方文档 Expose a Kubernetes cluster workload to your tailnet (cluster ingress)

子网路由

之前说到,基于 tailscale 组网,会自动分发 pod 的路由,使你在 任何时间任何地点都可以访问pod的ip,那如何实现访问 svc 的 ip 呢。
之前尝试过,在 k8s 节点分发额外分发 svc 的 ip, 会导致经常性网络问题,不知道大家有没有遇到类似问题?

也比较简单, 其中 10.25.0.0/16" 是我的集群 svc 的 cidr

apiVersion: tailscale.com/v1alpha1
kind: Connector
metadata:
  name: ts-svc-cidrs
  namespace: tailscale
spec:
  hostname: ts-svc-cidrs
  subnetRouter:
    advertiseRoutes:
      - "10.25.0.0/16"

等 pod 状态 ok,需要控制台 allow 一下(记得不是特别清楚是否需要可以确定一下)

在此之后,你也可以实现任何时间任何地点都可以访问 svc 的 ip 了。

总结

到这里 tailscale 在 k8s 上常用技能点就点完了,如果有其他感兴趣的,可以留言。后面大概还有两三篇讲讲 tailscale 最近的新功能

开源备份软件Restic简单教程

2024年7月14日 19:43

开源备份软件 Restic 简单教程

Restic 是一个快速、安全、高效的备份工具,特别适用于存储在不同位置的数据

安装

该工具提供多平台安装部署

macOS

brew install restic

Debian

apt update
apt install restic

Alpine

apk add restic

其他

其他系统可以参考官网文档

升级

除了包安装的方式升级外,还支持自身升级

restic self-update

补全命令行

执行如下命令可以使我们在使用 restic 时参数自动补全,提升使用效率

restic generate --bash-completion /etc/bash_completion.d/restic

存储库

安装好了 Restic 后,还需要配置下存储方式(本地或者远程), 配置过程中都会要你输入密码。

记住密码很重要!如果你失去了它,你就不会 能够访问存储库中存储的数据.

为了自动向 restic 提供存储库密码,有几个选项支持配置:

  • 设置环境变量 RESTIC_PASSWORD
  • 通过选项或环境变量使用密码指定文件的路径 --password-file RESTIC_PASSWORD_FILE
  • 配置在需要密码时通过 option 或环境变量 --password-command RESTIC_PASSWORD_COMMAND

接下来介绍一下我常用的存储方式

Local 本地存储

备份到本地 /data/restic-repo

restic init --repo /data/restic-repo
enter password for new repository:
enter password again:
created restic repository b8107af4fd at /data/restic-repo

Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.

S3 协议存储

远程备份, 备份到支持 S3 协议的对象存储中,如 minio

export AWS_ACCESS_KEY_ID=<MY_ACCESS_KEY>
export AWS_SECRET_ACCESS_KEY=<MY_SECRET_ACCESS_KEY>

restic -r s3:http://localhost:9000/restic init

利用 rclone

restic 本身支持的存储库有限,但是 rclone 支持多,于是乎支持 rclone 集成

restic -r rclone:foo:bar init

更多可以参考官方文档 other-services-via-rclone

备份

目录中特定时间点的内容在 Restic 中称为 快照

以本地备份为例进行演示说明:

# 第一次备份数据
restic -r /data/restic-repo backup /etc/sb
enter password for repository:
repository b8107af4 opened successfully, password is correct
created new cache in /root/.cache/restic

Files:          77 new,     0 changed,     0 unmodified
Dirs:           56 new,     0 changed,     0 unmodified
Added to the repo: 113.555 KiB

processed 77 files, 65.949 KiB in 0:00
snapshot aa2f8849 saved

# 再次运行backup命令,Retic将创建数据的另一个快照
restic -r /data/restic-repo backup /etc/sb
enter password for repository:
repository b8107af4 opened successfully, password is correct

Files:           0 new,     0 changed,    77 unmodified
Dirs:            0 new,     0 changed,    56 unmodified
Added to the repo: 0 B

processed 77 files, 65.949 KiB in 0:00
snapshot c8b23ba8 saved

也可以备份同一个存储库中的单个文件

restic -r /data/restic-repo --verbose backup /etc/sb/hy2.yaml
open repository
enter password for repository:
repository b8107af4 opened successfully, password is correct
lock repository
load index files
start scan on [/etc/sb/hy2.yaml]
start backup on [/etc/sb/hy2.yaml]
scan finished in 0.207s: 1 files, 265 B

Files:           1 new,     0 changed,     0 unmodified
Dirs:            2 new,     0 changed,     0 unmodified
Data Blobs:      1 new
Tree Blobs:      3 new
Added to the repo: 1.330 KiB

processed 1 files, 265 B in 0:00
snapshot 822f2e6c saved

相关常用参数

--exclude 指定一次或多次排除一个或多个项
--exclude-file 指定一次排除包含特殊文件的文件夹
--exclude-if-present foo 排除文件夹包含名为 foo 的文件,不支持文件名的通配符
--exclude-larger-than size 指定一次以排除大于给定大小的文件

操作使用存储库

列出所有快照

restic -r /data/restic-repo snapshots
enter password for repository:
repository b8107af4 opened successfully, password is correct
ID        Time                 Host        Tags        Paths
-----------------------------------------------------------------------
aa2f8849  2024-07-14 06:54:47  nat4                    /etc/sb
c8b23ba8  2024-07-14 06:57:08  nat4                    /etc/sb
822f2e6c  2024-07-14 06:59:27  nat4                    /etc/sb/hy2.yaml
-----------------------------------------------------------------------
3 snapshots

还支持过滤策略

restic -r /data/restic-repo snapshots --path "/etc/sb"
enter password for repository:
repository b8107af4 opened successfully, password is correct
ID        Time                 Host        Tags        Paths
--------------------------------------------------------------
aa2f8849  2024-07-14 06:54:47  nat4                    /etc/sb
c8b23ba8  2024-07-14 06:57:08  nat4                    /etc/sb
--------------------------------------------------------------
2 snapshots

验证

运行检查命令来验证所有数据都正确地存储在存储库中了,应该 定期运行此命令,以确保存储库的内部结构没有错误

restic check -r /data/restic-repo

using temporary cache in /tmp/restic-check-cache-106234855
enter password for repository:
repository b8107af4 opened successfully, password is correct
created new cache in /tmp/restic-check-cache-106234855
create exclusive lock for repository
load indexes
check all packs
check snapshots, trees and blobs
no errors were found

默认情况下不检测数据库磁盘上文件是否被修改,以使用 restic 命令也验证存储库中包文件的完整性

restic -r /data/restic-repo check --read-data
using temporary cache in /tmp/restic-check-cache-770072337
enter password for repository:
repository b8107af4 opened successfully, password is correct
created new cache in /tmp/restic-check-cache-770072337
create exclusive lock for repository
load indexes
check all packs
check snapshots, trees and blobs
read all data
[0:00] 100.00%  4 / 4 packs
no errors were found

从备份恢复数据

从快照中恢复数据

restic -r /data/restic-repo restore c8b23ba8 --target /tmp/restore-work
enter password for repository:
repository b8107af4 opened successfully, password is correct
restoring <Snapshot c8b23ba8 of [/etc/sb] at 2024-07-14 06:57:08.982881207 -0400 EDT by root@nat4> to /tmp/restore-work

恢复部分文件

restic -r /data/restic-repo restore latest --target /tmp/restore-work2 --path "/etc/sb" --host nat4
enter password for repository:
repository b8107af4 opened successfully, password is correct
restoring <Snapshot c8b23ba8 of [/etc/sb] at 2024-07-14 06:57:08.982881207 -0400 EDT by root@nat4> to /tmp/restore-work2

标准输出

我的简单理解就是导出文件,用的不多

restic -r /data/restic-repo dump latest /etc/sb/hy2.yaml > /tmp/hy2.yaml

删除备份的快照

指定快照 ID 来删除快照 forget ID

root@nat4:~# restic -r /data/restic-repo snapshots
enter password for repository:
repository b8107af4 opened successfully, password is correct
ID        Time                 Host        Tags        Paths
-----------------------------------------------------------------------
aa2f8849  2024-07-14 06:54:47  nat4                    /etc/sb
c8b23ba8  2024-07-14 06:57:08  nat4                    /etc/sb
822f2e6c  2024-07-14 06:59:27  nat4                    /etc/sb/hy2.yaml
-----------------------------------------------------------------------
3 snapshots
root@nat4:~# restic -r /data/restic-repo forget c8b23ba8
enter password for repository:
repository b8107af4 opened successfully, password is correct
[0:00] 100.00%  1 / 1 files deleted
root@nat4:~# restic -r /data/restic-repo snapshots
enter password for repository:
repository b8107af4 opened successfully, password is correct
ID        Time                 Host        Tags        Paths
-----------------------------------------------------------------------
aa2f8849  2024-07-14 06:54:47  nat4                    /etc/sb
822f2e6c  2024-07-14 06:59:27  nat4                    /etc/sb/hy2.yaml
-----------------------------------------------------------------------
2 snapshots

虽然上述命令将快照删除了,但文件引用的数据仍然存储在存储库中, 要清除未引用的数据,必须运行 prune 命令

restic -r /data/restic-repo prune

当然也可以综合这两步一起操作

# 仅保留最新的快照
restic forget  -r /data/restic-repo --keep-last 1 --prune

根据策略删除快照

根据策略删除快照这个用法会多一些

  • 可以指定保留多少小时/每日/每周/每月和每年快照,以及删除多少其他快照
  • 可以使用 --dry-run 参数来测试需要删除的文件和目录列表
--keep-last n 保留最后(最新)n个快照
--keep-hourly n 不删除快照的最后 n 个小时;每小时只保留最后一个快照
--keep-daily n 不删除快照的最后 n 个天;每小时只保留最后一个快照
--keep-weekly n 不删除快照的最后 n 个周;每小时只保留最后一个快照

更多的可以参考官方文档 060_forget

保留每天一个快照,最多保留最近的 4 天的快照。举个例子,如果你有 10 天的备份,这个选项会删除除了最近 4 天以外的每天的备份

restic -r /data/restic-repo  forget --keep-daily 4 --dry-run

最后

到这里基本的使用基本就完成了,其他还是挺简单的。

git stash常用命令

2024年7月7日 10:16

git stash 命令的作用是将你的工作目录和暂存区的修改保存起来,以便稍后恢复。这个命令在以下情况下非常有用:

  1. 当你正在一个分支上进行工作,但需要切换到另一个分支来修复 bug 时,可以使用 git stash 保存当前分支上的修改,然后切换到另一个分支进行工作。
  2. 当你正在进行一项工作,但需要紧急修复其他问题时,可以使用 git stash 保存当前的修改,以便稍后恢复。

下面是使用 git stash 的基本流程:

  1. 保存当前分支上的修改:git stash
  2. ... 新切分支或者原分支干活...
  3. 恢复之前保存的修改:git stash pop 或者 git stash apply

git stash 常用命令:

1.git stash save "message":将当前的修改暂存,并添加一个描述性的消息。
    git stash save "Work in progress - fixing bugs"

2.git stash list:列出当前所有的stash记录。

3.git stash apply:将最新的stash恢复到当前分支,但不会删除stash记录。

4.git stash pop:将最新的stash恢复到当前分支,并从stash列表中删除该记录。

5.git stash drop:删除最新的stash记录。

6.git stash branch <branch_name>:创建一个新分支,并将stash中的修改应用到新分支上。

利用群晖部署开源密码管理器vaultwarden

2024年6月24日 21:11

利用群晖部署开源密码管理器 vaultwarden

VaultwardenBitwarden 的一个轻量级开源实现,非常适合在家庭服务器或小型企业环境中运行。本文将介绍如何在群晖 NAS 上部署 Vaultwarden

优点

  • 简单易用且开源
  • 资源占用极低
  • 兼容 Bitwarden 所有扩展

镜像

  • 官方镜像: vaultwarden/server
  • 腾讯云镜像: ccr.ccs.tencentyun.com/k7scn/vaultwarden
  • 阿里云镜像: registry.cn-beijing.aliyuncs.com/k7scn/vaultwarden

国内镜像我会 定期更新

下载 Vaultwarden 镜像

可视化操作

前提是能正常访问 docker hub

  1. 打开 Docker 应用程序
  2. 点击左侧的“注册表”
  3. 在搜索栏中输入 vaultwarden,然后点击回车
  4. 在搜索结果中找到 vaultwarden/server,点击并选择“下载此映像”

命令行操作

远程连接到群晖,切到 root 用户后执行 docker pull, 具体如下

docker pull ccr.ccs.tencentyun.com/k7scn/vaultwarden

申请证书

由于需要 https 访问,这里通过腾讯云临时申请了一个证书, 然后将证书托管到群晖

  • 控制面板/安全性/证书/新增 上传证书就可以了

启动 vaultwarden

在映像里选择 vaultwarden 并启动

  • 配置自启动
  • 勾选启动网页门户,80 HTTP

  • 存储空间持久化,添加文件夹,映射 /data

启动

配置证书

  • 控制面板/安全性/证书/设置, 勾选你上传的证书

访问

通过域名访问,完成初始化。

配置

浏览器扩展还是其他,都可以通过 bitwarden.com 解决

其他

docker compose 部署

version: '3'
services:
  vaultwarden:
    image: vaultwarden/server
    container_name: vaultwarden
    restart: always
    volumes:
      - /data/vaultwarden:/data
    ports:
      - '8888:80'

启动 docker compose up -d

caddy 配置

vpass.your.domain {
  reverse_proxy http://127.0.0.1:8888
}

总结

配置很简单,部署也很简单

k3s新特性分布式注册表镜像,加速镜像拉取

2024年6月18日 20:36

k3s 新特性分布式注册表镜像,加速镜像拉取

自 2024 年 1 月起,分布式注册表镜像作为实验性功能提供:v1.26.13+k3s1、v1.27.10+k3s1、v1.28.6+k3s1、v1.29.1+k3s1

该功能基于开源项目 spegel 实现

什么是 spegel

一个无状态集群本地 OCI 注册表镜像

应用场景

  • 本地缓存来自外部注册表的映像,无需显式配置
  • 避免在外部注册表停机期间发生群集故障
  • 通过首先从本地缓存中拉取镜像来提高镜像拉取速度和 Pod 启动时间。
  • 从外部注册表(例如 Docker Hub)提取映像时避免速率限制。
  • 减少群集网络外部的出口流量。
  • 提高边缘节点部署中的映像拉取效率

总结版: 通过公网只需要拉取一次后,共享给所有节点使用。集群中的每个节点都可以充当本地注册表镜像服务,允许节点在它们之间 共享 映像,节点已拉取的任何映像都可供群集中的任何其他节点拉取。

硬性要求

  • 只支持 containerd

其他更多细节,可以阅读官方文档 spegel-org/spegel

k3s 配置

需要将 k3s 更新到 最近版本,且运行时使用 内置containerd 才行。

server 管理节点

控制平面节点,需要添加 --embedded-registry 参数来开启

--embedded-registry                        (experimental/components) Enable embedded distributed container registry; requires use of embedded containerd

agent 计算节点

计算节点,需要添加 --disable-default-registry-endpoint

配置文件方式

使用配置文件方式: /etc/rancher/k3s/config.yaml

write-kubeconfig-mode: "0644"
embedded-registry: true
disable-default-registry-endpoint: true
node-external-ip: 1.1.1.1

配置文件方式或者上述参数方式任选一个即可

registries.yaml 配置文件

这个文件需要所有参与共享的节点都需要

mirrors:
  docker.io:
  registry.k8s.io:
  gcr.io:
  quay.io:
  ghcr.io:

私有仓库也是可以支持

mirrors:
  ccr.ccs.tencentyun.com:
    endpoint:
      - https://ccr.ccs.tencentyun.com
configs:
  ccr.ccs.tencentyun.com:
    auth:
      username: testuser
      password: password

自 2024 年 3 月版本起提供通配符支持:v1.26.15+k3s1、v1.27.12+k3s1、v1.28.8+k3s1、v1.29.3+k3s1

mirrors:
  "*":

配置完成后验证

kubectl get --raw /api/v1/nodes/<NODENAME>/proxy/metrics | grep -F 'spegel'

--disable-default-registry-endpoint 禁用默认回退

如果没有特殊需求,我觉得没必要禁用回退,除非你指定了回退。

mirrors:
  docker.io:           # 没有回退,会尝试从节点拉取,如果节点都没有拉取失败
  registry.k8s.io:     # 没有回退,会尝试从节点拉取,如果节点都没有拉取失败
  mirror.example.com:  # 有个默认回退,会尝试从节点拉取,如果节点都没有,默认尝试从endpoint节点处拉取
    endpoint:
      - https://mirror.example.com

具体还可以阅读官网文档: Default Endpoint Fallback

其他问题

  • 安全性,你要保证你的环境可信,不然就 一人中毒,全家中毒 这种
  • 由于分布式注册表是只读模式,不支持 push,但是你可以通过 ctr 相关操作将镜像加到都 k8s.io 命名空间就可以了, 例如 ctr -n k8s.io image pull
  • 缓存问题,推荐每次都用新 tag,而不是反复一个 latest 或者同一个 tag 来更新,因为同名 tag 存在后,就不会更新了

群晖Docker组件配置镜像加速源

2024年6月9日 10:08

群晖 Docker 组件配置镜像加速源

我的群辉是 DS218+,目前最新只能升到 7.1 版本,下面涉及到的操作都按 7.1 版本来,如果高于这个版本,部分包名可能不太一样。

前言

由于近期的骚操作,其实对于我们没啥特别影响,除了

顺便修改 Bridge 网桥默认的网段,避免网段冲突

Docker 组件

  • DSM7.2 之前版本是 Docker
  • DSM7.2 及之后版本是 Container Manager

具体有啥优化不清楚,但是明确知道了,配置路径、存储路径和服务名改了

配置文件

通过 ssh 连接到 DSM 上后,切到 root 用户下。

编辑 /var/packages/Docker/etc/dockerd.json

原文件是:

{
   "data-root" : "/var/packages/Docker/var/docker",
   "log-driver" : "db",
   "registry-mirrors" : [],
   "storage-driver" : "btrfs"
}

修改为:

{
   "bip" : "169.254.123.1/24",
   "data-root" : "/var/packages/Docker/var/docker",
   "default-address-pools" : [
      {
         "base" : "169.254.123.0/24",
         "size" : 24
      }
   ],
   "log-driver" : "db",
   "registry-mirrors" : ["https://h.ysicing.net" ],
   "storage-driver" : "btrfs"
}

说明: 配置不可省略 data-root 路径,否则配置不生效

另外 mirrors 可以自行搭建,我的不保证 SLA。

具体可以看看我之前写的自建 Docker 镜像加速教程.

根据我个人测试 RN 的圣何塞要比洛杉矶好,但是洛杉矶有 IPv6

重启 Docker

systemctl restart pkgctl-Docker

重启如果容器比较多,会稍微比较耗时。

常见国内加速镜像源

现在来看,国内镜像加速源基本都 takedown 了或者仅在内部使用。

目前唯一可行的方案大概如下:

  • 配置全局代理,进行分流
  • 使用官方 registry 配置 PROXY_REMOTE_URL
  • 利用 Harbor 或者 Nexus 配置镜像仓库代理(唯一不便之处,要求资源配置比较高)
  • 按需同步镜像到国内免费镜像仓库, 可以使用 skopeo 工具

上述方案中 1、2 是最简单的

最后

内网环境或NAT环境下Caddy基于DNSPOD签发证书

2024年6月5日 21:19

纯个人喜好,Docker 环境下比较喜欢 Caddy,k8s 环境下比较喜欢 Traefik

前提条件

  • 域名托管在 DNSPOD(腾讯云 DNS)
  • 内网环境或者 NAT 环境(即没有办法使用 HTTP-01 方式签发证书)

通常来说(不负责任), 内网环境没必要使用证书。

本文演示环境为鸡仔云 NAT,端口映射方式暴露 Caddy HTTP(S)端口,使用非标准协议端口,故而只能使用 DNS-01 方式

简单科普

HTTP-01

适合简单、快速的验证,通常访问 http://yourdomain.com/.well-known/.... 这个目录下的文件并验证其内容是否正确,然后签发证书,依赖 80 端口可被公网访问

DNS-01

添加 TXT 记录来验证域名

其他

如果域名托管在 CF,还可以选择 CF 的 15 年证书

腾讯云 DNS 配置

创建普通用户

通常情况下,选择新建一个普通用户,只给 编程访问权限, 其他默认即可

腾讯云访问管理

创建自定义策略

出于某些考虑,限制我这个 API 使用,只允许白名单 IP(合法 IP,示例可以理解为马赛克)可访问,不需要去掉即可

{
    "statement": [
        {
            "action": [
                "dnspod:DescribeDomainDigResult",
                "dnspod:DescribeDomainExistRecordList",
                "dnspod:DescribeRecord",
                "dnspod:DescribeRecordImpactInfo",
                "dnspod:CreateRecord",
                "dnspod:DeleteRecord"
            ],
            "condition": {
                "ip_equal": {
                    "qcs:ip": [
                        "2409:...",
                        "183..."
                    ]
                }
            },
            "effect": "allow",
            "resource": [
                "qcs::dnspod::uin/账号ID:domain/DomainID"
            ]
        }
    ],
    "version": "2.0"
}
  • 账号 ID: 点击右上角 主账号 就可以看到了, 也可以通过账号中心/账号信息
  • DomainID: 云解析-域名设置中可看

关联策略

用户列表-关联策略,效果如下

完成之后,获取 API 密钥备用

构建 Caddy 镜像

目前情况下 Caddy 是不支持 DNSPOD 方式签发证书的。这里我提供一下我构建好的镜像

  • ccr.ccs.tencentyun.com/k7scn/caddy:2024

我还是推荐自行构建好,因为我会 经常调整 我的镜像,增删插件

构建 Dockerfile 如下

FROM ccr.ccs.tencentyun.com/k7scn/god AS builder

RUN go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest

WORKDIR /go/src/

RUN xcaddy build \
            --with github.com/caddy-dns/cloudflare \
            --with github.com/caddy-dns/tencentcloud \
            --with github.com/caddy-dns/alidns \
            --with github.com/caddy-dns/dnspod

RUN /go/src/caddy list-modules

FROM ccr.ccs.tencentyun.com/k7scn/debian

COPY --from=builder /go/src/caddy /usr/bin/caddy

RUN chmod +x /usr/bin/caddy && \
  mkdir -p \
  /config/caddy \
  /etc/caddy \
  /data/caddy \
  /var/log/caddy

ENV XDG_CONFIG_HOME /config

ENV XDG_DATA_HOME /data

EXPOSE 80
EXPOSE 443
EXPOSE 443/udp

VOLUME /config

VOLUME /data

VOLUME /var/log/caddy

CMD caddy run --config /etc/caddy/Caddyfile --adapter caddyfile

结构还是比较清晰的

部署 Caddy

使用 compose 方式部署镜像

services:

  caddy:
    image: ccr.ccs.tencentyun.com/k7scn/caddy:2024
    container_name: caddy
    volumes:
      - /etc/caddy:/etc/caddy
      - /var/log/caddy:/var/log/caddy
      - /data/caddy/data:/data
      - /data/caddy/config:/config
    ports:
      - "38080:38080"
      - "38443:38443"
    restart: always
    network_mode: "host"

给大家看下 /etc/caddy 目录结构

.
├── Caddyfile # 全局配置
├── site # 域名配置
│   ├── default.caddy
│   ├── tea.caddy
│   └── tts.caddy
└── ssl # CF15证书、自签证书或其他证书
    └── ysicing.eu.org
        ├── ysicing.key
        └── ysicing.pem

全局配置 Caddyfile

主要定义了 3 个全局模块,方式域名里单独引用

(LOG) {
	log {
		output file "{args[0]}" {
			roll_size 50M
			roll_uncompressed
			roll_local_time
			roll_keep 3
			roll_keep_for 7d
		}
		format json
	}
}

(TLS) {
	tls {
		load /etc/caddy/ssl
	}
}

(CFIP) {
	@ip_whitelist {
		not remote_ip 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32 fd7a:115c:a1e0::/96 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22
	}
	route @ip_whitelist {
		respond 451
	}
}

{
	debug
	admin off
	http_port 38080
	https_port 38443
	email 邮箱(建议写上)
	acme_dns tencentcloud {
		secret_id "腾讯云AK"
		secret_key "腾讯云Key"
	}
}

import /etc/caddy/site/*.caddy

独立站点示例

这里以 /etc/caddy/site/default.caddy 简单说下,主要是对接 CF 的,设置了日志和 IP 访问策略

:38080 {
	import CFIP
	import LOG "/var/log/caddy/default-http.log"
	respond "http, cf: {remote_host}, ip: {http.request.header.CF-Connecting-IP}"
}

:38443 {
	import CFIP
	import LOG "/var/log/caddy/default-https.log"
	import TLS
	respond "tls, cf: {remote_host}, ip: {http.request.header.CF-Connecting-IP}"
}

验证我的想法可以访问 ysicing.eu.org

其他站点按照 Caddy 的规则写就可以了,随便编个大概示例如下

nat.ysicing.net {
    import CFIP
    import LOG "/var/log/caddy/nat-ysicing-net.log"
    import TLS
    reverse_proxy http://127.0.0.1:3333
}

其他问题

由于使用非标准端口,默认配置是没办法实现 http 自动跳转 https。

使用 Docker 搭建你专属的下载神器: qBittorrent

2024年5月29日 20:48

本服务推荐部署在网速较好且存储较大的环境下,如大盘鸡或者群晖上。本文示例跑在鸡仔云大盘鸡上,也可以跑在物语云上。

qBittorrent 是什么

qBittorrent 是一款开源免费的 BitTorrent 客户端,支持多种操作系统,具有简洁易用的界面和丰富的功能,是广大用户进行种子下载的首选工具之一。

以下是 qBittorrent 的一些我认为比较好的主要特点和功能:

  • 开源免费,没有任何商业限制
  • 跨平台支持, 场景不多,但是不能没有
  • 拥有一个简洁且直观的用户界面,易于使用
  • 集成 搜索引擎(插件支持),允许用户直接在客户端中搜索种子文件
  • 支持 RSS 订阅和下载
  • IPv6支持

部署环境

  • 已安装 docker
  • 带宽足够
  • 硬盘足够

这里推荐两家服务:

目前这两款我都有在用,都挺好的。物语云可以考虑活动,有流量加倍,黄鸡可能问问老板有没有折扣码了。

部署

部署比较简单,这里简单记录一下

qbittorrent:
    image: linuxserver/qbittorrent
    container_name: qbittorrent
    restart: always
    ports:
      - "6881:6881"
      - "6881:6881/udp"
      - "8080:8080"
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Shanghai
      # - WEBUI_PORT=8080
      # - TORRENTING_PORT=6881
    volumes:
      - /data/qbittorrent/config:/config
      - /data/qbittorrent/downloads:/downloads

将上面的文件保存为 docker-compose.yaml

启动服务

docker compose pull
docker compose up -d

端口设置

如果本地环境端口冲突,可以通过环境变量解决, 修改的同时还需要同步修改映射端口

  • 需要更改 Web UI 的端口, WEBUI_PORT 变量设置为新端口
  • 客户端通信端口,TORRENTING_PORT

访问

访问你的 ip:8080 端口

默认用户名是 admin
密码需要查看容器标准输出

docker logs -f qbittorrent

The WebUI administrator password was not set. A temporary password is provided for this session: QFC6j2t3Y

使用

自行添加种子文件或使用磁力链接进行下载

修改语言项

修改或禁用密码

我这里方便,默认我的大内网忽略验证

安装搜索插件

插件地址 qbittorrent/search-plugins

我这里随便选个最新的插件,复制 Download link

添加插件

添加完成后

验证插件, 随便搜的

最后

其实还是很简单的,群晖上也可以的,另外我更推荐使用 docker 方式在群晖上部署。

植物大战僵尸docker版

2024年5月24日 20:54

最早接触的单机游戏,最近 B 站 UP 主更新了魔改版,目前只支持 Windows 版本,但是我找到了 docker 版本

部署比较简单,这里简单记录一下

version: '3'

services:
  pvz:
    image: danbai225/pvz:he
    container_name: pvz
    restart: always
    ports:
      - "8080:8080"

将上面的文件保存为 docker-compose.yaml

启动服务

docker compose pull
docker compose up -d

访问你的 ip:8080 端口,选择 vnc 的 html,任意一个都可以, 这里我选择 vnc_auto.html@ 那个

点击之后,会跳转到终端,输入 pvz 启动游戏

游戏页面

参考项目地址 danbai225/pvz

目前存在的问题:

  • 没有声音
  • 对资源的要求比较高(黄鸡龙年可以跑)

吐槽通义灵码送的日历

2024年5月18日 20:32
  • 2024 年的日历,都快过去一半了,才到
  • 说是程序猿日历,结果一点程序猿元素都没有
  • 发货的还是个食品公司
  • 质量很差,拆开就丢了

真心不如给我发个阿里云几块钱代金券呢

群晖服务使用 Cloudflare tunnel进行内网穿透教程

2024年5月16日 21:33

群晖服务使用 Cloudflare tunnel 进行内网穿透教程

迫于家里没有公网,在外面有时候又要使用家里的群晖。在目前这种 开源节流 的环境下,想到了 cloudflare 有提供了 tunnel 功能,用来内网穿透,完全可以运用到群晖上

创建 Cloudflare Tunnel

老生常谈,已经操作很多次了。

  • 登录进 Cloudflare 控制台,点击 ZeroTrust 进入 tunnel 配置页面
  • 新建一个 tunnel,随便起个名字,如 nas,然后复制 token 留待后面使用

安装 cloudflared

推荐使用 docker 去安装,简单方便

在 docker 注册表中找到官方的 cloudflare/cloudflared, 选中下载最新版本 latest 即可

在映像中双击下载好的镜像启动

其他参数默认,这里只列出需要修改的部分

  • 选择共享宿主机网络,方面内网穿透

  • 启用自动重新启动

  • 高级设置, 配置启动参数,具体参数你可以参考第二步 docker token 部分

  • 完成后续,等待启动

  • 等待就绪,返回 cloudflare 的 tunnel 页面,查看连接状态为 HEALTHY,说明链接成功

配置内网服务域名

配置域名,所有的内网服务都可以配置一个域名,而且 cloudflare 默认提供了 https 证书,很方便,也不需要考虑证书过期问题,爽歪歪

其实原理比较简单,由于 cloudflared 使用共享宿主机网络,我们只要掌握我们的服务监听什么端口,直接在 cloudflare 配置即可

如果不清楚相关服务端口的话,可以在群晖的 控制面板 - 信息中心-服务 中查看当前的服务的端口信息

Web 服务

理论上支持所有的 HTTP 服务,群晖的内部服务或 Docker 安装的服务

例如: 群晖 DiskStation Manager (登录页)使用了 5000 端口,服务类型是 HTTP,新增一条 public hostname,配置如下

保存后,浏览器打开刚设置好 public hostname,输入用户名和密码,现在你可以通过浏览器公网访问到家中的 nas 了,并且可以管理群晖的内部服务如 Photo、Drive、Download Station 等

群晖管家群晖Photo群晖Drive 等应用也通过支持此域名进行登录。

如果是其他的 HTTP 服务,比如你安装了 Aria2 的 WebUI 服务,也可以按照这种方式配置选择服务类型为 HTTP,URL 为 127.0.0.1:监听端口 即可

非 Web 服务

如 ssh 或者 smb 等协议,还要求当前客户端还需要跑 cloudflared

这种情况下,不如 tailscale

使用体验

  • 速度一般,回家看片基本不行
  • 访问家里的服务还算可以,但是会暴露在公网,这里需要结合之前说的安全策略,开启白名单访问

使用Docker体验群晖DSM系统

2024年5月4日 10:15

virtual-dsm 是一个开源项目,旨在通过容器模拟 Synology 群晖 NAS 的 DiskStation Manager (DSM) 系统环境。该项目由开源社区开发者维护,并并非 Synology 官方支持的产品。

开源项目地址:https://github.com/vdsm/virtual-dsm

特性

  • 多硬盘支持
  • KVM 加速
  • 支持升级

部署

docker compose 方式

version: "3"
services:
  dsm:
    container_name: dsm
    image: vdsm/virtual-dsm
    environment:
      DISK_SIZE: "16G"
    devices:
      - /dev/kvm
    cap_add:
      - NET_ADMIN
    ports:
      - 5000:5000
    volumes:
      - /var/dsm:/storage
    restart: on-failure
    stop_grace_period: 2m

docker cli 方式

docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 vdsm/virtual-dsm

常见问题

主要针对 compose 方式

与标准 DSM 相比有什么区别

只有两个细微的区别:

  • Virtual Machine Manager 软件包不可用(虚拟机服务)
  • Surveillance Station 将不包含任何免费许可证(没啥印象 😂)

如何安装特定版本的 DSM

默认情况下,将安装版本 7.2,但如果您更喜欢旧版本,则可以将其下载 URL 添加到 docker compose 文件中,如下所示:

environment:
  URL: "https://global.synologydownload.com/download/DSM/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"

使用这种方法,甚至可以在保持所有文件数据完好无损的同时在不同版本之间切换

部署完成如何访问

启动容器并使用 Web 浏览器连接到端口 5000
等到 DSM 准备就绪,创建用户名和密码,按照引导流程走就可以了啊。

如何更改存储位置

volumes:
  - /var/dsm:/storage

将示例路径 /var/dsm 替换为所需的存储文件夹即可。

如何修改磁盘大小

如果想要修改默认的磁盘大小(默认:16G),需要修改环境变量 DISK_SIZE

environment:
   DISK_SIZE: "100G"

这也可用于将现有磁盘的大小调整为更大的容量,而不会丢失任何数据

如何创建自动增长的磁盘

默认情况下,磁盘的全部容量是预先预留的,若要创建仅分配实际使用空间的可增长磁盘,请添加以下环境变量:

environment:
  DISK_FMT: "qcow2"

这可能会降低磁盘的写入性能,但是经过我的测试没有特别大影响,我觉得还是推荐这种,用多少分配多少,当然了如果你的硬盘足够大,推荐预留方式,写死磁盘大小

如何添加多个磁盘

environment:
   DISK2_SIZE: "32G"
   DISK3_SIZE: "64G"
volumes:
  - /home/example:/storage2
  - /mnt/data/example:/storage3

如何直通硬盘

可以通过以下方式直通硬盘

environment:
  DEVICE: "/dev/sda"
  DEVICE2: "/dev/sdb"
devices:
  - /dev/disk/by-uuid/12345-12345-12345-12345-12345:/dev/disk2
  - /dev/disk/by-uuid/45678-45678-45678-45678-45678:/dev/disk3

确保通过其 UUID 绑定磁盘,以防止在驱动器号发生更改时绑定错误的磁盘。lsblk -o name,uuid/dev/sdc

请注意,设备需要完全为空(没有任何分区表),否则 DSM 并不总是将其格式化为卷。

请勿将此功能用于共享主机文件,当 DSM 创建宗卷时,它们将 全部丢失,恕不另行通知. 有风险,请谨慎操作

如何增加 CPU 和 RAM 的大小

默认情况下,单个 CPU 内核和 1 GB RAM 分配给容器

如果需要增加此值,请添加以下环境变量

environment:
  RAM_SIZE: "4G"
  CPU_CORES: "4"

如何直通显卡

environment:
  GPU: "Y"
devices:
  - /dev/dri

这可用于在 Synology Photos 中启用面部识别功能

如何验证我的系统是否支持 KVM

要验证您的系统是否支持 KVM,请运行以下命令:

apt install cpu-checker
kvm-ok

执行结果

root@nat7:~$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

如果收到指示无法使用 KVM 加速的错误,请检查 BIOS 中的虚拟化设置

这个项目合法吗?

此项目仅包含开源代码,不分发任何受版权保护的材料。它也没有试图规避任何版权保护措施。因此,根据所有适用法律,该项目将被视为 合法

但是,安装 Synology 的 Virtual DSM 时,您必须接受其最终用户许可协议,该协议不允许在非 Synology 硬件上安装。因此,只能在官方 Synology NAS 上运行此容器,因为任何其他用途都将违反其条款和条件。

应用场景

大盘鸡系统,可以试一试

Traefik Proxy V3版本正式发布: 支持WebAssem)bly等特性

2024年5月1日 18:29

特性简单介绍

主要摘自官方博客Announcing Traefik Proxy v3.0 RC1

V3版本增加了对流行、新兴技术的支持——WebAssemblyWasm)、OpenTelemetryKubernetes Gateway API

代理的核心是路由和安全,我们对路由规则的关键部分进行了迭代,并增加了对一些前沿技术的支持,如 HTTP/3、SPIFFE 和 Tailscale

路由与安全

  • HTTP/3稳定版本支持,基于quic-go
  • 支持Brotli 压缩算法, 网站加载速度加快
  • grpc支持
  • tailscale联动,支持通过tailscale签发证书

扩展

支持Wasm开发traefik插件,提升性能与安全性。

〉WebAssembly(Wasm)是一种可在现代 Web 浏览器中运行的二进制代码格式。由于其高效性能和安全性,WebAssembly 在许多领域都得到了广泛应用。

可观测性

支持了OpenTelemetry

集成Kubernetes Gateway API

Traefik可以说是Gateway API先锋,最早支持GatewayAPI版本的,现在全面支持,也很正常。

v2迁移v3

总体上来说,没有什么特别重点变更。如果你是从很早版本之前升级上来的可能需要注意了。

CRD更新

目前更新charts版本不会自动更新已经存在的crd,老版本升级可能需要注意,更新一下CRD资源

kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/master/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml

安装参数变更

# 老版本
    expose: true
# 新版本
    expose:
      default: true

资源版本

v3版本移除对traefik.containo.us的支持

这个在v2版本里已经调整为traefik.io/v1alpha1

IP白名单插件调整

目前使用ipAllowList,

ipWhiteList已经废弃,可能后续版本就不支持了,暂时没影响

测试Demo

apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - protocol: TCP
      name: web
      port: 80
  selector:
    app: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoami
  labels:
    app: whoami
spec:
  replicas: 2
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      nodeSelector:
        node-role.kubernetes.io/bj: "true"
      containers:
        - name: whoami
          image: h2.ysicing.net/containous/whoami
          resources:
            limits:
              cpu: 100m
              memory: 128M
          ports:
            - name: web
              containerPort: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-http
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`whoami.bjslb.ysicing.net`) && PathPrefix(`/notls`)
      kind: Rule
      services:
        - name: whoami
          port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-https
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`whoami.bjslb.ysicing.net`) && PathPrefix(`/tls`)
      kind: Rule
      services:
        - name: whoami
          port: 80
  tls:
   certResolver: myresolver
❌
❌