AlexiaChen.github.io icon indicating copy to clipboard operation
AlexiaChen.github.io copied to clipboard

Docker swarm使用NFS跨主机Docker容器间共享持久化数据

Open AlexiaChen opened this issue 5 years ago • 0 comments

可以解决docker swarm集群下容器的漂移共享不到历史数据问题。(因为区块链的节点容器不是无状态的服务,容器一旦漂移到另外的swarm worker节点上去,以前存在本地LevelDB的历史数据就找不到了,使用上会出问题)

这种解决办法都是需要外挂一个存储。把状态放到一个地方共享,这个地方可以是NFS,也可以是分布式文件系统,也可以是AWS提供的存储服务。我想这点上k8s提供的比较强大,这里不做讨论,我也暂时不会k8s。

没有采用Docker最推荐的方式volume。而是使用了bind。比较笨,主要是使用volume报出了/var/lib/docker/volumes/nfs_volume/的权限问题,时间紧急,一下子没搞明白,就直接用了bind方式。

在特定节点上搭建NFS服务器,其他的swarm集群节点上搭建NFS客户端,然后df -h查看以下是否有 [nfs server ip]:/[nfs server root dir] 20G 19G 1.3G 94% /mnt/[client mount point] 这样的项就表示成功了。

可以先自己写个不停写文件的程序,用Dockerfile打包成镜像,测试下,然后docker run bind到客户端挂载点:

docker run -d  --mount type=bind,src=/mnt/[client mount point],dst=/home/[data-dir] [image id or tag name]

如果可以了,那么swarm service create的go API也是与命令行接口(--mount 参数)保持一致的。

serviceSpec := swarm.ServiceSpec{
		Annotations: swarm.Annotations{
			Name:   serviceName,
			Labels: map[string]string{},
		},
		TaskTemplate: swarm.TaskSpec{
			ContainerSpec: swarm.ContainerSpec{
				Image:    cfg.Image,
				Hostname: serviceName,
				Args:     strings.Split(args, " "),
				Mounts: []mount.Mount{
					{
						Type:   mount.TypeBind,
						Source: cfg.NFSBindSource,
						Target: target,
					},
				},
			},
			Networks: []swarm.NetworkAttachmentConfig{
				{Target: cfg.Overlay},
			},
		},
	}
	res, err := cli.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{})

参考

  • https://www.cnblogs.com/Honeycomb/p/10148715.html
  • https://docs.docker.com/engine/reference/commandline/service_create/
  • https://docs.docker.com/storage/volumes/
  • https://godoc.org/github.com/docker/docker/api/types/swarm#ServiceMode
  • https://docs.docker.com/engine/reference/builder/
  • http://collabnix.com/docker-1-12-swarm-mode-persistent-storage-using-nfs/

AlexiaChen avatar Oct 29 '19 02:10 AlexiaChen