为极客天成改写一套CSI存储插件

极客天成有个很厉害的scaleflash网络文件系统,充分利用rdma的无损网络特性,并进一步发扬光大。研发出来了可以顶替EMC盘阵的存储系统,可以在其上跑Oracle等数据库系统,真的是国货之光了。 帮它们改写了一个csi的存储插件,记录一下,基于yandex的s3 csi而来,这样既可以跑到底层上提供文件块设备,也可以上升到类似NFS或者S3的层次提供文件系统,能满足大多数需求。那源代码就绝对不提供了,只说一下过程: CSI PLUGIN的使用方法: 一、导入镜像 csi存储插件的image cr.yandex/crp9ftr22d26age3hulg/csi-s3:0.42.66 文件:csi.tar 将文件放到所有worknode上,导入本地镜像库: ctr --address /run/k3s/containerd/containerd.sock -n k8s.io images import /root/csi.tar crictl -r unix:///run/k3s/containerd/containerd.sock images 看到有 cr.yandex/crp9ftr22d26age3hulg/csi-s3:0.42.66 既是导入成功 二、安装controller和nodeserver 安装driver 文件:driver.yaml kubectl apply -f driver.yaml 安装controller 文件:controller.yaml kubectl apply -f controller.yaml 安装nodeserver 文件:nodeserver.yaml 解释一下,controller是一个statefulset,整个集群运行一个即可;而nodeservershi则是一个daemonset,每个worknode都会运行一个副本 上面 worknode 是3个,所以有3个副本 三、scaleflash 块设备的使用 块设备最小单位是G,所以如果需求了100M,那也是1G。 首先必须定义一个storageclass,以后使用这一个storageclass就可以了: cat << EOF >scaleflash-storageclass.yaml --- kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: scaleflash provisioner: ru.yandex.s3.csi parameters: mounter: scaleflash clstID: "nvmatrix_101" fsType: "xfs" EOF kubectl apply -f scaleflash-storageclass.yaml 再定义pvc ...

2025年08月07日 · 4 分钟 · 712 字 · 八戒

vault使用agent验证approle生成.env环境变量

Vault是个很厉害的 secret 引擎了,不多说了,主要用于集中管理各种密码、密钥。 用来管理Kubernetes的凭据相当好,但是我们通常是自己开发的程序,然后需要读各种配置文件,比如连接DB的用户名,密码等等,最后连接到数据库。 那么这种情况下,如果管理好配置项呢? 方法如下,用approle读取Vault的配置信息: 一、启动vault引擎测试环境 首先启动vault引擎,测试,用Docker,方便创建和销毁 # 启动容器 # 我们手动指定了ROOT_TOKEN是root,这只用于测试环境 docker run -d --rm \ --add-host host.docker.internal:host-gateway \ --cap-add=IPC_LOCK \ --name vault \ -p 8200:8200 \ -e VAULT_DEV_ROOT_TOKEN_ID=root \ -e VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200 \ hashicorp/vault --add-host host.docker.internal:host-gateway 这个个参数的作用是在容器的 /etc/hosts 文件中添加一个主机名和 IP 地址的映射。 --add-host: 这是 docker run 的一个选项,用来在容器的 /etc/hosts 文件中添加一个自定义的主机条目。 host.docker.internal: 这是主机名。在 Docker Desktop(macOS 和 Windows)中,host.docker.internal 是一个特殊的 DNS 名称,它会被解析为宿主机的内部 IP 地址。 host-gateway: 这是 docker 在较新版本中引入的一个特殊关键字。它代表了宿主机与 Docker 网络之间的网关 IP 地址。在许多 Linux 环境中,这个关键字会指向 Docker 的网桥 IP(例如 172.17.0.1)。 综合起来,--add-host host.docker.internal:host-gateway 的作用是: ...

2025年08月06日 · 2 分钟 · 339 字 · 八戒

上难度---->内网vps用lego申请route53 DNS证书并更新到BT宝塔

上一篇我们说了 Aws的EC2服务器用lego获得免费证书并更新到ACM,这下又来了个更加有难度的挑战: DNS解析是放在了AWS Route 53上,然后vps上跑着BT宝塔,用来代理转发开发环境的https证书 这个环境如何用lego来安全的申请到证书并配置宝塔呢?这回可不像EC2那样可以自动附加IAM角色了 我们先来看看lego的用法吧: https://go-acme.github.io/lego/dns/route53/ 语法如下: 继续看,看来必须需要IAM的凭据才可以,继续下拉,有使用IAM的policy,那我们必须创建一个Role角色,然后再建立一个代理用户,gen出key,通过这个代理用户的凭据来间接进行访问 步骤如下: 一、去route53,拿到arn 我们要拿到具体域名的zone ID,就是Z0打头的那一串 二、建立IAM实际工作的Role 首先建立一个Policy,route53AcmeCert { "Version": "2012-10-17 "Statement": [ "Effect": "Allow", "Action": "route53:GetChange", "Resource": "arn:aws:route53:::change/*" }, { "Effect": "Allow", "Action": "route53:ListHostedZonesByName", }, { "Effect": "Allow", "Action": [ "route53:ListResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/Z01111111111111111111" ] }, { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/Z01111111111111111111" ], "Condition": { "ForAllValues:StringEquals": { "route53:ChangeResourceRecordSetsNormalizedRecordNames": [ "_acme-challenge.example.com" ], "route53:ChangeResourceRecordSetsRecordTypes": [ "TXT" ] } } } ] } 然后建立一个Role,RealUpdateCertRole,绑定上面的策略 ...

2025年07月29日 · 2 分钟 · 229 字 · 八戒

Postgres的wal和PITR时间点恢复

研究了Postgres的库数据恢复和转移,再来研究一下PITR按时间点恢复 类比到MySQL,因为我们是运维,不是专业的DBA,所以恢复到正确数据即可 那跟阿里云以及自建的MySQL恢复一样,首先都要有一个每天的基础备份,然后类比MySQL的Binlog,Postgres这里就相当于wal。 这么类比就对了,那么恢复过程的思路是一样的: 首先建立一个新的实例 第二步把每天的基础物理全备给恢复上去 第三步把之后的wal日志传到新实例,恢复到指定时间点 第四步最后把表或库Dump下来,灌入到旧实例的新表或新库 那我们一步一步来解释: 一、每天建立一个基础备份,这样在Base基础上,只需恢复当天的wal,速度够快 建立每天的Base基础物理备份 pg_basebackup -Ft -Pv -Xf -z -Z5 -U postgres -h localhost -p 5432 -D /pg_backup 解释一下: -Ft: 指定备份格式为 tar。 如果使用 tar 格式,备份会输出 tar 文件,并且不需要直接访问 PostgreSQL 数据目录。 -Pv: -P:显示备份进度。 -v:启用详情模式(verbose),显示更多日志。 -Xf: -X:控制 WAL 日志的处理方式,f 表示在备份中包含 WAL 文件(Write Ahead Logs),确保备份可以用于恢复到完整的一致状态。 -z: 启用压缩功能。 -Z5: 设置压缩级别为 5(压缩级别从 0 到 9,9 为最高压缩)。 -U postgres: 使用 postgres 用户来连接数据库。 -h localhost: 指定数据库主机为当前机器(localhost)。 -p 5432: 指定 PostgreSQL 监听端口为 5432(默认端口)。 -D /pg_backup: 将备份文件保存到指定路径 /pg_backup 中。 这样我们就在 /pg_backup 中有了备份文件,包括一个backup_manifest的文件清单,以及一个压缩包 ...

2025年07月28日 · 2 分钟 · 344 字 · 八戒

单机部署kafka用kraft不依赖zookeeper

上一篇说了用Docker部署kafka,后端不用zookeeper,改用kraft。 这一篇说说不用Docker,直接单机部署kafka用kraft的方法。 一、准备,虚机的话需要4cpu 8G内存 # 装好java java --version 建3个目录 # 放kafka的2进制可执行文件 mkdir -p /opt/kafka # 放kafka的数据文件和日志文件 mkdir -p /var/lib/kafka 二、下载并配置kafka # 释放到指定目录 tar -xzf kafka_2.13-3.5.0.tgz -C /opt/kafka # 先注释掉 #broker.id=1 #zookeeper.connect=localhost:2181 # 添加/opt/kafka/config/server.properties # 9092对局域网开放,9093只用于本地单节点 process.roles=broker,controller node.id=1 controller.quorum.voters=1@localhost:9093 listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://localhost:9093 advertised.listeners=PLAINTEXT://192.168.20.59:9092 listener.security.protocol.map=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT controller.listener.names=CONTROLLER inter.broker.listener.name=PLAINTEXT log.dirs=/var/lib/kafka/data metadata.log.dir=/var/lib/kafka/metadata # 然后需要再追加到server.properties的部分 metadata.log.dir=/var/lib/kafka/metadata num.replica.fetchers=1 offsets.topic.replication.factor=1 transaction.state.log.replication.factor=1 transaction.state.log.min.isr=1 三、初始化kafka集群 # 生成一个uuid cd /opt/kafka bin/kafka-storage.sh random-uuid # 初始化 cd /opt/kafka bin/kafka-storage.sh format -t <UUID> -c config/server.properties # 启动 bin/kafka-server-start.sh config/server.properties # 检查一下代理的状态 bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 四、推送数据验证 ...

2025年07月28日 · 1 分钟 · 125 字 · 八戒

用Docker部署kafka且不依赖zookeeper

用redpanda居然还要每隔30天更新一下License文件,叔可忍婶不可忍啊。 换掉换掉,直接用Docker部署kafka,后端不用zookeeper,用kraft,天下苦zk也久矣! 方法很简单,用docker-compose,编辑docker-compose.yml文件 name: 'stream' services: kafka: image: confluentinc/cp-kafka:latest hostname: kafka container_name: kafka ports: - 9092:9092 - 9093:9093 environment: KAFKA_KRAFT_MODE: true # This enables KRaft mode in Kafka. KAFKA_PROCESS_ROLES: controller,broker # Kafka acts as both broker and controller. KAFKA_NODE_ID: 1 # A unique ID for this Kafka instance. KAFKA_CONTROLLER_QUORUM_VOTERS: 1@10.8.1.119:9093 # Defines the controller voters. KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://10.8.1.119:9092 KAFKA_LOG_DIRS: /var/lib/kafka/data # Where Kafka stores its logs. KAFKA_AUTO_CREATE_TOPICS_ENABLE: true # Kafka will automatically create topics if needed. KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 # Since we’re running one broker, one replica is enough. KAFKA_LOG_RETENTION_HOURS: 168 # Keep logs for 7 days. KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0 # No delay for consumer rebalancing. CLUSTER_ID: Mk3OEYBSD34fcwNTJENDM2Qk # A unique ID for the Kafka cluster. volumes: - /var/run/docker.sock:/var/run/docker.sock - ./data:/var/lib/kafka/data # Store Kafka logs on your local machine. 注意以上的文件,暴露了2个端口,9092和9093,9092用于客户端连接,9093用于集群通讯;KAFKA_KRAFT_MODE: true用kraft不用zk. ClUSTER_ID可以换个不同的。 ...

2025年07月28日 · 2 分钟 · 245 字 · 八戒

aws的EC2服务器用lego获得免费证书并更新到ACM

交代一下背景: 公司在AWS上用的是EKS+Fargate,还有一个跳板机,证书呢就不太想用aws收费的了,干脆用免费的证书好了。 那问题就来了,Let‘s encrypt的证书90天到期,已经手动更新过3次了,实在太麻烦了,能不能自动申请并更新到ACM呢? 答案是可以的,原理是:利用EC2可以携带IAM角色的原理,就可以无凭证更新免费证书到AWS Certificate Manager了 做法如下: 一、首先去ACM中拿到证书的ARN,要确保IAM权限不外泄,避免更新错证书 二、生成一个IAM的policy,命名为AllowUpdateCertificate,只允许更新这两个特定的证书 具体策略内容如下: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "acm:ImportCertificate" ], "Resource": [ "arn:aws:acm:ap-southeast-1:111111111111:certificate/arn01", "arn:aws:acm:ap-southeast-1:111111111111:certificate/arn02" ] } ] } 三、IAM生成一个role角色,命名为Ec2UpdateCertificateRole,把AllowUpdateCertificate策略给附上 四、到EC2的实例详细信息中,操作–>安全–>修改IAM角色 附上Ec2UpdateCertificateRole这个角色 五、在EC2的机器上,装好AWS CLI,还有lego(申请Let’s encrypt证书的软件) 先写好获得证书的脚本 get_cert.sh,域名DNS解析是托管到cloudflare的,所以也直接用API TOKEN来处理 #!/bin/bash CLOUDFLARE_DNS_API_TOKEN=######## /usr/local/bin/lego --path /usr/local/bin/certs --email zhangranrui@rendoumi.com --dns cloudflare --domains *.rendoumi.com --domains rendoumi.com renew --renew-hook="/usr/local/bin/update_aws_cert.sh" 参数--renew-hook如果有新证书,就调用后面的脚本。如果没有新证书,就无操作,避免无用功。 然后再写好 update_aws_cert.sh,这就是个千字文了,由gemini生成的: 由于lego生成的crt是证书+证书链,所以第一步要把证书部分给单独拆出来 #!/bin/bash cd /usr/local/bin/certs/certificates #首先把证书单独拆出来 awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/ {print} /-----END CERTIFICATE-----/ {exit}' _.rendoumi.com.crt > _.rendoumi.com.only # --- 配置部分 --- # 您要更新的现有 ACM 证书的 ARN # 示例:CERTIFICATE_ARN="arn:aws:acm:ap-southeast-1:123456789012:certificate/abcdefab-1234-5678-abcd-1234567890ab" CERTIFICATE_ARN="arn:aws:acm:ap-southeast-1:111111111111:certificate/11111111-1111-1111-1111-111111111111" # 新证书文件的路径(例如:/opt/certs/new_certificate.crt) # 确保这个路径在您的EC2实例上是正确的 CERTIFICATE_BODY_PATH="_.rendoumi.com.only" # 新私钥文件的路径(例如:/opt/certs/private.key) # 确保这个路径在您的EC2实例上是正确的 PRIVATE_KEY_PATH="_.rendoumi.com.key" # 证书链文件的路径(可选) # 如果没有证书链,请将此变量留空或注释掉 # 示例:CERTIFICATE_CHAIN_PATH="/opt/certs/ca_bundle.crt" CERTIFICATE_CHAIN_PATH="_.rendoumi.com.issuer.crt" # 如果没有链,请将其留空 "" # ACM 证书所在的 AWS 区域 # 这个区域应该与 CERTIFICATE_ARN 中的区域匹配 # 示例:AWS_REGION="ap-southeast-1" AWS_REGION="ap-southeast-1" # --- 配置部分结束 --- echo "--- 开始使用实例角色重新导入 ACM 证书 ---" echo "证书 ARN: ${CERTIFICATE_ARN}" echo "区域: ${AWS_REGION}" # 检查文件是否存在 if [ ! -f "${CERTIFICATE_BODY_PATH}" ]; then echo "错误:证书文件 '${CERTIFICATE_BODY_PATH}' 不存在。" exit 1 fi if [ ! -f "${PRIVATE_KEY_PATH}" ]; then echo "错误:私钥文件 '${PRIVATE_KEY_PATH}' 不存在。" exit 1 fi if [ -n "${CERTIFICATE_CHAIN_PATH}" ] && [ ! -f "${CERTIFICATE_CHAIN_PATH}" ]; then echo "警告:证书链文件 '${CERTIFICATE_CHAIN_PATH}' 已指定但不存在。将不包含证书链进行导入。" CERTIFICATE_CHAIN_PATH="" # 如果文件不存在,则清空路径 fi # 构造 AWS CLI 命令。AWS CLI 会自动使用实例角色提供的凭证。 IMPORT_CMD="aws acm import-certificate \ --certificate-arn ${CERTIFICATE_ARN} \ --certificate fileb://${CERTIFICATE_BODY_PATH} \ --private-key fileb://${PRIVATE_KEY_PATH} \ --region \"${AWS_REGION}\"" # 如果有证书链,则添加到命令中 if [ -n "${CERTIFICATE_CHAIN_PATH}" ]; then IMPORT_CMD="${IMPORT_CMD} --certificate-chain fileb://${CERTIFICATE_CHAIN_PATH}" fi echo "正在执行命令:" echo "$IMPORT_CMD" echo "--------------------------" # 执行命令 # 注意:这里我们不指定 --profile 或任何凭证,AWS CLI 会自动使用实例IAM角色。 eval $IMPORT_CMD # 检查命令执行结果 if [ $? -eq 0 ]; then echo "--- 证书重新导入成功!---" echo "ACM 证书 ${CERTIFICATE_ARN} 已更新。" else echo "--- 证书重新导入失败!---" echo "请检查错误消息,确保:" echo "1. EC2 实例已正确附加了具有 acm:ImportCertificate 权限的 IAM 角色。" echo "2. 证书、私钥和链文件路径正确且可读。" echo "3. 证书/私钥/链的格式正确。" fi echo "--- 脚本执行完毕 ---" 看起来真的是又臭又长,废话连篇。注意:gemini 生成的代码有问题,aws acm import-certificate 的参数中,证书文件的前缀是fileb://,gemini给的是file://,调试了半天,最后去aws看了文档才发现。 ...

2025年07月25日 · 2 分钟 · 285 字 · 八戒

Redpanda到期后如何续License

上回我们在 Kafka的测试替代品-Redpanda 中说了怎么搭建,结果用了一个月,问题就来了 license过期了,擦的,只允许用30天,需要续费了。 方法如下: 一、打开网站,申请30天的免费license https://cloud.redpanda.com/try-enterprise 打开网站,然后填入姓名和邮箱,就会得到一个长字符串xyz,拷贝下来 二、去机器上 我们是用docker compose启动的,所以需要进入容器,导入license docker exec -it redpanda-0 /bin/sh rpk cluster license set xyz 三、重启容器 按道理上一步弄完,就应该好了的,可惜这产品做的稀烂。还必须重启容器才起作用 docker compose restart 就ok了,但是30天就更新一次license,而且必须要重启容器,这谁受得了啊。 下周就抽空装一个不依赖Zookeeper,用Rraft的Kafka来用,彻底去掉这个不伦不类的软件。

2025年07月25日 · 1 分钟 · 28 字 · 八戒

Postgres不同实例、不同用户直接的数据导出导入

公司生产环境在AWS使用了 Aurora Postgres Serveless 的数据库。 测试环境是在内网搭建了一个postgres 13数据库。 那测试和生产的实例不同,数据库不同,用户名也不同,需要把测试环境的A库的schema.public迁移到生产B库的schema.public。 普及一下概念,PG的权限分三层,数据库、schema、schema中的对象。 那么用pg_dump的话,如果不带任何参数,那会把权限也给带上,那就麻烦大了去了! 所以正确的导出、导入步骤如下: 一、首先要观察源库,看看都有什么extention,在schema.public有什么Functions 如上图所示,看到uuid_generate # 看看服务器版本 select version(); PostgreSQL 13.14 那就很奇怪,extension 只有一个plpgsql,functions却有一堆uuid_generate 那十有八九需要用到extension uuid-oosp 先去目的库建一个吧 create extension "uuid-ossp"; 二、dump数据 这里要注意,不要把任何权限的东西带进来 pg_dump -h 172.16.8.1 -U postgres -d source --schema=public --no-owner --no-privileges --file=export.sql # 全备份的命令 # export PGPASSWORD="xxxxxxxx" # pg_dump -U bbc -h localhost -p 5432 bbc > dc_system.sql 然后要编辑看看这个导入的文件 发现有create schema的语句,如果目的数据库已经有了,那需要去掉。 再看下面: 建立了一个FUNCTION,如果已经建立了extension,那也会报错,不过这2种错误我们都可以直接不用管,直接执行试试 三、导入目标库 跑一跑,看一看: psql -h 10.8.0.1 -U dest -d dest -f export.sql 报了不少错 ...

2025年07月23日 · 1 分钟 · 132 字 · 八戒

内网kubernetes+cloudflare+cert-manager自动签发证书

这个场景非常的有意思: 公司内部有若干个kubernetes集群,属于测试环境,研发搭建了一套SAAS的环境,这个环境需要xxx.abc.com的域名来访问,域名解析记录全都是192.168.0.x,供内部访问,域名会动态生成,需要证书也随之生成,且dns域名托管在cloudflare上。 基本环境如上,麻烦的是 cert-manager 不可能签发私网的证书,只能曲线救国,用dns验证的方式来签发证书了,如果配上 external-dns,那dns解析也不用做了;只要发布一个ingress,就直接生成dns解析记录和对应的https证书。 具体做法如下: 一、配置 cloudflare API token 登录cloudflare,去生成API Token,路径是:User Profile > API Tokens > API Tokens. Permissions: Zone - DNS - Edit Zone Resources: Include - All Zones cert-manager的官方文档居然是错的,https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/ 推荐的 Zone - Zone - Read 是加不上的,有Edit就足够了 然后获得Token的字符串xxxxxx 二、安装cert-manager 这个简单,直接用helm安装 现在这个时间节点,2025.07.09,cert-manager 是 v1.18.2,所以用新命令执行安装 helm repo add jetstack https://charts.jetstack.io helm repo update #老版本比如1.0 helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true #新版本v1.18.2 helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true 三、准备签发机构Issuer ...

2025年07月09日 · 2 分钟 · 276 字 · 八戒