简介
任务需求很简单,获取所有docker容器查询指定容器是否在运行中,如果运行状态非Up,则重启该容器
使用到的docker 命令
docker ps
语法: docker ps [OPTIONS]
参数 | 说明 |
---|---|
-a | 显示所有的容器,包括未运行的。 |
-f | 根据条件过滤显示的内容。 |
- -format | 指定返回值的模板文件。
-l | 显示最近创建的容器。
-n | 列出最近创建的n个容器。
–no-trunc | 不截断输出。
-q |静默模式,只显示容器编号。
-s | 显示总的文件大小。
此教程用到了-a和- -format参数
ps参数的format可选项
列名称 | 描述 |
---|---|
.ID | 容器ID |
.Image | 镜像 ID |
.Command | 引用命令 |
.CreatedAt | 创建容器的时间 |
.RunningFor - | 自容器构建后存在的时间 |
.Ports | 暴露的端口. |
.Status | 运行状态 |
.Size | 容器磁盘大小. |
.Names | 容器名称. |
.Labels | 分配给容器的所有标签。 |
.Label | 此容器的特定标签的值 |
.Mounts | 安装在此容器中的卷的名称. |
例如只看容器名称和运行状态
docker ps -a --format "table {{.Names}}\t{{.Status}}"
docker restart
重启elk容器
docker restart elk
Java代码
封装容器属性的类
你们可以根据需求自定扩展参数
public class ContainerInfo {
/**
* 容器名称
*/
private String name;
/**
* 容器运行状态
*/
private String status;
public ContainerInfo(String name, String status) {
this.name = name;
this.status = status;
}
//此处 省略 get,set 方法.....
@Override
public String toString() {
return "ContainerInfo{" +
"name='" + name + "\'\t" +
"status='" + status + '\'' +
"}";
}
}
获取容器信息的工具类
public class DockerPsUtils {
private DockerPsUtils() {}
/**
* 此处设置只显示容器名称和运行状态,可以自定义扩展
*/
private static final String FORMAT = "\"table {{.Names}}\\t{{.Status}}\"";
public static void main(String[] args) throws Exception {
//此处检测是elk容器
checkContainerIsRuning("elk");
}
/**
* 获取容器信息
*/
private static List<ContainerInfo> getContainerInfoList() throws Exception {
List<ContainerInfo> 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<ContainerInfo> containerInfoList = getContainerInfoList();
//非空检测
if (containerInfoList.size() == 0 || containerName == null || containerName.trim().length() == 0) {
return;
}
//从Java 8 引入的一个很有趣的特性是 Optional 类,Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException)
Optional<ContainerInfo> 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);
}
}
}
测试用的elk容器默认是关闭状态下的
第一次执行效果图
第二次执行效果图
看到容器已经是重启成功了,本教程也圆满结束了。