脚本宝典收集整理的这篇文章主要介绍了

解决Docker Machine中的容器文件不能持久的问题

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

解决Docker Machine中的容器文件不能持久的问题

目前Mac下使用docker的主流方式还是使用Docker machine.
Docker machine需要借用Virtual Box虚拟器启动一个Linux宿主机, 才能在上面启动多个Docker容器.

当我们在docker容器中运行服务时,经常会有需要将服务数据持久化的场景.比如运行Elasticsearch集群时, 需要将索引数据持久保存到磁盘.

那具体保存到哪里呢?容器的无状态特性决定了我们不应该将数据保存在容器中, 因为容器一旦重启, 文件数据就会丢失.一般应该使用volume参数,通过挂载外部文件系统到Docker容器中来保存数据.

当我在Mac下使用Docker开发时, 遇到这种场景, 自然就想到了将服务数据保存到Linux宿主机上. 结果很不辛, 使用Docker Machine创建的Linux宿主机的文件系统几乎也是不能持久的, Linux重启后, 之前写入的文件都会丢失.

不过好在使用Docker Machine创建的Linux宿主机上面,自动挂载了Mac上的用户目录到Linux宿主机上. 如下:

Linux: /Users   --->   Mac  : /Users

我们挂载文件系统时, 将应用的数据保存到/Users不久可以了吗?

然而现实还是那么残酷. 当我使用按照这个方式启动Elasticsearch时:

docker run -v "/Users/isaac/work/data":/usr/share/elasticsearch/data elasticsearch:2.3.3

却得到了以下错误:

Exception in thread "main" java.lang.IllegalStateException: Unable to access 'path.data' (/usr/share/elasticsearch/data/elasticsearch) Likely root cause: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/elasticsearch     at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)     at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)     at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)     at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:384)     at java.nio.file.Files.createDirectory(Files.java:674)     at java.nio.file.Files.createAndCheckIsDirectory(Files.java:781)     at java.nio.file.Files.createDirectories(Files.java:767)     at org.elasticsearch.bootstrap.Security.ensureDirectoryExists(Security.java:337)     at org.elasticsearch.bootstrap.Security.addPath(Security.java:314)     at org.elasticsearch.bootstrap.Security.addFilePermissions(Security.java:259)     at org.elasticsearch.bootstrap.Security.createPermissions(Security.java:212)     at org.elasticsearch.bootstrap.Security.configure(Security.java:118)     at org.elasticsearch.bootstrap.Bootstrap.setupSecurity(Bootstrap.java:196)     at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:167)     at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:270)     at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35) 

经过分析, 文件操作失败是因为用户权限的问题.
查看Linux宿主机的用户信息:

docker-machine ssh default cat /etc/passwd

得到以下内容:

root:x:0:0:root:/root:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/false tc:x:1001:50:Linux User,,,:/home/tc:/bin/sh docker:x:1000:50:Linux User,,,:/home/docker:/bin/sh

所以通过指定启动Docker容器的用户, 可以解决此问题:

docker run -u 1000 -v "/Users/isaac/work/data":/usr/share/elasticsearch/data elasticsearch:2.3.3 

其中:-u 1000 代表使用id为1000的docker用户来启动应用

在docker-compose.yml中指定启动用户为docker用户:

elasticsearch1:     image: elasticsearch:2.3.3     command: "elasticsearch -Des.cluster.name=elasticsearch -Des.discovery.zen.ping.unicast.hosts=elasticsearch_master"     links:       - elasticsearch_master     volumes:       - /Users/isaac/work/data:/usr/share/elasticsearch/data     user: "1000" 

ok,启动服务后, 数据终于持久不丢失了.

总结

以上是脚本宝典为你收集整理的

解决Docker Machine中的容器文件不能持久的问题

全部内容,希望文章能够帮你解决

解决Docker Machine中的容器文件不能持久的问题

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过