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


    目录

    前言

    1. 新建项目引入依赖

    2.新建工具类

    3.新建测试类JavaClientDemo

    (1)静态代码块获取docekrClient 

    (2)静态代码块获取docekrClient 

    (3) 打印镜像列表

    (4) 从本地导入镜像

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

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

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

    (8) 完整代码

    结语


    前言

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

    1. 新建项目引入依赖

     

    1. <dependency>
    2. <groupId>com.github.docker-javagroupId>
    3. <artifactId>docker-javaartifactId>
    4. <version>3.2.8version>
    5. dependency>
    6. <dependency>
    7. <groupId>com.github.docker-javagroupId>
    8. <artifactId>docker-java-transport-httpclient5artifactId>
    9. <version>3.2.8version>
    10. dependency>

    本文引入docker-java的依赖。

    2.新建工具类

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

    1. package com.workhard.utils;
    2. import com.alibaba.fastjson.JSON;
    3. import com.github.dockerjava.api.DockerClient;
    4. import com.github.dockerjava.api.async.ResultCallback;
    5. import com.github.dockerjava.api.command.BuildImageCmd;
    6. import com.github.dockerjava.api.command.BuildImageResultCallback;
    7. import com.github.dockerjava.api.command.LoadImageCmd;
    8. import com.github.dockerjava.api.command.TagImageCmd;
    9. import com.github.dockerjava.api.model.*;
    10. import com.github.dockerjava.core.DefaultDockerClientConfig;
    11. import com.github.dockerjava.core.DockerClientImpl;
    12. import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
    13. import com.github.dockerjava.transport.DockerHttpClient;
    14. import org.slf4j.Logger;
    15. import org.slf4j.LoggerFactory;
    16. import java.io.File;
    17. import java.io.InputStream;
    18. import java.util.List;
    19. public class DockerUtils {
    20. private final static Logger logger = LoggerFactory.getLogger(DockerUtils.class);
    21. // docker服务端IP地址
    22. public static final String DOCKER_HOST="tcp://192.168.79.131:4243";
    23. // docker安全证书配置路径
    24. public static final String DCOEKR_CERT_PATH="";
    25. // docker是否需要TLS认证
    26. public static final Boolean DOCKER_TLS_VERIFY=false;
    27. // Harbor仓库的IP
    28. public static final String REGISTRY_URL="192.168.79.131:8443";
    29. // Harbor仓库的名称
    30. public static final String REGISTRY_PROJECT_NAME="test";
    31. // Harbor仓库的登录用户名
    32. public static final String REGISTRY_USER_NAME="admin";
    33. // Harbor仓库的登录密码
    34. public static final String REGISTRY_PASSWORD="Harbor12345";
    35. // docker远程仓库的类型,此处默认是harbor
    36. public static final String REGISTRY_TYPE="harbor";
    37. public static final String REGISTRY_PROTOCAL="https://";
    38. /**
    39. * 构建DocekrClient实例
    40. * @param dockerHost
    41. * @param tlsVerify
    42. * @param dockerCertPath
    43. * @param registryUsername
    44. * @param registryPassword
    45. * @param registryUrl
    46. * @return
    47. */
    48. public static DockerClient getDocekrClient(String dockerHost,boolean tlsVerify,String dockerCertPath,
    49. String registryUsername, String registryPassword,String registryUrl){
    50. DefaultDockerClientConfig dockerClientConfig = null;
    51. if(tlsVerify){
    52. dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
    53. .withDockerHost(DOCKER_HOST)
    54. .withDockerTlsVerify(true)
    55. .withDockerCertPath(DCOEKR_CERT_PATH)
    56. .withRegistryUsername(REGISTRY_USER_NAME)
    57. .withRegistryPassword(REGISTRY_PASSWORD)
    58. .withRegistryUrl(registryUrl)
    59. .build();
    60. }else {
    61. dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
    62. .withDockerHost(DOCKER_HOST)
    63. .withDockerTlsVerify(false)
    64. .withDockerCertPath(DCOEKR_CERT_PATH)
    65. .withRegistryUsername(REGISTRY_USER_NAME)
    66. .withRegistryPassword(REGISTRY_PASSWORD)
    67. .withRegistryUrl(registryUrl)
    68. .build();
    69. }
    70. DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
    71. .dockerHost(dockerClientConfig.getDockerHost())
    72. .sslConfig(dockerClientConfig.getSSLConfig())
    73. .build();
    74. return DockerClientImpl.getInstance(dockerClientConfig,httpClient);
    75. }
    76. public static DockerClient getDockerClient(){
    77. return getDocekrClient(DOCKER_HOST,DOCKER_TLS_VERIFY,DCOEKR_CERT_PATH,REGISTRY_USER_NAME,REGISTRY_PASSWORD,REGISTRY_URL);
    78. }
    79. /**
    80. * 获取docker基础信息
    81. * @param dockerClient
    82. * @return
    83. */
    84. public static String getDockerInfo(DockerClient dockerClient){
    85. Info info = dockerClient.infoCmd().exec();
    86. return JSON.toJSONString(info);
    87. }
    88. /**
    89. * 给镜像打标签
    90. * @param dockerClient
    91. * @param imageIdOrFullName
    92. * @param respository
    93. * @param tag
    94. */
    95. public static void tagImage(DockerClient dockerClient, String imageIdOrFullName, String respository,String tag){
    96. TagImageCmd tagImageCmd = dockerClient.tagImageCmd(imageIdOrFullName, respository, tag);
    97. tagImageCmd.exec();
    98. }
    99. /**
    100. * load镜像
    101. * @param dockerClient
    102. * @param inputStream
    103. */
    104. public static void loadImage(DockerClient dockerClient, InputStream inputStream){
    105. LoadImageCmd loadImageCmd = dockerClient.loadImageCmd(inputStream);
    106. loadImageCmd.exec();
    107. }
    108. /**
    109. * 推送镜像
    110. * @param dockerClient
    111. * @param imageName
    112. * @return
    113. * @throws InterruptedException
    114. */
    115. public static Boolean pushImage(DockerClient dockerClient,String imageName) throws InterruptedException {
    116. final Boolean[] result = {true};
    117. ResultCallback.Adapter callBack = new ResultCallback.Adapter() {
    118. @Override
    119. public void onNext(PushResponseItem pushResponseItem) {
    120. if (pushResponseItem != null){
    121. ResponseItem.ErrorDetail errorDetail = pushResponseItem.getErrorDetail();
    122. if (errorDetail!= null){
    123. result[0] = false;
    124. logger.error(errorDetail.getMessage(),errorDetail);
    125. }
    126. }
    127. super.onNext(pushResponseItem);
    128. }
    129. };
    130. dockerClient.pushImageCmd(imageName).exec(callBack).awaitCompletion();
    131. return result[0];
    132. }
    133. /**
    134. * 从镜像的tar文件中获取镜像名称
    135. * @param imagePath
    136. * @return
    137. */
    138. public static String getImageName(String imagePath){
    139. try {
    140. return UnCompress.getImageName(imagePath);
    141. } catch (Exception e) {
    142. e.printStackTrace();
    143. return null;
    144. }
    145. }
    146. /**
    147. * 通过dockerFile构建镜像
    148. * @param dockerClient
    149. * @param dockerFile
    150. * @return
    151. */
    152. public static String buildImage(DockerClient dockerClient, File dockerFile){
    153. BuildImageCmd buildImageCmd = dockerClient.buildImageCmd(dockerFile);
    154. BuildImageResultCallback buildImageResultCallback = new BuildImageResultCallback() {
    155. @Override
    156. public void onNext(BuildResponseItem item) {
    157. logger.info("{}", item);
    158. super.onNext(item);
    159. }
    160. };
    161. return buildImageCmd.exec(buildImageResultCallback).awaitImageId();
    162. // logger.info(imageId);
    163. }
    164. /**
    165. * 获取镜像列表
    166. * @param dockerClient
    167. * @return
    168. */
    169. public static List imageList(DockerClient dockerClient){
    170. List imageList = dockerClient.listImagesCmd().withShowAll(true).exec();
    171. return imageList;
    172. }
    173. }

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

    1. package com.workhard.utils;
    2. import java.io.BufferedInputStream;
    3. import java.io.BufferedOutputStream;
    4. import java.io.File;
    5. import java.io.FileInputStream;
    6. import java.io.FileOutputStream;
    7. import java.io.InputStream;
    8. import java.util.List;
    9. import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
    10. import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
    11. import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
    12. import com.alibaba.fastjson.JSONArray;
    13. import com.alibaba.fastjson.JSONObject;
    14. /**
    15. * 解压缩
    16. * @author Administrator
    17. *
    18. */
    19. public class UnCompress {
    20. private static final String BASE_DIR = "";
    21. // 符号"/"用来作为目录标识判断符
    22. private static final String PATH = File.separator;
    23. private static final int BUFFER = 1024;
    24. private static final String EXT = ".tar";
    25. /**
    26. * 归档
    27. *
    28. * @param srcPath
    29. * @param destPath
    30. * @throws Exception
    31. */
    32. public static void archive(String srcPath, String destPath)
    33. throws Exception {
    34. File srcFile = new File(srcPath);
    35. archive(srcFile, destPath);
    36. }
    37. /**
    38. * 归档
    39. *
    40. * @param srcFile
    41. * 源路径
    42. * @param destFile
    43. * 目标路径
    44. * @throws Exception
    45. */
    46. public static void archive(File srcFile, File destFile) throws Exception {
    47. TarArchiveOutputStream taos = new TarArchiveOutputStream(
    48. new FileOutputStream(destFile));
    49. archive(srcFile, taos, BASE_DIR);
    50. taos.flush();
    51. taos.close();
    52. }
    53. /**
    54. * 归档
    55. *
    56. * @param srcFile
    57. * @throws Exception
    58. */
    59. public static void archive(File srcFile) throws Exception {
    60. String name = srcFile.getName();
    61. String basePath = srcFile.getParent();
    62. String destPath = basePath+File.separator + name + EXT;
    63. archive(srcFile, destPath);
    64. }
    65. /**
    66. * 归档文件
    67. *
    68. * @param srcFile
    69. * @param destPath
    70. * @throws Exception
    71. */
    72. public static void archive(File srcFile, String destPath) throws Exception {
    73. archive(srcFile, new File(destPath));
    74. }
    75. /**
    76. * 归档
    77. *
    78. * @param srcPath
    79. * @throws Exception
    80. */
    81. public static void archive(String srcPath) throws Exception {
    82. File srcFile = new File(srcPath);
    83. archive(srcFile);
    84. }
    85. /**
    86. * 归档
    87. *
    88. * @param srcFile
    89. * 源路径
    90. * @param taos
    91. * TarArchiveOutputStream
    92. * @param basePath
    93. * 归档包内相对路径
    94. * @throws Exception
    95. */
    96. private static void archive(File srcFile, TarArchiveOutputStream taos,
    97. String basePath) throws Exception {
    98. if (srcFile.isDirectory()) {
    99. archiveDir(srcFile, taos, basePath);
    100. } else {
    101. archiveFile(srcFile, taos, basePath);
    102. }
    103. }
    104. /**
    105. * 目录归档
    106. *
    107. * @param dir
    108. * @param taos
    109. * TarArchiveOutputStream
    110. * @param basePath
    111. * @throws Exception
    112. */
    113. private static void archiveDir(File dir, TarArchiveOutputStream taos,
    114. String basePath) throws Exception {
    115. File[] files = dir.listFiles();
    116. if (files.length < 1) {
    117. TarArchiveEntry entry = new TarArchiveEntry(basePath
    118. + dir.getName() + PATH);
    119. taos.putArchiveEntry(entry);
    120. taos.closeArchiveEntry();
    121. }
    122. for (File file : files) {
    123. // 递归归档
    124. archive(file, taos, basePath + dir.getName() + PATH);
    125. }
    126. }
    127. /**
    128. * 归档内文件名定义
    129. *
    130. *
    131. * 如果有多级目录,那么这里就需要给出包含目录的文件名
    132. * 如果用WinRAR打开归档包,中文名将显示为乱码
    133. *
  • */
  • 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();
  • }
  • /**
  • * 文件探针
  • *
  • *
  • * 当父目录不存在时,创建目录!
  • *
  • *
  • * @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 jsonList = (List) JSONArray.parse(content);
  • System.out.println("jsonList = " + jsonList);
  • return ((List)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 list = (List) json.get("RepoTags");
  • System.out.println("list = " + list);
  • return list.get(0);*/
  • }
  • }
  • 解压tar的工具类。

    3.新建测试类JavaClientDemo

    (1)静态代码块获取docekrClient 

    1. private static final DockerClient docekrClient;
    2. static {
    3. docekrClient = DockerUtils.getDocekrClient(DockerUtils.DOCKER_HOST, DockerUtils.DOCKER_TLS_VERIFY,
    4. DockerUtils.DCOEKR_CERT_PATH, DockerUtils.REGISTRY_USER_NAME, DockerUtils.REGISTRY_PASSWORD,
    5. DockerUtils.REGISTRY_URL);
    6. }

    (2)静态代码块获取docekrClient 

    1. /**
    2. * 获取当前镜像客户端的信息
    3. */
    4. public static void getDockerInfo() {
    5. String dockerInfo = DockerUtils.getDockerInfo(docekrClient);
    6. System.out.println("dockerInfo:" + dockerInfo);
    7. }
    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) 打印镜像列表

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

    输出:

    1. imageRepoTags:[hello-build:test2] ===> mageId:sha256:8c20ddb133379b4a73b2a7481fe7a4ed63de8dea3e4ec877aa2aa417775a4ed2
    2. imageRepoTags:[:] ===> mageId:sha256:5c30ffc469d3c6a8db6ad9905802fd8ab3572659ba3dfbb248a993cc73e6d37a
    3. imageRepoTags:[:] ===> mageId:sha256:4c73e947b1e69af2a93b094dfae2b14b7874cf8029de6cb28e70b1c5a6b36751
    4. imageRepoTags:[springboot-helloworld:latest] ===> mageId:sha256:7b2e5a76242b5dadda62339c3777e89d1a9d54a870295e8628c48a5a8149eb85
    5. imageRepoTags:[:] ===> mageId:sha256:90bfa85b778eaa830e9180499d724e7d714c203cf31e1120ac73526eddbb9086
    6. imageRepoTags:[:] ===> mageId:sha256:e703cff57539b2a7214e9cd7a0dcfbd57c1157e05591f4672f52baa5b58636d3
    7. imageRepoTags:[:] ===> mageId:sha256:40f2dd1e76975a836a6c0a38215852a105d7202d440d06b7798f3c2587872896
    8. imageRepoTags:[springboot-hello2:latest] ===> mageId:sha256:8947f838965555106a5002675d65abf3d288b386ef0aa4b91c01c26d4a3efbec
    9. imageRepoTags:[:] ===> mageId:sha256:8a95fc87c5709918b633d2f55f89cb7d950ae84a63ca3d08c2e31077075afcd1
    10. imageRepoTags:[:] ===> mageId:sha256:3cac50b9ad744e84a77ac935cfeca7a6d89c9bb1744b2eff720d5cbf2965dafc
    11. imageRepoTags:[busybox:latest] ===> mageId:sha256:beae173ccac6ad749f76713cf4440fe3d21d1043fe616dfbe30775815d1d0f6a
    12. imageRepoTags:[openjdk:8-jre-slim] ===> mageId:sha256:54301e8a1f0de01e692e3808333cc0f808d825efbe98e08600a98e3859fc8a35
    13. imageRepoTags:[registry:latest] ===> mageId:sha256:b8604a3fe8543c9e6afc29550de05b36cd162a97aa9b2833864ea8a5be11f3e2
    14. imageRepoTags:[ubuntu:latest] ===> mageId:sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1
    15. imageRepoTags:[hello-world:latest] ===> mageId:sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
    16. imageRepoTags:[java:8] ===> mageId:sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8
    17. imageRepoTags:[training/webapp:latest] ===> mageId:sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557

    (4) 从本地导入镜像

    1. /**
    2. * 导入镜像
    3. *
    4. * @param imageFilePath
    5. * @param currImageId
    6. * @return
    7. */
    8. public static String loadImage(String imageFilePath, String currImageId) {
    9. String uploadImageName = "";
    10. File file = new File(imageFilePath);
    11. try (InputStream inputStream = new FileInputStream(file)) {
    12. System.out.println("Start LoadImage ====>" + imageFilePath);
    13. DockerUtils.loadImage(docekrClient, inputStream);
    14. List imageList = DockerUtils.imageList(docekrClient);
    15. for (Image image : imageList) {
    16. if (currImageId.contains(image.getId())) {
    17. uploadImageName = image.getRepoTags()[0];
    18. }
    19. }
    20. } catch (FileNotFoundException e) {
    21. e.printStackTrace();
    22. } catch (IOException e) {
    23. e.printStackTrace();
    24. }
    25. return uploadImageName;
    26. }

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

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

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

    1. /**
    2. * 通过Dockerfile构建镜像并打标签
    3. * @param dokcerFilePath
    4. * @param buildImageName
    5. * @param newTag
    6. */
    7. public static void buildImage(String dokcerFilePath, String buildImageName, String newTag){
    8. File dokcerFile = new File(dokcerFilePath);
    9. String imageId = DockerUtils.buildImage(docekrClient, dokcerFile);
    10. System.out.println("构建镜像Id为:" + imageId);
    11. DockerUtils.tagImage(docekrClient, imageId, buildImageName, newTag);
    12. }

    其中DockerFile如下

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

     构建之后的镜像

     

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

    1. /**
    2. * 将镜像推送到Harbor仓库上
    3. *
    4. * @param fullImageName
    5. * @return
    6. */
    7. public static Boolean pushImage(String fullImageName) {
    8. Boolean pushResult = true;
    9. // 推送镜像
    10. try {
    11. DockerUtils.pushImage(docekrClient, fullImageName);
    12. } catch (InterruptedException e) {
    13. e.printStackTrace();
    14. pushResult = false;
    15. }
    16. return pushResult;
    17. }

    推送成功:

    (8) 完整代码

    1. package com.workhard.demo;
    2. import com.github.dockerjava.api.DockerClient;
    3. import com.github.dockerjava.api.model.Image;
    4. import com.workhard.utils.DockerUtils;
    5. import java.io.*;
    6. import java.util.Arrays;
    7. import java.util.List;
    8. import java.util.stream.Collectors;
    9. /**
    10. * auther:akenseren
    11. */
    12. public class JavaClientDemo {
    13. private static final DockerClient docekrClient;
    14. static {
    15. docekrClient = DockerUtils.getDocekrClient(DockerUtils.DOCKER_HOST, DockerUtils.DOCKER_TLS_VERIFY,
    16. DockerUtils.DCOEKR_CERT_PATH, DockerUtils.REGISTRY_USER_NAME, DockerUtils.REGISTRY_PASSWORD,
    17. DockerUtils.REGISTRY_URL);
    18. }
    19. /**
    20. * 获取当前镜像客户端的信息
    21. */
    22. public static void getDockerInfo() {
    23. String dockerInfo = DockerUtils.getDockerInfo(docekrClient);
    24. System.out.println("dockerInfo:" + dockerInfo);
    25. }
    26. /**
    27. * 输出当前docker下的所有的镜像
    28. */
    29. public static void getImageList() {
    30. List imageList = DockerUtils.imageList(docekrClient);
    31. for (Image image : imageList) {
    32. String toString = Arrays.stream(image.getRepoTags()).collect(Collectors.toList()).toString();
    33. System.out.println("imageRepoTags:" + toString + " ===> mageId:" + image.getId());
    34. }
    35. }
    36. /**
    37. * 导入镜像
    38. *
    39. * @param imageFilePath
    40. * @param currImageId
    41. * @return
    42. */
    43. public static String loadImage(String imageFilePath, String currImageId) {
    44. String uploadImageName = "";
    45. File file = new File(imageFilePath);
    46. try (InputStream inputStream = new FileInputStream(file)) {
    47. System.out.println("Start LoadImage ====>" + imageFilePath);
    48. DockerUtils.loadImage(docekrClient, inputStream);
    49. List imageList = DockerUtils.imageList(docekrClient);
    50. for (Image image : imageList) {
    51. if (currImageId.contains(image.getId())) {
    52. uploadImageName = image.getRepoTags()[0];
    53. }
    54. }
    55. } catch (FileNotFoundException e) {
    56. e.printStackTrace();
    57. } catch (IOException e) {
    58. e.printStackTrace();
    59. }
    60. return uploadImageName;
    61. }
    62. /**
    63. * 给镜像打上要推送的到的harbor仓库的标签
    64. *
    65. * @param uploadImageName
    66. * @param newImageName
    67. * @param newTag
    68. * @return
    69. */
    70. public static String tagImage(String uploadImageName, String newImageName, String newTag) {
    71. // docker tag SOURCE_IMAGE[:TAG] 192.168.79.131:8443/test/REPOSITORY[:TAG]
    72. String fullImageName = DockerUtils.REGISTRY_URL + "/" + DockerUtils.REGISTRY_PROJECT_NAME + "/" + newImageName;
    73. String fullImageNameWithTag = fullImageName + ":" + newTag;
    74. DockerUtils.tagImage(docekrClient, uploadImageName, fullImageName, newTag);
    75. System.out.println("原始镜像名:" + uploadImageName + " 修改后的镜像名:" + fullImageNameWithTag);
    76. return fullImageNameWithTag;
    77. }
    78. /**
    79. * 将镜像推送到Harbor仓库上
    80. *
    81. * @param fullImageName
    82. * @return
    83. */
    84. public static Boolean pushImage(String fullImageName) {
    85. Boolean pushResult = true;
    86. // 推送镜像
    87. try {
    88. DockerUtils.pushImage(docekrClient, fullImageName);
    89. } catch (InterruptedException e) {
    90. e.printStackTrace();
    91. pushResult = false;
    92. }
    93. return pushResult;
    94. }
    95. /**
    96. * 通过Dockerfile构建镜像并打标签
    97. * @param dokcerFilePath
    98. * @param buildImageName
    99. * @param newTag
    100. */
    101. public static void buildImage(String dokcerFilePath, String buildImageName, String newTag){
    102. File dokcerFile = new File(dokcerFilePath);
    103. String imageId = DockerUtils.buildImage(docekrClient, dokcerFile);
    104. System.out.println("构建镜像Id为:" + imageId);
    105. DockerUtils.tagImage(docekrClient, imageId, buildImageName, newTag);
    106. }
    107. public static void main(String[] args) {
    108. String currImageId = "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412";
    109. String imageFilePath = "E:\\Docker\\images\\hello.tar";
    110. String newImageName = "hello-test";
    111. String buildImageName = "hello-build";
    112. String newTag = "test2";
    113. String dockerFilePath = "E:\\Docker\\images\\java8\\springboothelloworld";
    114. // getDockerInfo();
    115. String loadImageName = loadImage(imageFilePath, currImageId);
    116. System.out.println("导入的本地镜像名称为:" + loadImageName);
    117. String tagImageName = tagImage(loadImageName, newImageName, newTag);
    118. System.out.println("打完标签之后的镜像名称:"+ tagImageName);
    119. Boolean aBoolean = pushImage(tagImageName);
    120. String result = aBoolean ? "成功" : "失败";
    121. System.out.println("镜像推送结果:" + result);
    122. // getImageList();
    123. // 从docker镜像的tar文件中获取镜像的名称
    124. // String imageName = DockerUtils.getImageName(imageFilePath);
    125. // System.out.println("imageName:"+ imageName);
    126. // 通过dockerFile构建镜像
    127. // buildImage(dockerFilePath,buildImageName,newTag);
    128. }
    129. }

    结语

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

  • 相关阅读:
    公司员工微信如何管理?
    c++进阶教程:我见过最好的c++教程
    SAP-MM-查找采购订单的创建和修改日期
    JavaScript高级,ES6 笔记 第四天
    tiobe的内容项怎么回事?
    JVM面试重点-2
    从一则12年前的提问中学习:从配对序列联配到多序列联配
    【pen200-lab】10.11.1.8
    4、MySQL 多版本并发控制原理-数据可见性算法
    分享5个和安全相关的 VSCode 插件
  • 原文地址:https://blog.csdn.net/akenseren/article/details/126593928