• 使用Docker-Java监听Docker容器的信息


    使用Docker-Java监听Docker容器的信息

    Docker作为一种轻量级的容器化平台,极大地方便了应用的部署与管理。然而,在实际使用过程中,我们常常需要对运行中的容器进行监控,以确保其健康状态,并能及时响应各种异常情况。本文将介绍如何使用Docker-Java这个库来监听Docker容器的信息。

    什么是Docker-Java?

    Docker-Java是一个开源的Java库,旨在通过Java程序与Docker守护进程进行通信。它提供了丰富的API,可以用于管理Docker容器、镜像、网络等各种资源。

    安装Docker-Java

    在开始之前,确保你已经安装了Docker,并且可以正常运行Docker命令,还需要开放23752376。然后,你需要在你的Java项目中添加Docker-Java的依赖。对于Maven项目,可以在pom.xml中添加以下依赖:

    
    <dependency>
        <groupId>com.github.docker-javagroupId>
        <artifactId>docker-java-apiartifactId>
        <version>3.3.4version>
    dependency>
    
    

    初始化Docker客户端

    首先,我们需要创建一个Docker客户端实例,用于与Docker守护进程进行通信。以下是初始化Docker客户端的示例代码:

    publi static DockerClient buildDockerClient(String dockerHost) {
            DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
                    // 这里填最上面填的ip端口号,ip换成服务器ip
                    .withDockerHost("tcp://" + dockerHost + ":" + PORT)
                    // 这里也可以用另一种配置的
                    // .withDockerHost("unix://var/run/docker.sock")
                    .build();
            /**
             * 创建一个ApacheDockerHttpClient实例,用于与Docker服务器进行通信。
             * 这里使用了Apache HTTP客户端作为HTTP通信的实现,通过配置各种参数来优化通信效果。
             *
             * @param config 提供Docker主机信息、SSL配置等必要信息的配置对象。
             * @return DockerHttpClient 一个配置好的HTTP客户端,用于与Docker服务进行通信。
             */
            DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
                    .dockerHost(config.getDockerHost())
                    .sslConfig(config.getSSLConfig())
                    .maxConnections(100)
                    .connectionTimeout(Duration.ofSeconds(30))
                    .responseTimeout(Duration.ofSeconds(45))
                    .build();
            return DockerClientImpl.getInstance(config, httpClient);
        }
    

    监听Docker事件

    Docker支持通过事件流(Event Stream)来监听容器的各种状态变化,例如启动、停止、删除等。我们可以使用Docker-Java提供的API来监听这些事件。

    以下是监听Docker容器事件的示例代码:

      /**
         * @param containerId 容器ID
         * @Description: 获取容器的基本信息
         */
        public static Map<String, String> getContainerInfo(DockerClient dockerClient, String containerId) {
            HashMap<String, String> map = new HashMap<>();
            // 获取容器信息
            InspectContainerResponse containerInfo = dockerClient.inspectContainerCmd(containerId).exec();
            // 获取容器的名称
            map.put("containerName", containerInfo.getName());
            // 获取容器的镜像名称
            String image = containerInfo.getConfig().getImage();
            map.put("dockerImage", image);
            // 获取容器的端口信息
            Ports ports = containerInfo.getNetworkSettings().getPorts();
            map.put("ports", StrUtil.join(",", ports.getBindings().keySet()));
            // 获取容器的运行状态
            String containerState = containerInfo.getState().getStatus();
            map.put("dockerState", containerState);
            // 获取容器的创建时间戳(以毫秒为单位)
            String createdTimeMillis = containerInfo.getCreated();
            map.put("created", formattedTimeZone(createdTimeMillis));
            // 获取容器的运行状态
            Boolean running = containerInfo.getState().getRunning();
            map.put("state", Boolean.TRUE.equals(running) ? "1" : "2");
            return map;
        }
    
        /**
         * 获取容器内存占用
         *
         * @param containerId 容器ID
         * @return 占用内存(MB)
         */
        public static double getMemoryStats(DockerClient dockerClient, String containerId) {
            Statistics containerStats = dockerClient.statsCmd(containerId).exec(new InvocationBuilder.AsyncResultCallback<>()).awaitResult();
            long memoryUsageInBytes = 0;
            if (containerStats != null && containerStats.getMemoryStats() != null) {
                memoryUsageInBytes = containerStats.getMemoryStats().getUsage();
            }
            // 将字节数转换为 MB
            return NumberUtil.div(memoryUsageInBytes, 1024.0 * 1024.0, 1);
        }
    
        /**
         * @param isoTimeMillis ISO8601格式的时间
         * @return {@code String } 时间
         * @Description: 格式化时间
         */
        private static String formattedTimeZone(String isoTimeMillis) {
            // 解析ISO 8601格式的字符串为Instant对象
            Instant instant = Instant.parse(isoTimeMillis);
            // 将Instant对象转换为ZonedDateTime对象(UTC时区)
            ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
            // 转换为本地时区(如果需要)
            ZonedDateTime localZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.systemDefault());
            // 定义时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            // 格式化时间
            return localZonedDateTime.format(formatter);
        }
    

    处理具体事件

    根据项目需求,我们可以进一步对不同类型的事件进行分类处理。例如,如果我们只关心容器的启动和停止事件,可以这样处理:

     /**
         * @return {@code List }
         * @Description: 获取所有容器列表
         */
        public static List<Container> getAllContainers(DockerClient dockerClient) {
            return dockerClient.listContainersCmd().exec();
        }
    
        /**
         * @param containerId 容器ID
         * @Description: 启动容器
         */
        public static void startContainer(DockerClient dockerClient, String containerId) {
            dockerClient.startContainerCmd(containerId).exec();
        }
    
        /**
         * @param containerId 容器ID
         * @Description: 停止容器
         */
        public static void stopContainer(DockerClient dockerClient, String containerId) {
            dockerClient.stopContainerCmd(containerId).exec();
        }
    
        /**
         * @param containerId 容器ID
         * @Description: 重启容器
         */
        public static void restartContainer(DockerClient dockerClient, String containerId) {
            dockerClient.restartContainerCmd(containerId).exec();
        }
    

    结论

    通过Docker-Java库,我们可以轻松地在Java应用中与Docker进行交互,并实时监听Docker容器的状态变化。这对于需要动态监控和管理容器的项目来说,非常实用。希望本文的介绍能帮助你更好地利用Docker-Java来实现容器的监控与管理。

  • 相关阅读:
    GitHub私有派生仓库(fork仓库) | 派生仓库改为私有
    关于awd赛制的学习路程·awd的理论内容
    《Java基础——方法的调用》
    Git错误:Incorrect username or password (access token)
    代码随想录算法训练营第23期day32|122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II
    CSS 平面转换 渐变
    2024年新算法-牛顿-拉夫逊优化算法(NRBO)优化BP神经网络回归预测
    alpha-beta剪枝
    计算机网络-网络安全(一)
    前端食堂技术周刊第 115 期:Rolldown 正式开源、马斯克宣布 xAI 本周将开源 Grok、如何使用 Copilot 完成 50% 的日常工作?
  • 原文地址:https://blog.csdn.net/weixin_45626288/article/details/139626394