Docker Volume Access Error

2019-09-15 07:40发布

问题:

I have created a Dockerfile to build an image for Elasticsearch using Docker on Windows Server 2016. Creating an image works perfectly, and I can run it using docker run --rm -p 9200:9200 <imageid>. I can successfully access Elasticsearch using the ip address of the container. Link to Github Project.

The elasticsearch.yml file configures the log and data path:

cluster.name: docker-cluster
network.host: 0.0.0.0

path.logs: C:/persistent/logs/
path.data: C:/persistent/data/

discovery.zen.minimum_master_nodes: 1

I run into trouble when I try to use a volume to persist the logs and the data on the host. I created a volume with the command

docker volume create elasticsearch  

and run the container:

docker run --rm -p 9200:9200 -v elasticsearch:C:\persistent <imageid>

Which gives me a java exception:

[2017-05-10T09:00:47,568][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: Unable to access 'path.logs' (C:\persistent\logs)
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:127) ~[elasticsearch-5.4.0.jar:5.4.0]
        <snip>
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:84) ~[elasticsearch-5.4.0.jar:5.4.0]
Caused by: java.lang.IllegalStateException: Unable to access 'path.logs' (C:\persistent\logs)
        at org.elasticsearch.bootstrap.Security.addPath(Security.java:413) ~[elasticsearch-5.4.0.jar:5.4.0]
        <snip>
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:123) ~[elasticsearch-5.4.0.jar:5.4.0]
        ... 6 more
Caused by: java.nio.file.NoSuchFileException: C:\persistent\logs
        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) ~[?:1.8.0_131]
        <snip>
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:123) ~[elasticsearch-5.4.0.jar:5.4.0]
        ... 6 more

The strange thing is that the log files are created in the volume and include the exception detail. So the log file in the logs folder says the logs folder can't be accessed.

I have tried creating the logs and data folder on the host and letting Elasticsearch create them. I've tried using two different volumes, one for logs and one for data. They all result in the same error.

What do I need to do to make it so the logs and data folder are properly accessible to Elasticsearch?

回答1:

Finally found the answer here. Or at least the workaround. The Java Path.toRealPath() method doesn't translate the symlink of the volumes path properly. The workaround is to "map" the volume folder inside the container to a drive letter, and have the java program access it using the mapped drive.

VOLUME c:/data
RUN powershell Set-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices' -Name 'G:' -Value '\??\C:\data' -Type String