我们的笔记

  • 友情链接
  • 关于

  • 腾讯云轻量对象存储的简单体验

    腾讯云给轻量服务器锐驰型的用户发了相同时长的轻量对象存储 50G 免费额度,正好来体验一下。

    控制台上挂载到轻量服务器上使用

    控制台上面非常简洁,看起来基本上就是只希望客户使用这种方式了。使用门槛很低,只需要配置相同地域的服务器(不一定非要锐驰型)和路径就会自动帮忙挂载。

    底层也是 cosfs 实现的,应该是用 Agent 自动下发的挂载命令,对新手很友好。搭配 200M 的机器,对于个人开发者来说可以省下一笔不少的费用。

    这种方式没有什么更多要说的了,唯一可能要注意的事情是:部分修改文件可能会导致整个文件重传。更多类似限制,可以查阅 cosfs 的相关文档。另外,cosfs 也有了支持 posix 的后继者 GooseFS-Lite,参见这里。但未来趋势可能还是存储网关。

    当然了,对象存储更多的使用场景还是得通过 API 来进行存取,下面简单来尝试一下。还是有所要注意的地方的。

    通过 API/SDK 调用 – 以 Loki 为例

    看轻量对象存储的文档的话,会发现其实它还是支持 API/SDK 调用的,Endpoint 和标准的 COS 是一样的:

    那么我们就先来创建子账号和对应所需的权限。经过尝试,如果按照 lhcos(轻量对象存储)进行授权的话,通过 S3 兼容接口调用还是会报错 403,这里按 cos(标准对象存储)授权就可以了。这里也吐槽一下,由于这个 appid 不是用户主账号 uid,就没法使用对象存储的诊断工具了。

    {
        "statement": [
            {
                "action": [
                    "cos:GetBucket",
                    "cos:GetObject",
                    "cos:PutObject",
                    "cos:DeleteObject"
                ],
                "effect": "allow",
                "resource": [
                    "qcs::cos:<region>:uid/<uid>:<bucketName>-<uid>/*"
                ]
            }
        ],
        "version": "2.0"
    }

    配置 Loki 使用轻量对象存储,这里给出关键的配置片段:

    loki:
      storage:
        type: s3
        s3:
          endpoint: cos.ap-hongkong.myqcloud.com
          region: ap-hongkong
          accessKeyId: <ak>
          secretAccessKey: <sk>
        bucketNames:
          chunks: <bucketName>-<uid>
          ruler: <bucketName>-<uid>
          admin: <bucketName>-<uid>
      schemaConfig:
        configs:
          - from: 2024-04-01
            object_store: s3
            store: tsdb
            schema: v13
            index:
              prefix: index_
              period: 24h

    由于我这里是跨云的集群,如果 CoreDNS 不在内网会导致解析对象存储的 Endpoint 是公网 IP,会把账单打爆,所以这里还需要配置 DNS:(说明一下,这里不知道什么毛病,dnsConfig 居然用了 tpl 方法,但是 values.yaml 里面又是个 map,所以只能喂个 string,然后部署的时候会有警告)

    singleBinary:
      replicas: 1
      nodeSelector:
        kubernetes.io/hostname: hkg-qcloud
      dnsConfig: |-
        nameservers:
          - 183.60.83.19
          - 183.60.82.98

    启动后发现 Loki 有报错,日志没有持久化:

    level=error ts=2025-04-23T08:34:33.088568269Z caller=flush.go:261 component=ingester loop=29 org_id=xxx msg="failed to flush" retries=1 err="failed to flush chunks: store put chunk: InvalidArgument: invalid x-cos-storage-class for role mode bucket, only support intellingent tiering or default\n\tstatus code: 400, request id: xxx, host id: , num_chunks: 1, labels: {app=\"loki\", component=\"gateway\", container=\"nginx\", filename=\"/var/log/pods/monitoring_loki-gateway-6fb5686c6f-42wcc_ce7d81e7-a5fb-4436-b2e8-51abf866f056/nginx/0.log\", instance=\"loki\", job=\"monitoring/loki\", namespace=\"monitoring\", node_name=\"hkg-qcloud\", pod=\"loki-gateway-6fb5686c6f-42wcc\", service_name=\"loki\", stream=\"stderr\"}"

    看起来是 Loki 在调用上传的时候,加了对象的预期存储类型,轻量对象存储可能刚好简化了这个类型。尝试从代码里面找的话, 可以发现确实支持进行配置:

    文档中也给出了相应说明:Grafana Loki configuration parameters | Grafana Loki documentation。所以我们可以新增配置:

    loki:
      storage_config:
        aws:
          storage_class: INTELLIGENT_TIERING

    问题解决。Loki 日志显示开始正常存取日志块,并且轻量对象存储控制台上也能看见相应的文件了。

    附录

    完整的 Loki values.yaml

    deploymentMode: SingleBinary
    loki:
      commonConfig:
        replication_factor: 1
      storage:
        type: s3
        s3:
          endpoint: cos.ap-hongkong.myqcloud.com
          region: ap-hongkong
          accessKeyId: <ak>
          secretAccessKey: <sk>
        bucketNames:
          chunks: <bucketName>-<uid>
          ruler: <bucketName>-<uid>
          admin: <bucketName>-<uid>
      storage_config:
        aws:
          storage_class: INTELLIGENT_TIERING
      schemaConfig:
        configs:
          - from: 2024-04-01
            object_store: s3
            store: tsdb
            schema: v13
            index:
              prefix: index_
              period: 24h
      limits_config:
        retention_period: 4320h
      compactor:
        retention_enabled: true
        delete_request_store: s3
    singleBinary:
      replicas: 1
      nodeSelector:
        kubernetes.io/hostname: hkg-qcloud
      dnsConfig: |-
        nameservers:
          - 183.60.83.19
          - 183.60.82.98
    chunksCache:
      enabled: false
    gateway:
      nodeSelector:
        kubernetes.io/hostname: hkg-qcloud
    resultsCache:
      enabled: false
    read:
      replicas: 0
    backend:
      replicas: 0
    write:
      replicas: 0
    domain

    在

    云原生

    于

    2025年4月25日

  • domain 的自言自语 2504

    Linux

    深入理解Linux Netlink机制:进程间通信的关键 – 知乎

    The proc/net/tcp and proc/net/tcp6 variables — The Linux Kernel documentation

    kernel.org/doc/Documentation/networking/proc_net_tcp.txt

    How to increase swap space? – Ask Ubuntu

    GitHub – canonical/cloud-utils: This package provides a useful set of utilities for interacting with a cloud.

    apt install cloud-guest-utils -y
    growpart /dev/sda 1
    e2fsck -f /dev/sda1
    resize2fs /dev/sda1

    读书

    大教堂与集市 (豆瓣)

    网络

    HTTPS 温故知新(四) —— 直观感受 TLS 握手流程(下)

    Submarine Cable Map

    杂项

    calculator-app – Chad Nauseam Home
    搞个计算器是真的不容易。

    Site Names in Google Search | Google Search Central  |  Documentation  |  Google for Developers
    发现搜索的时候,站点名称没有展示,而是显示为域名。

    找到了从哪里获取的就比较好办了,这段可以直接在 functions.php 里面注入:

    add_action('wp_head', function () {
        echo '<script type="application/ld+json">{"@context":"http://schema.org","@type":"WebSite","name":"我们的笔记","url":"' . home_url() . '"}</script>';
    });
    domain

    在

    自言自语

    于

    2025年4月1日

  • linuxserver/openssh-server mods

    最近希望给一个服务器启动一个独立的 openssh-server 容器用于安全转发内部接口请求,发现 linuxserver/openssh-server 镜像非常适合这一场景。

    不过这个镜像默认是不开启 TCP 转发的,官方提供了一个较为优雅的模块插件机制来实现类似功能,模块可以在这里找到:Linuxserver Container Mods。只要配置环境变量 DOCKER_MODS=linuxserver/mods:openssh-server-ssh-tunnel 就可以自动加载了。

    看起来模块只是一些脚本,具体的实现在这里:docker-mods/root/etc/s6-overlay/s6-rc.d/init-mod-openssh-server-ssh-tunnel-setup/run at f7fc561d103d6832bb75a4cb4f575b1166180430 · linuxserver/docker-mods · GitHub。

    那么模块是怎么被拉取的呢,离线的私有化场景中怎么处理?可以在这里找到:docker-mods/docker-mods.v3 at cac9e7450a0698f19d750b67db61c4aa214d5290 · linuxserver/docker-mods。

    也就是说,模块实际上都是 Docker 镜像,并且这个脚本已经支持了自定义制品库拉取,我们应该可以编写自己的模块,放到私仓,然后在离线环境中拉取并加载使用了。有空的时候来测试一下这个场景。

    引用

    For the ones who don’t know about the existence of Linuxserver Docker mods : r/selfhosted

    domain

    在

    云原生

    于

    2025年3月15日

  • webpack loader

    webpack 只能理解 JavaScript 和 JSON 文件。

    在 webpack 中,loader 用于对模块的源代码进行转换。可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内联图像转换为 data URL。

    配置

    module.rules 允许你在 webpack 配置中指定多个 loader。

    loader 从右到左(或从下到上)地取值(evaluate)/执行(execute)

    module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [
              { loader: 'style-loader' },
              {
                loader: 'css-loader',
                options: {
                  modules: true,
                },
              },
              { loader: 'sass-loader' },
            ],
          },
        ],
      },
    };

    在以上例子中:

    1. 执行 sass-loader :Sass 或 SCSS 文件编译成 CSS 代码。
    2. 执行 css-loader:解析第一步生成的 CSS 文件,将 CSS 代码转换成 JavaScript 模块;options: { modules: true } 启用 CSS 模块化功能,这意味着每个 CSS 文件都会被视为一个独立的模块,可以避免样式冲突。
    3. 执行 style-loader :将 css-loader 处理后的 CSS 代码动态地插入到 HTML 页面的 <style> 标签中。

    特性

    • 链式调用:一组链式的 loader 将按照相反的顺序执行。链中的第一个 loader 将其结果(也就是应用过转换后的资源)传递给下一个 loader,依此类推。最后,链中的最后一个 loader,返回 webpack 所期望的 JavaScript。
    • loader 可以是同步的,也可以是异步的
    • loader 运行在 Node.js 中,并且能够执行任何操作
    • loader 可以通过 options 对象配置
    • 除了常见的通过 package.json 的 main 来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用 loader 字段直接引用一个模块。
    • 插件(plugin)可以为 loader 带来更多特性。
    • loader 能够产生额外的任意文件。

    类型

    • loader: 核心的转换器,负责将源文件转换成 webpack 可以理解的模块。
    • preLoader: 在普通 loader 之前执行的 loader,主要用于预处理文件,例如代码检查(linting)。
    • postLoader: 在普通 loader 之后执行的 loader,主要用于后处理文件,例如优化或添加额外功能。

    执行顺序

    webpack 在处理模块时,loader 的执行顺序如下:

    1. preLoader
    2. loader
    3. postLoader

    举个例子

    preLoader 示例:ESLint 代码检查

    module: {
      rules: [
        {
          enforce: 'pre', // 指定为 preLoader
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'eslint-loader',
          options: {
            // eslint 配置选项
          },
        },
        // 其他 loader 配置
      ],
    },

    postLoader 示例:添加版权信息

    • 创建一个自定义的 postLoader,在代码处理完成后,自动添加版权信息到 JavaScript 文件的顶部。
    //copyright-loader.js
    module.exports = function(source) {
      const copyright = '// Copyright (c) 2024 Your Company\n';
      return copyright + source;
    };
    module: {
      rules: [
        {
          enforce: 'post',  // 指定为 postLoader
          test: /\.js$/,
          exclude: /node_modules/,
          use:{
            loader:path.resolve(__dirname,'copyright-loader.js')
          }
        },
        // 其他 loader 配置
      ],
    },

    Allison

    在

    前端, 工程化

    于

    2025年3月8日

  • 新版 K3s CNI 目录变化导致 Istio 安装失败

    最近在研究 Istio,在最新正式版的 K3s v1.31.5+k3s1 版本下,安装最新正式版 Istio 1.24.3 时,一直卡在 ztunnel 安装这里,于是来发个牢骚。

    现象

    使用 Helm 安装 ztunnel 之后,发现 ztunnel 无法调度,报错 IP 池不足:failed to allocate for range 0: no IP addresses available in range set。事实上每个节点上调度的 Pod 相当少,IP 不足是不可能的。而且在这之后,其它 Pod 如果重新调度,也会报同样错误,说明集群网络可能出现问题了。

    调查

    任选一个节点,发现 /var/lib/cni/networks/cbr0 目录下已经整个 IP 池被占用,没有释放。参考一个 Issue:pod creation failure: “no IP addresses available in range set” · Issue #4682 · k3s-io/k3s,尝试将 IP 释放,释放后发现,如果再次尝试安装 ztunnel 就会导致 IP 快速被耗尽,而且 ztunnel 的报错信息中有 CNI 组件相关内容(忘记截图),因此考虑 K3s 中是否有其它不同的因素导致其工作异常。

    经过一番搜寻之后发现 K3s 还真的有一个相关的变化,CNI bin dir changes with K3s version · Issue #10869 · k3s-io/k3s 这里引入了一个 CNI 路径的变化,从 /var/lib/rancher/k3s/data/current/bin/ 变为了 /var/lib/rancher/k3s/data/cni/!

    一开始我看到 Rancher 当下的文档 Additional Steps for Installing Istio on RKE2 and K3s Clusters | Rancher 中提到的路径都是前者,就没有怀疑,看来问题就恰好出在这里。

    注意到 Istio 的 Helm Chart 中,有一个提交对此做出了适配:fix: fix k3s cniBinDir to static path (#54112) · istio/istio@7693f57 · GitHub,但是不幸的是还没有正式版的 Release,也就是说,当前安装的 Istio 1.24.3 仍然是旧的 CNI 路径,因此和较新版本的 K3s 不兼容。不过,我发现当下已经有 RC 版本(1.25.0-rc.0)的 Helm Chart 带上了这个变更,所以尝试清理 IP 池后,将 Istio 组件都更新到 1.25.0-rc.0,果然 ztunnel 成功运行了。

    引用

    Istio / Platform-Specific Prerequisites

    kubenet/kubelet leaks ips on docker restart · Issue #34278 · kubernetes/kubernetes

    kubenet ip泄漏 – xiaoqing blog

    「Bug」K8s 节点的 IP 地址泄漏,导致 IP 被耗尽 – 於清樂 – 博客园

    failed to allocate for range 0: no IP addresses available in range set: 172.20.xx.1-172.20.xx.254 – yuxiaoba – 博客园

    Containerd IP leakage · Issue #5768 · containerd/containerd

    Kubernetes-cni issue with 1.9.0 – no ip address available in range · Issue #57280 · kubernetes/kubernetes

    domain

    在

    云原生, 没用的知识

    于

    2025年3月3日

  • domain 的自言自语 2503

    开发者

    Bedtime Stories For Children: Storage Engines (pub-ver) – Google 幻灯片

    网络

    从流量控制算法谈网络优化 – 从 CUBIC 到 BBRv2 算法 | 亚马逊AWS官方博客

    BBR Testing Using iperf3

    AI

    Reverse Prompt Engineering for Fun and (no) Profit

    杂项

    Powercfg command-line options | Microsoft Learn
    最近发现有台 Windows 机器总是意外唤醒,一个个找唤醒设备有点麻烦,发现有命令行工具 powercfg 可以用。

    domain

    在

    自言自语

    于

    2025年3月1日

  • domain 的自言自语 2502

    开发者

    Rust can be faster than C

    BashFAQ/105 – Greg’s Wiki
    set -e 可能存在意外行为,需要小心处理。

    网络

    CNNIC费用分析

    居然还有 2 亿多 IPv4 地址未分配!-ipv4地址总数多少亿

    网络设备(特指 TP-Link)距离正确处理 IPv6 Fragmentation 还有多远 – 属于CYY自己的世界

    domain

    在

    自言自语

    于

    2025年2月1日

  • 为阿里云 RDS MySQL 开启 SSL,并使用自签证书

    最近发现阿里云 99 计划的数据库,竟然包含香港地区,于是又冲动消费了。整了一个给 K3s 玩,试试它的 HA 模式。不过现有的节点很多都不在阿里云内网,需要开放数据库的公网访问才可以。开放数据库公网访问必然要开启 SSL 了,不然数据直接在公网上面明文传输十分危险。

    问题

    一开始我直接在阿里云 RDS 控制台上启用 SSL,使用默认的云端证书,然后先用 Grafana 去尝试连接,发现无法成功校验证书,报错:

    Error: ✗ failed to connect to database: tls: failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead

    猜测默认的云端证书只有在 Common Name 字段带上了数据库连接地址,而 Go 1.15 之后需要从 Subject Alternative Names 中进行校验,综合考虑后决定使用自签证书。

    自签证书

    平时 OpenSSL 用得不多,于是直接使唤 AI 干活:

    openssl genpkey -algorithm RSA -out ca-key.pem
    openssl req -new -x509 -key ca-key.pem -out ca-cert.pem -days 3650 -subj "/CN=MySQL CA"
    
    openssl genpkey -algorithm RSA -out server-key.pem
    openssl req -new -key server-key.pem -out server-req.pem -subj "/CN=rm-foo.mysql.rds.aliyuncs.com"
    openssl x509 -req -in server-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 3650 -extfile <(printf "subjectAltName=DNS:rm-foo.mysql.rds.aliyuncs.com")

    然后在 RDS 控制台上传生成的服务端证书就可以了。

    在 Grafana 上配置

    我们需要先将上面生成的 CA 证书先挂载到 Grafana 容器中,然后参考官方文档进行配置,使其可以经由 TLS 连接数据库。

    我的 Grafana 是使用官方的 Helm Chart 部署的,其提供了一个可以注入 ConfigMap 的配置项,因此我们先创建一个包含了 CA 的 ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      creationTimestamp: null
      name: grafana-database-tls-ca
      namespace: monitoring
    data:
      certificates.crt: |
        -----BEGIN CERTIFICATE-----
        -----END CERTIFICATE-----

    然后在 values.yaml 中配置挂载它:

    extraConfigmapMounts:
      - name: database-tls-ca
        mountPath: /etc/grafana/ssl/
        subPath: certificates.crt
        configMap: grafana-database-tls-ca
        readOnly: true

    这样的话,CA 就已经被挂载到 Grafana 容器中了。接下来我们需要配置 Grafana 以开启 TLS,同样,这里也是在 values.yaml 中配置就行。

    grafana.ini:
      database:
        type: mysql
        host: rm-foo.mysql.rds.aliyuncs.com
        ssl_mode: true
        ssl_sni: rm-foo.mysql.rds.aliyuncs.com
        server_cert_name: rm-foo.mysql.rds.aliyuncs.com
        ca_cert_path: /etc/grafana/ssl
        user: $__file{/etc/secrets/grafana-database/username}
        password: $__file{/etc/secrets/grafana-database/password}

    如果配置没有问题的话,此时执行更新之后应该就可以了。

    在 K3s 上配置

    同样,官方文档给出了配置项。我们需要先把刚才的 CA 证书复制到 K3s server 服务器上,然后修改启动脚本。

    curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--flannel-backend=wireguard-native --disable=servicelb --disable=traefik --disable=metrics-server" \
            sh -s - server \
            --datastore-endpoint="mysql://username:password@tcp(host:3306)/database" \
            --datastore-cafile="/usr/local/share/ca-certificates/mysql.crt" \
            --flannel-external-ip \
            --node-ip 1.2.3.4 \
            --kubelet-arg=node-ip=0.0.0.0

    因为配置变化,安装脚本会更新配置并重启 K3s。如果配置没有问题,K3s 会正常启动。

    后记

    强制指定用户使用加密连接

    如果全部的工作负载已经迁移至 TLS 连接,那么我们就可以配置数据库特定用户必须使用加密连接。

    ALTER USER k3s@'%' REQUIRE SSL;
    FLUSH PRIVILEGES;

    配置生效之后,我们可以重启工作负载进行验证。

    为什么不通过一些 workaround 来使用默认的云端证书

    为了行文的连贯性,我把这段放到了这里。你可能会想到几个问题:

    Q:为什么不直接 skip-verify?省得折腾半天。

    A:不安全,这不是我的风格。而且根据 K3s 文档,其至今仍然暂时无法跳过证书检查。虽然 K3s 的数据库读写垫片 kine 项目已经有人实现了 skip-verify 选项并且已经合入主干+发布,但是当下等待 K3s 支持还早,感兴趣的可以看下面的链接。

    k3s can’t utilize tls option with mysql external database · Issue #1093 · k3s-io/k3s · GitHub

    Add support for TLS skip verification by tuxillo · Pull Request #306 · k3s-io/kine · GitHub

    Q:为什么不使用 GODEBUG=x509ignoreCN=0 环境变量使其可以校验 CN 而不是 SANs?

    A:Go 从 1.15 开始校验 SANs 而不是 CN,从 1.17 开始将会移除这个选项,出于长远考虑我不会这么做。

    x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0 · Issue #775 · rancher/rke2 · GitHub

    引用

    Configure Grafana | Grafana documentation

    Cluster Datastore | K3s

    certificates – Provide subjectAltName to openssl directly on the command line – Information Security Stack Exchange

    How do I use SANs with openSSL instead of common name? – Stack Overflow

    domain

    在

    云原生, 没用的知识

    于

    2025年1月10日

  • domain 的自言自语 2501

    开发

    Go能实现AOP吗? – 掘金

    Complete list of environment variables on Windows 10, 11 – Pureinfotech

    运维

    Incident communication best practices | Atlassian

    腾讯云 4g 服务器实际可用内存只有 3.3g – V2EX
    kdump 有预留 128MB 内存,如果不需要可以考虑关闭。

    DIY 一个运维神器 Open IP-KVM – 知乎
    DIY PiKVM V2 – PiKVM Handbook

    Proxmox VE 8 换源 | fallen’s attic
    Proxmox VE 8 配置国内软件源并删除订阅弹窗 – Song`s Blog

    SSH ProxyCommand example: Going through one host to reach another server – nixCraft

    tls-san parameter won’t change · Issue #4149 · k3s-io/k3s
    kubernetes – How to add a domain to k3s certificate – Server Fault
    最近为 K3s 集群添加了入口域名来实现负载均衡,中途 tls-san 长时间未刷新,原因还未细究。

    网络

    排除指定连接的FastTrack加速 – YuS
    RouterOS 开启 fasttrack 后,如果有 mangle 表修改后的连接被 fasttrack,会导致连接异常,所以可以根据 connection mark 或地址等元素进行排除。

    domain

    在

    自言自语

    于

    2025年1月1日

  • SSH: no matching host key type found.

    最近在使用 SSH 连接服务器时有报错:

    Unable to negotiate with xx.xx.xx.xx port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss

    主要原因是服务端较旧,客户端较新,服务端提供的密钥算法在客户端均已经默认被禁用。其中:

    • ssh-rsa 在 8.2 版本默认被禁用:openssh.com/txt/release-8.2
    • ssh-dss 在 7.0 版本默认被禁用:openssh.com/txt/release-7.0

    这里只能进行一个 workaround,在连接时临时允许特定算法/密钥。

    ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa user@host

    如果是 Git 推拉代码的场景,也是同理:

    GIT_SSH_COMMAND="ssh -oHostKeyAlgorithms=+ssh-rsa" git clone ssh://user@host/repo

    引用

    OpenSSH: Legacy Options

    web hosting – Unable to negotiate with XX.XXX.XX.XX: no matching host key type found. Their offer: ssh-dss – Stack Overflow

    Git error no matching host key type found. Their offer: ssh-rsa – Stack Overflow

    Allison

    在

    没用的知识

    于

    2024年12月25日

←上一页
1 2 3 4 … 11
下一页→

我们的笔记

Keep Coding

  • Mail
  • GitHub
  • Telegram
  • 首页
  • 友情链接
  • 关于

粤ICP备2021143753号-1

以 WordPress 设计