Java 使用fabric8io kubernetes-client操作k8s集群
Java kubernetes-client获取client通过File获取通过数据库字段获取使用client操作k8s集群获取Pod执行kubectl exec pod [-n namespace]cmd读取Pod中的File拓展:OpenShift Client获取OpenShiftClient用途获取clientk8s集群的config文件位于:$HOME/.kube$HOME/.kube/
Java kubernetes-client
获取client
k8s集群的config文件位于:$HOME/.kube
$HOME/.kube/config中包含相关集群、权限验证信息(这里是集群最高权限)
如果需要限制访问权限需要单独生成config文件
Config kubeConfig = new ConfigBuilder()
.withMasterUrl("https://192.168.66.66:666/")
.build()
try (final KubernetesClient client = new DefaultKubernetesClient(config)) {
// Do stuff with client
}
这里额外提供两种获取Config的方法:
通过File获取
File configFile = new File("E:/a/b/config");
final String configYAML = String.join("\n", Files.readAllLines(configFile.toPath()));
Config config = Config.fromKubeconfig(configYAML);
config.setTrustCerts(true);
KubernetesClient client = new DefaultKubernetesClient(config);
通过数据库字段获取
// get the KubernetesClient by clusterCode
public KubernetesClient getKubernetesClient(int id) throws IOException {
// 从数据库查询config文件的字节数组
CustomerEntity entity= customerService.selectById(id);
byte[] configFile = clusterEntity.getConfigFile();
// 创建Config对象
final String configYAML = String.join("\n", byte2yamlString(configFile));
Config config = Config.fromKubeconfig(configYAML);
config.setTrustCerts(true);
return new DefaultKubernetesClient(config);
}
// 参考 Files.readAllLines 源码
private List<String> byte2yamlString(byte[] bytes) throws IOException{
if (bytes == null || bytes.length == 0) {
return null;
}
InputStream inputStream = new ByteArrayInputStream(bytes);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);
List<String> result = new ArrayList<>();
for (;;) {
String line = reader.readLine();
if (line == null)
break;
result.add(line);
}
return result;
}
使用client操作k8s集群
上一步获取的KubernetesClient 可操作集群中的以下资源:
Pods
Service
Deployment
ReplicaSet
ReplicationController
ConfigMap
Secret
Job
CronJob
Namespace
ServiceAccount
Ingress
StatefulSet
DaemonSet
PersistentVolumeClaim
PersistentVolume
NetworkPolicy
PodDisruptionBudget
SelfSubjectAccessReview
SubjectAccessReview
LocalSubjectAccessReview
SelfSubjectRulesReview
Top/Metrics
Generic Resource API
Generic ResourceList API
CustomResourceDefinition
CustomResource Typed API
CustomResource Typeless API
CertificateSigningRequest
SharedInformers
List Options
Delete Options
Watch Options
Log Options
Serializing to yaml
Running a Pod
这里举几个常用的例子:
获取Pod
// 通过指定的namespace和podName直接获取
client.pods().inNamespace(nsName).withName(podName).get()
但这样的方式真正的用途不大,因为你的pod很可能是这样的:
并且当pod重启后,后面的字符串还会发生改变。
虽然可以先获取到PodList,之后在程序中使用podName进行模糊匹配,但这并不是一个很好的解决方式。
pod的name虽然会改变,但是deployment的name不会改变,因此可以通过deploymentName再加上matchLabels获取到对应得PodList(List的长度是由deployment中的spec.replicas 决定的)
// getpod by deploymentName
public Pod getPodByLabel(String clusterCode, String nsName, String deploymentName) throws IOException {
KubernetesClient client = getKubernetesClient(clusterCode);
//通过 deploymentName、namespace 获取matchLabels
Map<String, String> matchLabels = client.apps()
.deployments()
.inNamespace(nsName)
.withName(deploymentName)
.get()
.getSpec()
.getSelector()
.getMatchLabels();
// 获取PodList
List<Pod> items = client.pods().inNamespace(nsName).withLabels(matchLabels).list().getItems();
if (CollectionUtils.isEmpty(items)) {
return null;
}
int podCount = 0;
Iterator<Pod> iterator = items.iterator();
// 检验Pod状态
while (iterator.hasNext()) {
Pod it = iterator.next();
if ("Running".equals(it.getStatus().getPhase())) {
podCount ++;
} else {
iterator.remove();
}
}
// 随机获取单个Pod
double d = Math.random();
int i = (int)(d*100);
int index = i % podCount ;
return items.get(index);
}
执行kubectl exec pod [-n namespace] cmd
ExecWatch watch = client.pods()
.inNamespace(nsName)
.withName(podName)
.inContainer(containerName) // 如果Pod中只有一个容器,不需要指定
.writingOutput(System.out)
.exec("sh", "-c", cmd);
writingOutput() 需要指定一个OutPutStream,可以使用PipedOutputStream获取。
读取Pod中的File
CopyOrReadable<Boolean, InputStream, Boolean> file = client.pods()
.inNamespace(nsName)
.withName(podName)
.inContainer(containerName) // 如果Pod中只有一个容器,不需要指定
.file(fileName);
// 转String
try (InputStream is = file.read()) {
return new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
}
拓展:OpenShift Client
获取OpenShiftClient
Config kubeConfig = new ConfigBuilder()
.withMasterUrl("https://api.ci-ln-3sbdl1b-d5d6b.origin-ci-int-aws.dev.examplecloud.com:6443")
.withOauthToken("xxxxxxxx-41oafKI6iU637-xxxxxxxxxxxxx")
.build())) {
try (final OpenShiftClient client = new DefaultOpenShiftClient(config)) {
// Do stuff with client
}
同样可以通过KubernetesClient 获取 KubernetesClient
KubernetesClient client = new DefaultKubernetesClient();
KubernetesClient openShiftClient = client.adapt(OpenShiftClient.class);
用途
可以直接直接操作一些常用的资源,比如:Prometheus ……
DeploymentConfig
BuildConfig
Route
Project
ImageStream
CatalogSource
PrometheusRule
ServiceMonitor
CluserResourceQuota
ClusterVersion
EgressNetworkPolicy
对于具体资源的操作比直接使用KubernetesClient 略为方便。
参考:kubernetes-client.
更多推荐
所有评论(0)