目录

  • 引言
  • Client认证方式
  • CRD客户定义资源的API
  • watch过于敏感


引言

参考连接:github kubernetes-client参考连接:K8s api reference K8S API即K8S集群提供的RESTFUL接口,通过接口可以操作K8S集群资源(可以理解为kubectl的restful api版),例如可以进行list、read、patch、replace、create、delete、watch等操作。
可通过K8S官方维护的Java库访问K8S集群的API接口,
示例代码:

import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.util.Config;
import com.google.gson.reflect.TypeToken;
import io.kubernetes.client.openapi.models.V1Namespace;
import io.kubernetes.client.util.Watch;

import java.io.IOException;

public class Example {
    public static void main(String[] args) throws IOException, ApiException{
        //加载默认配置
        ApiClient client = Config.defaultClient();
        Configuration.setDefaultApiClient(client);
        
        CoreV1Api api = new CoreV1Api();
        //查询pod列表
        V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null);
        for (V1Pod item : list.getItems()) {
            System.out.println(item.getMetadata().getName());
        }
        
        //监控namespace变化
        Watch<V1Namespace> watch = Watch.createWatch(
                client,
                api.listNamespaceCall(null, null, null, null, null, 5, null, null, Boolean.TRUE, null, null),
                new TypeToken<Watch.Response<V1Namespace>>(){}.getType());

        for (Watch.Response<V1Namespace> item : watch) {
            System.out.printf("%s : %s%n", item.type, item.object.getMetadata().getName());
        }
    }
}

Client认证方式

关于K8S api接口认证方式可以通过查看源码Config.defaultClient()发现,分为以下三种:

k8s init aggregate api 开启 k8s api调用_直接访问

k8s init aggregate api 开启 k8s api调用_.net_02

(1)从环境变量KUBECONFIG获取config文件位置并解析;

(2)从路径$HOME/.kube/config获取config文件位置并解析;

(3)获取k8s容器内serviceAccount的ca.crt和token信息;

可见方式(1)、(2)适用于程序运行在K8S节点的宿主机上,即节点上存在$HOME/.kube/config文件,同时通过方式(1)也可实现本地开发联调K8S API,即在本地$HOME/.kube/config文件路径下设置对应的K8S集群的config文件即可,之后client程序会自动加载该config文件(实际测试时可直接通过config文件中的server直接访问k8s api,即可在非K8S 集群pod内可直接访问K8S API,无需认证);

k8s init aggregate api 开启 k8s api调用_直接访问_03


关于config文件基本结构如下:

k8s init aggregate api 开启 k8s api调用_API_04


clusters:定义k8s集群列表

users:定义k8s用户列表

contexts:定义集群+用户绑定关系列表

在kubectl中可通过kubectl config use-context {contextName}来进行切换

而方式(3)适用于程序运行在K8S的POD中,即POD中容器会自动生成serviceAccount的相关信息,同时若想使用api需要先设置RBAC(参考:Kubernetes分布式任务调度方案 - K8s API替代zookeeper),设置完RBAC后即可在K8S POD中通过如下命令直接访问K8S API:

curl -v 
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" 
https://kubernetes.default:443/api/v1/namespaces/youNamespace/pods?labelSelector=app=youAppLabel

CRD客户定义资源的API

可查看对应的crd定义,然后根据crd中资源的相关定义来拼接对应的restful api uri,例如Istio中VirtualService的crd定义如下:

root@k8s-node-01:~/.kube# kubectl edit -n istio-system crd virtualservices.networking.istio.io 

# reopened with the relevant failures.
#
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  annotations:
    helm.sh/resource-policy: keep
    kubectl.kubernetes.io/last-applied-configuration: |
  creationTimestamp: "2019-05-20T09:13:02Z"
  generation: 1
  labels:
    app: istio-pilot
    chart: istio
    heritage: Tiller
    release: istio
  name: virtualservices.networking.istio.io
  resourceVersion: "15386455"
  selfLink: /apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/virtualservices.networking.istio.io
  uid: 7831b266-7adf-11e9-92ef-00e0665bc0bf
spec:
  additionalPrinterColumns:
  - JSONPath: .spec.gateways
    description: The names of gateways and sidecars that should apply these routes
    name: Gateways
    type: string
  - JSONPath: .spec.hosts
    description: The destination hosts to which traffic is being sent
    name: Hosts
    type: string
  - JSONPath: .metadata.creationTimestamp
    description: |-

      Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
    name: Age
    type: date
  conversion:
    strategy: None
  group: networking.istio.io
  names:
    categories:
    - istio-io
    - networking-istio-io
    kind: VirtualService
    listKind: VirtualServiceList
    plural: virtualservices
    shortNames:
    - vs
    singular: virtualservice
  scope: Namespaced
  version: v1alpha3
  versions:
  - name: v1alpha3
    served: true
    storage: true
status:
  acceptedNames:
    categories:
    - istio-io
    - networking-istio-io
    kind: VirtualService
    listKind: VirtualServiceList
    plural: virtualservices
    shortNames:
    - vs
    singular: virtualservice
  conditions:
  - lastTransitionTime: "2019-05-20T09:13:02Z"
    message: no conflicts found
    reason: NoConflicts
    status: "True"
    type: NamesAccepted
  - lastTransitionTime: null
    message: the initial names have been accepted
    reason: InitialNamesAccepted
    status: "True"
    type: Established
  storedVersions:
  - v1alpha3

可提取CRD中的相关属性拼接对应的K8S API url如下:

https://kubernetes.default:443/apis/{spec.group}/{spec.version}/namespaces/{resouceNamespace}/{spec.names.plural}

例如查询Istio VirtualService定义的url最终如下:

https://kubernetes.default:443/apis/networking.istio.io/v1alpha3/namespaces/tsp/virtualservices/my-vs

watch过于敏感

例如对deployment修改了配置(本示例修改了limits.cpu)后,会在一秒内同时收到4个通知,之后在deployment管理的pod副本数稳定后,又再收到2个通知。本来想通过watch机制来实时同步K8s资源信息,但是由于watch太过敏感,最终采用了定时调度来同步k8s资源,如每隔1小时同步一次,同时支持紧急情况下手动触发同步。

k8s init aggregate api 开启 k8s api调用_直接访问_05