Java获取docker容器状态
最近接到一个小需求,就是通过java应用程序获取服务器上docker容器的运行状态,所以就再网上搜了搜,发现实现此方式大体有2种思路。
1、通过连入系统(ssh),执行docker ps 等命令,然后根据命令返回的字符串结果,解析出其中的状态信息。此方法的特点就是:非常暴力,如果连接其他主机,需要知晓用户名和密码。
附上相关代码DockerPsService类:
package com.collection.dockerdemo.service;
import com.collection.dockerdemo.bean.ContainerInfo;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* 通过本地执行cmd命令获取docker的一些状态参数
*/
public class DockerPsService {
private DockerPsService() {}
/**
* 此处设置只显示容器名称和运行状态,可以自定义扩展
*/
private static final String FORMAT = "\"table {{.Names}}\\t{{.Status}}\"";
/**
* 获取容器信息
*/
public static List getContainerInfoList() throws Exception {
List containerInfoList = new ArrayList();
//执行shell命令获取容器信息
Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "docker ps -a --format " + FORMAT}, null, null);
InputStreamReader ir = new InputStreamReader(process.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
String line;
process.waitFor();
System.out.println("********************linux 收集docker容器启动状态 开始*****************************");
int rowIndex = 0;
while ((line = input.readLine()) != null) {
System.out.println(line);
//表格头部信息不需要获取
if (rowIndex != 0) {
//把连续的空格转成1个空格
line = line.replaceAll(" + ", " ");
String arr[] = line.split(" ");
containerInfoList.add(new ContainerInfo(arr[0], arr[1]));
}
rowIndex++;
}
System.out.println("********************linux 收集docker容器启动状态 结束*****************************");
System.out.println("*************************打印容器名称和状态***************************************");
containerInfoList.forEach(item -> System.out.println(item.toString()));
return containerInfoList;
}
/**
* 检测容器是否启动
* 如果未启动,执行重启命令
*/
public static void checkContainerIsRuning(String containerName) throws Exception {
List containerInfoList = getContainerInfoList();
//非空检测
if (containerInfoList.size() == 0 || containerName == null || containerName.trim().length() == 0) {
return;
}
//从Java 8 引入的一个很有趣的特性是 Optional 类,Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException)
Optional containerInfoOptiona = containerInfoList.stream().filter(containerInfo -> containerName.equals(containerInfo.getName())).findFirst();
//如果容器存在
if (containerInfoOptiona.isPresent()) {
ContainerInfo containerInfo = containerInfoOptiona.get();
//Up 状态标识运行中
if ("Up".equals(containerInfo.getStatus())) {
System.out.printf("容器:{%s} 心跳检测正常......", containerName);
return;
}
System.err.printf("容器:{%s} 运行状态为:{%s},正在准备重启....\n", containerName, containerInfo.getStatus());
//docker命令去掉-a 只看运行中的容器
Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "docker restart " + containerName}, null, null);
InputStreamReader ir = new InputStreamReader(process.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
process.waitFor();
String line;
//输出执行docker restart命令的返回结果
while ((line = input.readLine()) != null) {
System.out.println(line);
}
} else {
System.err.printf("容器:{%s}不存在!", containerName);
}
}
}
2、通过docker-java api调取docker提供的统一接口获取容器相关状态。此方法的特点就是:需要开启docker对应端口,测试前务必测试下docker 2375端口时候开启,接口是否能够打开,一般都需要手动开启(踩坑了的地方)。
附上相关代码DockerJavaService :
package com.collection.dockerdemo.service;
import com.collection.dockerdemo.bean.ContainerStatisticsInfo;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.Statistics;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.InvocationBuilder;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@Service
public class DockerJavaService {
//注意,务必开启docker的2375监听,否则无法连接
private final String localDockerHost = SystemUtils.IS_OS_WINDOWS ? "tcp://203.86.235.53:2375" : "unix:///var/run/docker.sock";
private DockerClient dockerClient = null;
@PostConstruct
public void connectDocker() {
dockerClient = DockerClientBuilder.getInstance(localDockerHost).build();
System.out.println("dockerClient:>>>>>>>>>>>>>"+dockerClient);
}
// docker run ...
public String createContainer(String imageName, String containerName, HostConfig hostConfig, List cmd){
CreateContainerResponse container = dockerClient.createContainerCmd(imageName)
.withName(containerName)
.withHostConfig(hostConfig)
.withCmd(cmd)
.exec();
return container.getId();
}
public void startContainer(String containerId) {
dockerClient.startContainerCmd(containerId).exec();
}
// docker stop containerId
public void stopContainer(String containerId) {
dockerClient.stopContainerCmd(containerId).exec();
}
//docker rm containerId
public void removeContainer(String containerId) {
dockerClient.removeContainerCmd(containerId).exec();
}
//docker inspect containerId
public InspectContainerResponse.ContainerState inspectContainerStatus(String containerId) {
InspectContainerResponse response = dockerClient.inspectContainerCmd(containerId).exec();
return response.getState();
}
// docker stats --no-stream containerId
//ContainerStatisticsInfo.java 中只有两个属性Statistics statistics 和 boolean ok
public ContainerStatisticsInfo containerState(String containerId) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
ContainerStatisticsInfo statistics = new ContainerStatisticsInfo();
InvocationBuilder.AsyncResultCallback callback = new InvocationBuilder.AsyncResultCallback(){
@Override
public void onNext(Statistics object) {
try {
statistics.setStatistics(object);
statistics.setOk(true);
} finally {
countDownLatch.countDown();
}
}
};
dockerClient.statsCmd(containerId).withNoStream(true).exec(callback);
countDownLatch.await(5000, TimeUnit.MILLISECONDS);
return statistics;
}
}
以上代码均经过实际测试,可以当作工具类或者service直接调用或改造,希望可能帮助到有需要的朋友!
1.本站所有资源收集于互联网,仅用于学习和研究,若用于违法,与本站无关,仅限学习交流请勿用于商业用途。
2.会员在本站下载的VIP素材后,只拥有使用权,著作权归原作者及49vps所有。
3.VIP素材,未经合法授权,会员不得以任何形式发布、传播、复制、转售该素材,否则一律封号处理。
4.如果素材损害你的权益,请联系客服删除。
49资源网 » Java获取docker容器状态
49资源网 » Java获取docker容器状态