K8s无法感知到Fabric Chaincode容器的解决方案

Ros ·
更新时间:2024-11-14
· 707 次阅读

文章目录事情起因解决方案 事情起因 相信在使用k8s进行fabric部署的时候,很多人克服了重重困难,最终倒在了dns解析下的悲剧。 在使用k8s的时候,通过flannel网络能够在pod容器内进行内部local访问,也可以使用NodePort或者ClusterIP进行外部的访问。然而,在启动fabric-peer的的env里,通过CORE_VM_ENDPOINT=unix:///var/run/docker.sock能够让peer节点创建并启动fabric chaincode容器(链码容器的启动是通过Docker API启动的)。 在使用单机docker-compose的情况下,使用CORE_VM_HOSTCONFIG_DNS加之本机docker的桥接模式,能够让启动无碍。然而,chaincode容器是docker创建的,在k8s感知之外,是无法通过NodePort抑或是ClusterIP访问peer或者orderer节点的。 解决方案 其中一种解决方案是:修改docker的dns 通过修改docker文件来使得启动的chaincode容器自带dns(该方法不知是我配置出错还是其他原因,我没有成功,网上有成功案例)。 本文主要的讲的解决方案不是上面这种,毕竟是偏方,这里说的是IBM自己实现的Baas里的方案——dind。 dind也就是Docker in Docker,在使用Gitlab-ci的时候,曾经在CI/CD服务器的Docker container里面来构建(build)与运行(run)我们的Docker镜像。 很多不使用dind的人,替代做法就是将docker.sock文件volume进容器里,然后在容器里调用容器外的docker daemon来创建新的容器。所以这个做法与peer节点的做法如出一辙。所以,我们逆过程,直接使用dind也是可以的。 IBM的部署方案,就是上述的思路,进一步的它使用了Docker in Docker(dind)的方案,即K8s中运行一个Docker Pod,然后将链码在这个Docker环境中启动进程, 这样的好处是:我们所能看到的都在k8s环境中;dind在k8s环境,所以链码容器可以直接利用k8s的dns系统,无需再手动配置。 缺点是: 链码容器放在了dind中,k8s环境是无法直接管理链码容器的,不利于我们的外部监控。 至于链码容器的存活,链码增多,dind负担也将增加,崩溃的可能性增大。虽然可以通过持久化存储实现dind重启后Pod重启,然而fabric虽然通过心跳机制感知到了chaincode容器的崩溃,但是k8s不能知道dind里嵌套的后一个docker的崩溃,所以fabric 无法重启chaincode,k8s也无法重启Pod。 在dind中运行链码容器还是存在较多问题的,主要是它仍没有完全纳入k8s环境,那我们能不能将dind接受的链码启动命令转化为k8s中pod创建命令,将链码部署到pod中,这样就将链码纳入到k8s环境中。这个改动有两个方向: fabric的链码实例化源码改动,让其支持k8s启动; 从dind入手,拦截创建链码容器的命令,然后通过k8s api创建pod,这其实相当于做了一个代理。 第一种方式,需要fabric源码作出改动,这是真正的治标治本的方案,因为第二种方案我们已经分析了其缺点。 我们这里主要分析第二种方式: 我们看下IBM-BLOCKCHAIN-NETWORK-ON-K8S的链码部署流程 正常的各组件启动 jobs:安装链码 jobs:实例化链码 Peer接收到实例化链码请求,共识通过后,连接CORE_VM_ENDPOINT参数配置的远程Docker(实际是dind),发送部署链码容器消息 Docker in Docker(dind),启动链码容器 这里追踪一下yaml: 下面是dind的配置。 --- apiVersion: v1 kind: Service metadata: name: docker #docker的域名,k8s的dns可以将域名docker解析为ip labels: run: docker spec: selector: name: docker ports: - protocol: TCP targetPort: 2375 port: 2375 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: docker-dind spec: replicas: 1 template: metadata: labels: name: docker spec: volumes: - name: dockervolume persistentVolumeClaim: claimName: docker-pvc containers: - name: docker securityContext: privileged: true image: "docker:stable-dind" ports: - containerPort: 2375 volumeMounts: - mountPath: /var/lib/docker name: dockervolume 重头戏来了(CORE_VM_ENDPOINT),接下来是peer的配置: apiVersion: extensions/v1beta1 kind: Deployment metadata: name: blockchain-org1peer1 spec: replicas: 1 template: metadata: labels: name: org1peer1 spec: volumes: - name: sharedvolume persistentVolumeClaim: claimName: shared-pvc - name: dockersocket hostPath: path: /var/run/docker.sock containers: - name: org1peer1 image: hyperledger/fabric-peer:1.4 command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done; peer node start"] env: - name: CORE_PEER_ADDRESSAUTODETECT value: "true" - name: CORE_PEER_NETWORKID value: nid1 - name: CORE_PEER_ID value: org1peer1 - name: CORE_PEER_ADDRESS value: blockchain-org1peer1:30110 - name: CORE_PEER_LISTENADDRESS value: 0.0.0.0:30110 ... - name: CORE_PEER_COMMITTER_ENABLED value: "true" - name: CORE_PEER_PROFILE_ENABLED value: "true" - name: CORE_VM_ENDPOINT #重点是这里,接收到链码实例化请求,Peer向此地址的Docker发送启动链码容器命令/api调用 value: tcp://docker:2375 - name: CORE_PEER_LOCALMSPID value: Org1MSP - name: CORE_PEER_MSPCONFIGPATH value: /shared/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/ - name: FABRIC_LOGGING_SPEC value: debug ... 配置到这里,一目了然。 参考: https://github.com/IBM/blockchain-network-on-kubernetes https://blog.csdn.net/scylhy/article/details/94635655 作者:No_Game_No_Life_



Chaincode fabric k8s 解决方案

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章
Tricia 2020-10-13
661
Noya 2021-01-29
844