1.30 k8s pods查询
This commit is contained in:
parent
07eb96e582
commit
be6b6d75ac
@ -2,8 +2,10 @@ package com.qqchen.deploy.backend.deploy.api;
|
|||||||
|
|
||||||
import com.qqchen.deploy.backend.deploy.dto.K8sDeploymentDTO;
|
import com.qqchen.deploy.backend.deploy.dto.K8sDeploymentDTO;
|
||||||
import com.qqchen.deploy.backend.deploy.entity.K8sDeployment;
|
import com.qqchen.deploy.backend.deploy.entity.K8sDeployment;
|
||||||
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse;
|
||||||
import com.qqchen.deploy.backend.deploy.query.K8sDeploymentQuery;
|
import com.qqchen.deploy.backend.deploy.query.K8sDeploymentQuery;
|
||||||
import com.qqchen.deploy.backend.deploy.service.IK8sDeploymentService;
|
import com.qqchen.deploy.backend.deploy.service.IK8sDeploymentService;
|
||||||
|
import com.qqchen.deploy.backend.deploy.service.IK8sPodService;
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -29,6 +31,9 @@ public class K8sDeploymentApiController extends BaseController<K8sDeployment, K8
|
|||||||
@Resource
|
@Resource
|
||||||
private IK8sDeploymentService k8sDeploymentService;
|
private IK8sDeploymentService k8sDeploymentService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IK8sPodService k8sPodService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<K8sDeploymentDTO> create(@Validated @RequestBody K8sDeploymentDTO dto) {
|
public Response<K8sDeploymentDTO> create(@Validated @RequestBody K8sDeploymentDTO dto) {
|
||||||
return super.create(dto);
|
return super.create(dto);
|
||||||
@ -99,6 +104,23 @@ public class K8sDeploymentApiController extends BaseController<K8sDeployment, K8
|
|||||||
return Response.success(k8sDeploymentService.findByNamespaceId(namespaceId));
|
return Response.success(k8sDeploymentService.findByNamespaceId(namespaceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询Deployment的Pod列表", description = "查询指定Deployment下的所有Pod")
|
||||||
|
@GetMapping("/{deploymentId}/pods")
|
||||||
|
public Response<List<K8sPodResponse>> getDeploymentPods(
|
||||||
|
@Parameter(description = "Deployment ID", required = true) @PathVariable Long deploymentId
|
||||||
|
) {
|
||||||
|
return Response.success(k8sPodService.listPodsByDeployment(deploymentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询Pod详情", description = "查询指定Pod的详细信息")
|
||||||
|
@GetMapping("/{deploymentId}/pods/{podName}")
|
||||||
|
public Response<K8sPodResponse> getPodDetail(
|
||||||
|
@Parameter(description = "Deployment ID", required = true) @PathVariable Long deploymentId,
|
||||||
|
@Parameter(description = "Pod名称", required = true) @PathVariable String podName
|
||||||
|
) {
|
||||||
|
return Response.success(k8sPodService.getPodDetailByDeployment(deploymentId, podName));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void exportData(HttpServletResponse response, List<K8sDeploymentDTO> data) {
|
protected void exportData(HttpServletResponse response, List<K8sDeploymentDTO> data) {
|
||||||
log.info("导出K8S Deployment数据,数据量:{}", data.size());
|
log.info("导出K8S Deployment数据,数据量:{}", data.size());
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.qqchen.deploy.backend.deploy.integration;
|
|||||||
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
|
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
|
||||||
import com.qqchen.deploy.backend.deploy.integration.response.K8sDeploymentResponse;
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sDeploymentResponse;
|
||||||
import com.qqchen.deploy.backend.deploy.integration.response.K8sNamespaceResponse;
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sNamespaceResponse;
|
||||||
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse;
|
||||||
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
|
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -45,6 +46,35 @@ public interface IK8sServiceIntegration extends IExternalSystemIntegration {
|
|||||||
*/
|
*/
|
||||||
List<K8sDeploymentResponse> listAllDeployments(ExternalSystem externalSystem);
|
List<K8sDeploymentResponse> listAllDeployments(ExternalSystem externalSystem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询指定命名空间下的所有Pod
|
||||||
|
*
|
||||||
|
* @param externalSystem K8S系统配置
|
||||||
|
* @param namespace 命名空间名称
|
||||||
|
* @return Pod列表
|
||||||
|
*/
|
||||||
|
List<K8sPodResponse> listPods(ExternalSystem externalSystem, String namespace);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询指定Deployment下的所有Pod
|
||||||
|
*
|
||||||
|
* @param externalSystem K8S系统配置
|
||||||
|
* @param namespace 命名空间名称
|
||||||
|
* @param deploymentName Deployment名称
|
||||||
|
* @return Pod列表
|
||||||
|
*/
|
||||||
|
List<K8sPodResponse> listPodsByDeployment(ExternalSystem externalSystem, String namespace, String deploymentName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询单个Pod详情
|
||||||
|
*
|
||||||
|
* @param externalSystem K8S系统配置
|
||||||
|
* @param namespace 命名空间名称
|
||||||
|
* @param podName Pod名称
|
||||||
|
* @return Pod详情
|
||||||
|
*/
|
||||||
|
K8sPodResponse getPod(ExternalSystem externalSystem, String namespace, String podName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统类型
|
* 获取系统类型
|
||||||
*
|
*
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.qqchen.deploy.backend.framework.utils.JsonUtils;
|
|||||||
import com.qqchen.deploy.backend.deploy.integration.IK8sServiceIntegration;
|
import com.qqchen.deploy.backend.deploy.integration.IK8sServiceIntegration;
|
||||||
import com.qqchen.deploy.backend.deploy.integration.response.K8sDeploymentResponse;
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sDeploymentResponse;
|
||||||
import com.qqchen.deploy.backend.deploy.integration.response.K8sNamespaceResponse;
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sNamespaceResponse;
|
||||||
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse;
|
||||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
|
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
|
||||||
@ -317,6 +318,273 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询指定命名空间下的所有Pod
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<K8sPodResponse> listPods(ExternalSystem externalSystem, String namespace) {
|
||||||
|
log.info("查询K8S Pod,集群: {}, 命名空间: {}", externalSystem.getName(), namespace);
|
||||||
|
|
||||||
|
try {
|
||||||
|
K8sApiClientCache cache = getApiClientCache(externalSystem);
|
||||||
|
CoreV1Api api = new CoreV1Api(cache.apiClient);
|
||||||
|
|
||||||
|
V1PodList podList = api.listNamespacedPod(
|
||||||
|
namespace, null, null, null, null, null, null, null, null, null, null
|
||||||
|
);
|
||||||
|
|
||||||
|
List<K8sPodResponse> pods = new ArrayList<>();
|
||||||
|
for (V1Pod pod : podList.getItems()) {
|
||||||
|
pods.add(convertPodToResponse(pod));
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("查询到 {} 个Pod", pods.size());
|
||||||
|
return pods;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询K8S Pod失败,集群: {}, 命名空间: {}, 错误: {}",
|
||||||
|
externalSystem.getName(), namespace, e.getMessage(), e);
|
||||||
|
throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询指定Deployment下的所有Pod
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<K8sPodResponse> listPodsByDeployment(ExternalSystem externalSystem, String namespace, String deploymentName) {
|
||||||
|
log.info("查询K8S Deployment的Pod,集群: {}, 命名空间: {}, Deployment: {}",
|
||||||
|
externalSystem.getName(), namespace, deploymentName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
K8sApiClientCache cache = getApiClientCache(externalSystem);
|
||||||
|
|
||||||
|
// 1. 先查询Deployment获取selector
|
||||||
|
AppsV1Api appsApi = new AppsV1Api(cache.apiClient);
|
||||||
|
V1Deployment deployment = appsApi.readNamespacedDeployment(deploymentName, namespace, null);
|
||||||
|
|
||||||
|
if (deployment.getSpec() == null || deployment.getSpec().getSelector() == null
|
||||||
|
|| deployment.getSpec().getSelector().getMatchLabels() == null) {
|
||||||
|
log.warn("Deployment没有selector: {}/{}", namespace, deploymentName);
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 构建label selector
|
||||||
|
Map<String, String> matchLabels = deployment.getSpec().getSelector().getMatchLabels();
|
||||||
|
String labelSelector = matchLabels.entrySet().stream()
|
||||||
|
.map(entry -> entry.getKey() + "=" + entry.getValue())
|
||||||
|
.reduce((a, b) -> a + "," + b)
|
||||||
|
.orElse("");
|
||||||
|
|
||||||
|
// 3. 使用label selector查询Pod
|
||||||
|
CoreV1Api coreApi = new CoreV1Api(cache.apiClient);
|
||||||
|
V1PodList podList = coreApi.listNamespacedPod(
|
||||||
|
namespace, null, null, null, null, labelSelector, null, null, null, null, null
|
||||||
|
);
|
||||||
|
|
||||||
|
List<K8sPodResponse> pods = new ArrayList<>();
|
||||||
|
for (V1Pod pod : podList.getItems()) {
|
||||||
|
pods.add(convertPodToResponse(pod));
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("查询到 {} 个Pod", pods.size());
|
||||||
|
return pods;
|
||||||
|
|
||||||
|
} catch (ApiException e) {
|
||||||
|
if (e.getCode() == 404) {
|
||||||
|
log.warn("Deployment不存在: {}/{}", namespace, deploymentName);
|
||||||
|
throw new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
log.error("查询K8S Deployment的Pod失败,集群: {}, 命名空间: {}, Deployment: {}, 错误: {}",
|
||||||
|
externalSystem.getName(), namespace, deploymentName, e.getMessage(), e);
|
||||||
|
throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询K8S Deployment的Pod失败,集群: {}, 命名空间: {}, Deployment: {}, 错误: {}",
|
||||||
|
externalSystem.getName(), namespace, deploymentName, e.getMessage(), e);
|
||||||
|
throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询单个Pod详情
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public K8sPodResponse getPod(ExternalSystem externalSystem, String namespace, String podName) {
|
||||||
|
log.info("查询K8S Pod详情,集群: {}, 命名空间: {}, Pod: {}",
|
||||||
|
externalSystem.getName(), namespace, podName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
K8sApiClientCache cache = getApiClientCache(externalSystem);
|
||||||
|
CoreV1Api api = new CoreV1Api(cache.apiClient);
|
||||||
|
|
||||||
|
V1Pod pod = api.readNamespacedPod(podName, namespace, null);
|
||||||
|
|
||||||
|
return convertPodToResponse(pod);
|
||||||
|
|
||||||
|
} catch (ApiException e) {
|
||||||
|
if (e.getCode() == 404) {
|
||||||
|
log.warn("Pod不存在: {}/{}", namespace, podName);
|
||||||
|
throw new BusinessException(ResponseCode.K8S_POD_NOT_FOUND);
|
||||||
|
}
|
||||||
|
log.error("查询K8S Pod详情失败,集群: {}, 命名空间: {}, Pod: {}, 错误: {}",
|
||||||
|
externalSystem.getName(), namespace, podName, e.getMessage(), e);
|
||||||
|
throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询K8S Pod详情失败,集群: {}, 命名空间: {}, Pod: {}, 错误: {}",
|
||||||
|
externalSystem.getName(), namespace, podName, e.getMessage(), e);
|
||||||
|
throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将K8S Pod对象转换为响应对象
|
||||||
|
*/
|
||||||
|
private K8sPodResponse convertPodToResponse(V1Pod pod) {
|
||||||
|
K8sPodResponse response = new K8sPodResponse();
|
||||||
|
|
||||||
|
// 基本信息
|
||||||
|
response.setName(pod.getMetadata().getName());
|
||||||
|
response.setNamespace(pod.getMetadata().getNamespace());
|
||||||
|
response.setLabels(pod.getMetadata().getLabels());
|
||||||
|
response.setAnnotations(pod.getMetadata().getAnnotations());
|
||||||
|
|
||||||
|
// 时间信息
|
||||||
|
if (pod.getMetadata().getCreationTimestamp() != null) {
|
||||||
|
response.setCreationTimestamp(
|
||||||
|
LocalDateTime.ofInstant(
|
||||||
|
pod.getMetadata().getCreationTimestamp().toInstant(),
|
||||||
|
ZoneId.systemDefault()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 状态信息
|
||||||
|
if (pod.getStatus() != null) {
|
||||||
|
response.setPhase(pod.getStatus().getPhase());
|
||||||
|
response.setReason(pod.getStatus().getReason());
|
||||||
|
response.setMessage(pod.getStatus().getMessage());
|
||||||
|
response.setPodIP(pod.getStatus().getPodIP());
|
||||||
|
response.setHostIP(pod.getStatus().getHostIP());
|
||||||
|
|
||||||
|
if (pod.getStatus().getStartTime() != null) {
|
||||||
|
response.setStartTime(
|
||||||
|
LocalDateTime.ofInstant(
|
||||||
|
pod.getStatus().getStartTime().toInstant(),
|
||||||
|
ZoneId.systemDefault()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 容器状态
|
||||||
|
if (pod.getStatus().getContainerStatuses() != null) {
|
||||||
|
List<K8sPodResponse.ContainerInfo> containers = new ArrayList<>();
|
||||||
|
int totalRestartCount = 0;
|
||||||
|
boolean allReady = true;
|
||||||
|
|
||||||
|
for (V1ContainerStatus containerStatus : pod.getStatus().getContainerStatuses()) {
|
||||||
|
K8sPodResponse.ContainerInfo containerInfo = new K8sPodResponse.ContainerInfo();
|
||||||
|
containerInfo.setName(containerStatus.getName());
|
||||||
|
containerInfo.setImage(containerStatus.getImage());
|
||||||
|
containerInfo.setImageID(containerStatus.getImageID());
|
||||||
|
containerInfo.setReady(containerStatus.getReady());
|
||||||
|
containerInfo.setRestartCount(containerStatus.getRestartCount());
|
||||||
|
containerInfo.setContainerID(containerStatus.getContainerID());
|
||||||
|
|
||||||
|
totalRestartCount += containerStatus.getRestartCount();
|
||||||
|
if (!containerStatus.getReady()) {
|
||||||
|
allReady = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 容器状态
|
||||||
|
V1ContainerState state = containerStatus.getState();
|
||||||
|
if (state != null) {
|
||||||
|
if (state.getRunning() != null) {
|
||||||
|
containerInfo.setState("running");
|
||||||
|
if (state.getRunning().getStartedAt() != null) {
|
||||||
|
containerInfo.setStartedAt(
|
||||||
|
LocalDateTime.ofInstant(
|
||||||
|
state.getRunning().getStartedAt().toInstant(),
|
||||||
|
ZoneId.systemDefault()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (state.getWaiting() != null) {
|
||||||
|
containerInfo.setState("waiting");
|
||||||
|
containerInfo.setStateReason(state.getWaiting().getReason());
|
||||||
|
containerInfo.setStateMessage(state.getWaiting().getMessage());
|
||||||
|
} else if (state.getTerminated() != null) {
|
||||||
|
containerInfo.setState("terminated");
|
||||||
|
containerInfo.setStateReason(state.getTerminated().getReason());
|
||||||
|
containerInfo.setStateMessage(state.getTerminated().getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
containers.add(containerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setContainers(containers);
|
||||||
|
response.setRestartCount(totalRestartCount);
|
||||||
|
response.setReady(allReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spec信息
|
||||||
|
if (pod.getSpec() != null) {
|
||||||
|
response.setNodeName(pod.getSpec().getNodeName());
|
||||||
|
|
||||||
|
// 容器资源配置
|
||||||
|
if (pod.getSpec().getContainers() != null && response.getContainers() != null) {
|
||||||
|
for (int i = 0; i < pod.getSpec().getContainers().size() && i < response.getContainers().size(); i++) {
|
||||||
|
V1Container container = pod.getSpec().getContainers().get(i);
|
||||||
|
K8sPodResponse.ContainerInfo containerInfo = response.getContainers().get(i);
|
||||||
|
|
||||||
|
if (container.getResources() != null) {
|
||||||
|
if (container.getResources().getRequests() != null) {
|
||||||
|
containerInfo.setCpuRequest(
|
||||||
|
container.getResources().getRequests().get("cpu") != null
|
||||||
|
? container.getResources().getRequests().get("cpu").toSuffixedString()
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
containerInfo.setMemoryRequest(
|
||||||
|
container.getResources().getRequests().get("memory") != null
|
||||||
|
? container.getResources().getRequests().get("memory").toSuffixedString()
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (container.getResources().getLimits() != null) {
|
||||||
|
containerInfo.setCpuLimit(
|
||||||
|
container.getResources().getLimits().get("cpu") != null
|
||||||
|
? container.getResources().getLimits().get("cpu").toSuffixedString()
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
containerInfo.setMemoryLimit(
|
||||||
|
container.getResources().getLimits().get("memory") != null
|
||||||
|
? container.getResources().getLimits().get("memory").toSuffixedString()
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Owner信息
|
||||||
|
if (pod.getMetadata().getOwnerReferences() != null && !pod.getMetadata().getOwnerReferences().isEmpty()) {
|
||||||
|
V1OwnerReference owner = pod.getMetadata().getOwnerReferences().get(0);
|
||||||
|
response.setOwnerKind(owner.getKind());
|
||||||
|
response.setOwnerName(owner.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 序列化为YAML
|
||||||
|
try {
|
||||||
|
response.setYamlConfig(Yaml.dump(pod));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("序列化Pod为YAML失败: {}", pod.getMetadata().getName(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建K8S ApiClient(对外接口,使用缓存)
|
* 创建K8S ApiClient(对外接口,使用缓存)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -0,0 +1,180 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.integration.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* K8S Pod响应对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class K8sPodResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pod名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命名空间
|
||||||
|
*/
|
||||||
|
private String namespace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pod状态阶段(Running, Pending, Succeeded, Failed, Unknown)
|
||||||
|
*/
|
||||||
|
private String phase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pod状态原因
|
||||||
|
*/
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pod状态消息
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pod IP地址
|
||||||
|
*/
|
||||||
|
private String podIP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 宿主机IP
|
||||||
|
*/
|
||||||
|
private String hostIP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点名称
|
||||||
|
*/
|
||||||
|
private String nodeName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 容器列表
|
||||||
|
*/
|
||||||
|
private List<ContainerInfo> containers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重启次数(所有容器的总和)
|
||||||
|
*/
|
||||||
|
private Integer restartCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime creationTimestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签
|
||||||
|
*/
|
||||||
|
private Map<String, String> labels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注解
|
||||||
|
*/
|
||||||
|
private Map<String, String> annotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属控制器类型(Deployment, StatefulSet, DaemonSet等)
|
||||||
|
*/
|
||||||
|
private String ownerKind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属控制器名称
|
||||||
|
*/
|
||||||
|
private String ownerName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否就绪
|
||||||
|
*/
|
||||||
|
private Boolean ready;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YAML配置
|
||||||
|
*/
|
||||||
|
private String yamlConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 容器信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class ContainerInfo {
|
||||||
|
/**
|
||||||
|
* 容器名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 镜像
|
||||||
|
*/
|
||||||
|
private String image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 镜像ID
|
||||||
|
*/
|
||||||
|
private String imageID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 容器状态(running, waiting, terminated)
|
||||||
|
*/
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否就绪
|
||||||
|
*/
|
||||||
|
private Boolean ready;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重启次数
|
||||||
|
*/
|
||||||
|
private Integer restartCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 容器ID
|
||||||
|
*/
|
||||||
|
private String containerID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime startedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU请求
|
||||||
|
*/
|
||||||
|
private String cpuRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU限制
|
||||||
|
*/
|
||||||
|
private String cpuLimit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存请求
|
||||||
|
*/
|
||||||
|
private String memoryRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存限制
|
||||||
|
*/
|
||||||
|
private String memoryLimit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态原因(如果是waiting或terminated状态)
|
||||||
|
*/
|
||||||
|
private String stateReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态消息
|
||||||
|
*/
|
||||||
|
private String stateMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.service;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* K8S Pod服务接口
|
||||||
|
*/
|
||||||
|
public interface IK8sPodService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据K8sDeployment ID查询Pod列表
|
||||||
|
*
|
||||||
|
* @param deploymentId K8sDeployment ID
|
||||||
|
* @return Pod列表
|
||||||
|
*/
|
||||||
|
List<K8sPodResponse> listPodsByDeployment(Long deploymentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据K8s信息查询Pod列表
|
||||||
|
*
|
||||||
|
* @param externalSystemId K8S集群ID
|
||||||
|
* @param namespaceId 命名空间ID
|
||||||
|
* @param deploymentName Deployment名称
|
||||||
|
* @return Pod列表
|
||||||
|
*/
|
||||||
|
List<K8sPodResponse> listPodsByDeploymentInfo(Long externalSystemId, Long namespaceId, String deploymentName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询Pod详情
|
||||||
|
*
|
||||||
|
* @param externalSystemId K8S集群ID
|
||||||
|
* @param namespace 命名空间名称
|
||||||
|
* @param podName Pod名称
|
||||||
|
* @return Pod详情
|
||||||
|
*/
|
||||||
|
K8sPodResponse getPodDetail(Long externalSystemId, String namespace, String podName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据DeploymentId查询Pod详情
|
||||||
|
*
|
||||||
|
* @param deploymentId Deployment ID
|
||||||
|
* @param podName Pod名称
|
||||||
|
* @return Pod详情
|
||||||
|
*/
|
||||||
|
K8sPodResponse getPodDetailByDeployment(Long deploymentId, String podName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据命名空间ID查询所有Pod
|
||||||
|
*
|
||||||
|
* @param namespaceId 命名空间ID
|
||||||
|
* @return Pod列表
|
||||||
|
*/
|
||||||
|
List<K8sPodResponse> listPodsByNamespace(Long namespaceId);
|
||||||
|
}
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.service.impl;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
|
||||||
|
import com.qqchen.deploy.backend.deploy.entity.K8sDeployment;
|
||||||
|
import com.qqchen.deploy.backend.deploy.entity.K8sNamespace;
|
||||||
|
import com.qqchen.deploy.backend.deploy.integration.IK8sServiceIntegration;
|
||||||
|
import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse;
|
||||||
|
import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository;
|
||||||
|
import com.qqchen.deploy.backend.deploy.repository.IK8sDeploymentRepository;
|
||||||
|
import com.qqchen.deploy.backend.deploy.repository.IK8sNamespaceRepository;
|
||||||
|
import com.qqchen.deploy.backend.deploy.service.IK8sPodService;
|
||||||
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* K8S Pod服务实现
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class K8sPodServiceImpl implements IK8sPodService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IK8sDeploymentRepository k8sDeploymentRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IK8sNamespaceRepository k8sNamespaceRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IExternalSystemRepository externalSystemRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IK8sServiceIntegration k8sServiceIntegration;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<K8sPodResponse> listPodsByDeployment(Long deploymentId) {
|
||||||
|
log.info("查询K8sDeployment的Pod列表,deploymentId: {}", deploymentId);
|
||||||
|
|
||||||
|
// 1. 查询K8sDeployment
|
||||||
|
K8sDeployment deployment = k8sDeploymentRepository.findById(deploymentId)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND));
|
||||||
|
|
||||||
|
// 2. 查询K8sNamespace
|
||||||
|
K8sNamespace namespace = k8sNamespaceRepository.findById(deployment.getNamespaceId())
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND));
|
||||||
|
|
||||||
|
// 3. 查询ExternalSystem
|
||||||
|
ExternalSystem externalSystem = externalSystemRepository.findById(deployment.getExternalSystemId())
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
|
||||||
|
|
||||||
|
// 4. 调用K8s API查询Pod
|
||||||
|
return k8sServiceIntegration.listPodsByDeployment(
|
||||||
|
externalSystem,
|
||||||
|
namespace.getNamespaceName(),
|
||||||
|
deployment.getDeploymentName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<K8sPodResponse> listPodsByDeploymentInfo(Long externalSystemId, Long namespaceId, String deploymentName) {
|
||||||
|
log.info("根据K8s信息查询Pod列表,externalSystemId: {}, namespaceId: {}, deploymentName: {}",
|
||||||
|
externalSystemId, namespaceId, deploymentName);
|
||||||
|
|
||||||
|
// 1. 查询K8sNamespace
|
||||||
|
K8sNamespace namespace = k8sNamespaceRepository.findById(namespaceId)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND));
|
||||||
|
|
||||||
|
// 2. 查询ExternalSystem
|
||||||
|
ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
|
||||||
|
|
||||||
|
// 3. 调用K8s API查询Pod
|
||||||
|
return k8sServiceIntegration.listPodsByDeployment(
|
||||||
|
externalSystem,
|
||||||
|
namespace.getNamespaceName(),
|
||||||
|
deploymentName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public K8sPodResponse getPodDetail(Long externalSystemId, String namespace, String podName) {
|
||||||
|
log.info("查询Pod详情,externalSystemId: {}, namespace: {}, podName: {}",
|
||||||
|
externalSystemId, namespace, podName);
|
||||||
|
|
||||||
|
// 1. 查询ExternalSystem
|
||||||
|
ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
|
||||||
|
|
||||||
|
// 2. 调用K8s API查询Pod详情
|
||||||
|
return k8sServiceIntegration.getPod(externalSystem, namespace, podName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<K8sPodResponse> listPodsByNamespace(Long namespaceId) {
|
||||||
|
log.info("查询命名空间的所有Pod,namespaceId: {}", namespaceId);
|
||||||
|
|
||||||
|
// 1. 查询K8sNamespace
|
||||||
|
K8sNamespace namespace = k8sNamespaceRepository.findById(namespaceId)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND));
|
||||||
|
|
||||||
|
// 2. 查询ExternalSystem
|
||||||
|
ExternalSystem externalSystem = externalSystemRepository.findById(namespace.getExternalSystemId())
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
|
||||||
|
|
||||||
|
// 3. 调用K8s API查询Pod
|
||||||
|
return k8sServiceIntegration.listPods(externalSystem, namespace.getNamespaceName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public K8sPodResponse getPodDetailByDeployment(Long deploymentId, String podName) {
|
||||||
|
log.info("根据DeploymentId查询Pod详情,deploymentId: {}, podName: {}", deploymentId, podName);
|
||||||
|
|
||||||
|
// 1. 查询K8sDeployment
|
||||||
|
K8sDeployment deployment = k8sDeploymentRepository.findById(deploymentId)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND));
|
||||||
|
|
||||||
|
// 2. 查询K8sNamespace
|
||||||
|
K8sNamespace namespace = k8sNamespaceRepository.findById(deployment.getNamespaceId())
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND));
|
||||||
|
|
||||||
|
// 3. 查询ExternalSystem
|
||||||
|
ExternalSystem externalSystem = externalSystemRepository.findById(deployment.getExternalSystemId())
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
|
||||||
|
|
||||||
|
// 4. 调用K8s API查询Pod详情
|
||||||
|
return k8sServiceIntegration.getPod(externalSystem, namespace.getNamespaceName(), podName);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user