Java 整合常用docker Api

news2024/12/30 2:22:29

整合环境:

  • 与docker 版本差异不大,基本都可以
 API version:     1.26

开放docker api ,两种方式

  • /etc/sysconfig/docker ,最后一行添加;开放端口:2375
    -H tcp://0.0.0.0:2375
  • systemctl status docker 查询 docker.service 路径
    vi /lib/systemd/system/docker.service
    -H tcp://0.0.0.0:2375
    在这里插入图片描述

重启docker

  • systemctl daemon-reload && systemctl restart docker
    开放端口:
  • irewall-cmd --zone=public --add-port=2375/tcp --permanent
    测试API:
  • GET ip:2375/images/json

Java client 对接 docker api

<dependency>
      <groupId>com.github.docker-java</groupId>
      <artifactId>docker-java</artifactId>
      <version>3.3.0</version>
 </dependency>

初始化client

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.core.DockerClientBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;

/**
 * @author xiaoshu
 * @description docker client初始化
 * @date 2023年03月19日 15:31
 */
@Slf4j
@Component
public class DockerApiConfig {

    @Resource
    private VirtualProperties virtualProperties;

    @Bean
    public DockerClient dockerClient(){
        String url=virtualProperties.getDockerUrl();
        //String url="tcp://192.168.1.250:2375";
        DockerClient dockerClient = DockerClientBuilder.getInstance(url).build();
        log.info("docker API初始化成功");
        return dockerClient;
    }

}

常用api封装

import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Image;
import com.param.ImageParam;
import com.vo.DockerBuildImageVo;
import com.vo.DockerContainerVo;
import com.vo.DockerPushVo;
import java.io.InputStream;
import java.util.List;

/**
 * java-client docker-api 相关接口
 *
 * @author heyonghao
 * @date 2023/4/12
 */
public interface DockerService {

    /**
     * 容器列表
     * @return List<Container>
     */
    List<Container> listContainer(Boolean showAll);

    /**
     * 查询容器日志信息
     * @param containerId 容器id
     * @param tail 行数
     * @return List<String>
     */
    List<String> logContainer(String containerId,Integer tail);

    /**
     * 查询容器详情,返回vo待定
     * @param containerId
     * @return
     */
    String infoContainer(String containerId);

    /**
     * 删除容器
     * @param containerId 容器id
     * @return Boolean
     */
    Boolean removeContainer(String containerId);

    /**
     * 停止容器
     * @param containerId 容器id
     * @return Boolean
     */
    Boolean stopContainer(String containerId);

    /**
     * 启动容器
     * @param containerId 容器id
     * @return Boolean
     */
    Boolean startContainer(String containerId);

    /**
     * 创建容器
     * @param dockerContainerVo dockerContainerVo
     * @return Boolean
     */
    Boolean createContainer(DockerContainerVo dockerContainerVo);

    /**
     * 镜像列表
     * @param imageParam
     * @return List<Image>
     */
    List<Image> images(ImageParam imageParam);

    /**
     * 镜像详情
     * 返回vo待封装
     * @param imageId 镜像id
     * @return Image
     */
    String imageInfo(String imageId);

    /**
     * 导入镜像文件
     * @param tarInputStream 镜像tar文件流
     * @return Boolean
     */
    Boolean importImage(InputStream tarInputStream);

    /**
     * 镜像构建vo
     * @param dockerBuildImageVo 构建参数
     * @return Boolean
     */
    Boolean buildImage(DockerBuildImageVo dockerBuildImageVo);

    /**
     * 推送本地镜像到 harbor 仓库
     * @param dockerPushVo 推送参数
     * @return Boolean
     */
    Boolean pushDockerImageToHarbor(DockerPushVo dockerPushVo);

}
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.config.VirtualProperties;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.*;
import com.github.dockerjava.api.model.*;
import com.github.dockerjava.core.command.LogContainerResultCallback;
import com.param.ImageParam;
import com.service.DockerService;
import com.vo.DockerBuildImageVo;
import com.vo.DockerContainerVo;
import com.vo.DockerPushVo;
import com.vo.LabelsOrKvVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.io.InputStream;
import java.util.*;

/**
 * xxx
 *
 * @author heyonghao
 * @date 2023/4/12
 */
@Slf4j
@Service
public class DockerServiceImpl implements DockerService {
    @Resource
    private DockerClient dockerClient;

    @Resource
    private VirtualProperties virtualProperties;

    @Override
    public List<Container> listContainer(Boolean showAll) {
        ListContainersCmd listContainersCmd = dockerClient.listContainersCmd();
        ListContainersCmd containersCmd = listContainersCmd.withShowAll(showAll);
        return containersCmd.exec();
    }

    @Override
    public List<String> logContainer(String containerId, Integer tail) {
        List<String> logs = new LinkedList<>();
        LogContainerCmd logContainerCmd = dockerClient.logContainerCmd(containerId);
        logContainerCmd.withStdOut(true).withStdErr(true);
        //显示行数
        logContainerCmd.withTail(10);
        try {
            logContainerCmd.exec(new LogContainerResultCallback() {
                @Override
                public void onNext(Frame item) {
                    logs.add(item.toString());
                }
            }).awaitCompletion();
        } catch (InterruptedException e) {
            throw new RuntimeException("Failed to retrieve logs of container " + containerId, e);
        }
        return logs;
    }

    @Override
    public String infoContainer(String containerId) {
        InspectContainerCmd inspectContainerCmd = dockerClient.inspectContainerCmd(containerId);
        InspectContainerResponse response = inspectContainerCmd.exec();
        return response.toString();
    }

    @Override
    public Boolean removeContainer(String containerId) {
        RemoveContainerCmd removeContainerCmd = dockerClient.removeContainerCmd(containerId);
        try {
            removeContainerCmd.exec();
        }catch (Exception e){
            e.printStackTrace();
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean stopContainer(String containerId) {
        StopContainerCmd stopContainerCmd = dockerClient.stopContainerCmd(containerId);
        try {
            stopContainerCmd.exec();
        }catch (Exception e){
            e.printStackTrace();
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean startContainer(String containerId) {
        StartContainerCmd startContainerCmd = dockerClient.startContainerCmd(containerId);
        try {
            startContainerCmd.exec();
        }catch (Exception e){
            e.printStackTrace();
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean createContainer(DockerContainerVo dockerContainerVo) {
        //会在服务器目录: home/dockerdata/docker/tmp ,上传打包容器文件
        String containerName = dockerContainerVo.getContainerName();
        if (StrUtil.isEmpty(containerName)){
            return Boolean.FALSE;
        }
        CreateContainerCmd containerCmd = dockerClient.createContainerCmd(containerName);
        containerCmd.withImage(dockerContainerVo.getImageName());
        containerCmd.withName(containerName);
        HostConfig hostConfig=HostConfig.newHostConfig();

        List<LabelsOrKvVo> exposePorts = dockerContainerVo.getExposePorts();
        exposePorts.forEach(e->{
            ExposedPort tcp8300 = ExposedPort.tcp(Integer.parseInt(e.getValue()));
            Ports portBindings = new Ports();
            portBindings.bind(tcp8300, Ports.Binding.bindPort(Integer.parseInt(e.getKey())));
            hostConfig.withPortBindings(portBindings);
            containerCmd.withExposedPorts(tcp8300);
        });
        List<LabelsOrKvVo> volumePaths = dockerContainerVo.getVolumePath();
        if (CollectionUtil.isEmpty(volumePaths)){
            return Boolean.FALSE;
        }
        List<Bind> binds = new LinkedList<>();
        volumePaths.forEach(e->{
            Bind bind = new Bind(e.getKey(),new Volume(e.getValue()));
            binds.add(bind);
        });
        containerCmd.withHostConfig(hostConfig);
        hostConfig.setBinds(binds.toArray(new Bind[]{}));
        try {
            containerCmd.exec();
        }catch (Exception e){
            e.printStackTrace();
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    public List<Image> images(ImageParam imageParam) {
        ListImagesCmd imagesCmd = dockerClient.listImagesCmd();
        List<LabelsOrKvVo> labelsOrKvVo = imageParam.getLabelsOrKvVo();
        if (CollectionUtil.isNotEmpty(labelsOrKvVo)){
            Map<String,String> lables = new HashMap<>(labelsOrKvVo.size());
            labelsOrKvVo.forEach(e->{
                lables.put(e.getKey(), e.getValue());
            });
            imagesCmd.withLabelFilter(lables);
        }
        if (StrUtil.isNotEmpty(imageParam.getName())){
            imagesCmd.withImageNameFilter(imageParam.getName());
        }
        ListImagesCmd all = imagesCmd.withShowAll(false);
        return all.exec();
    }

    @Override
    public String imageInfo(String imageId) {
        InspectImageCmd imageCmd = dockerClient.inspectImageCmd(imageId);
        InspectImageResponse response = imageCmd.exec();
        return response.toString();
    }

    @Override
    public Boolean importImage(InputStream tarInputStream) {
        dockerClient.loadImageCmd(tarInputStream).exec();
        return Boolean.TRUE;
    }

    @Override
    public Boolean buildImage(DockerBuildImageVo dockerBuildImageVo) {
        boolean flag =true;
        try {
            String dockerFilePath = dockerBuildImageVo.getDockerFilePath();
            if (StrUtil.isEmpty(dockerFilePath)){
                return false;
            }
            List<LabelsOrKvVo> tagsVo = dockerBuildImageVo.getTags();
            Set<String> tags = new HashSet<>();
            if (CollectionUtil.isNotEmpty(tagsVo)){
                tagsVo.forEach(e->{
                    String curTag = String.format("%s:%s", e.getKey(), e.getValue());
                    tags.add(curTag);
                });
            }
            List<LabelsOrKvVo> labelsVo = dockerBuildImageVo.getLabels();
            Map<String,String> labels = new HashMap<>(2);
            if (CollectionUtil.isNotEmpty(labelsVo)){
                //添加元数据,user-id 或者 xxx-id 与本地数据绑定起来
                labelsVo.forEach(e->{
                    labels.put(e.getKey(),e.getValue());
                });
            }
            BuildImageCmd buildImageCmd = dockerClient
                    .buildImageCmd(new File(dockerFilePath))
                    .withLabels(labels)
                    .withTags(tags);
            BuildImageResultCallback callback = new BuildImageResultCallback();
            buildImageCmd.exec(callback);
            String imageId = callback.awaitImageId();
            System.out.println("镜像创建成功,镜像id:"+imageId);
        } catch (Exception e) {
            flag=false;
            e.printStackTrace();
        }
        return flag;
    }

    @Override
    public Boolean pushDockerImageToHarbor(DockerPushVo dockerPushVo) {
        AuthConfig autoConfig = new AuthConfig().withRegistryAddress(virtualProperties.getHarborUrl())
                .withUsername(virtualProperties.getHarborUname()).withPassword(virtualProperties.getHarborPwd());
        String localImg=dockerPushVo.getImageName()+":"+dockerPushVo.getImageTag();
        String pushImg=virtualProperties.getHarborUrl()+"/"+dockerPushVo.getPushProject()+"/"+dockerPushVo.getImageName();
        dockerClient.tagImageCmd(localImg,pushImg,dockerPushVo.getPushImgVersion()).exec();
        String pushTo=virtualProperties.getHarborUrl()+"/"+dockerPushVo.getPushProject()+"/"+dockerPushVo.getImageName()+":"+dockerPushVo.getPushImgVersion();
        try {
            dockerClient.pushImageCmd(pushTo).withAuthConfig(autoConfig).start().awaitCompletion();
        } catch (InterruptedException e) {
            log.info(e.getMessage());
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
}

涉及vo

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;

/**
 * @author xiaoshu
 * @description
 * @date 2023年05月01日 15:23
 */
@Data
@ApiModel(value = "镜像构建Vo")
public class DockerBuildImageVo implements Serializable {
    private static final long serialVersionUID = -6058239843827052127L;

    @ApiModelProperty(value = "tags")
    List<LabelsOrKvVo> tags;

    @ApiModelProperty(value = "labels")
    List<LabelsOrKvVo> labels;

    @ApiModelProperty(value = "镜像文件路径;最后是 docker与镜像文件单独放一个目录")
    private String dockerFilePath;

}
@ApiModel(value = "docker 容器创建VO")
@Data
public class DockerContainerVo implements Serializable {
    private static final long serialVersionUID = 5791026160216793895L;

    @ApiModelProperty(value = "容器名称")
    private String containerName;

    @ApiModelProperty(value = "镜像名称:tag")
    private String imageName;

    @ApiModelProperty(value = "暴露端口 容器端口 :内部端口")
    private List<LabelsOrKvVo> exposePorts;

    @ApiModelProperty(value = "挂载路径  主机路径 :容器路径")
    private List<LabelsOrKvVo> volumePath;
}
@ApiModel(value = "k-v Vo")
@Data
public class LabelsOrKvVo implements Serializable {

    @ApiModelProperty(value = "标签key")
    private String key;
    @ApiModelProperty(value = "标签value")
    private String value;

}
@ApiModel(value = "docker 镜像推送VO")
@Data
public class DockerPushVo implements Serializable {

    @ApiModelProperty(value = "原镜像名称")
    private String imageName;

    @ApiModelProperty(value = "原镜像tag")
    private String imageTag;

    @ApiModelProperty(value = "推送项目名称")
    private String pushProject;

    @ApiModelProperty(value = "推送后镜像版本号")
    private String pushImgVersion;

}

yml 配置

virtual:
  docker-url: tcp://192.168.2.207:8088
  k8s-url: https://192.168.2.207:6443
  k8s-token: xxx
  server-url: 192.168.2.207
  server-name: root
  server-pwd: 123456
  harbor-url: core.harbor.domain
  harbor-uname: admin
  harbor-pwd: Harbor12345
@Data
@ConfigurationProperties(prefix = "virtual")
@Configuration
public class VirtualProperties {

    /**
     * docker服务地址
     */
    private String dockerUrl;
    /**
     * k8s服务地址
     */
    private String k8sUrl;
    /**
     * k8s服务token
     */
    private String k8sToken;
    /**
     * 服务器地址
     */
    private String serverUrl;
    /**
     * 服务器账号
     */
    private String serverName;
    /**
     * 服务器账号密码
     */
    private String serverPwd;
    /**
     * harbor私有仓库地址
     */
    private String harborUrl;
    /**
     * harbor 账号
     */
    private String harborUname;
    /**
     * harbor 密码
     */
    private String harborPwd;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/480848.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vsftpd.conf参数配置

文章目录 初始vsftdp.conf翻译后需修改参数write_enableYES&#xff08;启用任何形式的FTP写入命令&#xff09;userlist_file/etc/vsftpd.user_list、userlist_enableYES、userlist_denyNOlocal_umask022&#xff08;放开权限&#xff09;chroot_local_userYES&#xff08;限定…

每日学术速递4.29

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.LG 1.A Cookbook of Self-Supervised Learning 标题&#xff1a;自监督学习食谱 作者&#xff1a;Randall Balestriero, Mark Ibrahim, Vlad Sobal, Ari Morcos, Shashank Shekhar, Tom…

学知识变现,看完这些就够了

点击查看【18本知识变现电子书】 100个实用知识点 60万字知识变现精华 资深知识变现教练海哥扛鼎之作 2000多位学员实战经验干货总结 从理论到实践&#xff0c;从思维到实操 教你彻底学透如何知识变财富 .......... 全网最全知识变现知识付费电子教程 资深知识变现教练海…

Linux线程相关函数:线程的创建、属性、回收、退出、取消

1. 线程号 进程号在系统中唯一&#xff0c;但线程号只在其所属进程环境中有效。 &#xff08;1&#xff09;pthread_self函数 #include<pthread.h>pthread_t pthread_self(void); /* 功能&#xff1a;获取线程号 返回值&#xff1a;调用此函数线程的ID */ pthread_se…

【Unity-UGUI控件全面解析】| Panel 容器组件详解

🎬【Unity-UGUI控件全面解析】| Panel 容器组件详解一、组件介绍二、组件属性面板三、代码操作组件💯总结🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉 🎄 学习专栏推荐:Unity系统学习专栏 🌲 游戏制作专栏推荐:游…

2007-2020年上市公司数字经济化指标含原始数据和计算代码(do文档)

2007-2020年上市公司数字经济化指标含原始数据和计算代码&#xff08;do文档&#xff09; 1、时间&#xff1a;2007-2020 2、范围&#xff1a;A股上市公司剔除jin rong行业 3、数据说明&#xff1a;包含计算过程和原始数据 4、参考文献&#xff1a;祁怀锦,数字经济对公司治…

利用C#实现动态替换桌面快捷方式对应的应用程序

公司有一个特殊的业务可能会用到这个&#xff0c;至于什么业务就不展开了。本文的内容作为备用方案。 实现思路&#xff1a; 1 获取当前exe程序运行的全路径 2 获取桌面的所有快捷方式 3 遍历快捷方式&#xff0c;获取快捷键方式对应程序的运行路径&#xff0c;并与当前…

【开发工具】 今天我要教会你安装Office 2021 RTM 专业增强零售版 你开不开心

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

统一请求封装和pytest入门使用

统一请求封装解决的问题 解决多个py文件共享session的问题 统计请求的数据 统一异常处理 统一日志监控 封装 在项目文件中创建一个common文件夹&#xff0c; 用来进行统一接口封装 import requestsclass RequestUtil:# 调用底层的requests.session()方法进行封装sess r…

超详细的R语言svykm函数绘制复杂抽样设计数据cox回归生存曲线(Kaplan-Meier)

我们在既往的文章《R语言绘制复杂抽样设计数据cox回归生存曲线(Kaplan-Meier)》中介绍了怎么使用jskm包的svykm函数绘制复杂抽样设计数据cox回归生存曲线(Kaplan-Meier)&#xff0c;但是有粉丝觉得讲得不够详细&#xff0c;希望讲得详细一点&#xff0c;今天我们继续来介绍一下…

flinkCDC在Delta.io中是什么 是CDF

类似flink CDC databricks 官方文档: How to Simplify CDC With Delta Lakes Change Data Feed - The Databricks Blog delta.io 官方文档: Change data feed — Delta Lake Documentation 概述 更改数据馈送 (CDF) 功能允许 Delta 表跟踪 Delta 表版本之间的行级更改 在…

vue+element-plus角色权限管理分配

这里的图片是截图这个老师的项目 在src/uitls/permission.js加入以下内容 本段代码讲解: 参数一:后台传来的路由 参数二:前端所有的路由 先遍历前端所有路由,在里面继续遍历后台路由,通过二者某一个关键字的是否相同判断用户是否有权限(这里老师使用的是title关键字),关键字相…

21安徽练习

题目分为4部分 APK 集群 流量 exe 我尽量都做一下&#xff0c;逆向不是很会&#xff0c;就当提升自己。 [填空题]请获取app安装包的SHA256校验值&#xff08;格式&#xff1a;不区分大小写&#xff09;&#xff08;10分&#xff09; e15095d49efdccb0ca9b2ee125e4d8136cac5…

树莓派Pico W无线开发板MQTT协议通信MicroPython编程实践

本博文介绍采用ThonnyMicroPython和umqtt.simple库MQTTClient类的对象方法编制树莓派Pico W无线开发板MQTT协议通信程序&#xff0c;将Pico W无线开发板、电脑或Android手机无线连接到远程MQTT服务器&#xff0c;给出采用电脑MQTTX应用程序及手机Android MQTT客户端App远程控制…

用python的QT做界面

文章目录 入口文件界面参数调整数据从dat解析出来的文件从界面点击打开文件夹的功能实现主要功能代码网络参数存图替换功能&#xff0c;比如把倒频谱替换成倒频谱2 入口文件 入口文件&#xff0c;主要用来实例化窗口&#xff08;不重要&#xff09;&#xff0c;只要知道从这里…

每日学术速递4.30

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Masked Frequency Modeling for Self-Supervised Visual Pre-Training(ICLR 2023) 标题&#xff1a;用于自监督视觉预训练的掩蔽频率建模 作者&#xff1a;Jiahao Xie, Wei Li, Xi…

SwiftUI 设计和调试复杂界面的基本技巧示例

功能需求 对于比较复杂的 SwiftUI 界面,我们需要在充分了解 SwiftUI 各个视图基本特性的同时,合理利用 Xcode 强大的预览(Preview)机制,实时且全面的测试所有场景下的显示情况。 如上图所示:我们在 App 支持的每种语言环境中都对界面进行了全面的测试,并解决了 Cell 里…

使用Lambda表达式mutable有感

使用Lambda表达式mutable有感 在学Qt的时候&#xff0c;我看着mutable陷入了沉思&#xff0c;总觉得它和C中的某个特性很像&#xff1f;没错&#xff0c;就是 深拷贝 如果你忘记了深拷贝和浅拷贝是什么&#xff0c;那跟着我来一起回忆一下吧。首先来看深拷贝与浅拷贝的概念 浅…

从零开始学习Linux运维,成为IT领域翘楚(四)

文章目录 &#x1f525;Linux路径&#x1f525;Linux处理文件目录的常用命令&#x1f525;Linux文件编辑工具vi/vim&#x1f525;Linux文件内容查看命令 &#x1f525;Linux路径 路径&#xff0c;顾名思议&#xff0c;是指从树形目录中的某个目录层次到某个文件的一条道路。 Li…

设计模式-工厂、装饰模式

一. 设计模式-工厂模式 package com.factory.pattern;/**目标&#xff1a;工厂模式。什么是工厂设计模式&#xff1f;工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的方…