开发OJ系统也好多天了,主要是前面几天都没啥时间,今天打算开发完代码沙箱功能。使用Docker沙箱时遇到的坑还是比较多的。下面一个一个讲。
Docker代码沙箱的作用就是在程序执行时隔离程序,防止其污染到外部环境,执行恶意代码什么的。
一般程序都要经过编译、执行过程。鱼皮在这里实现了Java原生沙箱和Docker沙箱两种。但是我不推荐Java沙箱,因为安全性无法保证是第一;第二服务器Java环境复杂,一般可能会使用Java 11、Java17等,而不同版本的代码执行效果肯定也不一样,服务器不能说因为我这一个OJ系统需要JDK8而只用JDK8,肯定是不行的。于是推荐使用Docker沙箱。不过他这里实现两种沙箱也只是单纯为了在面试时有东西可讲,实际应用肯定不行。
由上面的JDK版本问题就引出了我遇到的第一个坑,就是因为之前都是把代码在创建容器之前执行,而我服务器JDK是11,Docker是JDK8导致编译文件无法执行。
java// 3.5 编译文件
ExecCreateCmdResponse compileFileResponse = dockerClient.execCreateCmd(containerId)
.withCmd("javac", "-encoding", "utf-8", "/app/Main.java")
.withAttachStderr(true)
.withAttachStdin(true)
.withAttachStdout(true)
.exec();
第二是鱼皮的代码没有删除容器,导致执行代码后一堆容器,有点麻烦。
想过复用容器,想想没啥必要,直接删除就好了。
就像这样。
java// 5. 文件清理,删除容器
dockerClient.stopContainerCmd(containerId).exec();
dockerClient.removeContainerCmd(containerId).exec();
在Ubuntu中使用Docker是要root权限的,我发现这个Java Docker不太好使用sudo,因此我还开启了我Ubuntu虚拟机的root用户ssh远程连接(默认是不支持的)。
这样才能执行代码
本文作者:peepdd864
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!