1.31 k8s开发
This commit is contained in:
parent
8c9aec2e0c
commit
4ca37a506d
@ -43,6 +43,42 @@ public class K8sDeploymentDTO extends BaseDTO {
|
|||||||
@Schema(description = "总重启次数(所有Pod的重启次数总和)")
|
@Schema(description = "总重启次数(所有Pod的重启次数总和)")
|
||||||
private Integer totalRestartCount;
|
private Integer totalRestartCount;
|
||||||
|
|
||||||
|
@Schema(description = "实际Pod总数(通过Pod API统计,包括所有状态的Pod:Running/Failed/Pending等)")
|
||||||
|
private Integer actualPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "Running状态的Pod数量")
|
||||||
|
private Integer runningPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "Pending状态的Pod数量")
|
||||||
|
private Integer pendingPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "Failed状态的Pod数量")
|
||||||
|
private Integer failedPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "Succeeded状态的Pod数量")
|
||||||
|
private Integer succeededPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "Unknown状态的Pod数量")
|
||||||
|
private Integer unknownPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "Ready状态的Pod数量(所有容器健康检查通过)")
|
||||||
|
private Integer readyPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "Not Ready状态的Pod数量(至少一个容器健康检查未通过)")
|
||||||
|
private Integer notReadyPodCount;
|
||||||
|
|
||||||
|
@Schema(description = "CPU请求总和(如\"2000m\"或\"2\")")
|
||||||
|
private String totalCpuRequest;
|
||||||
|
|
||||||
|
@Schema(description = "内存请求总和(如\"4Gi\")")
|
||||||
|
private String totalMemoryRequest;
|
||||||
|
|
||||||
|
@Schema(description = "CPU限制总和")
|
||||||
|
private String totalCpuLimit;
|
||||||
|
|
||||||
|
@Schema(description = "内存限制总和")
|
||||||
|
private String totalMemoryLimit;
|
||||||
|
|
||||||
@Schema(description = "容器镜像")
|
@Schema(description = "容器镜像")
|
||||||
private String image;
|
private String image;
|
||||||
|
|
||||||
@ -55,9 +91,6 @@ public class K8sDeploymentDTO extends BaseDTO {
|
|||||||
@Schema(description = "K8S中的创建时间")
|
@Schema(description = "K8S中的创建时间")
|
||||||
private LocalDateTime k8sCreateTime;
|
private LocalDateTime k8sCreateTime;
|
||||||
|
|
||||||
@Schema(description = "K8S中的更新时间")
|
|
||||||
private LocalDateTime k8sUpdateTime;
|
|
||||||
|
|
||||||
@Schema(description = "K8s资源版本号,用于增量同步")
|
@Schema(description = "K8s资源版本号,用于增量同步")
|
||||||
private String resourceVersion;
|
private String resourceVersion;
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,78 @@ public class K8sDeployment extends Entity<Long> {
|
|||||||
@Column(name = "total_restart_count")
|
@Column(name = "total_restart_count")
|
||||||
private Integer totalRestartCount;
|
private Integer totalRestartCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际Pod总数(通过Pod API统计,包括所有状态的Pod:Running/Failed/Pending等)
|
||||||
|
*/
|
||||||
|
@Column(name = "actual_pod_count")
|
||||||
|
private Integer actualPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Running状态的Pod数量
|
||||||
|
*/
|
||||||
|
@Column(name = "running_pod_count")
|
||||||
|
private Integer runningPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pending状态的Pod数量
|
||||||
|
*/
|
||||||
|
@Column(name = "pending_pod_count")
|
||||||
|
private Integer pendingPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failed状态的Pod数量
|
||||||
|
*/
|
||||||
|
@Column(name = "failed_pod_count")
|
||||||
|
private Integer failedPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Succeeded状态的Pod数量
|
||||||
|
*/
|
||||||
|
@Column(name = "succeeded_pod_count")
|
||||||
|
private Integer succeededPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unknown状态的Pod数量
|
||||||
|
*/
|
||||||
|
@Column(name = "unknown_pod_count")
|
||||||
|
private Integer unknownPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ready状态的Pod数量(所有容器健康检查通过)
|
||||||
|
*/
|
||||||
|
@Column(name = "ready_pod_count")
|
||||||
|
private Integer readyPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not Ready状态的Pod数量(至少一个容器健康检查未通过)
|
||||||
|
*/
|
||||||
|
@Column(name = "not_ready_pod_count")
|
||||||
|
private Integer notReadyPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU请求总和(如"2000m"或"2")
|
||||||
|
*/
|
||||||
|
@Column(name = "total_cpu_request", length = 50)
|
||||||
|
private String totalCpuRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存请求总和(如"4Gi")
|
||||||
|
*/
|
||||||
|
@Column(name = "total_memory_request", length = 50)
|
||||||
|
private String totalMemoryRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU限制总和
|
||||||
|
*/
|
||||||
|
@Column(name = "total_cpu_limit", length = 50)
|
||||||
|
private String totalCpuLimit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存限制总和
|
||||||
|
*/
|
||||||
|
@Column(name = "total_memory_limit", length = 50)
|
||||||
|
private String totalMemoryLimit;
|
||||||
|
|
||||||
@Column(name = "image")
|
@Column(name = "image")
|
||||||
private String image;
|
private String image;
|
||||||
|
|
||||||
@ -91,9 +163,6 @@ public class K8sDeployment extends Entity<Long> {
|
|||||||
@Column(name = "k8s_create_time")
|
@Column(name = "k8s_create_time")
|
||||||
private LocalDateTime k8sCreateTime;
|
private LocalDateTime k8sCreateTime;
|
||||||
|
|
||||||
@Column(name = "k8s_update_time")
|
|
||||||
private LocalDateTime k8sUpdateTime;
|
|
||||||
|
|
||||||
@Column(name = "yaml_config", columnDefinition = "TEXT")
|
@Column(name = "yaml_config", columnDefinition = "TEXT")
|
||||||
private String yamlConfig;
|
private String yamlConfig;
|
||||||
|
|
||||||
|
|||||||
@ -134,6 +134,113 @@ public interface IK8sServiceIntegration extends IExternalSystemIntegration {
|
|||||||
List<K8sDeploymentResponse> deployments
|
List<K8sDeploymentResponse> deployments
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量计算namespace下所有Deployment的Pod统计信息(重启次数和实际Pod数量)
|
||||||
|
* 性能优化:一次性查询所有Pod,在内存中按Deployment分组计算
|
||||||
|
*
|
||||||
|
* @param externalSystem K8S系统配置
|
||||||
|
* @param namespace 命名空间名称
|
||||||
|
* @param deployments Deployment列表
|
||||||
|
* @return Map<deploymentName, PodStats>,其中PodStats包含restartCount和actualPodCount
|
||||||
|
*/
|
||||||
|
java.util.Map<String, PodStats> batchCalculatePodStats(
|
||||||
|
ExternalSystem externalSystem,
|
||||||
|
String namespace,
|
||||||
|
List<K8sDeploymentResponse> deployments
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pod统计信息
|
||||||
|
*/
|
||||||
|
class PodStats {
|
||||||
|
private final Integer restartCount;
|
||||||
|
private final Integer actualPodCount;
|
||||||
|
private final Integer runningPodCount;
|
||||||
|
private final Integer pendingPodCount;
|
||||||
|
private final Integer failedPodCount;
|
||||||
|
private final Integer succeededPodCount;
|
||||||
|
private final Integer unknownPodCount;
|
||||||
|
private final Integer readyPodCount;
|
||||||
|
private final Integer notReadyPodCount;
|
||||||
|
private final String totalCpuRequest;
|
||||||
|
private final String totalMemoryRequest;
|
||||||
|
private final String totalCpuLimit;
|
||||||
|
private final String totalMemoryLimit;
|
||||||
|
|
||||||
|
public PodStats(Integer restartCount, Integer actualPodCount,
|
||||||
|
Integer runningPodCount, Integer pendingPodCount, Integer failedPodCount,
|
||||||
|
Integer succeededPodCount, Integer unknownPodCount,
|
||||||
|
Integer readyPodCount, Integer notReadyPodCount,
|
||||||
|
String totalCpuRequest, String totalMemoryRequest,
|
||||||
|
String totalCpuLimit, String totalMemoryLimit) {
|
||||||
|
this.restartCount = restartCount;
|
||||||
|
this.actualPodCount = actualPodCount;
|
||||||
|
this.runningPodCount = runningPodCount;
|
||||||
|
this.pendingPodCount = pendingPodCount;
|
||||||
|
this.failedPodCount = failedPodCount;
|
||||||
|
this.succeededPodCount = succeededPodCount;
|
||||||
|
this.unknownPodCount = unknownPodCount;
|
||||||
|
this.readyPodCount = readyPodCount;
|
||||||
|
this.notReadyPodCount = notReadyPodCount;
|
||||||
|
this.totalCpuRequest = totalCpuRequest;
|
||||||
|
this.totalMemoryRequest = totalMemoryRequest;
|
||||||
|
this.totalCpuLimit = totalCpuLimit;
|
||||||
|
this.totalMemoryLimit = totalMemoryLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRestartCount() {
|
||||||
|
return restartCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getActualPodCount() {
|
||||||
|
return actualPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRunningPodCount() {
|
||||||
|
return runningPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPendingPodCount() {
|
||||||
|
return pendingPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getFailedPodCount() {
|
||||||
|
return failedPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSucceededPodCount() {
|
||||||
|
return succeededPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getUnknownPodCount() {
|
||||||
|
return unknownPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getReadyPodCount() {
|
||||||
|
return readyPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getNotReadyPodCount() {
|
||||||
|
return notReadyPodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotalCpuRequest() {
|
||||||
|
return totalCpuRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotalMemoryRequest() {
|
||||||
|
return totalMemoryRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotalCpuLimit() {
|
||||||
|
return totalCpuLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotalMemoryLimit() {
|
||||||
|
return totalMemoryLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统类型
|
* 获取系统类型
|
||||||
*
|
*
|
||||||
|
|||||||
@ -819,6 +819,158 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量计算namespace下所有Deployment的Pod统计信息(重启次数和实际Pod数量)
|
||||||
|
* 性能优化:一次性查询所有Pod,在内存中按Deployment分组计算
|
||||||
|
*
|
||||||
|
* @param externalSystem K8s集群
|
||||||
|
* @param namespace 命名空间
|
||||||
|
* @param deployments Deployment列表
|
||||||
|
* @return Map<deploymentName, PodStats>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, IK8sServiceIntegration.PodStats> batchCalculatePodStats(
|
||||||
|
ExternalSystem externalSystem,
|
||||||
|
String namespace,
|
||||||
|
List<K8sDeploymentResponse> deployments) {
|
||||||
|
|
||||||
|
log.debug("批量计算Deployment Pod统计信息,集群: {}, 命名空间: {}, Deployment数量: {}",
|
||||||
|
externalSystem.getName(), namespace, deployments.size());
|
||||||
|
|
||||||
|
Map<String, IK8sServiceIntegration.PodStats> statsMap = new java.util.HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 一次性查询namespace下所有Pod
|
||||||
|
List<K8sPodResponse> allPods = listPods(externalSystem, namespace);
|
||||||
|
|
||||||
|
if (allPods.isEmpty()) {
|
||||||
|
log.debug("命名空间 {} 下没有Pod", namespace);
|
||||||
|
return statsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 为每个Deployment计算统计信息
|
||||||
|
for (K8sDeploymentResponse deployment : deployments) {
|
||||||
|
try {
|
||||||
|
Map<String, String> selector = deployment.getSelector();
|
||||||
|
if (selector == null || selector.isEmpty()) {
|
||||||
|
log.debug("Deployment {} 没有selector,跳过", deployment.getName());
|
||||||
|
statsMap.put(deployment.getName(),
|
||||||
|
new IK8sServiceIntegration.PodStats(0, 0, 0, 0, 0, 0, 0, 0, 0, "0", "0", "0", "0"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 在内存中过滤匹配该Deployment的Pod
|
||||||
|
List<K8sPodResponse> matchedPods = allPods.stream()
|
||||||
|
.filter(pod -> matchesSelector(pod.getLabels(), selector))
|
||||||
|
.collect(java.util.stream.Collectors.toList());
|
||||||
|
|
||||||
|
// 4. 计算重启次数
|
||||||
|
int totalRestartCount = matchedPods.stream()
|
||||||
|
.mapToInt(pod -> pod.getRestartCount() != null ? pod.getRestartCount() : 0)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
// 5. 计算Pod总数
|
||||||
|
int actualPodCount = matchedPods.size();
|
||||||
|
|
||||||
|
// 6. 按Phase统计Pod数量
|
||||||
|
int runningCount = 0, pendingCount = 0, failedCount = 0, succeededCount = 0, unknownCount = 0;
|
||||||
|
for (K8sPodResponse pod : matchedPods) {
|
||||||
|
if (pod.getPhase() == null) {
|
||||||
|
unknownCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (pod.getPhase()) {
|
||||||
|
case RUNNING:
|
||||||
|
runningCount++;
|
||||||
|
break;
|
||||||
|
case PENDING:
|
||||||
|
pendingCount++;
|
||||||
|
break;
|
||||||
|
case FAILED:
|
||||||
|
failedCount++;
|
||||||
|
break;
|
||||||
|
case SUCCEEDED:
|
||||||
|
succeededCount++;
|
||||||
|
break;
|
||||||
|
case UNKNOWN:
|
||||||
|
default:
|
||||||
|
unknownCount++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 按Ready状态统计Pod数量
|
||||||
|
long readyCount = matchedPods.stream()
|
||||||
|
.filter(pod -> pod.getReady() != null && pod.getReady())
|
||||||
|
.count();
|
||||||
|
int notReadyCount = actualPodCount - (int) readyCount;
|
||||||
|
|
||||||
|
// 8. 聚合资源统计(CPU和内存)
|
||||||
|
long totalCpuRequestMillicores = 0;
|
||||||
|
long totalMemoryRequestBytes = 0;
|
||||||
|
long totalCpuLimitMillicores = 0;
|
||||||
|
long totalMemoryLimitBytes = 0;
|
||||||
|
|
||||||
|
for (K8sPodResponse pod : matchedPods) {
|
||||||
|
if (pod.getContainers() != null) {
|
||||||
|
for (K8sPodResponse.ContainerInfo container : pod.getContainers()) {
|
||||||
|
// 累加CPU request
|
||||||
|
if (container.getCpuRequest() != null) {
|
||||||
|
totalCpuRequestMillicores += com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.parseCpuToMillicores(container.getCpuRequest());
|
||||||
|
}
|
||||||
|
// 累加Memory request
|
||||||
|
if (container.getMemoryRequest() != null) {
|
||||||
|
totalMemoryRequestBytes += com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.parseMemoryToBytes(container.getMemoryRequest());
|
||||||
|
}
|
||||||
|
// 累加CPU limit
|
||||||
|
if (container.getCpuLimit() != null) {
|
||||||
|
totalCpuLimitMillicores += com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.parseCpuToMillicores(container.getCpuLimit());
|
||||||
|
}
|
||||||
|
// 累加Memory limit
|
||||||
|
if (container.getMemoryLimit() != null) {
|
||||||
|
totalMemoryLimitBytes += com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.parseMemoryToBytes(container.getMemoryLimit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为K8s格式字符串
|
||||||
|
String totalCpuRequest = com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.formatCpuResource(totalCpuRequestMillicores);
|
||||||
|
String totalMemoryRequest = com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.formatMemoryResource(totalMemoryRequestBytes);
|
||||||
|
String totalCpuLimit = com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.formatCpuResource(totalCpuLimitMillicores);
|
||||||
|
String totalMemoryLimit = com.qqchen.deploy.backend.framework.utils.K8sResourceUtils.formatMemoryResource(totalMemoryLimitBytes);
|
||||||
|
|
||||||
|
IK8sServiceIntegration.PodStats stats = new IK8sServiceIntegration.PodStats(
|
||||||
|
totalRestartCount, actualPodCount,
|
||||||
|
runningCount, pendingCount, failedCount, succeededCount, unknownCount,
|
||||||
|
(int) readyCount, notReadyCount,
|
||||||
|
totalCpuRequest, totalMemoryRequest, totalCpuLimit, totalMemoryLimit
|
||||||
|
);
|
||||||
|
|
||||||
|
statsMap.put(deployment.getName(), stats);
|
||||||
|
log.debug("Deployment {} 的统计信息: 重启次数={}, 实际Pod数={}, Running={}, Pending={}, Failed={}, Succeeded={}, Unknown={}, Ready={}, NotReady={}, CPU请求={}, 内存请求={}, CPU限制={}, 内存限制={}",
|
||||||
|
deployment.getName(), totalRestartCount, actualPodCount,
|
||||||
|
runningCount, pendingCount, failedCount, succeededCount, unknownCount,
|
||||||
|
readyCount, notReadyCount, totalCpuRequest, totalMemoryRequest, totalCpuLimit, totalMemoryLimit);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("计算Deployment {} 统计信息失败: {}", deployment.getName(), e.getMessage());
|
||||||
|
statsMap.put(deployment.getName(),
|
||||||
|
new IK8sServiceIntegration.PodStats(0, 0, 0, 0, 0, 0, 0, 0, 0, "0", "0", "0", "0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("批量计算完成,成功计算 {} 个Deployment的统计信息", statsMap.size());
|
||||||
|
return statsMap;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("批量计算Pod统计信息失败,集群: {}, 命名空间: {}, 错误: {}",
|
||||||
|
externalSystem.getName(), namespace, e.getMessage(), e);
|
||||||
|
// 失败时返回空Map,不影响同步流程
|
||||||
|
return statsMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断Pod的labels是否匹配Deployment的selector
|
* 判断Pod的labels是否匹配Deployment的selector
|
||||||
*
|
*
|
||||||
@ -895,6 +1047,7 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 填充容器资源配置信息
|
* 填充容器资源配置信息
|
||||||
|
* 按容器名称匹配,确保资源信息正确填充到对应容器
|
||||||
*
|
*
|
||||||
* @param specContainers Pod Spec中的容器列表
|
* @param specContainers Pod Spec中的容器列表
|
||||||
* @param containerInfos 响应对象中的容器信息列表
|
* @param containerInfos 响应对象中的容器信息列表
|
||||||
@ -904,12 +1057,19 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = Math.min(specContainers.size(), containerInfos.size());
|
// 将Spec容器列表转换为Map,key为容器名称
|
||||||
for (int i = 0; i < size; i++) {
|
Map<String, V1Container> specContainerMap = specContainers.stream()
|
||||||
V1Container container = specContainers.get(i);
|
.collect(java.util.stream.Collectors.toMap(V1Container::getName, c -> c));
|
||||||
K8sPodResponse.ContainerInfo containerInfo = containerInfos.get(i);
|
|
||||||
|
|
||||||
V1ResourceRequirements resources = container.getResources();
|
// 遍历ContainerInfo,根据名称匹配Spec容器
|
||||||
|
for (K8sPodResponse.ContainerInfo containerInfo : containerInfos) {
|
||||||
|
V1Container specContainer = specContainerMap.get(containerInfo.getName());
|
||||||
|
if (specContainer == null) {
|
||||||
|
log.debug("容器 {} 在Spec中不存在,跳过资源填充", containerInfo.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
V1ResourceRequirements resources = specContainer.getResources();
|
||||||
if (resources == null) {
|
if (resources == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,11 +72,70 @@ public class K8sDeploymentResponse {
|
|||||||
*/
|
*/
|
||||||
private Integer totalRestartCount;
|
private Integer totalRestartCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际Pod总数(通过Pod API统计,包括所有状态的Pod:Running/Failed/Pending等)
|
||||||
|
*/
|
||||||
|
private Integer actualPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Running状态的Pod数量
|
||||||
|
*/
|
||||||
|
private Integer runningPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pending状态的Pod数量
|
||||||
|
*/
|
||||||
|
private Integer pendingPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failed状态的Pod数量
|
||||||
|
*/
|
||||||
|
private Integer failedPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Succeeded状态的Pod数量
|
||||||
|
*/
|
||||||
|
private Integer succeededPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unknown状态的Pod数量
|
||||||
|
*/
|
||||||
|
private Integer unknownPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ready状态的Pod数量(所有容器健康检查通过)
|
||||||
|
*/
|
||||||
|
private Integer readyPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not Ready状态的Pod数量(至少一个容器健康检查未通过)
|
||||||
|
*/
|
||||||
|
private Integer notReadyPodCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU请求总和(如"2000m"或"2")
|
||||||
|
*/
|
||||||
|
private String totalCpuRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存请求总和(如"4Gi")
|
||||||
|
*/
|
||||||
|
private String totalMemoryRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU限制总和
|
||||||
|
*/
|
||||||
|
private String totalCpuLimit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存限制总和
|
||||||
|
*/
|
||||||
|
private String totalMemoryLimit;
|
||||||
|
|
||||||
private String image;
|
private String image;
|
||||||
private Map<String, String> labels;
|
private Map<String, String> labels;
|
||||||
private Map<String, String> selector;
|
private Map<String, String> selector;
|
||||||
private LocalDateTime creationTimestamp;
|
private LocalDateTime creationTimestamp;
|
||||||
private LocalDateTime lastUpdateTime;
|
|
||||||
private String yamlConfig;
|
private String yamlConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -83,25 +83,28 @@ public class K8sDeploymentServiceImpl extends BaseServiceImpl<K8sDeployment, K8s
|
|||||||
.map(K8sDeploymentResponse::getName)
|
.map(K8sDeploymentResponse::getName)
|
||||||
.collect(java.util.stream.Collectors.toSet());
|
.collect(java.util.stream.Collectors.toSet());
|
||||||
|
|
||||||
// 性能优化:批量计算所有Deployment的重启次数(一次K8s API调用)
|
// 性能优化:批量计算所有Deployment的Pod统计信息(一次K8s API调用)
|
||||||
Map<String, Integer> restartCountMap = k8sServiceIntegration.batchCalculateRestartCounts(
|
Map<String, IK8sServiceIntegration.PodStats> podStatsMap = k8sServiceIntegration.batchCalculatePodStats(
|
||||||
externalSystem, namespace.getNamespaceName(), deploymentResponses
|
externalSystem, namespace.getNamespaceName(), deploymentResponses
|
||||||
);
|
);
|
||||||
|
|
||||||
List<K8sDeployment> deploymentsToSave = new ArrayList<>();
|
List<K8sDeployment> deploymentsToSave = new ArrayList<>();
|
||||||
int unchangedCount = 0; // 统计未变化的资源数量
|
int unchangedCount = 0; // 统计Deployment本身未变化的数量
|
||||||
|
int podStatsOnlyUpdateCount = 0; // 统计仅更新Pod统计信息的数量
|
||||||
|
|
||||||
// 1. 更新/新增K8S中存在的资源
|
// 1. 更新/新增K8S中存在的资源
|
||||||
for (K8sDeploymentResponse response : deploymentResponses) {
|
for (K8sDeploymentResponse response : deploymentResponses) {
|
||||||
K8sDeployment deployment = existingMap.get(response.getName());
|
K8sDeployment deployment = existingMap.get(response.getName());
|
||||||
|
|
||||||
// 增量同步优化:如果资源未变化(resourceVersion相同),跳过
|
// 判断Deployment本身是否变化(通过resourceVersion)
|
||||||
|
boolean deploymentChanged = true;
|
||||||
if (deployment != null &&
|
if (deployment != null &&
|
||||||
response.getResourceVersion() != null &&
|
response.getResourceVersion() != null &&
|
||||||
response.getResourceVersion().equals(deployment.getResourceVersion())) {
|
response.getResourceVersion().equals(deployment.getResourceVersion())) {
|
||||||
|
// Deployment本身未变化,但仍需更新Pod统计信息
|
||||||
|
deploymentChanged = false;
|
||||||
unchangedCount++;
|
unchangedCount++;
|
||||||
log.debug("Deployment {} 未变化,跳过更新", response.getName());
|
log.debug("Deployment {} 本身未变化(resourceVersion相同),但更新Pod统计信息", response.getName());
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deployment == null) {
|
if (deployment == null) {
|
||||||
@ -110,12 +113,17 @@ public class K8sDeploymentServiceImpl extends BaseServiceImpl<K8sDeployment, K8s
|
|||||||
deployment.setNamespaceId(namespace.getId());
|
deployment.setNamespaceId(namespace.getId());
|
||||||
deployment.setDeploymentName(response.getName());
|
deployment.setDeploymentName(response.getName());
|
||||||
log.debug("新增Deployment: {}", response.getName());
|
log.debug("新增Deployment: {}", response.getName());
|
||||||
|
} else if (!deploymentChanged) {
|
||||||
|
// Deployment本身未变化,仅更新Pod统计信息
|
||||||
|
podStatsOnlyUpdateCount++;
|
||||||
} else {
|
} else {
|
||||||
// 如果之前被软删除,恢复它
|
// 如果之前被软删除,恢复它
|
||||||
deployment.setDeleted(false);
|
deployment.setDeleted(false);
|
||||||
log.debug("更新Deployment: {}", response.getName());
|
log.debug("更新Deployment: {}", response.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 只在Deployment本身变化时更新基础信息
|
||||||
|
if (deploymentChanged) {
|
||||||
deployment.setDesiredReplicas(response.getDesiredReplicas());
|
deployment.setDesiredReplicas(response.getDesiredReplicas());
|
||||||
deployment.setCurrentReplicas(response.getCurrentReplicas());
|
deployment.setCurrentReplicas(response.getCurrentReplicas());
|
||||||
deployment.setAvailableReplicas(response.getAvailableReplicas());
|
deployment.setAvailableReplicas(response.getAvailableReplicas());
|
||||||
@ -126,15 +134,43 @@ public class K8sDeploymentServiceImpl extends BaseServiceImpl<K8sDeployment, K8s
|
|||||||
deployment.setLabels(response.getLabels());
|
deployment.setLabels(response.getLabels());
|
||||||
deployment.setSelector(response.getSelector());
|
deployment.setSelector(response.getSelector());
|
||||||
deployment.setK8sCreateTime(response.getCreationTimestamp());
|
deployment.setK8sCreateTime(response.getCreationTimestamp());
|
||||||
deployment.setK8sUpdateTime(response.getLastUpdateTime());
|
|
||||||
deployment.setYamlConfig(response.getYamlConfig());
|
deployment.setYamlConfig(response.getYamlConfig());
|
||||||
|
|
||||||
// 更新resourceVersion字段为新的K8s resourceVersion
|
// 更新resourceVersion字段为新的K8s resourceVersion
|
||||||
deployment.setResourceVersion(response.getResourceVersion());
|
deployment.setResourceVersion(response.getResourceVersion());
|
||||||
|
}
|
||||||
|
|
||||||
// 从批量计算结果中获取重启次数
|
// 从批量计算结果中获取Pod统计信息
|
||||||
Integer totalRestartCount = restartCountMap.get(response.getName());
|
IK8sServiceIntegration.PodStats podStats = podStatsMap.get(response.getName());
|
||||||
deployment.setTotalRestartCount(totalRestartCount != null ? totalRestartCount : 0);
|
if (podStats != null) {
|
||||||
|
deployment.setTotalRestartCount(podStats.getRestartCount());
|
||||||
|
deployment.setActualPodCount(podStats.getActualPodCount());
|
||||||
|
deployment.setRunningPodCount(podStats.getRunningPodCount());
|
||||||
|
deployment.setPendingPodCount(podStats.getPendingPodCount());
|
||||||
|
deployment.setFailedPodCount(podStats.getFailedPodCount());
|
||||||
|
deployment.setSucceededPodCount(podStats.getSucceededPodCount());
|
||||||
|
deployment.setUnknownPodCount(podStats.getUnknownPodCount());
|
||||||
|
deployment.setReadyPodCount(podStats.getReadyPodCount());
|
||||||
|
deployment.setNotReadyPodCount(podStats.getNotReadyPodCount());
|
||||||
|
deployment.setTotalCpuRequest(podStats.getTotalCpuRequest());
|
||||||
|
deployment.setTotalMemoryRequest(podStats.getTotalMemoryRequest());
|
||||||
|
deployment.setTotalCpuLimit(podStats.getTotalCpuLimit());
|
||||||
|
deployment.setTotalMemoryLimit(podStats.getTotalMemoryLimit());
|
||||||
|
} else {
|
||||||
|
deployment.setTotalRestartCount(0);
|
||||||
|
deployment.setActualPodCount(0);
|
||||||
|
deployment.setRunningPodCount(0);
|
||||||
|
deployment.setPendingPodCount(0);
|
||||||
|
deployment.setFailedPodCount(0);
|
||||||
|
deployment.setSucceededPodCount(0);
|
||||||
|
deployment.setUnknownPodCount(0);
|
||||||
|
deployment.setReadyPodCount(0);
|
||||||
|
deployment.setNotReadyPodCount(0);
|
||||||
|
deployment.setTotalCpuRequest("0");
|
||||||
|
deployment.setTotalMemoryRequest("0");
|
||||||
|
deployment.setTotalCpuLimit("0");
|
||||||
|
deployment.setTotalMemoryLimit("0");
|
||||||
|
}
|
||||||
|
|
||||||
deploymentsToSave.add(deployment);
|
deploymentsToSave.add(deployment);
|
||||||
}
|
}
|
||||||
@ -155,9 +191,9 @@ public class K8sDeploymentServiceImpl extends BaseServiceImpl<K8sDeployment, K8s
|
|||||||
|
|
||||||
int syncCount = (int) deploymentResponses.size();
|
int syncCount = (int) deploymentResponses.size();
|
||||||
|
|
||||||
log.info("K8S Deployment同步完成,集群: {}, Namespace: {}, 总数: {}, 更新: {}, 未变化: {}",
|
log.info("K8S Deployment同步完成,集群: {}, Namespace: {}, 总数: {}, 保存: {}, Deployment未变化: {}, 仅更新Pod统计: {}",
|
||||||
externalSystem.getName(), namespace.getNamespaceName(), syncCount,
|
externalSystem.getName(), namespace.getNamespaceName(), syncCount,
|
||||||
deploymentsToSave.size(), unchangedCount);
|
deploymentsToSave.size(), unchangedCount, podStatsOnlyUpdateCount);
|
||||||
return syncCount;
|
return syncCount;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1499,6 +1499,24 @@ CREATE TABLE deploy_k8s_deployment
|
|||||||
updated_replicas INT NULL COMMENT '已更新副本数(来自status.updatedReplicas,已更新到最新版本的Pod数)',
|
updated_replicas INT NULL COMMENT '已更新副本数(来自status.updatedReplicas,已更新到最新版本的Pod数)',
|
||||||
unavailable_replicas INT NULL COMMENT '不可用副本数(来自status.unavailableReplicas,不可用的Pod数)',
|
unavailable_replicas INT NULL COMMENT '不可用副本数(来自status.unavailableReplicas,不可用的Pod数)',
|
||||||
total_restart_count INT NULL COMMENT '总重启次数(所有Pod的重启次数总和)',
|
total_restart_count INT NULL COMMENT '总重启次数(所有Pod的重启次数总和)',
|
||||||
|
actual_pod_count INT NULL COMMENT '实际Pod总数(通过Pod API统计,包括所有状态的Pod:Running/Failed/Pending等)',
|
||||||
|
|
||||||
|
-- Pod Phase统计(通过Pod API聚合)
|
||||||
|
running_pod_count INT NULL COMMENT 'Running状态的Pod数量',
|
||||||
|
pending_pod_count INT NULL COMMENT 'Pending状态的Pod数量',
|
||||||
|
failed_pod_count INT NULL COMMENT 'Failed状态的Pod数量',
|
||||||
|
succeeded_pod_count INT NULL COMMENT 'Succeeded状态的Pod数量',
|
||||||
|
unknown_pod_count INT NULL COMMENT 'Unknown状态的Pod数量',
|
||||||
|
|
||||||
|
-- Pod Ready统计(通过Pod API聚合)
|
||||||
|
ready_pod_count INT NULL COMMENT 'Ready状态的Pod数量(所有容器健康检查通过)',
|
||||||
|
not_ready_pod_count INT NULL COMMENT 'Not Ready状态的Pod数量(至少一个容器健康检查未通过)',
|
||||||
|
|
||||||
|
-- Pod资源统计(通过Pod API聚合)
|
||||||
|
total_cpu_request VARCHAR(50) NULL COMMENT 'CPU请求总和(如"2000m"或"2")',
|
||||||
|
total_memory_request VARCHAR(50) NULL COMMENT '内存请求总和(如"4Gi")',
|
||||||
|
total_cpu_limit VARCHAR(50) NULL COMMENT 'CPU限制总和',
|
||||||
|
total_memory_limit VARCHAR(50) NULL COMMENT '内存限制总和',
|
||||||
|
|
||||||
image VARCHAR(500) NULL COMMENT '容器镜像',
|
image VARCHAR(500) NULL COMMENT '容器镜像',
|
||||||
labels JSON NULL COMMENT '标签',
|
labels JSON NULL COMMENT '标签',
|
||||||
@ -1507,7 +1525,6 @@ CREATE TABLE deploy_k8s_deployment
|
|||||||
resource_version VARCHAR(50) NULL COMMENT 'K8s资源版本号,用于增量同步',
|
resource_version VARCHAR(50) NULL COMMENT 'K8s资源版本号,用于增量同步',
|
||||||
|
|
||||||
k8s_create_time DATETIME NULL COMMENT 'K8S中的创建时间',
|
k8s_create_time DATETIME NULL COMMENT 'K8S中的创建时间',
|
||||||
k8s_update_time DATETIME NULL COMMENT 'K8S中的更新时间',
|
|
||||||
|
|
||||||
UNIQUE KEY uk_namespace_deployment (namespace_id, deployment_name),
|
UNIQUE KEY uk_namespace_deployment (namespace_id, deployment_name),
|
||||||
INDEX idx_external_system (external_system_id),
|
INDEX idx_external_system (external_system_id),
|
||||||
|
|||||||
@ -12,12 +12,22 @@ INSERT INTO system_release (
|
|||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
'system', NOW(), 'system', NOW(), 1, 0,
|
'system', NOW(), 'system', NOW(), 1, 0,
|
||||||
1.22, 'ALL', NOW(),
|
1.31, 'ALL', NOW(),
|
||||||
'【后端】
|
'【后端】
|
||||||
|
|
||||||
服务器监控网络流量BUG修复:修复 接口中网络流量(rxMBps/txMBps)始终显示为0的问题
|
- 实现K8S多集群接入与管理,支持通过kubeconfig配置连接集群、集群连接测试、集群信息查看。
|
||||||
|
- 实现Deployment列表查询(支持跨Namespace)、详情查看、重启(滚动更新)、扩缩容、副本数实时监控功能。
|
||||||
|
- 实现Pod列表查询、详情查看、日志查看(支持实时日志流)、状态监控(Phase + Ready)功能。
|
||||||
|
- 实现基于resourceVersion的增量同步、批量并行同步(多Namespace)、同步历史记录、性能优化(批量查询+内存聚合)。
|
||||||
|
- 修复K8S Deployment接口中Pod状态统计不完整的问题,新增9个Pod统计字段(actualPodCount、runningPodCount、pendingPodCount、failedPodCount、succeededPodCount、unknownPodCount、readyPodCount、notReadyPodCount、totalRestartCount),用于显示Pod的详细状态分布和重启次数。
|
||||||
|
|
||||||
【前端】
|
【前端】
|
||||||
- 告警规则管理弹窗滚动问题修复',
|
- 实现K8S管理页面的完整功能,包括集群选择、命名空间管理、Deployment列表查询与操作、Pod详情查看与日志监控。
|
||||||
|
- 新增K8S管理页面(/resource/k8s),支持多集群切换、命名空间选择、Deployment列表展示(包含健康状态可视化、副本数监控、Pod状态分布统计)、Deployment操作(重启、扩缩容、删除)、YAML配置查看、标签管理。
|
||||||
|
- 实现Pod列表展开查看功能,支持Pod详情展示(状态、节点、IP、镜像、资源配额)、实时日志查看、YAML配置查看、标签和注解查看。
|
||||||
|
- 实现同步功能,支持手动触发命名空间同步、Deployment同步,查看同步历史记录。
|
||||||
|
- 实现统计卡片展示,包括Deployment总数、健康状态分布(健康/警告/异常)、总重启次数统计。
|
||||||
|
- 实现筛选和搜索功能,支持按健康状态筛选、按名称和镜像搜索、自动刷新(Deployment 30秒、Pod 10秒)。
|
||||||
|
',
|
||||||
0, NULL, NULL, 0
|
0, NULL, NULL, 0
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user