【Java】基于fabric8io库操作k8s集群实战(pod、deployment、service、volume)

目录

    • 前言
    • 一、基于fabric8io操作pod
      • 1.1 yaml创建pod
      • 1.2 fabric8io创建pod案例
    • 二、基于fabric8io创建Service(含Deployment)
      • 2.1 yaml创建Service和Deployment
      • 2.2 fabric8io创建service案例
    • 三、基于fabric8io操作Volume
      • 3.1 yaml配置挂载存储卷
      • 3.2 基于fabric8io实现挂载存储卷

前言

一开始了解到Java Api库操作k8s集群,有两个,分别为:

  • kubernetes-client/java
  • fabric8io/kubernetes-client

但个人对比使用了两个发现,还是fabric8io更易用,用的人多是有道理的,fabric8io和yaml文件十分贴切,所以通俗易懂。本文前提是已配置好集群,已经熟悉了kubectl工具常用命令。

首先,需要导入fabric8io依赖核心库,如下:

<dependency><groupId>io.fabric8</groupId><artifactId>kubernetes-client</artifactId><version>6.3.1</version>
</dependency>

注:本文采用6.3.1版本,截止2023年12月14日,官方最新版本为6.9.2版本,如果你k8s是最新版本,那么可考虑最新版本。

如果你需要看官方api操作文档,可参考:官方使用说明

如果你初学k8s,关于k8s的基本概念和常用操作不熟强推先读另一个博主的文章:Kubernetes核心概念及命令使用

一、基于fabric8io操作pod

定义:pod 是包含一个或多个容器的容器组,是 Kubernetes 中创建和管理的最小对象。

1.1 yaml创建pod

如果我们在k8s集群上创建一个pod,常常会编写yaml文件,例如deploy.yaml

apiVersion: v1  
kind: Pod  
metadata:  name: cm-nginxlabels:  app: cm-nginx
spec:  containers:  - name: nginximage: nginx:latestports:  - containerPort: 80

编写好后执行:kubectl apply -f deploy.yaml,就会创建一个pod

1.2 fabric8io创建pod案例

首先,需要在k8s集群master上获取到/root/.kube/config文件,文件内容大致如下,证书密钥太长,省略,这个文件记录了连接k8s集群的信息,fabric8io操作集群就需要该文件。

注:只要你需要连接集群,就需要基于config文件,下载下来

apiVersion: v1
clusters:
- cluster:certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t..............server: https://192.168.20.130:6443name: kubernetes
contexts:
- context:cluster: kubernetesuser: kubernetes-adminname: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-adminuser:client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ................client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVk.................

将config文件下载到本地,就可以对pod进行CRUD操作,本文放在resources目录下

import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.apache.commons.io.FileUtils;import java.io.File;
import java.nio.charset.StandardCharsets;public class PodCrudExample {public static void main(String[] args) {String kubeConfigPath  = "D:\\IDEAProject\\k8sApi\\src\\main\\resources\\config";KubernetesClient client;try {client = new DefaultKubernetesClient(Config.fromKubeconfig(FileUtils.readFileToString(new File(kubeConfigPath), StandardCharsets.UTF_8)));// 创建 Pod// createPod(client);// 读取 Pod// readPod(client);// 更新 Pod// updatePod(client);// 删除 Pod// deletePod(client);} catch (Exception e) {e.printStackTrace();}}private static void createPod(KubernetesClient client) {// 创建 Pod 对象Pod pod = new PodBuilder().withNewMetadata().withName("my-pod-nginx").endMetadata().withNewSpec().addNewContainer().withName("nginx").withImage("nginx:latest").endContainer().endSpec().build();// 在指定的命名空间中创建 Podclient.pods().inNamespace("default").resource(pod).create();System.out.println("Pod created successfully.");}private static void readPod(KubernetesClient client) {// 读取 PodPod pod = client.pods().inNamespace("default").withName("my-pod-nginx").get();System.out.println("Pod read successfully:");System.out.println(pod);}private static void updatePod(KubernetesClient client) {// k8s禁止直接对容器中镜像进行更新操作,k8s更新本质还是删除原有的,然后根据配置创建新的// 删除旧的 Podclient.pods().inNamespace("default").withName("my-pod-nginx").delete();// 创建新的 Pod 对象Pod pod = new PodBuilder().withNewMetadata().withName("my-pod-tomcat").endMetadata().withNewSpec().addNewContainer().withName("tomcat").withImage("tomcat:latest").endContainer().endSpec().build();// 在指定的命名空间中创建新的 Podclient.pods().inNamespace("default").resource(pod).create();System.out.println("Pod updated successfully.");}private static void deletePod(KubernetesClient client) {// 删除 Pod,默认关闭期限30秒,即最多等待30秒// 这涉及k8s提供的优雅终止机制,允许容器有时间完成必要的清理工作client.pods().inNamespace("default").withName("my-pod-tomcat").delete();}
}

上面是创建一个普通的pod,无自愈、容灾等能力,一般我们会用deployment方式创建,deployment创建会在第二节【基于fabric8io创建Service】一并写到,因为Service和Deployment一般是一起使用的

二、基于fabric8io创建Service(含Deployment)

概念网络访问归Service管理,它用于定义一组 Pod 并提供这些 Pod 的稳定访问点,主要用于服务发现和负载均衡

Service 可以有不同的类型,其中最常见的两种类型是 ClusterIP (默认)和 NodePort

  • 当你创建一个 Service,类型为 ClusterIP 时,K8s 会为该 Service 分配一个集群地址(集群内部使用,外部不可见
  • NodePort 类型的 Service 具有 ClusterIP 的所有特性,同时还会在每个集群节点上映射一个静态端口(NodePort),这使得外部流量可以通过任何集群节点的 NodePort 访问 Service(外部可访问

2.1 yaml创建Service和Deployment

(1)先用Deployment创建两个pod副本,deploy_dep.yaml

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: my-depname: my-dep
spec:replicas: 2	# 副本数selector:matchLabels:app: my-deptemplate:	# 创建pod模板metadata:labels:app: my-depspec:containers:- image: nginxname: nginx

(2)创建Service,deploy_svc.yaml

apiVersion: v1
kind: Service
metadata:labels:app: my-depname: my-svc
spec:selector:app: my-dep	# 表示选择只代理具有标签(键值对)app: my-dep的podports:- port: 8000	# 表示 Service 在集群内部监听的端口targetPort: 80	# 表示将 Service 接收到的流量转发到 Pod 的 80 端口type: NodePort

kubectl apply -f xxx.yaml,先后执行Deployment和Service

如图,访问时会轮巡方式,将接收到的流量转发到对应两个pod的80端口(targetPort)
在这里插入图片描述
由于配置的是NodePort,所以在浏览器输入任意节点ip:暴露的端口号,官方规定了NodePort范围在 30000-32767 之间,这里分配的是32385,那么公网通过该端口可以访问到集群,公网的流量都会经过NodePort暴露的32385端口,转发到targetPort,即80端口。

总结:Service就像一个网关,只负责网络流量的分配和转发,比如将流量转发到部署的两个pod中,两个pod中目前部署的都是nginx容器。

2.2 fabric8io创建service案例

import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.api.model.apps.*;
import io.fabric8.kubernetes.client.*;
import io.fabric8.kubernetes.client.Config;
import org.apache.commons.io.FileUtils;import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;public class KubernetesDeployer {public static void main(String[] args) {String kubeConfigPath  = "D:\\IDEAProject\\k8sApi\\src\\main\\resources\\config";KubernetesClient client;try {client = new DefaultKubernetesClient(Config.fromKubeconfig(FileUtils.readFileToString(new File(kubeConfigPath), StandardCharsets.UTF_8))).inNamespace("default");// 1、创建 Deployment(2个pod)Map<String, String> labels = new HashMap();labels.put("app", "my-dep-fabric8");Deployment deployment = new DeploymentBuilder().withNewMetadata().withName("my-dep-fabric8").withLabels(labels).endMetadata().withNewSpec().withReplicas(2).withNewSelector().withMatchLabels(labels).endSelector().withNewTemplate().withNewMetadata().withLabels(labels).endMetadata().withNewSpec().withContainers(new ContainerBuilder().withName("mynginx").withImage("nginx").build()).endSpec().endTemplate().endSpec().build();client.apps().deployments().inNamespace("default").resource(deployment).create();// 2、创建 ServiceService service = new ServiceBuilder().withNewMetadata().withName("my-svc-fabric8").withLabels(labels) // 代理具有labels标签的pod.endMetadata().withNewSpec().withSelector(labels).withPorts(new ServicePortBuilder().withPort(8000) // 集群内部监听的端口.withNewTargetPort(80)  // 流量转发的目标端口.build()).withType("NodePort").endSpec().build();client.services().inNamespace("default").resource(service).create();System.out.println("Service Create Successfully");} catch (Exception e) {e.printStackTrace();}}
}

创建后,设置了NodePort,故用Ip+NodePort可以公网访问,但是两个nginx默认index.html都是Welcome to nginx,可以用echo "11112222" > index.html改动一个nginx容器的index.html页面。

注:用kubectl exec -it pod_name -- /bin/bash进入容器,默认这个页面就在/usr/shared/nginx/html/下。
在这里插入图片描述

三、基于fabric8io操作Volume

概念:存储卷(Volume)分为临时卷持久卷,在 Kubernetes 中,Volume 是一种抽象,用于表示容器中可以访问的存储

PV(PersistentVolume)

持久卷是集群级别的资源,它是集群中的一块持久化存储资源,可以由多个 Pod 共享。PV 可以来自集群中的各种存储后端,比如云存储、网络存储、本地存储等。PV 与实际的存储资源相对应。

PVC(PersistentVolumeClaim)

PersistentVolumeClaim 是对持久化存储资源的声明。它是一个请求,用于获取持久 Volume 的一部分或全部存储容量。PVC 允许开发者声明对存储资源的需求,而不用关心底层存储是如何实现的。

关系

PersistentVolumeClaim 是对存储资源的声明,而 Volume实际的存储资源。开发者通过 PVC 声明存储需求,并请求系统提供符合这些需求的 PersistentVolume(PV,实际存储卷)。

PV生命周期状态

Available(可用)、Bound(已绑定)、Released(已释放)、Failed(失败)

总结:即一个负责申明存储,一个是实际存储资源

3.1 yaml配置挂载存储卷

(1)创建一个 PersistentVolume(PV),类型为 nfs

apiVersion: v1
kind: PersistentVolume
metadata:name: my-nfs-pv
spec:capacity:storage: 300Mi	# 允许多个 Pod 以读写多模式访问,i是二进制volumeMode: FilesystemaccessModes:- ReadWriteManystorageClassName: nfsnfs:server: 192.168.20.133   # NFS 服务器地址path: /nfs/data/shared/  # 共享的目录

(2)创建 PersistentVolumeClaim (PVC)来请求使用这个 NFS 存储卷

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-nfs-pvc01labels:app: my-pvc
spec:accessModes:- ReadWriteManyresources:requests:storage: 200Mi	# Kubernetes 推荐使用二进制单位i,以避免混淆,确保一致性storageClassName: nfs

(3)创建Pod(可多个)

apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: mynginximage: nginxvolumeMounts:- name: pvc-html	# 这里的 name 对应 volumes 中的 namemountPath: "/mount/data"volumes:- name: pvc-html	# 这里的 name 是存储卷的名称persistentVolumeClaim:claimName: my-nfs-pvc

注:普通方式直接创建,此处未用Deployment创建pod

一旦 PVC 与 PV 绑定,Pod 只需声明使用该 PVC,而不需要显式绑定到 PV,Pod就能共享pvc对应的pv存储卷资源。

解释:如上,pv共享目录是/nfs/data/shared/,pvc和pv绑定后,创建pod容器对应的mountPath为/mount/data,那么/nfs/data/shared/中的内容就会挂载到pod定义的路径/mount/data中,实现多个pod共享存储卷pv中的内容。

为什么两个name要一致?(即例子pvc-html)

volumeMounts定义了存储卷挂载到容器中的路径,其中name 字段指定了与 volumes 中相应存储卷的名称。这样 K8s 就知道将哪个卷挂载到容器的哪个路径上。如果名字不一致,pod就不知道去找哪个存储卷挂载到对应路径。

在这里插入图片描述

3.2 基于fabric8io实现挂载存储卷

package com.yx.mount_volume;import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.apache.commons.io.FileUtils;import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Collections;/*** 挂载存储卷*/
public class MountVolumeExample {public static void main(String[] args) {String kubeConfigPath  = "D:\\IDEAProject\\k8sApi\\src\\main\\resources\\config";KubernetesClient client;try {client = new DefaultKubernetesClient(Config.fromKubeconfig(FileUtils.readFileToString(new File(kubeConfigPath), StandardCharsets.UTF_8))).inNamespace("default");// 1、创建 PersistentVolumePersistentVolume nfsPv = new PersistentVolumeBuilder().withNewMetadata().withName("my-pv-fabric8").endMetadata().withNewSpec().withCapacity(Collections.singletonMap("storage", new Quantity("100Mi"))).withAccessModes("ReadWriteMany").withPersistentVolumeReclaimPolicy("Retain").withStorageClassName("nfs").withNfs(new NFSVolumeSourceBuilder().withServer("192.168.20.133").withPath("/nfs/data/shared/").build()).endSpec().build();client.persistentVolumes().resource(nfsPv).create();// 2、创建 PersistentVolumeClaimPersistentVolumeClaim nfsPvc = new PersistentVolumeClaimBuilder().withNewMetadata().withName("my-pvc-fabric8").endMetadata().withNewSpec().withAccessModes("ReadWriteMany").withResources(new ResourceRequirementsBuilder().addToRequests("storage", new Quantity("80Mi")).build()).withStorageClassName("nfs").endSpec().build();client.persistentVolumeClaims().resource(nfsPvc).create();// 3、创建 Pod,并挂载 PersistentVolumeClaimPod pod = new PodBuilder().withNewMetadata().withName("my-pod-fabric8").endMetadata().withNewSpec().addNewContainer().withName("my-container").withImage("nginx").addNewVolumeMount().withName("pvc-fabric8").withMountPath("/mount/nginx/html/")    // 挂载到的目录.endVolumeMount().endContainer().addNewVolume().withName("pvc-fabric8").withPersistentVolumeClaim(new PersistentVolumeClaimVolumeSourceBuilder().withClaimName("my-pvc-fabric8").build()).endVolume().endSpec().build();client.pods().inNamespace("default").resource(pod).create();System.out.println("Pod created successfully.");} catch (Exception e) {e.printStackTrace();}}
}

以上为全部内容!有问题可以评论区交流讨论噢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/230372.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HBuilder X将Vue打包APP返回上一页退出问题、清除缓存页面历史防止返回登录页(上一页)、以及状态栏颜色切换

目录 一、返回上一页退出问题 二、清除缓存页面历史防止返回上一页 三、状态栏颜色切换 一、返回上一页退出问题 1.首先重新认识一下vue的页面跳转&#xff0c;这里我只说常用到的两个 goSkip(){//直接跳转this.$router.push(/test);this.$router.replace(/test);//带参数跳…

『 Linux 』重新理解挂起状态

文章目录 &#x1f984; 前言新建状态 &#x1f40b;挂起状态 &#x1f40b;唤入唤出 &#x1f40b;进程与操作系统间的联系 &#x1f40b; &#x1f984; 前言 『 Linux 』使用fork函数创建进程与进程状态的查看中提到了对挂起状态的一个理解&#xff1b; ​ 挂起状态相比于其…

LearnDash LMS ProPanel在线学习系统课程创作者的分析工具

点击阅读LearnDash LMS ProPanel在线学习系统课程创作者的分析工具原文 LearnDash LMS ProPanel在线学习系统课程创作者的分析工具通过整合报告和作业管理来增强您的 LearnDash 管理体验&#xff0c;使您能够发送特定于课程的通信&#xff0c;并显示课程的实时活动&#xff01…

Postgresql在Windows中使用pg_dump实现数据库(指定表)的导出与导入

场景 Windows中通过bat定时执行命令和mysqldump实现数据库备份&#xff1a; Windows中通过bat定时执行命令和mysqldump实现数据库备份_mysqldump bat-CSDN博客 Windows上通过bat实现不同数据库之间同步部分表的部分字段数据&#xff1a; Windows上通过bat实现不同数据库之间…

YOLOv5改进 | SPPF | 将RT-DETR模型AIFI模块和Conv模块结合替换SPPF(全网独家改进)

一、本文介绍 本文给大家带来是用最新的RT-DETR模型中的AIFI模块来替换YOLOv5中的SPPF。RT-DETR号称是打败YOLO的检测模型&#xff0c;其作为一种基于Transformer的检测方法&#xff0c;相较于传统的基于卷积的检测方法&#xff0c;提供了更为全面和深入的特征理解&#xff0c…

【Hadoop面试】HDFS读写流程

HDFS&#xff08;Hadoop Distributed File System&#xff09;是GFS的开源实现。 HDFS架构 HDFS是一个典型的主/备&#xff08;Master/Slave&#xff09;架构的分布式系统&#xff0c;由一个名字节点Namenode(Master) 多个数据节点Datanode(Slave)组成。其中Namenode提供元数…

neuq-acm预备队训练week 10 P1525 [NOIP2010 提高组] 关押罪犯

解题思路 本题用并查集的方法 AC代码 #include <bits/stdc.h> using namespace std; int f[55555]; struct S {int a,b,c;friend inline bool operator<(S a, S b){return a.c>b.c;} } d[100000];int find(int x) {return f[x]x? x:(f[x]find(f[x])); }int mai…

易点易动固定资产管理系统——提升固定资产管理透明度和可靠性

通过全面的资产跟踪、准确的数据记录和实时的报告分析&#xff0c;易点易动系统为企业提供了全新的固定资产管理解决方案&#xff0c;帮助企业实现高效、精确的资产管理&#xff0c;提高运营效率&#xff0c;降低风险&#xff0c;实现可持续发展。 固定资产是企业重要的资源和投…

2019系统修复

修改启动顺序 尝试从最后一次正确配置启动 然后删除最后安全的程序。 准备usb系统盘 用系统引导盘进入命令提示符 chkdsk c: 在只读模式看下是否磁盘有问题。 sfc /scannow命令 在管理员命令提示符窗口输入&#xff1a;sfc /scannow命令。 复制&#xff1a;sfc /scanno…

倚力未来:人工智能智能辅助医疗的前景与挑战

导言 人工智能在医疗领域的应用正迅速发展&#xff0c;为医疗行业带来了新的可能性。本文将深入探讨人工智能在医疗中的智能辅助应用&#xff0c;以及这一趋势面临的前景和挑战。智慧医疗是指通过先进的信息技术&#xff0c;如人工智能、物联网、大数据等&#xff0c;实现医疗数…

使用Pytorch从零开始构建StyleGAN2

这篇博文是关于 StyleGAN2 的&#xff0c;来自论文Analyzing and Improving the Image Quality of StyleGAN&#xff0c;我们将使用 PyTorch 对其进行干净、简单且可读的实现&#xff0c;并尝试尽可能地还原原始论文。 如果您没有阅读 StyleGAN2 论文。或者不知道它是如何工作…

如何戒掉懒惰这个坏习惯?

懒惰是一个常见的坏习惯&#xff0c;它会阻碍我们的进步&#xff0c;影响我们的生活质量。然而&#xff0c;戒掉懒惰并不容易&#xff0c;需要付出一定的努力和毅力。本文将介绍几种方法来戒掉懒惰习惯&#xff0c;帮助你走上一个积极向上的道路。首先&#xff0c;认识到懒惰的…

【MATLAB】数据拟合第11期-基于粒子群迭代的拟合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 基于粒子群迭代的拟合算法是一种优化技术&#xff0c;它基于粒子群优化算法&#xff08;PSO&#xff09;的基本思想。该算法通过群体中个体之间的协作和信息共享来寻找最优解。 在基于粒…

iPhone16:首款AI iPhone?

随着科技水平的不断发展&#xff0c;智能手机逐渐成为人们最依赖的电子产品之一。为能够满足用户需求&#xff0c;手机的硬件、外观设计与性能飞速提升&#xff0c;这也导致智能手机市场快速进入到瓶颈期。 为了能够带来更优秀的表现&#xff0c;苹果可能会为iPhone 16系列带来…

CSS学习笔记整理

CSS 即 层叠样式表/CSS样式表/级联样式表&#xff0c;也是标记语言&#xff0c; 用于设置HTML页面中的文本内容&#xff08;字体、大小、对齐方式等&#xff09;、图片的外形&#xff08;宽高、边框样式、边距&#xff09;以及版面的布局和外观显示样式 目录 准备工作 Chrome调…

Leetcode221 最大正方形

最大正方形 题解1 DP题解2 暴力(参考) 在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内&#xff0c;找到 只包含 ‘1’ 的最大正方形&#xff0c;并返回其面积。 提示&#xff1a; m matrix.length, n matrix[i].length1 < m, n < 300matrix[i][j] 为 ‘0’ 或 ‘1’ 题解…

mybatis中oracle的sql没走索引导致特别慢(未加jdbcType的)

如果直接跑sql是能走索引很快&#xff0c;在mybatis中不能&#xff0c;可能就是jdbcType的原因。 比如&#xff0c;我有一个属性A&#xff0c;在表里面是VARCHAR2类型&#xff0c;但是在mybatis中的sql是#{a}&#xff0c;缺少jdbcTypeJdbcType.VARCHAR&#xff0c;就会导致myba…

猜数字小游戏(猜错了会关机推荐让室友帮你玩)

前言 今天来带大家写一个简易的猜数字小游戏&#xff0c;如果连着猜错n次&#xff08;自己设定&#xff09;就会导致电脑关机&#xff0c;还在等什么呢&#xff1f;赶紧学会咯&#xff0c;发给你的室友让他帮你玩吧&#xff01; 正文 随机数的生成 首先我们还要学会如何创建随…

vue :SPA首屏加载速度慢的怎么解决?

一、什么是首屏加载 首屏时间&#xff08;First Contentful Paint&#xff09;&#xff0c;指的是浏览器从响应用户输入网址地址&#xff0c;到首屏内容渲染完成的时间&#xff0c;此时整个网页不一定要全部渲染完成&#xff0c;但需要展示当前视窗需要的内容 首屏加载可以说…

智能手表上的音频(五):录音

上篇讲了语音通话&#xff0c;本篇讲录音。录音功能就是把录到的音频保存成文件。保存文件的格式支持两种&#xff1a;一是PCM(16K采样)的WAV格式&#xff0c;二是AMR-NB&#xff08;8k采样&#xff09;的AMR格式。WAV格式简单&#xff1a;44字节的文件头PCM 数据&#xff0c;示…