Browse Source

本地镜像上传2个接口

pull/14/head
fanshuai 2 years ago
parent
commit
d2418fd381
6 changed files with 129 additions and 25 deletions
  1. +2
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/image/ImageController.java
  2. +4
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/tensorBoard/tensorBoard.java
  3. +1
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ImageService.java
  4. +46
    -11
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java
  5. +63
    -11
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java
  6. +13
    -0
      ruoyi-modules/management-platform/src/main/resources/k8sconfig/clusterrolebinding.yaml

+ 2
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/image/ImageController.java View File

@@ -122,8 +122,8 @@ public class ImageController {
@ApiOperation("从本地上传构建镜像")
public AjaxResult createImageFromLocal(@RequestParam("name") String imageName,
@RequestParam("tag") String imageTag,
@RequestParam("description") String imageDescription){
return AjaxResult.success(this.imageService.createImageFromLocal(imageName,imageTag,imageDescription));
@RequestParam("path") String path) throws Exception {
return AjaxResult.success(this.imageService.createImageFromLocal(imageName,imageTag,path));
}




+ 4
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/tensorBoard/tensorBoard.java View File

@@ -8,4 +8,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("tensorBoard")
@Api("流水线管理")
public class tensorBoard {

//状态查询接口

//启动tensorBoard接口
}

+ 1
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ImageService.java View File

@@ -74,7 +74,7 @@ public interface ImageService {
* @param imageDescription
* @return
*/
String createImageFromLocal(String imageName, String imageTag, String imageDescription);
String createImageFromLocal(String imageName, String imageTag, String imageDescription) throws Exception;

Map<String, String> uploadImageFiles(MultipartFile file) throws Exception;



+ 46
- 11
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java View File

@@ -8,9 +8,12 @@ import com.ruoyi.platform.service.ImageService;
import com.ruoyi.platform.service.ImageVersionService;
import com.ruoyi.platform.service.MinioService;
import com.ruoyi.platform.utils.FileUtil;
import com.ruoyi.platform.utils.K8sClientUtil;
import com.ruoyi.platform.vo.ImageVo;
import com.ruoyi.system.api.model.LoginUser;
import io.kubernetes.client.openapi.models.V1Pod;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
@@ -43,11 +46,22 @@ public class ImageServiceImpl implements ImageService {
@Resource
private ImageVersionDao imageVersionDao;


@Resource
private MinioService minioService;
@Value("${harbor.bucketName}")
private String bucketName;
@Value("${harbor.repository}")
private String repository;
@Value("${harbor.harborUrl}")
private String harborUrl;
@Value("${harbor.harborUser}")
private String harborUser;
@Value("${harbor.harborpassword}")
private String harborpassword;
@Value("${harbor.deploymentName}")
private String deploymentName;
@Value("${harbor.serviceNS}")
private String serviceNS;
/**
* 通过ID查询单条数据
*
@@ -178,15 +192,36 @@ public class ImageServiceImpl implements ImageService {
}

@Override
public String createImageFromLocal(String imageName, String imageTag, String fileName) {
// TODO 检查环境是否存在,如果不存在,请开启容器

// TODO 在容器的/data/admin 目录下执行命令 docker load -i fileName 得到返回的镜像名字name:tag

// TODO 在容器里执行 docker tag name:tag nexus3.kube-system.svc:8083/imageName:imageTag


return null;
public String createImageFromLocal(String imageName, String imageTag, String path) throws Exception {
// 得到容器
V1Pod pod = K8sClientUtil.getNSPodList(serviceNS, deploymentName);
if (pod == null) {
throw new Exception("镜像推送服务不存在");
}
String loginCmd = "docker login -u " + harborUser +" -p "+harborpassword+" "+harborUrl;
// 执行命令 docker login -u admin -p Harbor12345 172.20.32.187
String loginlog = K8sClientUtil.executeCommand(pod,loginCmd);
// 在这个容器的/data/admin 目录下执行命令 docker load -i fileName 得到返回的镜像名字name:tag
String username = SecurityUtils.getLoginUser().getUsername();
//
String filePath = "/data/argo-workflow/" + bucketName + "/" +path;
String logs2 = K8sClientUtil.executeCommand(pod,"docker load -i "+filePath);
// 在容器里执行 docker tag name:tag nexus3.kube-system.svc:8083/imageName:imageTag
if (StringUtils.isNoneBlank(logs2)){
String substring = logs2.substring(logs2.indexOf(harborUrl), logs2.length());
String cleanedString = substring.replaceAll("(\\r|\\n)", "");
String cmd1 = "docker tag " + cleanedString+ " " + harborUrl+"/"+repository+"/"+username+"/" + imageName + imageTag;
String imageUrl = harborUrl+"/"+repository+"/"+username+"/" + imageName + imageTag;
String cmd2 = "docker push " + imageUrl;
String s = K8sClientUtil.executeCommand(pod, cmd1);
if (StringUtils.isNotEmpty(K8sClientUtil.executeCommand(pod, cmd2))){
return imageUrl;
}else {
throw new Exception("解析镜像压缩包失败,请检查镜像文件");
}
}else {
throw new Exception("解析镜像压缩包失败,请检查镜像文件");
}
}

@Override


+ 63
- 11
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java View File

@@ -1,5 +1,6 @@
package com.ruoyi.platform.utils;

import io.kubernetes.client.Exec;
import io.kubernetes.client.custom.IntOrString;
import io.kubernetes.client.custom.Quantity;
import io.kubernetes.client.openapi.ApiClient;
@@ -13,6 +14,9 @@ import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -48,7 +52,7 @@ public class K8sClientUtil {
try {
this.apiClient = new ClientBuilder().
setBasePath("https://172.20.32.181:6443").setVerifyingSsl(false).
setAuthentication(new AccessTokenAuthentication("eyJhbGciOiJSUzI1NiIsImtpZCI6IjRWcFBPWl9YSFFxQ2tVanRuNHdRT1dnUlJNTnB2bG5TQlVSRjNKdExWNDQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXNteGxuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyZWY1ZjdkMC0zMTdkLTQxN2UtOWY4Ni1mYjA1OTFhYWVhZDQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.GMpReYK7YJ0nNy-F6VrUJQzjWQiSauAOeq0-DT8ik2Lx8f2eznYEm_3cHX4kIn_nYgfxo857urcHt4Ft6IgVtWzxLzVTCQVaNP_H2J8bnJn8W2tUKXzF_3d_GwO75H7kN8P3aoShULrOLpiIf3o3Az28_gwHkwCnd42npcKrCXfAKj8A2U7-KUFQXXA-etrWSw81C5t8ziL-2xaiDgwD3ewH-TNYsOpyWjGopNTxJn1F7GyJ7xDlmMJOaZhSnOrDggB7lqDEsE68YmZtqB7lcSaZHnKzvNhEdbKri4R7_urpjttz_k6qcfIi-l6GwPtJLatsPDg3OL3FFnzjvArJ-A")).build();
setAuthentication(new AccessTokenAuthentication("eyJhbGciOiJSUzI1NiIsImtpZCI6IjRWcFBPWl9YSFFxQ2tVanRuNHdRT1dnUlJNTnB2bG5TQlVSRjNKdExWNDQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImFkbWluLXNlcnZpY2UtYWNjb3VudC10b2tlbi14ZDk5eiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbi1zZXJ2aWNlLWFjY291bnQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmMGEzNmYyMS01MjQyLTQ4MTAtYWVmZS0xOTEwOTZlZjc5YmUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDphZG1pbi1zZXJ2aWNlLWFjY291bnQifQ.fo-Wf0-5-IRC5fhRh65yfqCJqKfE9MrNFIXL2fd1CqVAHD7JBpWO2IsFiSmz9Bm7VfLmFAp2NB7DjW4ZLjC7ODiGhpSseBP8x4ceFuHL6pRGUsEBvHQBBBuQcGhNOcsxIDHnDqUdUzoLprj223lMZNTQowITuqYFU4GVbethyEuS6G5Wh9KHI3KYHFtG4_AeWBgI5Ppz8pDrhHzSFWTFbzxQ3RPGEwF0V-9wEtdrSYnfETi3rdRWif9W4a0RW8HwD9Gf7UCYcyFOs7e5_3-IvmctS85g87PYIfHXMhu_kOw-_Il4bkwPEK5uiBFDw0M1-s9YP-F9r5sXXvOJlsAr1g")).build();
} catch (Exception e) {
log.error("构建K8s-Client异常", e);
throw new RuntimeException("构建K8s-Client异常");
@@ -62,16 +66,16 @@ public class K8sClientUtil {
*
* @param kubeConfigPath kube连接配置文件
*/
public K8sClientUtil(String kubeConfigPath) {
try {
this.apiClient = new ClientBuilder().
setBasePath("https://172.20.32.181:6443").setVerifyingSsl(false).
setAuthentication(new AccessTokenAuthentication("eyJhbGciOiJSUzI1NiIsImtpZCI6IjRWcFBPWl9YSFFxQ2tVanRuNHdRT1dnUlJNTnB2bG5TQlVSRjNKdExWNDQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXNteGxuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyZWY1ZjdkMC0zMTdkLTQxN2UtOWY4Ni1mYjA1OTFhYWVhZDQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.GMpReYK7YJ0nNy-F6VrUJQzjWQiSauAOeq0-DT8ik2Lx8f2eznYEm_3cHX4kIn_nYgfxo857urcHt4Ft6IgVtWzxLzVTCQVaNP_H2J8bnJn8W2tUKXzF_3d_GwO75H7kN8P3aoShULrOLpiIf3o3Az28_gwHkwCnd42npcKrCXfAKj8A2U7-KUFQXXA-etrWSw81C5t8ziL-2xaiDgwD3ewH-TNYsOpyWjGopNTxJn1F7GyJ7xDlmMJOaZhSnOrDggB7lqDEsE68YmZtqB7lcSaZHnKzvNhEdbKri4R7_urpjttz_k6qcfIi-l6GwPtJLatsPDg3OL3FFnzjvArJ-A")).build();
} catch (Exception e) {
log.error("构建K8s-Client异常", e);
throw new RuntimeException("构建K8s-Client异常");
}
}
// public K8sClientUtil(String kubeConfigPath) {
// try {
// this.apiClient = new ClientBuilder().
// setBasePath("https://172.20.32.181:6443").setVerifyingSsl(false).
// setAuthentication(new AccessTokenAuthentication("eyJhbGciOiJSUzI1NiIsImtpZCI6IjRWcFBPWl9YSFFxQ2tVanRuNHdRT1dnUlJNTnB2bG5TQlVSRjNKdExWNDQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXNteGxuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyZWY1ZjdkMC0zMTdkLTQxN2UtOWY4Ni1mYjA1OTFhYWVhZDQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.GMpReYK7YJ0nNy-F6VrUJQzjWQiSauAOeq0-DT8ik2Lx8f2eznYEm_3cHX4kIn_nYgfxo857urcHt4Ft6IgVtWzxLzVTCQVaNP_H2J8bnJn8W2tUKXzF_3d_GwO75H7kN8P3aoShULrOLpiIf3o3Az28_gwHkwCnd42npcKrCXfAKj8A2U7-KUFQXXA-etrWSw81C5t8ziL-2xaiDgwD3ewH-TNYsOpyWjGopNTxJn1F7GyJ7xDlmMJOaZhSnOrDggB7lqDEsE68YmZtqB7lcSaZHnKzvNhEdbKri4R7_urpjttz_k6qcfIi-l6GwPtJLatsPDg3OL3FFnzjvArJ-A")).build();
// } catch (Exception e) {
// log.error("构建K8s-Client异常", e);
// throw new RuntimeException("构建K8s-Client异常");
// }
// }

/**
* 获取所有的Pod
@@ -269,4 +273,52 @@ public class K8sClientUtil {
V1Service service = createService(namespace, podName + "-svc", port, selector);
return service.getSpec().getPorts().get(0).getNodePort();
}


/**
* 根据获取namespace,deploymentName的Pod Name
*
* @return podList
*/
public static V1Pod getNSPodList(String namespace,String deploymentName) throws Exception {
// new a CoreV1Api
CoreV1Api api = new CoreV1Api(apiClient);
V1PodList v1PodList = null;
try {
v1PodList = api.listNamespacedPod(namespace, null, null, null, null, null, null, null, null, null, null);
} catch (ApiException e) {
log.error("获取 POD 异常:", e);
}
// invokes the CoreV1Api client

for (V1Pod item : v1PodList.getItems()) {
if (item.getMetadata().getGenerateName().startsWith(deploymentName)) {
// 找到匹配的Pod,获取其名称
return item;
}
}
return null;
}

public static String executeCommand(V1Pod item, String command) {
try {
// 创建API实例
// 创建Exec实例
Exec exec = new Exec(apiClient);
String[] cmd = { "/bin/sh", "-c", command};
Process proc = exec.exec(item, cmd, false);
// 读取输出
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
return builder.toString();
} catch (Exception e) {
log.error("执行命令异常", e);
throw new RuntimeException("执行命令异常");
}
}
}

+ 13
- 0
ruoyi-modules/management-platform/src/main/resources/k8sconfig/clusterrolebinding.yaml View File

@@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-service-account-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-service-account
namespace: default


Loading…
Cancel
Save