Java获取所有docker容器信息并重启宕机的容器

11 篇文章 12 订阅

简介

任务需求很简单,获取所有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容器默认是关闭状态下的
第一次执行效果图
在这里插入图片描述
第二次执行效果图
在这里插入图片描述
看到容器已经是重启成功了,本教程也圆满结束了。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皓亮君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值