2021年6月19日星期六

java使用io.kubernetes.client-java调用k8s api创建pod/service/ingress示例

1.maven配置

<!-- k8s client --><dependency> <groupId>io.kubernetes</groupId> <artifactId>client-java</artifactId> <version>12.0.1</version></dependency>    

2.工具类

/** * k8s客户端 * * @author wanghuidong * @date 2021/6/18 14:14 */@Slf4jpublic class K8sClient { /**  * k8s-api客户端  */ private ApiClient apiClient; /**  * 构建集群POD内通过SA访问的客户端  * loading the in-cluster config, including:  * 1. service-account CA  * 2. service-account bearer-token  * 3. service-account namespace  * 4. master endpoints(ip, port) from pre-set environment variables  */ public K8sClient() {  try {   this.apiClient = ClientBuilder.cluster().build();  } catch (IOException e) {   log.error("构建K8s-Client异常", e);   throw new RuntimeException("构建K8s-Client异常");  } } /**  * 构建集群外通过UA访问的客户端  * loading the out-of-cluster config, a kubeconfig from file-system  *  * @param kubeConfigPath kube连接配置文件  */ public K8sClient(String kubeConfigPath) {  try {   this.apiClient = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();  } catch (IOException e) {   log.error("读取kubeConfigPath异常", e);   throw new RuntimeException("读取kubeConfigPath异常");  } catch (Exception e) {   log.error("构建K8s-Client异常", e);   throw new RuntimeException("构建K8s-Client异常");  } } /**  * 获取所有的Pod  *  * @return podList  */ public V1PodList getAllPodList() {  // new a CoreV1Api  CoreV1Api api = new CoreV1Api(apiClient);  // invokes the CoreV1Api client  try {   V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null);   return list;  } catch (ApiException e) {   log.error("获取podlist异常:" + e.getResponseBody(), e);  }  return null; } /**  * 创建k8s service  *  * @param namespace 命名空间  * @param serviceName 服务名称  * @param port  服务端口号(和目标pod的端口号一致)  * @param selector pod标签选择器  * @return 创建成功的service对象  */ public V1Service createService(String namespace, String serviceName, Integer port, Map<String, String> selector) {  //构建service的yaml对象  V1Service svc = new V1ServiceBuilder()    .withNewMetadata()    .withName(serviceName)    .endMetadata()    .withNewSpec()    .addNewPort()    .withProtocol("TCP")    .withPort(port)    .withTargetPort(new IntOrString(port))    .endPort()    .withSelector(selector)    .endSpec()    .build();  // Deployment and StatefulSet is defined in apps/v1, so you should use AppsV1Api instead of CoreV1API  CoreV1Api api = new CoreV1Api(apiClient);  V1Service v1Service = null;  try {   v1Service = api.createNamespacedService(namespace, svc, null, null, null);  } catch (ApiException e) {   log.error("创建service异常:" + e.getResponseBody(), e);  } catch (Exception e) {   log.error("创建service系统异常:", e);  }  return v1Service; } /**  * 创建k8s V1Ingress  *  * @param namespace 命名空间  * @param ingressName ingress名称  * @param annotations ingress注解  * @param path  匹配的路径  * @param serviceName 路由到的服务名称  * @param servicePort 路由到的服务端口  * @return 创建成功的ingress对象  */ public V1Ingress createV1Ingress(String namespace, String ingressName, Map<String, String> annotations, String path,          String serviceName, Integer servicePort) {  //构建ingress的yaml对象  V1Ingress ingress = new V1IngressBuilder()    .withNewMetadata()    .withName(ingressName)    .withAnnotations(annotations)    .endMetadata()    .withNewSpec()    .addNewRule()    .withHttp(new V1HTTPIngressRuleValueBuilder().addToPaths(new V1HTTPIngressPathBuilder()      .withPath(path)      .withPathType("Prefix")      .withBackend(new V1IngressBackendBuilder()        .withService(new V1IngressServiceBackendBuilder()          .withName(serviceName)          .withPort(new V1ServiceBackendPortBuilder()            .withNumber(servicePort).build()).build()).build()).build()).build())    .endRule()    .endSpec()    .build();  //调用对应的API执行创建ingress的操作  NetworkingV1Api api = new NetworkingV1Api(apiClient);  V1Ingress v1Ingress = null;  try {   v1Ingress = api.createNamespacedIngress(namespace, ingress, null, null, null);  } catch (ApiException e) {   log.error("创建ingress异常:" + e.getResponseBody(), e);  } catch (Exception e) {   log.error("创建ingress系统异常:", e);  }  return v1Ingress; } /**  * 创建k8s ExtensionIngress  *  * @param namespace 命名空间  * @param ingressName ingress名称  * @param annotations ingress注解  * @param path  匹配的路径  * @param serviceName 路由到的服务名称  * @param servicePort 路由到的服务端口  * @return 创建成功的ingress对象  */ public ExtensionsV1beta1Ingress createExtensionIngress(String namespace, String ingressName, Map<String, String> annotations, String path,               String serviceName, Integer servicePort) {  //构建ingress的yaml对象  ExtensionsV1beta1Ingress ingress = new ExtensionsV1beta1IngressBuilder()    .withNewMetadata()    .withName(ingressName)    .withAnnotations(annotations)    .endMetadata()    .withNewSpec()    .addNewRule()    .withHttp(new ExtensionsV1beta1HTTPIngressRuleValueBuilder().addToPaths(new ExtensionsV1beta1HTTPIngressPathBuilder()      .withPath(path)      .withBackend(new ExtensionsV1beta1IngressBackendBuilder()        .withServiceName(serviceName)        .withServicePort(new IntOrString(servicePort)).build()).build()).build())    .endRule()    .endSpec()    .build();  //调用对应的API执行创建ingress的操作  ExtensionsV1beta1Api api = new ExtensionsV1beta1Api(apiClient);  ExtensionsV1beta1Ingress extensionsV1beta1Ingress = null;  try {   extensionsV1beta1Ingress = api.createNamespacedIngress(namespace, ingress, null, null, null);  } catch (ApiException e) {   log.error("创建ingress异常:" + e.getResponseBody(), e);  } catch (Exception e) {   log.error("创建ingress系统异常:", e);  }  return extensionsV1beta1Ingress; }}

 

3.测试类

/** * @author wanghuidong * @date 2021/6/18 14:33 */public class K8sClientTest {// @Test public void getAllPodListTest() {  String kubeConfigPath = "C:\\Users\\admin\\.kube\\config";  if (!new File(kubeConfigPath).exists()) {   System.out.println("kubeConfig不存在,跳过");   return;  }  K8sClient k8sClient = new K8sClient(kubeConfigPath);  V1PodList podList = k8sClient.getAllPodList();  for (V1Pod item : podList.getItems()) {   System.out.println(item.getMetadata().getNamespace() + ":" + item.getMetadata().getName());  } }// @Test public void createServiceTest() {  String kubeConfigPath = "C:\\Users\\admin\\.kube\\config";  if (!new File(kubeConfigPath).exists()) {   System.out.println("kubeConfig不存在,跳过");   return;  }  K8sClient k8sClient = new K8sClient(kubeConfigPath);  String namespace = "default";  String serviceName = "my-nginx-service";  Integer port = 80;  Map<String, String> selector = new HashMap<>();  selector.put("run", "my-nginx");  V1Service v1Service = k8sClient.createService(namespace, serviceName, port, selector);  System.out.println(v1Service != null ? v1Service.getMetadata() : null); }// @Test public void createV1IngressTest() {  String kubeConfigPath = "C:\\Users\\admin\\.kube\\config";  if (!new File(kubeConfigPath).exists()) {   System.out.println("kubeConfig不存在,跳过");   return;  }  K8sClient k8sClient = new K8sClient(kubeConfigPath);  String namespace = "default";  String ingressName = "my-nginx-ingress";  Map<String, String> annotations = new HashMap<>();  annotations.put("nginx.ingress.kubernetes.io/rewrite-target", "/");  String path = "/my-nginx";  String serviceName = "my-nginx-service";  Integer servicePort = 80;  V1Ingress v1Ingress = k8sClient.createV1Ingress(namespace, ingressName, annotations, path, serviceName, servicePort);  System.out.println(v1Ingress != null ? v1Ingress.getMetadata() : null); }// @Test public void createExtensionIngressTest() {  String kubeConfigPath = "C:\\Users\\admin\\.kube\\config";  if (!new File(kubeConfigPath).exists()) {   System.out.println("kubeConfig不存在,跳过");   return;  }  K8sClient k8sClient = new K8sClient(kubeConfigPath);  String namespace = "default";  String ingressName = "my-nginx-ingress";  Map<String, String> annotations = new HashMap<>();  annotations.put("nginx.ingress.kubernetes.io/rewrite-target", "/");  String path = "/my-nginx";  String serviceName = "my-nginx-service";  Integer servicePort = 80;  ExtensionsV1beta1Ingress extensionsV1beta1Ingress = k8sClient.createExtensionIngress(namespace, ingressName, annotations, path, serviceName, servicePort);  System.out.println(extensionsV1beta1Ingress != null ? extensionsV1beta1Ingress.getMetadata() : null); }}

 

4.附录

4.1 创建pod应用

my-nginx.yaml

apiVersion: apps/v1kind: Deploymentmetadata: name: my-nginxspec: selector: matchLabels:  run: my-nginx replicas: 2 template: metadata:  labels:  run: my-nginx spec:  containers:  - name: my-nginx  image: nginx  ports:  - containerPort: 80

应用部署单,生成pod

kubectl apply -f ./my-nginx.yaml

查看相关pod信息
kubectl get pods -l run=my-nginx -o wide

 

4.2 创建service

my-nginx-service.yaml

apiVersion: v1kind: Servicemetadata: name: my-nginx-service labels: run: my-nginx-servicespec: ports: - port: 80 targetPort: 80 protocol: TCP selector: run: my-nginx  

应用service单,创建service

kubectl apply -f ./my-nginx-service.yaml

查看相关服务
kubectl get svc my-nginx-service

查询服务详情
kubectl describe svc my-nginx-service

查看service后端结点
kubectl get ep my-nginx-service

 

4.3 创建ingress(ExtensionV1beta1)

my-nginx-ingress.yaml

apiVersion: extensions/v1beta1kind: Ingressmetadata: name: my-nginx-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /spec: rules: - http:  paths:  - path: /my-nginx  backend:   serviceName: my-nginx-service   servicePort: 80

应用ingress单,创建ingress

kubectl apply -f ./my-nginx-ingress.yaml

查看ingress

kubectl get ingress

 

4.4 创建Ingress(V1)

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: my-nginx-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /spec: rules: - http:  paths:  - path: /my-nginx  pathType: Prefix  backend:   service:   name: my-nginx-service   port:    number: 80

 

4.5 相关概念总结

k8s中配置客户端访问pod中应用的流程如下:

client->ingress->service->pod->container

 

INGRESS

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。

Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

 

SERVICE

将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。 Service 所针对的 Pods 集合通常是通过选择算符来确定的。

 

POD

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。

Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的"逻辑主机",其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。

 

节点(Node)

Kubernetes 集群中其中一台工作机器,是集群的一部分。

 

集群(Cluster)

一组运行由 Kubernetes 管理的容器化应用程序的节点。 在此示例和在大多数常见的 Kubernetes 部署环境中,集群中的节点都不在公共网络中。

 









原文转载:http://www.shaoqun.com/a/815626.html

跨境电商:https://www.ikjzd.com/

老师你的好大好紧好多水 老师今晚让你爽个够:http://lady.shaoqun.com/a/248300.html

你家老公是怎么上你的 宝贝好想让你㖭我下面:http://www.30bags.com/m/a/249888.html

在教室深深挺进同桌花蕊里 脱下漂亮班花校裙按着臀强行干:http://lady.shaoqun.com/m/a/246826.html

办公室销魂刺激的一次 院长的粗大满足了我:http://lady.shaoqun.com/a/247620.html


1.maven配置<!--k8sclient--><dependency><groupId>io.kubernetes</groupId><artifactId>client-java</artifactId><version>12.0.1</version></dependency>2.工
加拿大旅游全攻略 :http://www.30bags.com/a/408731.html
张开腿,捅烂你 嗯啊,那晚表嫂的诱惑让我彻底失去理智:http://lady.shaoqun.com/a/274665.html
小说:他和妻子分居,很久没有见面。他们实际上利用他们的工作来骚扰女性尸体:http://lady.shaoqun.com/a/320331.html
那一夜他把我做到喷水 火车上爱爱好爽好刺激:http://lady.shaoqun.com/a/248425.html
口述强壮的公么征服我 公让我欲仙欲死3b:http://lady.shaoqun.com/a/247070.html
甘肃省文旅厅迅速贯彻落实省新型冠状病毒感染的肺炎疫情联防联控工作领导小组会议精神:http://www.30bags.com/a/426284.html
甘肃省召开2021年劳动节假期全省旅游景区有序开放管理工作电视电话会议:http://www.30bags.com/a/426645.html
甘肃十大特色美食推荐 - :http://www.30bags.com/a/407377.html
口述:小姨子与姐夫之间那些不要脸的事儿(上)(4/4):http://lady.shaoqun.com/a/82892.html
三亚亚特兰蒂斯水世界需要带什么?准备什么东西?:http://www.30bags.com/a/443878.html
苏念的婚外情故事(1):http://www.30bags.com/a/443879.html
真实故事:为了一部苹果手机,我成了别人的情人:http://www.30bags.com/a/443880.html

没有评论:

发表评论