通常我们都是采用 dos命令对 docker 进行操作,如果需要采用 Java程序来管理 docker,可以借助 docker-java。docker-java 是 Docker的 Java版本 API,下面通过样例演示其如何使用。
一、安装配置
1,服务端设置
(1)由于访问 dockerAPI需要设置一个远程访问端口,首先执行如下命令编辑服务器上的 docker.service 文件。
vi /lib/systemd/system/docker.service
(2)找到Execstart=/usr/bin/dockerd,并在后加上如下内容,然后保存退出。
-H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
(3)接着运行以下命令,重启 docker服务。
systemctl daemon-reload
service docker restart//重启启动docker
(4)执行如下命令可以查看相关内容,看看 2375是否已经设置好:
systemctl status docker
(5)最后分别执行下面两条命令配置 firewall防火墙策略:
firewall-cmd --permanent --add-port=2375/tcp
firewall-cmd --reload
2,项目配置
在 Java项目这边,编辑pom.xml文件添加 Docker开发相关的依赖即可:
com.github.docker-java
docker-java
3.0.14
javax.ws.rs
javax.ws.rs-api
2.1
org.glassfish.jersey.inject
jersey-hk2
2.26
二、基本用法
1,连接服务器、获取信息
(1)下面代码连接 docker服务器,获取相关信息并打印出来。
@RestController
public class HelloController {
@RequestMapping("/test")
public String test() {
// 连接docker服务器
DockerClient dockerClient = DockerClientBuilder
.getInstance("tcp://192.168.60.133:2375").build();
// 获取服务器信息
Info info = dockerClient.infoCmd().exec();
String infoStr = JSONObject.toJSONString(info);
System.out.println(infoStr);
return infoStr;
}
}
(2)运行结果如下:
2,查看服务器镜像
(1)获取服务器上所有的镜像:
// 获取服务器上的镜像
List images = dockerClient.listImagesCmd().exec();
for(Image image : images) {
System.out.println(image.getRepoTags()[0]);
}
(2)判断服务器上是否存在某个镜像:
// 筛选服务器上的镜像
List images = dockerClient.listImagesCmd().withImageNameFilter("busybox").exec();
if (images.isEmpty()) {
System.out.println("不存在 busybox 镜像。");
} else {
System.out.println("存在 busybox 镜像。");
}
3,搜索镜像
执行如下命令可以从镜像仓库上搜索镜像:
// 搜索镜像
List dockerSearch = dockerClient.searchImagesCmd("busybox").exec();
for(SearchItem item : dockerSearch) {
System.out.println(item.getName());
}
4,下载镜像
(1)下面代码会下载最新的 busybox镜像,同时在下载过程中会实时显示出相关信息。
dockerClient.pullImageCmd("busybox:latest").exec(new ResultCallback() {
public void onStart(Closeable closeable) {
System.out.println("开始下载!");
}
public void onNext(PullResponseItem object) {
// 实时显示出下载信息
System.out.println(object.getStatus());
}
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
public void onComplete() {
System.out.println("下载完毕!");
}
public void close() throws IOException {
}
});
(2)如果只需要单纯的下载镜像,也可以改用如下代码:
dockerClient.pullImageCmd("busybox:latest").exec(new PullImageResultCallback()).awaitSuccess();
System.out.println("下载完毕!");
5,删除镜像
下面代码将服务器上的 busybox镜像给删除。
// 删除镜像
dockerClient.removeImageCmd("busybox").exec();
System.out.println("删除完毕");
6,创建、运行容器
下面代码创建并运行一个 Apache容器,同时进行一些初始化设置:
容器命名:将运行的容器命名为 hangge_http_server
端口绑定:Apache端口是 80,将其映射到主机的 8080端口
Data Volume 实现数据持久化:/usr/local/apache2/htdocs 是Apache Server 存放静态文件的地方,我们将服务器上的/home/user/hangge/htdocs 目录 mount到容器中将其取代。
//创建容器
CreateContainerResponse container1 = dockerClient.createContainerCmd("httpd:latest")
.withName("hangge_http_server") //给容器命名
.withPortBindings(PortBinding.parse("8080:80")) //Apache端口是80,映射到主机的8080端口
.withBinds(Bind.parse("/home/user/hangge/htdocs:/usr/local/apache2/htdocs")) //目录挂载
.exec();
//运行容器
dockerClient.startContainerCmd(container1.getId()).exec();
7,进入容器执行命令
假设 container1是上面运行的 Apache容器,下面代码将进入该容器然后执行 ls命令,并将结果输出到控制台中:
// 创建命令
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container1.getId())
.withAttachStdout(true)
.withAttachStderr(true)
.withCmd("bash", "-c", "ls") //当前目录下列出所有文件
.exec();
// 执行命令
dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(
new ExecStartResultCallback(System.out, System.err));
8,获取容器
(1)下面代码获取服务器上所有运行的容器:
//获取所有运行的容器
List containers = dockerClient.listContainersCmd().exec();
for (Container container: containers){
System.out.println(container.getId() + ": " + container.getNames()[0]);
}
(2)下面代码获取服务器上所有运行结束的容器:
//获取所有运行的容器
List containers = dockerClient.listContainersCmd().withStatusFilter("exited").exec();
for (Container container: containers){
System.out.println(container.getId() + ": " + container.getNames()[0]);
}
(3)获取指定名字的容器:
//获取指定名字的容器
ListContainersCmd listContainersCmd = dockerClient.listContainersCmd();
listContainersCmd.getFilters().put("name", Arrays.asList("hangge_http_server"));
List containers = listContainersCmd.exec();
for (Container container: containers){
System.out.println(container.getId() + ": " + container.getNames()[0]);
}
9,停止、重启、暂停/恢复、删除容器
假设 container1为获取到的容器对象,执行下面命令可以对该容器信息停止、删除等操作。
// 停止容器
dockerClient.stopContainerCmd(container1.getId()).exec();
// 重启容器
dockerClient.restartContainerCmd(container1.getId()).exec();
// 暂停容器
dockerClient.pauseContainerCmd(container1.getId()).exec();
// 恢复容器
dockerClient.unpauseContainerCmd(container1.getId()).exec();
// 删除容器
dockerClient.removeContainerCmd(container1.getId()).exec();
10,自定义网络
(1)下面代码通过 bridge驱动创建一个名为java-docker-mssql 的自定义网络:
CreateNetworkResponse networkResponse = dockerClient.createNetworkCmd()
.withName("java-docker-mssql")
.withDriver("bridge").exec();
(2)下面代码在运行容器的时候使用 java-docker-mssql 这个自定义网络:
//创建容器
CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox")
.withNetworkMode("java-docker-mssql") //设置网络
.exec();
//运行容器
dockerClient.startContainerCmd(container1.getId()).exec();