|
@@ -0,0 +1,115 @@
|
|
|
|
|
+package seecoder.devcloud.core.pipeline.handler;
|
|
|
|
|
+
|
|
|
|
|
+import seecoder.devcloud.api.ApplicationProperties;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.DeploymentApi;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.K8sConstants;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.SecretApi;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.model.Container;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.model.ContainerPort;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.model.Deployment;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.util.SecretTypeEnum;
|
|
|
|
|
+import seecoder.devcloud.api.k8s.vo.SecretVO;
|
|
|
|
|
+import seecoder.devcloud.common.util.SpringUtil;
|
|
|
|
|
+import seecoder.devcloud.core.pipeline.Context;
|
|
|
|
|
+import seecoder.devcloud.core.pipeline.Handler;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.Collections;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @author PuHong Weng
|
|
|
|
|
+ * @date 2021/1/18
|
|
|
|
|
+ * @description: 创建一个k8s Deployment
|
|
|
|
|
+ * 因为是学生的Deployment构建的过程,有以下约束:
|
|
|
|
|
+ * 1. 每个Deployment只允许创建一个Pod,防止资源消耗太多
|
|
|
|
|
+ * 2. 以Group Name,作为Namespace, Project Name来作为Deployment name
|
|
|
|
|
+ * 3. 镜像存放在seecoder的内部私有镜像仓库,所以需要设置
|
|
|
|
|
+ */
|
|
|
|
|
+public class K8sDeploymentHandler extends AbstractHandler {
|
|
|
|
|
+
|
|
|
|
|
+ private final SecretApi secretApi;
|
|
|
|
|
+
|
|
|
|
|
+ private final DeploymentApi deploymentApi;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ //容器所使用的镜像
|
|
|
|
|
+ private String image;
|
|
|
|
|
+
|
|
|
|
|
+ //副本数
|
|
|
|
|
+ private int replicas;
|
|
|
|
|
+
|
|
|
|
|
+ //
|
|
|
|
|
+ private int port;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public K8sDeploymentHandler() {
|
|
|
|
|
+ secretApi = SpringUtil.getBean(SecretApi.class);
|
|
|
|
|
+ deploymentApi = SpringUtil.getBean(DeploymentApi.class);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 部署一个java项目
|
|
|
|
|
+ * 以小组名称作为namespace
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param context
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void process(Context context) {
|
|
|
|
|
+ //配置初始化
|
|
|
|
|
+ initConfig(context);
|
|
|
|
|
+ String groupName = context.getGroupName();
|
|
|
|
|
+ String projectName = context.getProjectName();
|
|
|
|
|
+
|
|
|
|
|
+ //配置容器暴露端口
|
|
|
|
|
+ ContainerPort containerPort = ContainerPort.builder()
|
|
|
|
|
+ .port(port)
|
|
|
|
|
+ .build();
|
|
|
|
|
+ //配置容器
|
|
|
|
|
+ Container container = Container.builder()
|
|
|
|
|
+ .image(image)
|
|
|
|
|
+ .name(projectName + K8sConstants.CONTAINER_SUFFIX)
|
|
|
|
|
+ .ports(Collections.singleton(containerPort))
|
|
|
|
|
+ .build();
|
|
|
|
|
+
|
|
|
|
|
+ //配置deployment
|
|
|
|
|
+ Deployment deployment = Deployment.builder()
|
|
|
|
|
+ .replicas(replicas)
|
|
|
|
|
+ .containers(Collections.singletonList(container))
|
|
|
|
|
+ .build();
|
|
|
|
|
+ deployment.setName(projectName + K8sConstants.DEPLOYMENT_SUFFIX);
|
|
|
|
|
+ deployment.setNamespace(groupName);
|
|
|
|
|
+ deployment.setLabel(K8sConstants.APPLICATION_LABEL, projectName);
|
|
|
|
|
+
|
|
|
|
|
+ // 密钥来源:在命名空间创建时,创建对应的secret存放密钥,见 K8sNamespaceHandler.class
|
|
|
|
|
+ // 将registry密钥作为imagePullSecrets注入, 使得此deployment可以访问私有镜像仓库
|
|
|
|
|
+ List<String> registrySecrets = secretApi
|
|
|
|
|
+ .getSecretListByType(
|
|
|
|
|
+ groupName,
|
|
|
|
|
+ SecretTypeEnum.REGISTRY)
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(SecretVO::getName)
|
|
|
|
|
+ .collect(Collectors.toList()
|
|
|
|
|
+ );
|
|
|
|
|
+ deployment.setImagePullSecrets(registrySecrets);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ K8sObjectRequest request = K8sObjectRequest.builder()
|
|
|
|
|
+ .namespace(groupName)
|
|
|
|
|
+ .name(projectName + K8sConstants.DEPLOYMENT_SUFFIX).build();
|
|
|
|
|
+ if (deploymentApi.getByCondition(request).size() == 0) {
|
|
|
|
|
+ deploymentApi.create(deployment);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ deploymentApi.update(deployment);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void initConfig(Context context) {
|
|
|
|
|
+ this.image = context.getConfigs().getOrDefault("image", "");
|
|
|
|
|
+ this.port = Integer.parseInt(context.getConfigs().getOrDefault("port", "8000"));
|
|
|
|
|
+ this.replicas = Integer.parseInt(context.getConfigs().getOrDefault("replicas", "1"));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|