Kubernetes api微服务开发之service与rc基本操作

目标:完成ServiceReplication Controller服务基本功能(CRUD)的开发,并且基于fabric8类方法优化pod服务代码

基本概念

Replication Controller:定义了一个模板,设定pod副本数,持续监控使pod数始终维持在期望值。
Service:定义了一种特定的服务,创建后在Kubernetes中拥有固定的通信地址,在其生命周期内不会改变,并且能够对外服务,转发外部请求至pod。

Pod代码优化

上一篇博文中使用fabric8框架,采取分别创建对象的方式传入参数,不够简洁,本文使用各资源对象类的创建方法进行代码优化:在DevK8sApiService.java中使用PodBuilder方法

//创建Pod
public static Pod createPod(String nsName, String podName, String labelkey, String labelvalue, String containerName, String imageName, int cnPort) {
    Pod pod = new PodBuilder()
            .withApiVersion("v1")
            .withKind("Pod")
            .withNewMetadata()
            .withName(podName)
            .withNamespace(nsName)
            .addToLabels(labelkey, labelvalue)
            .endMetadata()
            .withNewSpec()
            .addNewContainer()
            .withName(containerName)
            .withImage(imageName)
            .addNewPort()
            .withContainerPort(cnPort)
            .endPort()
            .endContainer()
            .endSpec()
            .build();
    try {
        //Pod 创建
        kubernetesClient.pods().create(pod);
        log.info("pod create success");
    } catch (Exception e) {
        log.error("pod create failed");
        log.error("", e);
    }
    return pod;
}

//删除pod
public Pod deletePod(String namespaceName, String podName) {
    Pod pod = new Pod();
    try {
        //获取要删除的pod
        pod = kubernetesClient.pods().inNamespace(namespaceName).withName(podName).get();
        //Pod 删除
        kubernetesClient.pods().inNamespace(namespaceName).withName(podName).delete();
        log.info("pod delete success");
    } catch (Exception e) {
        log.error("pod create failed");
        log.error("", e);
    }
    return pod;
}

//查询pod
public Pod readPod(String namespaceName, String podName) {
    Pod pod = new Pod();
    try {
        //获取要查询的pod
        pod = kubernetesClient.pods().inNamespace(namespaceName).withName(podName).get();
        log.info("pod read success");
    } catch (Exception e) {
        log.error("pod read failed");
        log.error("", e);
    }
    return pod;
}

Replication Controller服务基本功能开发

与pod服务开发类似,使用资源对象类的基本方法实现rc服务的CRUD功能

(1)DevK8sApiService.java

//创建Replication Controller
public ReplicationController createRC(String rcName, String nsName, String lbkey, String lbvalue, int replicas, String ctName, String imName, int cnPort) {
    ReplicationController rc = new ReplicationControllerBuilder()
            .withApiVersion("v1")
            .withKind("ReplicationController")
            .withNewMetadata()
            .withName(rcName)
            .withNamespace(nsName)
            .addToLabels(lbkey, lbvalue)
            .endMetadata()
            .withNewSpec()
            .withReplicas(replicas)
            .addToSelector(lbkey, lbvalue)
            .withNewTemplate()
            .withNewMetadata()
            .addToLabels(lbkey, lbvalue)
            .endMetadata()
            .withNewSpec()
            .addNewContainer()
            .withName(ctName)
            .withImage(imName)
            .addNewPort()
            .withContainerPort(cnPort)
            .endPort()
            .endContainer()
            .endSpec()
            .endTemplate()
            .endSpec()
            .build();
    try {
        kubernetesClient.replicationControllers().create(rc);
        log.info("replication controller create success");
    } catch (Exception e) {
        log.error("replication controller create failed");
        log.error("", e);
    }
    return rc;
}

//删除Replication Controller
public ReplicationController deleteRC(String nsName, String rcName) {
    ReplicationController rc = new ReplicationController();
    try {
        rc = kubernetesClient.replicationControllers().inNamespace(nsName).withName(rcName).get();
        kubernetesClient.replicationControllers().inNamespace(nsName).withName(rcName).delete();
        log.info("replication controller delete success");
    } catch (Exception e) {
        log.error("replication controller delete failed");
        log.error("", e);
    }
    return rc;
}

//查询Replication Controller
public ReplicationController readRC(String nsName, String rcName) {
    ReplicationController rc = new ReplicationController();
    try {
        rc = kubernetesClient.replicationControllers().inNamespace(nsName).withName(rcName).get();
        log.info("replication controller read success");
    } catch (Exception e) {
        log.error("replication controller read failed");
        log.error("", e);
    }
    return rc;
}

(2)DevK8sApiController.java

//k8s rc create
@RequestMapping(value = "/createRC", method = RequestMethod.POST)
public ReplicationController createK8sRC(@RequestParam(value = "ReplicationControllerName") String rcName,
                                         @RequestParam(value = "NamespaceName") String nsName,
                                         @RequestParam(value = "LabelKey") String lbkey,
                                         @RequestParam(value = "LabelValue") String lbvalue,
                                         @RequestParam(value = "Replicas") int replicas,
                                         @RequestParam(value = "ContainerName") String ctName,
                                         @RequestParam(value = "ImageName") String imName,
                                         @RequestParam(value = "ContainerPort") int cnPort) {
    return devK8sApiService.createRC(rcName, nsName, lbkey, lbvalue, replicas, ctName, imName, cnPort);
}

//k8s rc delete
@RequestMapping(value = "/deleteRC", method = RequestMethod.DELETE)
public ReplicationController deleteK8sRC(@RequestParam(value = "NamespaceName") String nsName,
                                         @RequestParam(value = "ReplicationControllerName") String rcName) {
    return devK8sApiService.deleteRC(nsName, rcName);
}

//k8s rc read
@RequestMapping(value = "/readRC", method = RequestMethod.GET)
public ReplicationController readK8sRC(@RequestParam(value = "NamespaceName") String nsName,
                                       @RequestParam(value = "ReplicationControllerName") String rcName) {
    return devK8sApiService.readRC(nsName, rcName);
}

Service服务基本功能开发

(1)DevK8sApiService.java

//创建Service
public Service createService(String seriveName, String nsName, String labelkey, String labelvalue, int cnPort, int nodePort) {
    Service service = new ServiceBuilder()
            .withApiVersion("v1")
            .withKind("Service")
            .withNewMetadata()
            .withName(seriveName)
            .withNamespace(nsName)
            .addToLabels(labelkey, labelvalue)
            .endMetadata()
            .withNewSpec()
            .addNewPort()
            .withPort(cnPort)
            .withNodePort(nodePort)
            .endPort()
            .withType("NodePort")
            .addToSelector(labelkey, labelvalue)
            .endSpec()
            .build();
    try {
        kubernetesClient.services().create(service);
        log.info("service create success");
    } catch (Exception e) {
        log.error("service create failed");
        log.error("", e);
    }
    return service;
}

//删除Service
public Service deleteService(String namespaceName, String serviceName) {
    Service service = new Service();
    try {
        service = kubernetesClient.services().inNamespace(namespaceName).withName(serviceName).get();
        kubernetesClient.services().inNamespace(namespaceName).withName(serviceName).delete();
        log.info("service delete success");
    } catch (Exception e) {
        log.error("service delete failed");
        log.error("", e);
    }
    return service;
}

//查询Service
public Service readService(String namespaceName, String serviceName) {
    Service service = new Service();
    try {
        service = kubernetesClient.services().inNamespace(namespaceName).withName(serviceName).get();
        log.info("service read success");
    } catch (Exception e) {
        log.error("service read failed");
        log.error("", e);
    }
    return service;
}

(2)DevK8sApiController.java

//k8s service create
@RequestMapping(value = "/createService", method = RequestMethod.POST)
public Service createK8sService(@RequestParam(value = "ServiceName") String srName,
                                @RequestParam(value = "NameSpaceName") String nsName,
                                @RequestParam(value = "LabelKey") String lbkey,
                                @RequestParam(value = "LabelValue") String lbvalue,
                                @RequestParam(value = "ContainerPort") int cnPort,
                                @RequestParam(value = "NodePort") int ndPort) {
    return devK8sApiService.createService(srName, nsName, lbkey, lbvalue, cnPort, ndPort);
}

//k8s service delete
@RequestMapping(value = "/deleteService", method = RequestMethod.DELETE)
public Service deleteK8sService(@RequestParam(value = "NamespaceName") String nsName,
                                @RequestParam(value = "ServiceName") String srName) {
    return devK8sApiService.deleteService(nsName, srName);
}

//k8s service read
@RequestMapping(value = "/readService", method = RequestMethod.GET)
public Service readK8sService(@RequestParam(value = "NamespaceName") String nsName,
                              @RequestParam(value = "ServiceName") String srName) {
    return devK8sApiService.readService(nsName, srName);
}

运行测试

测试:使用nginx镜像定义一个3副本RC,并定义一个Service以NodePort方式对接pods

RC创建

POST: http://127.0.0.1:8080/k8s/createRC
Content-Type: application/x-www-form-urlencoded
Body: {"ReplicationControllerName":"nginx-rc-1.17.0", "NameSpaceName":"appblog", "LabelKey":"name", "LabelValue":"nginx-1.17.0", "Replicas":"3", "ContainerName":"nginx-1170", "ImageName":"nginx", "ContainerPort":"80"}

{
    "apiVersion": "v1",
    "kind": "ReplicationController",
    "metadata": {
        "annotations": {},
        "labels": {
            "name": "nginx-1.17.0"
        },
        "name": "nginx-rc-1.17.0",
        "namespace": "appblog"
    },
    "spec": {
        "replicas": 3,
        "selector": {
            "name": "nginx-1.17.0"
        },
        "template": {
            "metadata": {
                "annotations": {},
                "labels": {
                    "name": "nginx-1.17.0"
                }
            },
            "spec": {
                "containers": [
                    {
                        "image": "nginx",
                        "name": "nginx-1170",
                        "ports": [
                            {
                                "containerPort": 80
                            }
                        ]
                    }
                ],
                "nodeSelector": {}
            }
        }
    }
}

结果查询

[root@k8s-master ~]# kubectl get rc -n appblog
NAME              DESIRED   CURRENT   READY   AGE
nginx-rc-1.17.0   3         3         3       8m14s
[root@k8s-master ~]# kubectl get pods -n appblog
NAME                    READY   STATUS    RESTARTS   AGE
nginx-rc-1.17.0-9fkq6   1/1     Running   0          8m6s
nginx-rc-1.17.0-dj2ft   1/1     Running   0          8m6s
nginx-rc-1.17.0-gwj7w   1/1     Running   0          8m6s

RC查询

URL: http://127.0.0.1:8080/k8s/readRC?NamespaceName=appblog&ReplicationControllerName=nginx-rc-1.17.0

{
    "apiVersion": "v1",
    "kind": "ReplicationController",
    "metadata": {
        "creationTimestamp": "2019-06-14T14:13:19Z",
        "generation": 1,
        "labels": {
            "name": "nginx-1.17.0"
        },
        "name": "nginx-rc-1.17.0",
        "namespace": "appblog",
        "resourceVersion": "355429",
        "selfLink": "/api/v1/namespaces/appblog/replicationcontrollers/nginx-rc-1.17.0",
        "uid": "8f4391ef-8eae-11e9-b4ff-525400a204f6"
    },
    "spec": {
        "replicas": 3,
        "selector": {
            "name": "nginx-1.17.0"
        },
        "template": {
            "metadata": {
                "labels": {
                    "name": "nginx-1.17.0"
                }
            },
            "spec": {
                "containers": [
                    {
                        "image": "nginx",
                        "imagePullPolicy": "Always",
                        "name": "nginx-1170",
                        "ports": [
                            {
                                "containerPort": 80,
                                "protocol": "TCP"
                            }
                        ],
                        "resources": {},
                        "terminationMessagePath": "/dev/termination-log",
                        "terminationMessagePolicy": "File"
                    }
                ],
                "dnsPolicy": "ClusterFirst",
                "restartPolicy": "Always",
                "schedulerName": "default-scheduler",
                "securityContext": {},
                "terminationGracePeriodSeconds": 30
            }
        }
    },
    "status": {
        "availableReplicas": 3,
        "fullyLabeledReplicas": 3,
        "observedGeneration": 1,
        "readyReplicas": 3,
        "replicas": 3
    }
}

Service创建

POST: http://127.0.0.1:8080/k8s/createService
Content-Type: application/x-www-form-urlencoded
Body: {"ServiceName":"nginx-service-1170", "NameSpaceName":"appblog", "LabelKey":"name", "LabelValue":"nginx-1.17.0", "ContainerPort":"80", "NodePort":"30080"}

{
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        "annotations": {},
        "labels": {
            "name": "nginx-1.17.0"
        },
        "name": "nginx-service-1170",
        "namespace": "appblog"
    },
    "spec": {
        "ports": [
            {
                "nodePort": 30080,
                "port": 80
            }
        ],
        "selector": {
            "name": "nginx-1.17.0"
        },
        "type": "NodePort"
    }
}

查询结果

[root@k8s-master ~]# kubectl get service -n appblog
NAME                 TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
nginx-service-1170   NodePort   10.97.37.57   <none>        80:30080/TCP   29s

服务测试

访问http://NodeIP:30080,其中NodeIP可以是任意一个集群节点的IP

查询Service

URL: http://127.0.0.1:8080/k8s/readService?NamespaceName=appblog&ServiceName=nginx-service-1170

{
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        "creationTimestamp": "2019-06-14T14:31:06Z",
        "labels": {
            "name": "nginx-1.17.0"
        },
        "name": "nginx-service-1170",
        "namespace": "appblog",
        "resourceVersion": "355029",
        "selfLink": "/api/v1/namespaces/appblog/services/nginx-service-1170",
        "uid": "0b7ad5bf-8eb1-11e9-b4ff-525400a204f6"
    },
    "spec": {
        "clusterIP": "10.97.37.57",
        "externalTrafficPolicy": "Cluster",
        "ports": [
            {
                "nodePort": 30080,
                "port": 80,
                "protocol": "TCP",
                "targetPort": 80
            }
        ],
        "selector": {
            "name": "nginx-1.17.0"
        },
        "sessionAffinity": "None",
        "type": "NodePort"
    },
    "status": {
        "loadBalancer": {}
    }
}

删除RC及Service

(1)删除RC

DELETE: http://127.0.0.1:8080/k8s/deleteRC
Content-Type: application/x-www-form-urlencoded
Body: {"NameSpaceName":"appblog", "ReplicationControllerName":"nginx-rc-1.17.0"}

(2)删除Service

DELETE: http://127.0.0.1:8080/k8s/deleteService
Content-Type: application/x-www-form-urlencoded
Body: {"NameSpaceName":"appblog", "ServiceName":"nginx-service-1170"}

结果查询

[root@k8s-master ~]# kubectl get rc -n appblog
No resources found.
[root@k8s-master ~]# kubectl get service -n appblog
No resources found.

以上,功能测试完成。

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/23/basic-operations-of-service-and-rc-for-kubernetes-api-microservice-development/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Kubernetes api微服务开发之service与rc基本操作
目标:完成Service与Replication Controller服务基本功能(CRUD)的开发,并且基于fabric8类方法优化pod服务代码 基本概念 Replication Controller:定义了一个……
<<上一篇
下一篇>>
文章目录
关闭
目 录