从抵触到真香:我在杭州用部署工具搞区块链产品的血泪史
说实话,一年前要是有人跟我说“AI写代码能帮上忙”,我大概会翻个白眼,顺手把键盘敲得震天响。作为一个死磕代码可读性和可维护性的 Mac 党(Windows?那只是我测试兼容性时的临时刑具),我一直觉得自动化部署这玩意儿不过是运维甩锅给开发的借口。然而——命运总爱打脸。
去年底,我被拉进一个新项目组:一个基于区块链的供应链金融产品,目标是赶在春节前上线 MVP。产品经理画饼说“轻量、敏捷、快速迭代”,结果需求文档改了七版,UI 设计师凌晨三点发来 Figma 链接,而我的 deadline 是——双11后第三周。更绝的是,团队里没人碰过区块链部署,连 Dockerfile 都写得像祖传代码。
于是,我这个“反 AI 部署战士”被迫踏上了寻找靠谱部署方案的不归路。今天这篇不是教程,也不是布道文,纯粹是踩坑实录 + 真香现场。如果你也在杭州(阿里网易圈子里混的应该懂),正被类似问题折磨,或许能少走点弯路。
起因:区块链产品 ≠ 普通 Web 应用
我们做的不是普通的 CRUD 应用,而是一个 Hyperledger Fabric 网络,包含 Orderer、Peer、CA 等节点,还要对接链码(Chaincode)。这意味着:
- 多容器协同(至少5个服务)
- TLS 证书动态生成
- 链码生命周期管理
- 网络拓扑必须严格隔离(开发/测试/预发不能混)
最初,我们天真地用了 docker-compose 手动部署。本地跑得飞起,但一到测试环境就炸:证书路径不对、Peer 连不上 Orderer、链码安装超时……运维小哥看我的眼神,仿佛在看一个刚学会 git push -f 的实习生。
“你们开发是不是以为生产环境也是 MacBook Pro M1?” —— 运维老张,周五晚上10点,钉钉语音
那一刻我意识到:手动部署在复杂系统面前就是耍流氓。
第一坑:Ansible?太重了!
我第一个想到的是 Ansible。毕竟社区教程多,YAML 写起来也“优雅”。但很快发现问题:
- 状态不可逆:Ansible 是过程式执行,一旦中间某步失败,回滚几乎不可能。
- 证书管理灾难:Fabric 的 crypto-config 依赖绝对路径,Ansible 的
copy模块在不同机器上路径不一致。 - 调试地狱:日志分散在各主机,查错全靠
grep+ 玄学。
最惨的是上周三,我写了个 playbook 自动部署 CA 服务,结果因为一台测试机时间不同步,证书签发失败,整个网络瘫痪。测试团队直接在群里@我:“兄弟,你这产品是‘去中心化’还是‘去可用’?”
转折点:拥抱 Terraform + Helm(真香预警)
被现实毒打后,我开始研究声明式部署工具。Terraform + Helm 组合成了救命稻草——虽然一开始我内心是拒绝的(“又一个 YAML 套娃?”)。
为什么选它?
| 工具 | 优势 | 劣势 |
|---|---|---|
| Ansible | 学习曲线平缓,适合简单任务 | 无状态,难回滚,不适合复杂拓扑 |
| Kubernetes Native | 弹性好,生态强 | 对 Fabric 支持弱,需大量自定义 CRD |
| Terraform + Helm | 声明式、可版本化、支持多云 | 初期配置复杂,需理解 Provider 模型 |
关键在于:Helm Chart 可以封装整个 Fabric 网络拓扑,而 Terraform 负责基础设施(比如 EKS 集群、安全组、存储卷)。
实战:用 Helm 部署 Fabric 网络
我花了三天时间,把官方 Fabric samples 改造成 Helm Chart。核心思路是:每个 Org 一个 Release,共享同一个 Namespace。
# values.yaml 示例(简化版)
orgName: org1
domain: example.com
peers:
- name: peer0
port: 7051
resources:
requests:
memory: "512Mi"
cpu: "200m"
ca:
enabled: true
port: 7054
orderer:
enabled: false # Org1 不托管 Orderer
tlsSecretName: "org1-tls" # 提前用 cert-manager 生成
然后用 Terraform 创建 EKS 集群并部署 Helm Release:
# main.tf
provider "aws" {
region = "cn-hangzhou"
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "19.18.0"
cluster_name = "blockchain-prod"
cluster_version = "1.27"
subnets = ["subnet-xxx", "subnet-yyy"]
}
resource "helm_release" "fabric_org1" {
name = "fabric-org1"
repository = "https://my-helm-repo.example.com"
chart = "fabric-network"
version = "0.3.1"
values = [file("values-org1.yaml")]
depends_on = [module.eks]
}
}
重点来了:我们用
cert-manager+ACME自动签发内网 TLS 证书,避免手动管理 crypto-config。这招是从阿里内部文档偷师的(感谢某位匿名 P8)。
第二坑:链码部署的“幽灵 Bug”
搞定基础设施后,我以为万事大吉。结果链码一部署,Peer 日志疯狂报错:
Error: failed to endorse transaction: timeout expired while waiting for chaincode to start
查了两天,发现是 Helm 的 initContainer 没等链码镜像拉取完成就启动 Peer。K8s 默认不会等 initContainer 完全 ready,而链码容器启动慢(Go build + 安装依赖要30秒+)。
解决方案:在 Peer 的 StatefulSet 中加入 readiness probe,并确保链码容器先于 Peer 启动。
# peer-statefulset.yaml 片段
initContainers:
- name: install-chaincode
image: hyperledger/fabric-ccenv:2.5
command: ["/bin/sh", "-c"]
args:
- >
peer lifecycle chaincode install mycc.tar.gz &&
peer lifecycle chaincode approveformyorg ...
readinessProbe:
exec:
command: ["sh", "-c", "peer channel list &>/dev/null"]
initialDelaySeconds: 10
periodSeconds: 5
教训:区块链应用对启动顺序极其敏感,声明式部署必须显式定义依赖关系。
第三坑:Mac 和 Linux 的“跨平台诅咒”
作为坚定的 Mac 用户,我本地开发用 Docker Desktop,一切正常。但 CI/CD 流水线跑在 Linux Runner 上,结果:
- 文件权限问题(Mac 默认忽略 chmod)
- 换行符差异(CRLF vs LF 导致 shell 脚本报错)
- ARM64 vs AMD64 镜像不兼容
最离谱的是,我在 Mac 上 build 的链码镜像,在 Linux 节点上直接 panic。后来发现是 Go 编译时没指定 GOOS=linux。
现在我们的 Makefile 里强制加了交叉编译:
build-chaincode:
docker run --rm \
-v $(PWD):/src \
-w /src \
golang:1.21 \
go build -o chaincode-linux-amd64 -tags nopkcs11 . \
&& chmod +x chaincode-linux-amd64
忠告:别信“一次构建到处运行”,除非你明确控制了平台和架构。
成果:从“救火队员”到“部署自由”
折腾两个月后,我们现在:
- 开发环境:
make deploy-dev→ 5分钟起一套完整 Fabric 网络 - 预发环境:Git push → 自动触发 Terraform Plan → 审批后 Apply
- 链码更新:只需改 Helm values,无需动基础设施
上周五,产品经理又提了个“紧急需求”(说是要赶春节档)。我淡定回了句:“没问题,明天中午前预发可用。” —— 这在以前是想都不敢想的。
更重要的是,代码可维护性大幅提升。所有部署逻辑集中在 Git 仓库,新人入职看 README.md 就能跑起来,再也不用问我“那个神秘的 deploy.sh 在哪”。
心得:工具没有银弹,但选对能救命
回顾这段经历,我最大的转变不是技术层面,而是心态:
- 别抵触新工具:当初嫌 Helm 复杂,其实是自己懒(承认吧)。
- 声明式 > 过程式:对于复杂系统,状态管理比步骤管理更重要。
- 本地 ≠ 生产:Mac 再香,也得尊重 Linux 的规则。
- 文档即代码:我们的部署文档直接嵌入在 Helm Chart 的 README 里,随版本迭代。
最后说句掏心窝的:在杭州这种大厂扎堆的地方,技术迭代快得像坐火箭。与其抱怨“又要学新东西”,不如早点拥抱变化——毕竟,真香虽迟但到。
下次团建,我请运维老张喝杯星巴克,顺便请教下 cert-manager 的高级用法。毕竟,好的部署体验,是开发和运维共同的孩子。
附:避坑清单
- ✅ 用
cert-manager管理 TLS,别手动生成证书- ✅ 链码容器必须有 readiness probe
- ✅ 所有构建命令显式指定
GOOS=linux- ✅ Helm values 分环境(dev/staging/prod)隔离
- ❌ 别在 Mac 上直接 build 生产镜像
- ❌ 别用 Ansible 管理有状态服务(如数据库、区块链节点)
希望这篇“血泪史”能帮你少熬几个夜。如果你们也在搞区块链产品,欢迎交流(钉钉:hz_dev_blockchain)—— 杭州的程序员,抱团取暖才活得久啊。

评论 0