使用Fabric8访问Kubernetes API&&K8S集群安全机制

近期在项目中需要获取一些Kubernetes REST API来获取集群的相关信息,于是使用了fabric8这个库创建Java-Client,获取资源信息,也可以对资源进行增删改查等操作。本文只介绍创建Client和获取资源信息这部分。
在创建访问API的客户端的时候涉及到身份认证和API server授权,这是集群安全机制的一部分。所以在文章中介绍的也只是开发中会遇到的这方面的问题,以及一些浅薄的扩展知识。

创建Client

在获取资源所在的类GetInfo中首先要做的就是创建Client

KubernetesClient client=GetClient.getClient("MasterIp");

即输入一个MasterIp,就可以通过GetClient类中的静态工厂方法创建一个客户端实例。(这里参考Effective Java中的第一条)
我在GetClient工厂类中写了两个静态方法,代码如下:

//每个key都是String类型的MasterIp,对应一个Client对象
private static Map<String, KubernetesClient> clientMap = new HashMap<>();
private String token="xxxx"; 

//先查询,没有则创建新的实例对象
public static KubernetesClient getClient(String k8sMasterIp) {
        if (!clientMap.containsKey(k8sMasterIp)) {
            synchronized (K8sClient.class) {
                if (!clientMap.containsKey(k8sMasterIp)) {
                    KubernetesClient client = createClient(k8sMasterIp);
                    clientMap.put(k8sMasterIp, client);
                    return client;
                }
            }
        }
        return CLIENTS.get(k8sMasterIp);
    }

    //使用Token通过身份认证,其他参数使用默认配置,创建一个新的client
    private static KubernetesClient createClient(String k8sMasterIp) {
        Config config = new ConfigBuilder()
//                .withUsername("user01")
                .withOauthToken(token)
                .withTrustCerts(true)
                .withMasterUrl("https://" + k8sMasterIp + ":6443/")
                .build();
        return new DefaultKubernetesClient(config);
    }

先在getClient方法中寻找masterIp对应的客户端实例对象。
createClient是在客户端的Map里没有找到输入的masterIp对应的客户端实例时,调用这个方法创建一个新的客户端。

扩展:
集群安全的关键就是客户端身份的认证(Authentication)和访问权限的授权(Authorization)。客户端身份认证有三种方式:
1.最严格的HTTPs证书认证:是基于CA根证书签名的双向数字证书认证方式。
2.HTTP Token认证:通过一个Token来识别合法用户。
3.HTTP Base认证:通过用户名+密码的方式认证。
代码中withOauthToken中填入的token是之前搭集群的dashboard的时候创建的service account,因为用这个token的用户权限可以对集群资源进行操作(dashboard的那些操作)。后来也试着用了一下default secret中的token,发现是无法访问的(所属的用户权限不够)。
关于Token和Oauth认证方式的说明可以看这个:http://www.361way.com/token-auth/5844.html

上一步提到的service account创建并绑定用户角色的步骤如下:
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
K8S的RABC机制,(Role-based access control)
简单的理解就是权限与角色关联,用户成为角色的成员来得到角色的权限。(此外还有ABAC模式的授权策略-使用用户配置的授权规则去匹配用户的请求。)
绑定的是“cluster-admin”这个角色。每个role中定义一些权限,roleBinding可以把这些权限分配给一些用户和用户组。(Namespace内用rolebinding,集群范围内使用clusterRoleBinding)
Verbs有get, list, watch, create, update, patch, delete, exec
资源有nodes, pods, deployments, services, endpoints, secrets 等等


获取资源信息

KubernetesClient client=GetClient.getClient("MasterIp");
        NodeList nodeList=client.nodes().list();
        //podList也能得到
        PodList podList=client.pods().list();

        for(Node node:nodeList.getItems()){
            //得到node名,加入只保存name的列表
            String nodeName=node.getMetadata().getName();
            if(nodeName!=null){
                nodeNameList.add(nodeName);
            }
            //可测试
            System.out.println(nodeName);
        }
        //实际上在Prometheus中对pod信息的查询也只需要$node$就行,这里可以查询资源yaml中定义的pod信息
        for(Pod pod:podList.getItems()){
            String podName=pod.getMetadata().getName();
            if(podName!=null){
                System.out.println(podName);
            }
        }

第一层的get可以得到下列信息
一级get
第二层的get(Metadata中)可以得到下列信息
得到Labels后可以进行按条件筛选等操作。
二级get
对于得到的一些数据,可以放入Map或List中作为返回值,或者写入一个NodeInfo实体中。


除了获取资源信息之外,还可以对资源进行一些操作(verbs),这个链接中更详细:https://blog.csdn.net/zzq900503/article/details/88352902。

发布了10 篇原创文章 · 获赞 5 · 访问量 1928

猜你喜欢

转载自blog.csdn.net/sparrow12138/article/details/103961729