分析IBM官方k8s部署fabric的方案
之前我们测试了IBM官方的k8s部署fabric的方案,比我们之间手动在k8s部署fabric要简洁与方便,所以,就想看看IBM究竟是怎么处理的。
我们之前,用k8s部署了fabric的各个组件,但是链码我们是直接运行在节点上的,并且是需要为每个节点的Docker配置k8s集群的DNS,所以还不能完全手动,也就是说这种部署方案,并没有将链码容器纳入到k8s的环境中。
需要注意的是,链码容器的启动是通过Docker API启动的,远程当然也可以,今天做阿里比赛的题目,想用Docker直接部署几个实例,查到maven可以远程部署,当然这里也可以,链码实例化启动容器是Peer完成的,查Peer参数,可以Docker地址参数,也就是说我们可以配置远程Docker地址,将链码容器启动在这个远程Docker中。
IBM的部署方案,就是上述的思路,进一步的它使用了Docker in Docker(dind)的方案,即K8s中运行一个Docker Pod,然后将链码在这个Docker环境中启动进程, 这样的好处是:我们所能看到的都在k8s环境中;dind在k8s环境,所以链码容器可以直接利用k8s的dns系统,无需再手动配置。缺点是:链码容器放在了dind中,k8s环境是无法直接管理链码容器的,不利于我们的外部监控;至于链码容器的存活,可以通过持久化存储实现dind重启后链码容器重启;还有一个最近比较关心的问题,链码增多,dind负担也将增加;最后dind成熟可靠了么?
(有个疑问?链码容器崩溃后,fabric感知不到链码的心跳,会重启链码容器吗?->文末测试,不会;同样dind pod挂掉重启后,链码容器也不会重启,由此看IBM这个仅仅是个测试方案)
在dind中运行链码容器还是存在较多问题的,主要是它仍没有完全纳入k8s环境,那我们能不能将dind接受的链码启动命令转化为k8s中pod创建命令,将链码部署到pod中,这样就将链码纳入到k8s环境中;这个改动有两个方向:1. fabric的链码实例化源码改动,让其支持k8s启动;2. 从dind入手,拦截创建链码容器的命令,然后通过k8s api创建pod,这其实相当于做了一个代理
其中代理方案,已经在国内某BaaS服务中看到相关影子,待研究。
我们看下IBM-BLOCKCHAIN-NETWORK-ON-K8S的链码部署流程
- 正常的各组件启动
- jobs:安装链码
- jobs:实例化链码
- Peer接收到实例化链码请求,共识通过后,连接CORE_VM_ENDPOINT参数配置的远程Docker(实际是dind),发送部署链码容器消息
- Docker in Docker(dind),启动链码容器
追踪一下在yaml文件中链码部署流:
- 启动docker pod,(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