MoreRSS

site iconThetbw | 黑羽修改

游戏宅男,后端开发
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Thetbw | 黑羽的 RSS 预览

写在新年之前

2025-12-27 22:56:41

这几年一直都有记录的习惯,一直都是在飞书上面,不过记录多是偏向一些负面的东西,心情不好的时候会写写,可能心情好玩的开心的时候,也不想去写这些东西了吧。
image.png

飞书还是我这几年用的最舒服的知识库,就是加载慢了一点,但是功能是真的多,对于个人还是免费。

关于这种应用,我最关系的还是它变卦了怎么办,毕竟我的数据都在上面,虽然不像企业那样有价值。今年就是经历了腾讯的coding宣布放弃的事件,公司也是重新迁移了代码库,耽误了一点时间。好在飞书这里提供了api,我整了个定时任务,每天备份我的飞书文档成pdf到本地,就算哪天飞书不在了,未来的某一天我还是可以看到这几年我的个人记录。

就像上面我的飞书概览一样,每年我都是会更新下概览,不过这两天我觉得没什么大区别。

学业方面算是我的今年最大的缺陷,家里条件也就那样,支撑不了自己脱产学习,下班的话真的没有那个精力,只想刷视频了。

博客是我今天觉得最好的,更新了不少,感觉自己越来越能写了,至于有多少人看我觉得并不是重要的。

摄影上半年其实没啥进展,下半年拍了很多,尤其是最近一两个,也是给我整自信了。


我觉得这两年没有看到什么成长,更多的还是心境上面,也是我最近感受到的,我想用一句话总结它,叫“润物细无声”。怎么说,就是有时候自己所做的事情当时感觉没什么,但是时间长了,回头看一下,就会觉得真的不一样,怎么变化会这么大。

这里表现在很多方面,之前没能看懂的技术,突然某一天感觉茅塞顿开,自己也不知道怎么就理解了;之前自己觉得很尴尬或者很紧张的事情,也是不知道哪一时刻就觉得无所谓了;还有自己在投资理财方面,肯定是亏了钱,但是自己突然没有想以前那么对陌生的事物感觉这么害怕了,但是还是因该保持该有的敬畏之心。


这两年也是每年都会感觉到行情不好,年初的时候我换了个租房的地方,大概一季度能省2000块钱吧,环境和之前没什么差别,甚至还好了点。

自己也是终于攒了一点钱,还被各个朋友分别借走了一点,下年就是把这些钱拿回来,也不打算借给别人了,这时候觉得自己人际关系窄也并不是什么坏事,以后的这种借钱的可能还会有吧,而且自己也不打算维护什么关系了。

我也是来现在这个公司几年了,上年之前,每年年底领导都会有个和各个员工的单独谈话,上年是没有的,今年估计也是没有了,本来就是在上年的年底,我就想说所谓涨薪的事情,但是谈话没了,我也不知道在哪说了,干脆就不说了。今年也是吧,反正下年我打算找新工作了,涨不涨薪也无所谓了,找不到更好的新工作的话就是我没本事,我也没什么好说的。

上了几年班,也是麻木了。


今年下半年也是内存硬盘狂涨,好在上半年,我就配了个32g内存的电脑,也买了两块14t硬盘用作nas上,下年应该暂时是够用了,只要我不乱搞那些没意义的折腾的话。

今年的游戏没怎么玩,好可惜显卡没有涨价,不然我可能会把我的显卡买了,换成intel的专业卡,因为我想玩虚拟化就缺那玩意。

今年也是填了一些其他设备,第一次用mac,感觉还行吧,第一次用4k显示器,感觉windows在4k下也是挺细腻呀。之前旧的电脑放公司了,公司都是我自己的设备,自费上班了属于是。

相机也是填了个还行的镜头,但是出门拍照真的不好拿,现在有馋那种卡片机了,至于为啥不用手机,我是用手机的,但就想要那一点点的仪式感,还有一点点的画质提升和真实性。


展望一下下年吧,虽然国内过年都是农历年,但是我觉得阳历年也挺好,起码他很准时,工作节奏其实都是按照阳历年来的。

之前下年多攒写钱吧,如果可以的话,来点桃花运也不是不行,但是我的抠门样,肯定不要坑我的钱就好。

今年的b站年度总结,我发现我视频看的太多了,每天上班刷论坛的时间也很多,下年希望能减少一点吧,自己的自制力真的不行。

今天喝了点啤酒写这个博文,因为今天不写完我肯定又要拖了,往后拖的感觉真不好也,也不知道怎么搞,希望下年可以更专注吧,能抛弃todo list这种玩意更好,这玩意也是挺让人焦虑的,但是没有又不行,会更焦虑。

之前写文章都是检查下错别字,这次就不检查了,如有错别字,就自行脑补吧。

通过SSH远程执行命令,以及多服务器管理

2025-12-22 16:48:38

SSH 除了可以直接连接远程服务器,以终端形式显示外,也可以直接用来执行命令,只需要把命令放到 ssh 的参数后面即可,例如:

ssh root@example "echo Hello"

这对于执行一些临时命令,例如运行备份之类的,还挺有用。

对于很长的或者多个命令,可以使用 << 多行文本,例如

  ssh root@example << HERE    echo "HELLO"    echo $USER  HERE

但是对于上面的第二个命令,$USER,存在转义问题,$USER 会在本地执行,而不是在服务器上。

解决方式是可以添加引号来避免本地提前解释执行。

  ssh root@example << 'HERE'    echo "HELLO"    echo $USER  HERE

此处是来自 POSIX 的规范,linux 和 mac 同样适用,具体出处我也不清楚,可以参考文章底部最后一个链接,和自行 ai 搜索


还有一种解决方法,也是我想说的,来自今天搜索 rpcssh,发现的一个十多年的帖子。

declare 命令可以返回变量或者方法的定义,使用这种方法,就可以自己不用写相关转义了。例如本地有个下面的方法:

hello() {    echo "Hello, world, I'm coming from $(uname -n)."}

可以这样执行

ssh root@example"$(declare -f hello); hello"

$(declare -f hello) 会自动把本地定义的这个hello方法的内容获取出来,并且发送到目标服务器时自动转义,然后在远程服务器执行这个hello方法。

注意这种方法只能用于 shell 中定义的方法,不能是二进制文件

原作者写了一个叫rpcsh的方法,用于把本地方法发送到远程,挺简洁方便的,我就直接放在下面了

# rpcsh -- Runs a function on a remote host# This function pushes out a given set of variables and functions to# another host via ssh, then runs a given function with optional arguments.# Usage:#   rpcsh -h remote_host [ -p ssh-port ] -u remote_login -v "variable list" \#     -f "function list" -m mainfunc## The "function list" is a list of shell functions to push to the remote host# (including the main function to execute, and any functions that it calls)# Use the "variable list" to send a group of variables to the remote host.# Finally "mainfunc" is the name of the function (from "function list") # to execute on the remote side.  Any additional parameters specified gets# passed along to mainfunc.rpcsh() {    if ! args=("$(getopt -l "rmthost:,rmthostport:,rmtlogin:,pushvars:,pushfuncs:,rmtmain:" -o "h:p:u:v:f:m:A" -- "$@")")    then        exit 1    fi    sshvars=( -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null )    eval set -- "${args[@]}"    while [ -n "$1" ]    do        case $1 in            -h|--rmthost) rmthost=$2; shift; shift;;            -p|--rmtport) sshvars=( "${sshvars[@]}" -p $2 ); shift; shift;;            -u|--rmtlogin) rmtlogin=$2; shift; shift;;            -v|--pushvars) pushvars=$2; shift; shift;;            -f|--pushfuncs) pushfuncs=$2; shift; shift;;            -m|--rmtmain) rmtmain=$2; shift; shift;;            -A) sshvars=( "${sshvars[@]}" -A ); shift;;            -i) sshvars=( "${sshvars[@]}" -i $2 ); shift; shift;;            --) shift; break;;        esac    done    rmtargs=( "$@" )    ssh ${sshvars[@]} ${rmtlogin}@${rmthost} "        $(declare -p rmtargs 2>/dev/null)        $([ -n "$pushvars" ] && declare -p $pushvars 2>/dev/null)        $(declare -f $pushfuncs 2>/dev/null)        $rmtmain \"\${rmtargs[@]}\"    "}

原地址 https://gist.github.com/derekp7/9978986


有什么用呢,如果你有多个服务器,需要维护什么备份脚本什么,按照传统的方法,比如把脚本上传到服务器,或者git,当你的脚本更新时候,所有的服务器上的文件都需要更新,你需要一个个登录过去获取最新文件,这显然不是很方便。

当然你可以使用类似宝塔面板这种,可以在一个地方控制好几个服务器,这显然又增加了复杂性,增加了依赖。

还有就是一个干净服务器,通常需要装一些东西,进行初始化,例如我想安装dockerfail2ban,然后配置相关参数,每次都要这么设置都挺费事的,就可以用上面的方法。

例如下面的脚本

#!/bin/bashset -euo pipefail# 定义远程服务器列表(可根据实际需求修改)REMOTE_SERVERS=("192.168.2.1" "192.168.2.2")# 默认SSH端口DEFAULT_SSH_PORT=22# 默认SSH登录用户DEFAULT_SSH_USER="root"# ===================== 核心远程执行函数 =====================rpcsh() {    local rmthost="" rmtport="${DEFAULT_SSH_PORT}" rmtlogin="${DEFAULT_SSH_USER}"    local pushvars="" pushfuncs="" rmtmain="" sshvars=() rmtargs=()    local use_ssh_agent=0 ssh_identity=""    # 解析命令行参数    if ! args=$(getopt -o h:p:u:v:f:m:Ai: --long rmthost:,rmthostport:,rmtlogin:,pushvars:,pushfuncs:,rmtmain: -- "$@"); then        echo "ERROR: 参数解析失败" >&2        return 1    fi    eval set -- "${args}"    sshvars=( -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=10 )    while [[ $# -gt 0 ]]; do        case "$1" in            -h|--rmthost)                rmthost="$2"                shift 2                ;;            -p|--rmtport)                rmtport="$2"                sshvars+=( "-p" "$2" )                shift 2                ;;            -u|--rmtlogin)                rmtlogin="$2"                shift 2                ;;            -v|--pushvars)                pushvars="$2"                shift 2                ;;            -f|--pushfuncs)                pushfuncs="$2"                shift 2                ;;            -m|--rmtmain)                rmtmain="$2"                shift 2                ;;            -A)                use_ssh_agent=1                sshvars+=( "-A" )                shift                ;;            -i)                ssh_identity="$2"                sshvars+=( "-i" "$2" )                shift 2                ;;            --)                shift                rmtargs=( "$@" )                break                ;;            *)                echo "ERROR: 未知参数 $1" >&2                return 1                ;;        esac    done    # 校验必要参数    if [[ -z "${rmthost}" || -z "${rmtmain}" ]]; then        echo "ERROR: 必须指定远程主机(--rmthost/-h)和执行函数(--rmtmain/-m)" >&2        return 1    fi    # 构建远程执行脚本    local remote_script=""    # 传递参数数组    remote_script+="$(declare -p rmtargs 2>/dev/null); "    # 传递指定变量    if [[ -n "${pushvars}" ]]; then        remote_script+="$(declare -p ${pushvars} 2>/dev/null); "    fi    # 传递指定函数    if [[ -n "${pushfuncs}" ]]; then        remote_script+="$(declare -f ${pushfuncs} 2>/dev/null); "    fi    # 执行主函数    remote_script+="${rmtmain} \"\${rmtargs[@]}\""    # 执行SSH远程命令    echo "INFO: 连接到 ${rmtlogin}@${rmthost}:${rmtport} 执行 ${rmtmain}"    ssh "${sshvars[@]}" "${rmtlogin}@${rmthost}" "${remote_script}"}# ===================== 业务功能函数 =====================# 安装Docker(含Docker Compose)install_docker() {    echo "===== 开始安装Docker ====="    if command -v docker &>/dev/null; then        echo "INFO: Docker已安装,跳过安装步骤"        return 0    fi    # 卸载旧版本    apt-get remove -y docker docker-engine docker.io containerd runc || true    # 设置仓库    apt-get update    apt-get install -y ca-certificates curl gnupg lsb-release    mkdir -p /etc/apt/trusted.gpg.d    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null    # 安装Docker Engine    apt-get update    apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin    # 启动并开机自启    systemctl enable --now docker    # 验证安装    if docker --version &>/dev/null; then        echo "SUCCESS: Docker安装完成"    else        echo "ERROR: Docker安装失败" >&2        return 1    fi}# 安装fail2baninstall_fail2ban() {    echo "===== 开始安装fail2ban ====="    if command -v fail2ban-server &>/dev/null; then        echo "INFO: fail2ban已安装,跳过安装步骤"        return 0    fi    apt-get update    apt-get install -y fail2ban    systemctl enable --now fail2ban    if fail2ban-server --version &>/dev/null; then        echo "SUCCESS: fail2ban安装完成"    else        echo "ERROR: fail2ban安装失败" >&2        return 1    fi}# 配置fail2ban(SSH防护为例)config_fail2ban() {    echo "===== 开始配置fail2ban ====="    local config_file="/etc/fail2ban/jail.local"    # 备份原有配置    if [[ -f "${config_file}" ]]; then        cp "${config_file}" "${config_file}.bak.$(date +%Y%m%d%H%M%S)"    fi    # 写入基础配置    cat > "${config_file}" << EOF[DEFAULT]ignoreip = 127.0.0.1/8 192.168.0.0/16bantime  = 86400findtime = 3600maxretry = 5banaction = iptables-multiportbackend = systemd[sshd]enabled = trueport = sshfilter = sshdlogpath = /var/log/auth.logmaxretry = 3EOF    # 重启服务    systemctl restart fail2ban    if systemctl is-active --quiet fail2ban; then        echo "SUCCESS: fail2ban配置完成并已重启"    else        echo "ERROR: fail2ban配置后启动失败" >&2        return 1    fi}# 服务器备份(示例:备份/etc目录到/backup)server_backup() {    echo "===== 开始服务器备份 ====="    local backup_dir="/backup/$(date +%Y%m%d)"    local backup_file="${backup_dir}/etc_backup.tar.gz"    # 创建备份目录    mkdir -p "${backup_dir}"    # 备份/etc目录    tar -zcf "${backup_file}" /etc \        --exclude=/etc/ssh/ssh_host_* \        --exclude=/etc/machine-id \        --exclude=/etc/resolv.conf    # 校验备份文件    if [[ -f "${backup_file}" && $(stat -c%s "${backup_file}") -gt 1024 ]]; then        echo "SUCCESS: 备份完成,文件路径: ${backup_file}"        # 可选:保留最近7天备份        find /backup -type d -mtime +7 -delete    else        echo "ERROR: 备份失败" >&2        return 1    fi}# ===================== 脚本入口/帮助信息 =====================# 显示帮助信息show_help() {    cat << EOF服务器管理脚本 - server_manager用法:  $0 [选项] <命令> [命令参数]可用命令:  install_docker      安装Docker及Docker Compose  install_fail2ban    安装fail2ban  config_fail2ban     配置fail2ban(SSH防护)  server_backup       执行服务器备份(默认备份/etc目录)  help                显示此帮助信息远程执行选项:  -r                  远程执行模式(需配合以下参数)  -h <IP>             远程服务器IP(必填)  -p <端口>           远程SSH端口(默认:22)  -u <用户>           远程SSH登录用户(默认:root)  -i <密钥文件>       SSH私钥文件路径  -A                  启用SSH Agent转发示例:  # 本地执行备份  $0 server_backup  # 远程执行备份(单个服务器)  $0 -r -h 192.168.2.1 server_backup  # 远程执行Docker安装(指定用户和端口)  $0 -r -h 192.168.2.2 -u ubuntu -p 2222 install_docker  # 显示帮助  $0 helpEOF}# 主执行逻辑main() {    local remote_mode=0    local remote_host="" remote_port="${DEFAULT_SSH_PORT}" remote_user="${DEFAULT_SSH_USER}"    local ssh_identity="" use_agent=0    local command="" command_args=()    # 解析顶层参数    while [[ $# -gt 0 ]]; do        case "$1" in            -r)                remote_mode=1                shift                ;;            -h)                remote_host="$2"                shift 2                ;;            -p)                remote_port="$2"                shift 2                ;;            -u)                remote_user="$2"                shift 2                ;;            -i)                ssh_identity="$2"                shift 2                ;;            -A)                use_agent=1                shift                ;;            help|--help|-h)                show_help                exit 0                ;;            *)                # 第一个非选项参数作为命令,剩余作为命令参数                command="$1"                shift                command_args=( "$@" )                break                ;;        esac    done    # 校验命令是否为空    if [[ -z "${command}" ]]; then        echo "ERROR: 必须指定要执行的命令" >&2        show_help        exit 1    fi    # 校验命令是否存在    if ! declare -f "${command}" &>/dev/null; then        echo "ERROR: 未知命令 '${command}'" >&2        show_help        exit 1    fi    # 执行逻辑:本地/远程    if [[ ${remote_mode} -eq 1 ]]; then        # 远程执行模式        if [[ -z "${remote_host}" ]]; then            echo "ERROR: 远程执行模式必须指定 -h <远程服务器IP>" >&2            exit 1        fi        # 构建rpcsh参数        local rpcsh_args=(            -h "${remote_host}"            -p "${remote_port}"            -u "${remote_user}"            -m "${command}"            -f "${command}"  # 传递要执行的函数到远程        )        [[ -n "${ssh_identity}" ]] && rpcsh_args+=( -i "${ssh_identity}" )        [[ ${use_agent} -eq 1 ]] && rpcsh_args+=( -A )        rpcsh_args+=( -- "${command_args[@]}" )        # 执行远程调用        rpcsh "${rpcsh_args[@]}"    else        # 本地执行模式        echo "INFO: 本地执行命令 ${command}"        "${command}" "${command_args[@]}"    fi}# 启动主程序main "$@"

之后就可以按照下面方法使用

# 显示帮助(可用命令)server_manager help# 本地执行备份server_manager server_backup# 远程执行备份server_manager -r -h 192.168.2.1 server_backup# 远程执行Docker安装(指定用户、端口、SSH密钥)server_manager -r -h 192.168.2.2 install_docker# 远程配置fail2ban(启用SSH Agent转发)server_manager -r -h 192.168.2.1 config_fail2ban

注意的是上面脚本我是ai生成的,我只是提供了思路,请不要直接使用。

服务器可以自己本地维护一个列表,输入-r时给出列表选择哪个服务器执行,就可以一个脚本管理多个服务器了。

像是后面脚本新增功能,哪里代码有问题,都只需要改本地的。也可以本地用定时任务定时执行,不需要每个服务器都部署定时任务。

虽然性能上肯定有损耗,但是好在没有任何第三方依赖,所有linux mac都能用,啥第三方软件也不用装(当然还是要openssh)


参考文章

KASM,还不错的云桌面产品

2025-12-04 20:34:50

最近在这个叫 KASM 的玩意,这个很久之前就见过,感觉很复杂就没弄,最近短暂的有空,搭建了一个玩玩。

KASM 和核心功能来自一个叫 KasmVNC 的产品,这个是开源的,虽然名字里有 VNC 这两个字,但是他并不是传统的 VNC ,它比VNC有着更好的性能,支持GPU加速,直接剪贴板,文件上传下载等。

接触这个是因为之前了解的另一个项目,docker-baseimage-gui,一个预装了虚拟屏幕和 noVNC 的 docker 镜像,有一个应用是 stardew-multiplayer-docker,在docker上运行的星露谷物语,可以在浏览器上通过 VNC 控制。

想想还挺有意思,如果把程序都隔离到 docker 里面,通过浏览器来访问,这样既不用限定设备,局域网随意访问,内网穿透之后远程也可以访问了,岂不挺好,github 上也有了一些例如 docker-wechat 的项目,就是通过 docker 运行微信 linux 版,然后用 noVNC 在网页上显示,也可以实现微信多开了。

KASM 就是这样一个项目,他打包了很多常用的镜像(可惜并不是国内常用),然后有个管理平台,可以在用户需要的时候创建对应的 docker 容器,通过 web 界面访问;我想要折腾这种东西的一个出发点,就是有时候手上做到一半的东西,可以直接放在那,后面我换个电脑,可以接着继续开始,不用各种同步。


image.png
image.png

配合 PWA 还挺有模有样的。

image.png

还有支持游戏手柄,打印机,摄像头等穿透,就可以看出来和传统VNC的不同之处了。

image.png

后台就是基本的那一套功能了,添加自定义镜像源,管理用户可以访问的镜像,限制资源,让 docker 扩容等。不过要说的是,他这个后台并不是开源的,只是镜像本省是开源的,不过功能也是免费的就是了。

感觉也可以搞个云游戏之类的东西,把自己的电脑分享给朋友一起玩,之前b站上有过类似的视频,叫什么多人一机之类。

这些功能都是基于 web 的,其实不需要安装 kasm 这个后台也可以单独用docker 运行的,例如 https://hub.docker.com/u/kasmweb 仓库下,有很多 kasm 使用的镜像,里面有运行说明,也可以基于这些镜像定制,比如安装自己的软件之类的。

安装的话直接官网的教程就好了
https://docs.kasm.com/docs/install/single_server_install

不过要说的几点:

  • 最好单独一个机子上安装,不要有其他东西,因为安装过程中会安装一些docker 插件,还会重启 docker,避免发生一些兼容问题。
  • 最好单独从 docker 官网的源安装 docker,虽然安装脚本会自动安装docker,但是是从包管理器的,有些发行的包管理器内的 docker 太老了。
  • 可以在 wsl 上装,但是不支持 windows 的那个 docker desktop,需要wsl 内单独安装 docker
  • nvidia 的 gpu 加速会很麻烦

最后折腾这个的一个感想,就是 nvidia 的 gpu 真的是麻烦,想搞 linux 玩,还是乖乖用 amd 或者 intel 的显卡吧,用 nvidia 就是浪费生命。windows 也真是牛逼,搞了个 GPU-PV 的东西,可以不需要 GPU 虚拟化就把显卡给 WSL 用,不过也是扣扣搜搜,东西只给你一半,折腾起来也是费事,看到github 上有过一个项目 Linux-GPU-V-Scripts-for-Hyper-V,把 WSL 内的驱动复制到 Hyper-v 中,实现虚拟机内使用显卡,其实 WSL 也是一个特殊的虚拟机罢了。

最近有看了 intel 最近新出的显卡,intel b50,虽然性能不是很强,但是它的定位是专业卡,所有显卡特性基本上全支持了,而且支持虚拟化,不需要折腾任何东西,较新的 linux 内核直接内置驱动了,后面想搞一个玩玩,不过京东这 3k 块钱的售价,还是等什么时候便宜一下吧。

最后一直在折腾这种乱七八糟的小玩意,后面很长一段时间应该不会去折腾了,这是最近最后一个折腾分享了吧,希望是,还是得专注于有价值的事情上面(专心搞钱)。

其他:摄影项目因为服务器过期不打算续了,只是当初不知道它跑在那个服务器上,数据我都是定时备份的,后面找个时间迁移一下。

docker修改存储位置,以及遇到的问题

2025-11-26 15:20:30

默认docker存储都是放在 /var/lib/docker 这个目录下面,随着使用时间越来越大。你可以使用 docker image prune 来清理不用的镜像。

做为一个 NAS 玩家,我打算直接把docker文件夹存到 NAS 的存储上。

使用 SMB 挂载目录的话可能会遇到一些问题,因为 SMB 不支持所有的 POSIX 标准,所以我是直接挂载了一个远程硬盘到虚拟机中。系统盘保持足够的小,方便后面备份和快照,而这个数据盘就不需要快照和备份了。


更改 docker 存储目录也是很简单。

首先关闭docker

service docker stop

更改docker配置

nano /etc/docker/daemon.json

添加data-root配置,类似下面这样,我是放到 /mnt/docker_data 目录

{  "data-root": "/mnt/docker_data"}

移动原来的docker数据

rsync -aHAX /var/lib/docker/ /mnt/docker_data/docker/# 或使用下面的直接移动:# mv /var/lib/docker /mnt/docker_data/

然后重启docker

service docker start

然后这样基本上就完了


如果只是这样也没什么好写的了,说下我遇到的其他问题。

之前我是一直用上面的方法,最近用这个方法的时候,用 KASM 拉取镜像的时候,还是提示空间不足,而且df -h显示的空间也不对,类似下面这样

KASM 感觉还蛮有意思的,有兴趣的可以去搜搜,是一个云桌面平台,后面我摸熟了可能会写个文章介绍一下。

Filesystem Size Used Avail Use% Mounted on
udev 3.9G 0 3.9G 0% /dev
tmpfs 795M 2.2M 792M 1% /run
/dev/sda1 18G 13G 4.1G 76% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda15 124M 12M 113M 10% /boot/efi
/dev/sdb1 492G 3.3G 463G 1% /mnt/docker_data
overlay 18G 13G 4.1G 76% /mnt/docker_data/rootfs/overlayfs/xxx
tmpfs 88M 0 88M 0% /run/user/0

明明 /mnt/docker_data 显示有 492G 空间,为什么 dockeroverlayfs 显示和系统根分区一样是 18G 呢。

后面也是问了 AI 才知道,原来 docker 自身的存储和依赖的 containerd 可能是分开的。我看了下,的确系统有个 containerd 服务。

按照docker的指引,修改 containerd 存储路径。

nano /etc/containerd/config.toml
root = "/mnt/docker_data/containerd"state = "/run/containerd"
systemctl restart docker

结尾,如果有遇到相同问题的,恰好搜到我这个文章,可以作为一个思路。如果从零开始,刚好看到我这个文章,不建议照抄命令,还是说只能作为思路的参考。

另外上面的大多数命令,例如 rsync -aHAX ,发送给 AI ,他都可以给你解释每一个参数的用处,建议在网上看到的教程,都了解每个参数的含义了,再进行操作。

docker的不同版本,每个发行版,都是不一样的,例如 docker compose,有些发行版上是用 docker compose 命令,有些是 docker-compose,另外发行版自身的包管理器和官方的源,都是有不一样的,建议判断下具体的环境,还有时间,综合做出决定。

【摘抄】天堂与地狱

2025-11-25 14:38:38

某人死后,灵魂来到一个地方,当他进门的时候,守门人对他说:“你不是贪吃吗?这里有的是东西随你吃。你不是贪睡吗?这里睡多久也没人打扰。你不是爱玩吗?这里有各种娱乐由你选择。你不是讨厌工作,不喜欢受拘束吗?这里保证没有事做,更没人管你。”

于是此人高高兴兴留了下来。吃完就睡,睡够就玩,边吃边玩。但是三个月下来,他渐渐觉得有点不是滋味,于是跑去见守门人:“这种日子过几天倒还不错,但是时间长了,不见得好。因为玩的太多,我对娱乐已经提不起什么兴趣;吃得太饱,是我身体不断发胖;睡得太久,头脑又变得迟钝,您能不能给我一点儿工作,早晨催我起床啊!” 守门人摇摇头说:“对不起!这里没有工作,跟没人催你早起。”

又过了三个月,这人实在太难受了,于是他又跑到守门人面前哭诉:“这种日子我实在是受不了了,如果你再不给我工作,我宁愿下地狱。”

“你以为这是天堂吗?这里本来就是地狱啊!” 守门人大笑道,“他使你没有理想,没有创造,没有前途,逐渐腐化。这种心灵得煎熬,要比上刀山下油锅的皮肉之苦,更令人无法忍受啊!”

来自 刘墉 《人生海海,自在独行》

立志成为英语大佬

2025-11-19 00:03:29

最近英语考试考的也太差了,而且越来越差,遂痛定思痛,决定每天早起1小时,学习英语,起码坚持1年,此贴为据,一年后我再来汇报成果。