四川网站建设开发,市场推广计划书,wordpress 2.8,电商设计个人作品集制作目录 前言一、基于fabric8io操作pod1.1 yaml创建pod1.2 fabric8io创建pod案例 二、基于fabric8io创建Service#xff08;含Deployment#xff09;2.1 yaml创建Service和Deployment2.2 fabric8io创建service案例 三、基于fabric8io操作Volume3.1 yaml配置挂载存储卷3.2 基于fa… 目录 前言一、基于fabric8io操作pod1.1 yaml创建pod1.2 fabric8io创建pod案例 二、基于fabric8io创建Service含Deployment2.1 yaml创建Service和Deployment2.2 fabric8io创建service案例 三、基于fabric8io操作Volume3.1 yaml配置挂载存储卷3.2 基于fabric8io实现挂载存储卷 前言
一开始了解到Java Api库操作k8s集群有两个分别为
kubernetes-client/javafabric8io/kubernetes-client
但个人对比使用了两个发现还是fabric8io更易用用的人多是有道理的fabric8io和yaml文件十分贴切所以通俗易懂。本文前提是已配置好集群已经熟悉了kubectl工具常用命令。
首先需要导入fabric8io依赖核心库如下
dependencygroupIdio.fabric8/groupIdartifactIdkubernetes-client/artifactIdversion6.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-adminkubernetes
current-context: kubernetes-adminkubernetes
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: nginx2创建Servicedeploy_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: NodePortkubectl 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)MapString, 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故用IpNodePort可以公网访问但是两个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 是一种抽象用于表示容器中可以访问的存储。
PVPersistentVolume
持久卷是集群级别的资源它是集群中的一块持久化存储资源可以由多个 Pod 共享。PV 可以来自集群中的各种存储后端比如云存储、网络存储、本地存储等。PV 与实际的存储资源相对应。
PVCPersistentVolumeClaim
PersistentVolumeClaim 是对持久化存储资源的声明。它是一个请求用于获取持久 Volume 的一部分或全部存储容量。PVC 允许开发者声明对存储资源的需求而不用关心底层存储是如何实现的。
关系
PersistentVolumeClaim 是对存储资源的声明而 Volume 是实际的存储资源。开发者通过 PVC 声明存储需求并请求系统提供符合这些需求的 PersistentVolumePV实际存储卷。
PV生命周期状态
Available可用、Bound已绑定、Released已释放、Failed失败
总结即一个负责申明存储一个是实际存储资源
3.1 yaml配置挂载存储卷
1创建一个 PersistentVolumePV类型为 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: nfs3创建Pod可多个
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: mynginximage: nginxvolumeMounts:- name: pvc-html # 这里的 name 对应 volumes 中的 namemountPath: /mount/datavolumes:- name: pvc-html # 这里的 name 是存储卷的名称persistentVolumeClaim:claimName: my-nfs-pvc注普通方式直接创建此处未用Deployment创建pod
一旦 PVC 与 PV 绑定Pod 只需声明使用该 PVC而不需要显式绑定到 PVPod就能共享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();}}
}以上为全部内容有问题可以评论区交流讨论噢