1. 前言
kubernetes及各开源社区为开发人员提供了各种语言版的Client Library,让我们可以通过编程的方式可以实现调用Kubernetes API,从而完成pod、service、RC等资源的图形化创建和管理。本篇主要介绍使用java语言的实现
2. 使用场景
开发基于kubernetes的容器云管理平台
3. 基于的框架
用java语言开发的有两种,一个是基于Jersey的,一个是基于Fabric8。
-Jersey是一个方便简化开发RESRFul Web Service的框架,契合kubernetesAPI的设计,所以采用jersey会比较省力,但还是需要开发者自己做很多工作。
-Fabric8中的kubernates-client.xx.jar,kubernates-model.xx.jar等工具包包对kubernates api做了很好的封装,访问代码比较简单。
本篇将选择fabric8实现
4. 使用步骤
4.1 首先导入核心jar包
4.2 创建连接API-Server的client
package org.demo.framework.engine.k8s.util;
import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.api.model.extensions.*;
import io.fabric8.kubernetes.api.model.extensions.Deployment;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.*;
import okhttp3.TlsVersion;
import org.apache.log4j.Logger;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class Fabric8KubeUtils implements KubeUtils<KubernetesClient> {
private KubernetesClient client;
private static final int CONNECTION_TIMEOUT = 3 * 1000;
private static final int REQUEST_TIMEOUT = 3 * 1000;
private static Logger logger = Logger.getLogger(Fabric8KubeUtils.class);
@Override
public KubernetesClient getClient() {
return client;
}
@Override
public void setClient(KubernetesClient client) {
this.client = client;
}
private Fabric8KubeUtils(KubernetesClient client) {
this.client = client;
}
/**传入参数,连接k8s的api server**/
public static KubeUtils buildKubeUtils(Cluster cluster, String namespace) throws K8sDriverException {
if (cluster == null) {
throw new K8sDriverException("cluster is null");
}
String key = cluster.md5Key(namespace);
if (KUBEUTILSMAP.containsKey(key)) {
return KUBEUTILSMAP.get(key);
}
String master = cluster.getApi();
master = CommonUtil.fullUrl(master);
if (StringUtils.isBlank(master)) {
throw new K8sDriverException("master api is null, cluster id=" + cluster.getId() + ", cluster name=" + cluster.getName());
}
Config config;
if (master.toLowerCase().startsWith("https://")) {
config = new ConfigBuilder().withMasterUrl(master)
.withTrustCerts(true)
.withNamespace(namespace)
.withOauthToken(cluster.getOauthToken())
.withUsername(cluster.getUsername())
.withPassword(cluster.getPassword())
.removeFromTlsVersions(TlsVersion.TLS_1_0)
.removeFromTlsVersions(TlsVersion.TLS_1_1)
.removeFromTlsVersions(TlsVersion.TLS_1_2)
.withRequestTimeout(REQUEST_TIMEOUT)
.withConnectionTimeout(CONNECTION_TIMEOUT)
.build();
} else {
config = new ConfigBuilder().withMasterUrl(master)
.withNamespace(namespace)
.withOauthToken(cluster.getOauthToken())
.withUsername(cluster.getUsername())
.withPassword(cluster.getPassword())
.removeFromTlsVersions(TlsVersion.TLS_1_0)
.removeFromTlsVersions(TlsVersion.TLS_1_1)
.removeFromTlsVersions(TlsVersion.TLS_1_2)
.withTrustCerts(true)
.withRequestTimeout(REQUEST_TIMEOUT)
.withConnectionTimeout(CONNECTION_TIMEOUT)
.build();
}
KubeUtils kubeUtils = buildKubeUtils(config);
KUBEUTILSMAP.putIfAbsent(key, kubeUtils);
return kubeUtils;
}
/**创建client**/
public static KubeUtils buildKubeUtils(Config config) throws K8sDriverException {
KubernetesClient client;
try {
client = new DefaultKubernetesClient(config);
} catch (Exception e) {
throw new K8sDriverException("instantialize kubernetes client error");
}
return new Fabric8KubeUtils(client);
}
}
4.3 创建k8s的资源对象,作为参传给client操作k8s(增删改时需要)
// 可以通过k8s??Builder()来创建资源对象
// 如下创建一个service对象,lb为包含service必要信息的实体类对象
Service newService = new K8sServiceBuilder(lb).build();
4.4 通过得到的client,可以对k8s的各种资源增删改查各种操作:
Nodes
Namespaces
Services
Replicationcontrollers
Pods
Deployments
Resourcequotas
/**创建pod**/
@Override
public Pod createPod(Pod pod)
throws K8sDriverException {
logger.debug("create pod with specify=" + pod.toString());
try {
return client.pods().create(pod);
} catch (KubernetesClientException e) {
throw new K8sDriverException(e.getMessage());
}
}
/**创建service**/
@Override
public Service createService(Service service)
throws K8sDriverException {
logger.debug("create service=" + service);
if (service == null) {
return null;
}
try {
return client.services().create(service);
} catch (KubernetesClientException e) {
throw new K8sDriverException(e.getMessage());
}
}
/**创建RC**/
@Override
public ReplicationController createReplicationController(ReplicationController rc)
throws K8sDriverException {
if (rc == null) {
return null;
}
logger.debug("create replication controller with rc=\n" + rc);
try {
return client.replicationControllers().create(rc);
} catch (KubernetesClientException e) {
throw new K8sDriverException(e.getMessage());
}
}
/**创建deployment**/
@Override
public Deployment createDeployment(Deployment deployment) throws K8sDriverException {
if (deployment == null) {
return null;
}
logger.debug("create deployment with deployment=\n" + deployment);
try {
return client.extensions().deployments().create(deployment);
} catch (KubernetesClientException e) {
throw new K8sDriverException(e.getMessage());
}
}
/**按条件列出所有node**/
@Override
public NodeList listNode(Map<String, String> labelSelector) throws K8sDriverException {
logger.debug("list node with selector=" + labelSelector);
try {
return client.nodes().withLabels(labelSelector).list();
} catch (KubernetesClientException e) {
throw new K8sDriverException(e.getMessage());
}
}