docker-java实现镜像管理的基本操作

目录

前言

1. 新建项目引入依赖

2.新建工具类

3.新建测试类JavaClientDemo

(1)静态代码块获取docekrClient 

(2)静态代码块获取docekrClient 

(3) 打印镜像列表

(4) 从本地导入镜像

(5) 给镜像打上要推送的到的harbor仓库的标签

(6) 通过Dockerfile构建镜像并打标签

(7)  将镜像推送到Harbor仓库上

(8) 完整代码

结语


前言

本篇旨在通过最基础的代码实现简单的docker镜像获取、构建加载及将镜像推送到harbor仓库等基础操作。前提已经安装好了docker和harbor。

1. 新建项目引入依赖

 

        <dependency>
            <groupId>com.github.docker-java</groupId>
            <artifactId>docker-java</artifactId>
            <version>3.2.8</version>
        </dependency>
        <dependency>
            <groupId>com.github.docker-java</groupId>
            <artifactId>docker-java-transport-httpclient5</artifactId>
            <version>3.2.8</version>
        </dependency>

本文引入docker-java的依赖。

2.新建工具类

新建client连接等操作的工具类DockerUtils 和 用来解压的工具类UnCompress

package com.workhard.utils;

import com.alibaba.fastjson.JSON;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.command.BuildImageCmd;
import com.github.dockerjava.api.command.BuildImageResultCallback;
import com.github.dockerjava.api.command.LoadImageCmd;
import com.github.dockerjava.api.command.TagImageCmd;
import com.github.dockerjava.api.model.*;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;
import java.util.List;

public class DockerUtils {
    private final static Logger logger = LoggerFactory.getLogger(DockerUtils.class);

    // docker服务端IP地址
    public static final String DOCKER_HOST="tcp://192.168.79.131:4243";
    // docker安全证书配置路径
    public static final String DCOEKR_CERT_PATH="";
    // docker是否需要TLS认证
    public static final Boolean DOCKER_TLS_VERIFY=false;
    // Harbor仓库的IP
    public static final String REGISTRY_URL="192.168.79.131:8443";
    // Harbor仓库的名称
    public static final String REGISTRY_PROJECT_NAME="test";
    // Harbor仓库的登录用户名
    public static final String REGISTRY_USER_NAME="admin";
    // Harbor仓库的登录密码
    public static final String REGISTRY_PASSWORD="Harbor12345";
    // docker远程仓库的类型,此处默认是harbor
    public static final String REGISTRY_TYPE="harbor";

    public static final String REGISTRY_PROTOCAL="https://";


    /**
     * 构建DocekrClient实例
     * @param dockerHost
     * @param tlsVerify
     * @param dockerCertPath
     * @param registryUsername
     * @param registryPassword
     * @param registryUrl
     * @return
     */
    public static DockerClient getDocekrClient(String dockerHost,boolean tlsVerify,String dockerCertPath,
                                                String registryUsername, String registryPassword,String registryUrl){
        DefaultDockerClientConfig dockerClientConfig = null;
        if(tlsVerify){
            dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
                    .withDockerHost(DOCKER_HOST)
                    .withDockerTlsVerify(true)
                    .withDockerCertPath(DCOEKR_CERT_PATH)
                    .withRegistryUsername(REGISTRY_USER_NAME)
                    .withRegistryPassword(REGISTRY_PASSWORD)
                    .withRegistryUrl(registryUrl)
                    .build();
        }else {
            dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
                    .withDockerHost(DOCKER_HOST)
                    .withDockerTlsVerify(false)
                    .withDockerCertPath(DCOEKR_CERT_PATH)
                    .withRegistryUsername(REGISTRY_USER_NAME)
                    .withRegistryPassword(REGISTRY_PASSWORD)
                    .withRegistryUrl(registryUrl)
                    .build();
        }
        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
                .dockerHost(dockerClientConfig.getDockerHost())
                .sslConfig(dockerClientConfig.getSSLConfig())
                .build();

        return DockerClientImpl.getInstance(dockerClientConfig,httpClient);
    }

    public static DockerClient getDockerClient(){
        return getDocekrClient(DOCKER_HOST,DOCKER_TLS_VERIFY,DCOEKR_CERT_PATH,REGISTRY_USER_NAME,REGISTRY_PASSWORD,REGISTRY_URL);
    }

    /**
     * 获取docker基础信息
     * @param dockerClient
     * @return
     */
    public static String getDockerInfo(DockerClient dockerClient){
        Info info = dockerClient.infoCmd().exec();
        return JSON.toJSONString(info);
    }

    /**
     * 给镜像打标签
     * @param dockerClient
     * @param imageIdOrFullName
     * @param respository
     * @param tag
     */
    public static void tagImage(DockerClient dockerClient, String imageIdOrFullName, String respository,String tag){
        TagImageCmd tagImageCmd = dockerClient.tagImageCmd(imageIdOrFullName, respository, tag);
        tagImageCmd.exec();
    }

    /**
     * load镜像
     * @param dockerClient
     * @param inputStream
     */
    public static void loadImage(DockerClient dockerClient, InputStream inputStream){
        LoadImageCmd loadImageCmd = dockerClient.loadImageCmd(inputStream);
        loadImageCmd.exec();
    }

    /**
     * 推送镜像
     * @param dockerClient
     * @param imageName
     * @return
     * @throws InterruptedException
     */
    public static Boolean pushImage(DockerClient dockerClient,String imageName) throws InterruptedException {
        final Boolean[] result = {true};
        ResultCallback.Adapter<PushResponseItem> callBack = new ResultCallback.Adapter<PushResponseItem>() {
            @Override
            public void onNext(PushResponseItem pushResponseItem) {
                if (pushResponseItem != null){
                    ResponseItem.ErrorDetail errorDetail = pushResponseItem.getErrorDetail();
                    if (errorDetail!= null){
                        result[0] = false;
                        logger.error(errorDetail.getMessage(),errorDetail);
                    }
                }
                super.onNext(pushResponseItem);
            }
        };
        dockerClient.pushImageCmd(imageName).exec(callBack).awaitCompletion();
        return result[0];
    }

    /**
     * 从镜像的tar文件中获取镜像名称
     * @param imagePath
     * @return
     */
    public static String getImageName(String imagePath){
        try {
            return UnCompress.getImageName(imagePath);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 通过dockerFile构建镜像
     * @param dockerClient
     * @param dockerFile
     * @return
     */
    public static String buildImage(DockerClient dockerClient, File dockerFile){
        BuildImageCmd buildImageCmd = dockerClient.buildImageCmd(dockerFile);
        BuildImageResultCallback buildImageResultCallback = new BuildImageResultCallback() {
            @Override
            public void onNext(BuildResponseItem item) {
                logger.info("{}", item);
                super.onNext(item);
            }
        };

        return buildImageCmd.exec(buildImageResultCallback).awaitImageId();
//        logger.info(imageId);
    }

    /**
     * 获取镜像列表
     * @param dockerClient
     * @return
     */
    public static List<Image> imageList(DockerClient dockerClient){
        List<Image> imageList = dockerClient.listImagesCmd().withShowAll(true).exec();
        return imageList;
    }
}

docker的所有基础操作通过工具类去实现,其中DOCKER_HOST 和 REGISTRY_URL 在实际生产中是不一样的,即docker_host所在的docker一般是在应用服务器上,而Harbor作为镜像仓库一般是单独独立的。

package com.workhard.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 解压缩
 * @author Administrator
 *
 */
public class UnCompress {
    private static final String BASE_DIR = "";

    // 符号"/"用来作为目录标识判断符
    private static final String PATH = File.separator;
    private static final int BUFFER = 1024;
    private static final String EXT = ".tar";
    /**
     * 归档
     *
     * @param srcPath
     * @param destPath
     * @throws Exception
     */
    public static void archive(String srcPath, String destPath)
            throws Exception {

        File srcFile = new File(srcPath);

        archive(srcFile, destPath);

    }

    /**
     * 归档
     *
     * @param srcFile
     *            源路径
     * @param destFile
     *            目标路径
     * @throws Exception
     */
    public static void archive(File srcFile, File destFile) throws Exception {

        TarArchiveOutputStream taos = new TarArchiveOutputStream(
                new FileOutputStream(destFile));

        archive(srcFile, taos, BASE_DIR);

        taos.flush();
        taos.close();
    }

    /**
     * 归档
     *
     * @param srcFile
     * @throws Exception
     */
    public static void archive(File srcFile) throws Exception {
        String name = srcFile.getName();
        String basePath = srcFile.getParent();
        String destPath = basePath+File.separator + name + EXT;
        archive(srcFile, destPath);
    }

    /**
     * 归档文件
     *
     * @param srcFile
     * @param destPath
     * @throws Exception
     */
    public static void archive(File srcFile, String destPath) throws Exception {
        archive(srcFile, new File(destPath));
    }

    /**
     * 归档
     *
     * @param srcPath
     * @throws Exception
     */
    public static void archive(String srcPath) throws Exception {
        File srcFile = new File(srcPath);

        archive(srcFile);
    }

    /**
     * 归档
     *
     * @param srcFile
     *            源路径
     * @param taos
     *            TarArchiveOutputStream
     * @param basePath
     *            归档包内相对路径
     * @throws Exception
     */
    private static void archive(File srcFile, TarArchiveOutputStream taos,
                                String basePath) throws Exception {
        if (srcFile.isDirectory()) {
            archiveDir(srcFile, taos, basePath);
        } else {
            archiveFile(srcFile, taos, basePath);
        }
    }

    /**
     * 目录归档
     *
     * @param dir
     * @param taos
     *            TarArchiveOutputStream
     * @param basePath
     * @throws Exception
     */
    private static void archiveDir(File dir, TarArchiveOutputStream taos,
                                   String basePath) throws Exception {

        File[] files = dir.listFiles();

        if (files.length < 1) {
            TarArchiveEntry entry = new TarArchiveEntry(basePath
                    + dir.getName() + PATH);

            taos.putArchiveEntry(entry);
            taos.closeArchiveEntry();
        }

        for (File file : files) {

            // 递归归档
            archive(file, taos, basePath + dir.getName() + PATH);

        }
    }

    /**
     * 归档内文件名定义
     *
     * <pre>
     * 如果有多级目录,那么这里就需要给出包含目录的文件名
     * 如果用WinRAR打开归档包,中文名将显示为乱码
     * </pre>
     */
    private static void archiveFile(File file, TarArchiveOutputStream taos, String dir) throws Exception {
        TarArchiveEntry entry = new TarArchiveEntry(dir + file.getName());
        //如果打包不需要文件夹,就用 new TarArchiveEntry(file.getName())
        entry.setSize(file.length());
        taos.putArchiveEntry(entry);
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                file));
        int count;
        byte data[] = new byte[BUFFER];
        while ((count = bis.read(data, 0, BUFFER)) != -1) {
            taos.write(data, 0, count);
        }

        bis.close();
        taos.closeArchiveEntry();
    }

    /**
     * 解归档
     *
     * @param srcFile
     * @throws Exception
     */
    public static void dearchive(File srcFile) throws Exception {
        String basePath = srcFile.getParent();
        dearchive(srcFile, basePath);
    }

    /**
     * 解归档
     *
     * @param srcFile
     * @param destFile
     * @throws Exception
     */
    public static void dearchive(File srcFile, File destFile) throws Exception {
        TarArchiveInputStream tais = new TarArchiveInputStream(
                new FileInputStream(srcFile));
        dearchive(destFile, tais);
        tais.close();

    }

    /**
     * 解归档
     *
     * @param srcFile
     * @param destPath
     * @throws Exception
     */
    public static void dearchive(File srcFile, String destPath) throws Exception {
        dearchive(srcFile, new File(destPath));
    }

    /**
     * 文件 解归档
     *
     * @param destFile
     *            目标文件
     * @param tais
     *            ZipInputStream
     * @throws Exception
     */
    private static void dearchive(File destFile, TarArchiveInputStream tais) throws Exception {
        TarArchiveEntry entry = null;
        while ((entry = tais.getNextTarEntry()) != null) {
            // 文件
            String dir = destFile.getPath() + File.separator + entry.getName();
            File dirFile = new File(dir);
            // 文件检查
            fileProber(dirFile);
            if (entry.isDirectory()) {
                dirFile.mkdirs();
            } else {
                dearchiveFile(dirFile, tais);
            }
        }
    }

    /**
     * 文件 解归档
     *
     * @param srcPath
     *            源文件路径
     *
     * @throws Exception
     */
    public static void dearchive(String srcPath) throws Exception {
        File srcFile = new File(srcPath);
        dearchive(srcFile);
    }

    /**
     * 文件 解归档
     *
     * @param srcPath
     *            源文件路径
     * @param destPath
     *            目标文件路径
     * @throws Exception
     */
    public static void dearchive(String srcPath, String destPath) throws Exception {
        File srcFile = new File(srcPath);
        dearchive(srcFile, destPath);
    }

    /**
     * 文件解归档
     *
     * @param destFile
     *            目标文件
     * @param tais
     *            TarArchiveInputStream
     * @throws Exception
     */
    private static void dearchiveFile(File destFile, TarArchiveInputStream tais)
            throws Exception {

        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(destFile));

        int count;
        byte data[] = new byte[BUFFER];
        while ((count = tais.read(data, 0, BUFFER)) != -1) {
            bos.write(data, 0, count);
        }

        bos.close();
    }

    /**
     * 文件探针
     *
     * <pre>
     * 当父目录不存在时,创建目录!
     * </pre>
     *
     * @param dirFile
     */
    private static void fileProber(File dirFile) {

        File parentFile = dirFile.getParentFile();
        if (!parentFile.exists()) {

            // 递归寻找上级目录
            fileProber(parentFile);

            parentFile.mkdir();
        }

    }

    public static String getImageName(String tempFilePath) throws Exception{
//        System.out.println("tempFilePath = " + tempFilePath);
        String dirPath = tempFilePath.substring(0, tempFilePath.lastIndexOf("."));
        File dirFile = new File(dirPath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        UnCompress.dearchive(tempFilePath, dirPath);
        if (!dirPath.endsWith(File.separator)) {
            dirPath += File.separator;
        }
        //目标文件
        String destFilePath = dirPath + "manifest.json";
        File destFile = new File(destFilePath);
        if (!destFile.exists()) {
            return null;
        }
        StringBuilder sb = new StringBuilder("");
        InputStream io = new FileInputStream(new File(destFilePath));
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = io.read(bytes)) > 0) {
            sb.append(new String(bytes, 0, len));
        }
        String content = sb.toString();
        //只取第一个配置项
        List<JSONObject> jsonList = (List<JSONObject>) JSONArray.parse(content);
        System.out.println("jsonList = " + jsonList);
        return ((List<String>)jsonList.get(0).get("RepoTags")).get(0);
        /*if (content.startsWith("[")) {
            content = content.substring(1, content.length() - 2);
        }
        System.out.println("content = " + content);
        JSONObject json = JSONObject.parseObject(content.toString());
        List<String> list = (List<String>) json.get("RepoTags");
        System.out.println("list = " + list);
        return list.get(0);*/
    }


}


解压tar的工具类。

3.新建测试类JavaClientDemo

(1)静态代码块获取docekrClient 

    private static final DockerClient docekrClient;

    static {
        docekrClient = DockerUtils.getDocekrClient(DockerUtils.DOCKER_HOST, DockerUtils.DOCKER_TLS_VERIFY,
                DockerUtils.DCOEKR_CERT_PATH, DockerUtils.REGISTRY_USER_NAME, DockerUtils.REGISTRY_PASSWORD,
                DockerUtils.REGISTRY_URL);
    }

(2)静态代码块获取docekrClient 

    /**
     * 获取当前镜像客户端的信息
     */
    public static void getDockerInfo() {
        String dockerInfo = DockerUtils.getDockerInfo(docekrClient);
        System.out.println("dockerInfo:" + dockerInfo);
    }
dockerInfo:{"architecture":"x86_64","bridgeNfIp6tables":true,"bridgeNfIptables":true,"clusterAdvertise":"","clusterStore":"","containers":11,"containersPaused":0,"containersRunning":10,"containersStopped":1,"cpuCfsPeriod":true,"cpuCfsQuota":true,"cpuSet":true,"cpuShares":true,"debug":false,"dockerRootDir":"/var/lib/docker","driver":"overlay2","driverStatuses":[["Backing Filesystem","xfs"],["Supports d_type","true"],["Native Overlay Diff","true"]],"experimentalBuild":false,"httpProxy":"","httpsProxy":"","iPv4Forwarding":true,"id":"DSRC:IPNT:GFY4:ZVC7:RQC3:W6BG:SHFT:AHHN:RKEN:F57O:I2YI:ETTV","images":32,"indexServerAddress":"https://index.docker.io/v1/","isolation":"","kernelVersion":"3.10.0-1160.el7.x86_64","labels":[],"loggingDriver":"json-file","memTotal":8181829632,"memoryLimit":true,"nCPU":8,"nEventsListener":0,"nFd":95,"nGoroutines":113,"name":"localhost.localdomain","noProxy":"","oomKillDisable":true,"operatingSystem":"CentOS Linux 7 (Core)","osType":"linux","plugins":{"Volume":["local"],"Network":["bridge","host","ipvlan","macvlan","null","overlay"],"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","local","logentries","splunk","syslog"]},"registryConfig":{"indexConfigs":{"docker.io":{"mirrors":["https://67fc11vv.mirror.aliyuncs.com/"],"name":"docker.io","official":true,"secure":true}},"insecureRegistryCIDRs":["127.0.0.0/8"],"mirrors":["https://67fc11vv.mirror.aliyuncs.com/"]},"securityOptions":["name=seccomp,profile=default"],"serverVersion":"19.03.6","swapLimit":true,"swarm":{"controlAvailable":false,"error":"","localNodeState":"INACTIVE","nodeAddr":"","nodeID":""},"systemTime":"2022-08-29T22:51:06.871489546+08:00"}

(3) 打印镜像列表

    /**
     * 输出当前docker下的所有的镜像
     */
    public static void getImageList() {
        List<Image> imageList = DockerUtils.imageList(docekrClient);
        for (Image image : imageList) {
            String toString = Arrays.stream(image.getRepoTags()).collect(Collectors.toList()).toString();
            System.out.println("imageRepoTags:" + toString + " ===> mageId:{}" + image.getId());
        }
    }

输出:

imageRepoTags:[hello-build:test2] ===> mageId:sha256:8c20ddb133379b4a73b2a7481fe7a4ed63de8dea3e4ec877aa2aa417775a4ed2
imageRepoTags:[<none>:<none>] ===> mageId:sha256:5c30ffc469d3c6a8db6ad9905802fd8ab3572659ba3dfbb248a993cc73e6d37a
imageRepoTags:[<none>:<none>] ===> mageId:sha256:4c73e947b1e69af2a93b094dfae2b14b7874cf8029de6cb28e70b1c5a6b36751
imageRepoTags:[springboot-helloworld:latest] ===> mageId:sha256:7b2e5a76242b5dadda62339c3777e89d1a9d54a870295e8628c48a5a8149eb85
imageRepoTags:[<none>:<none>] ===> mageId:sha256:90bfa85b778eaa830e9180499d724e7d714c203cf31e1120ac73526eddbb9086
imageRepoTags:[<none>:<none>] ===> mageId:sha256:e703cff57539b2a7214e9cd7a0dcfbd57c1157e05591f4672f52baa5b58636d3
imageRepoTags:[<none>:<none>] ===> mageId:sha256:40f2dd1e76975a836a6c0a38215852a105d7202d440d06b7798f3c2587872896
imageRepoTags:[springboot-hello2:latest] ===> mageId:sha256:8947f838965555106a5002675d65abf3d288b386ef0aa4b91c01c26d4a3efbec
imageRepoTags:[<none>:<none>] ===> mageId:sha256:8a95fc87c5709918b633d2f55f89cb7d950ae84a63ca3d08c2e31077075afcd1
imageRepoTags:[<none>:<none>] ===> mageId:sha256:3cac50b9ad744e84a77ac935cfeca7a6d89c9bb1744b2eff720d5cbf2965dafc
imageRepoTags:[busybox:latest] ===> mageId:sha256:beae173ccac6ad749f76713cf4440fe3d21d1043fe616dfbe30775815d1d0f6a
imageRepoTags:[openjdk:8-jre-slim] ===> mageId:sha256:54301e8a1f0de01e692e3808333cc0f808d825efbe98e08600a98e3859fc8a35
imageRepoTags:[registry:latest] ===> mageId:sha256:b8604a3fe8543c9e6afc29550de05b36cd162a97aa9b2833864ea8a5be11f3e2
imageRepoTags:[ubuntu:latest] ===> mageId:sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1
imageRepoTags:[hello-world:latest] ===> mageId:sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
imageRepoTags:[java:8] ===> mageId:sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8
imageRepoTags:[training/webapp:latest] ===> mageId:sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557

(4) 从本地导入镜像

    /**
     * 导入镜像
     *
     * @param imageFilePath
     * @param currImageId
     * @return
     */
    public static String loadImage(String imageFilePath, String currImageId) {
        String uploadImageName = "";
        File file = new File(imageFilePath);
        try (InputStream inputStream = new FileInputStream(file)) {
            System.out.println("Start LoadImage ====>" +  imageFilePath);
            DockerUtils.loadImage(docekrClient, inputStream);
            List<Image> imageList = DockerUtils.imageList(docekrClient);
            for (Image image : imageList) {
                if (currImageId.contains(image.getId())) {
                    uploadImageName = image.getRepoTags()[0];
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return uploadImageName;
    }

(5) 给镜像打上要推送的到的harbor仓库的标签

    /**
     * 给镜像打上要推送的到的harbor仓库的标签
     *
     * @param uploadImageName
     * @param newImageName
     * @param newTag
     * @return
     */
    public static String tagImage(String uploadImageName, String newImageName, String newTag) {
        // docker tag SOURCE_IMAGE[:TAG] 192.168.79.131:8443/test/REPOSITORY[:TAG]
        String fullImageName = DockerUtils.REGISTRY_URL + "/" + DockerUtils.REGISTRY_PROJECT_NAME + "/" + newImageName;
        String fullImageNameWithTag = fullImageName + ":" + newTag;
        DockerUtils.tagImage(docekrClient, uploadImageName, fullImageName, newTag);
        System.out.println("原始镜像名:" +  uploadImageName + " 修改后的镜像名:" +  fullImageNameWithTag);
        return fullImageNameWithTag;
    }
原始镜像名:hello-world:latest 修改后的镜像名:192.168.79.131:8443/test/hello-test:test2
打完标签之后的镜像名称:192.168.79.131:8443/test/hello-test:test2

(6) 通过Dockerfile构建镜像并打标签

  /**
     * 通过Dockerfile构建镜像并打标签
     * @param dokcerFilePath
     * @param buildImageName
     * @param newTag
     */
    public static void buildImage(String dokcerFilePath, String buildImageName, String newTag){
        File dokcerFile = new File(dokcerFilePath);
        String imageId = DockerUtils.buildImage(docekrClient, dokcerFile);
        System.out.println("构建镜像Id为:" +  imageId);
        DockerUtils.tagImage(docekrClient, imageId, buildImageName, newTag);
    }

其中DockerFile如下

# java8镜像是容器的运行环境
FROM java:8 as ship
# 为了安全起见,在生产环境运行容器时不要用指root帐号和群组
RUN addgroup --system app && adduser --system --ingroup app app
# 指定容器的运行帐号
user app
# 指定容器的工作目录
WORKDIR /home/app/
# 将jar包复制到容器内
ADD springboot-0.0.1-SNAPSHOT.jar /home/app/app.jar
# 容器启动命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]

 构建之后的镜像

 

(7)  将镜像推送到Harbor仓库上

 
/**
     * 将镜像推送到Harbor仓库上
     *
     * @param fullImageName
     * @return
     */
    public static Boolean pushImage(String fullImageName) {
        Boolean pushResult = true;
        // 推送镜像
        try {
            DockerUtils.pushImage(docekrClient, fullImageName);
        } catch (InterruptedException e) {
            e.printStackTrace();
            pushResult = false;
        }
        return pushResult;
    }

推送成功:

(8) 完整代码

package com.workhard.demo;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Image;
import com.workhard.utils.DockerUtils;


import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * auther:akenseren
 */
public class JavaClientDemo {
    private static final DockerClient docekrClient;

    static {
        docekrClient = DockerUtils.getDocekrClient(DockerUtils.DOCKER_HOST, DockerUtils.DOCKER_TLS_VERIFY,
                DockerUtils.DCOEKR_CERT_PATH, DockerUtils.REGISTRY_USER_NAME, DockerUtils.REGISTRY_PASSWORD,
                DockerUtils.REGISTRY_URL);
    }

    /**
     * 获取当前镜像客户端的信息
     */
    public static void getDockerInfo() {
        String dockerInfo = DockerUtils.getDockerInfo(docekrClient);
        System.out.println("dockerInfo:" + dockerInfo);
    }

    /**
     * 输出当前docker下的所有的镜像
     */
    public static void getImageList() {
        List<Image> imageList = DockerUtils.imageList(docekrClient);
        for (Image image : imageList) {
            String toString = Arrays.stream(image.getRepoTags()).collect(Collectors.toList()).toString();
            System.out.println("imageRepoTags:" + toString + " ===> mageId:" + image.getId());
        }
    }

    /**
     * 导入镜像
     *
     * @param imageFilePath
     * @param currImageId
     * @return
     */
    public static String loadImage(String imageFilePath, String currImageId) {
        String uploadImageName = "";
        File file = new File(imageFilePath);
        try (InputStream inputStream = new FileInputStream(file)) {
            System.out.println("Start LoadImage ====>" +  imageFilePath);
            DockerUtils.loadImage(docekrClient, inputStream);
            List<Image> imageList = DockerUtils.imageList(docekrClient);
            for (Image image : imageList) {
                if (currImageId.contains(image.getId())) {
                    uploadImageName = image.getRepoTags()[0];
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return uploadImageName;
    }

    /**
     * 给镜像打上要推送的到的harbor仓库的标签
     *
     * @param uploadImageName
     * @param newImageName
     * @param newTag
     * @return
     */
    public static String tagImage(String uploadImageName, String newImageName, String newTag) {
        // docker tag SOURCE_IMAGE[:TAG] 192.168.79.131:8443/test/REPOSITORY[:TAG]
        String fullImageName = DockerUtils.REGISTRY_URL + "/" + DockerUtils.REGISTRY_PROJECT_NAME + "/" + newImageName;
        String fullImageNameWithTag = fullImageName + ":" + newTag;
        DockerUtils.tagImage(docekrClient, uploadImageName, fullImageName, newTag);
        System.out.println("原始镜像名:" +  uploadImageName + " 修改后的镜像名:" +  fullImageNameWithTag);
        return fullImageNameWithTag;
    }

    /**
     * 将镜像推送到Harbor仓库上
     *
     * @param fullImageName
     * @return
     */
    public static Boolean pushImage(String fullImageName) {
        Boolean pushResult = true;
        // 推送镜像
        try {
            DockerUtils.pushImage(docekrClient, fullImageName);
        } catch (InterruptedException e) {
            e.printStackTrace();
            pushResult = false;
        }
        return pushResult;
    }

    /**
     * 通过Dockerfile构建镜像并打标签
     * @param dokcerFilePath
     * @param buildImageName
     * @param newTag
     */
    public static void buildImage(String dokcerFilePath, String buildImageName, String newTag){
        File dokcerFile = new File(dokcerFilePath);
        String imageId = DockerUtils.buildImage(docekrClient, dokcerFile);
        System.out.println("构建镜像Id为:" +  imageId);
        DockerUtils.tagImage(docekrClient, imageId, buildImageName, newTag);
    }


    public static void main(String[] args) {
        String currImageId = "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412";
        String imageFilePath = "E:\\Docker\\images\\hello.tar";
        String newImageName = "hello-test";
        String buildImageName = "hello-build";
        String newTag = "test2";
        String dockerFilePath = "E:\\Docker\\images\\java8\\springboothelloworld";

//        getDockerInfo();

        String loadImageName = loadImage(imageFilePath, currImageId);
        System.out.println("导入的本地镜像名称为:" +  loadImageName);


        String tagImageName = tagImage(loadImageName, newImageName, newTag);
        System.out.println("打完标签之后的镜像名称:"+  tagImageName);

        Boolean aBoolean = pushImage(tagImageName);
        String result = aBoolean ? "成功" : "失败";
        System.out.println("镜像推送结果:" + result);

//        getImageList();

        // 从docker镜像的tar文件中获取镜像的名称
//        String imageName = DockerUtils.getImageName(imageFilePath);
//        System.out.println("imageName:"+ imageName);

        // 通过dockerFile构建镜像
//        buildImage(dockerFilePath,buildImageName,newTag);

    }
}

结语

本次只是简单的对镜像构建推送相关功能的实现,以后有机会补充容器相关的操作实现,时间仓促,代码写的很简单,只实现基本功能。

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值