带你玩转kubernetes-k8s(第54篇-Kubernetes之使用API聚合机制扩展API资源)

API聚合机制是Kubernetes 1.7版本引入的特性,能够将用户扩展的API注册到kube-apiserver上,仍然通过API Server的HTTP URL对新的API进行访问和操作。为了实现这个机制,Kubernetes在kube-apiserver服务中引入了一个API聚合层(API Aggregation Layer),用于将扩展API的访问请求转发到用户服务的功能。

设计API聚合机制的主要目标如下。

◎ 增加API的扩展性:使得开发人员可以编写自己的API Server来发布他们的API,而无须对Kubernetes核心代码进行任何修改。
◎ 无须等待Kubernetes核心团队的繁杂审查:允许开发人员将其API作为单独的API Server发布,使集群管理员不用对Kubernetes核心代码进行修改就能使用新的API,也就无须等待社区繁杂的审查了。
◎ 支持实验性新特性API开发:可以在独立的API聚合服务中开发新的API,不影响系统现有的功能。
◎ 确保新的API遵循Kubernetes的规范:如果没有API聚合机制,开发人员就可能会被迫推出自己的设计,可能不遵循Kubernetes规范。

    总的来说,API聚合机制的目标是提供集中的API发现机制和安全的代理功能,将开发人员的新API动态地、无缝地注册到Kubernetes API Server中进行测试和使用。

下面对API聚合机制的使用方式进行详细说明。

1.在Master的API Server中启用API聚合功能

为了能够将用户自定义的API注册到Master的API Server中,首先需要配置kube-apiserver服务的以下启动参数来启用API聚合功能。

◎ --requestheader-client-ca-file=/etc/kubernetes/ssl_keys/ca.crt:客户端CA证书。
◎ --requestheader-allowed-names=:允许访问的客户端common names列表,通过header中--requestheader-username-headers参数指定的字段获取。客户端common names的名称需要在client-ca-file中进行设置,将其设置为空值时,表示任意客户端都可访问。
◎ --requestheader-extra-headers-prefix=X-Remote-Extra-::请求头中需要检查的前缀名。
◎ --requestheader-group-headers=X-Remote-Group:请求头中需要检查的组名。
◎ --requestheader-username-headers=X-Remote-User:请求头中需要检查的用户名。
◎ --proxy-client-cert-file=/etc/kubernetes/ssl_keys/kubelet_client.crt:在请求期间验证Aggregator的客户端CA证书。
◎ --proxy-client-key-file=/etc/kubernetes/ssl_keys/kubelet_client.key:在请求期间验证Aggregator的客户端私钥。

如果kube-apiserver所在的主机上没有运行kube-proxy,即无法通过服务的ClusterIP进行访问,那么还需要设置以下启动参数:

--enable-aggregator-routing=true

在设置完成重启kube-apiserver服务,就启用API聚合功能了。

2. 注册自定义APIService资源

    在启用了API Server的API聚合功能之后,用户就能将自定义API资源注册到Kubernetes Master的API Server中了。用户只需配置一个APIService资源对象,就能进行注册了。APIService示例的YAML配置文件如下:

apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  name: v1beta1.custom.metrics.k8s.io
spec:
  service:
    name: custom-metrics-server
    namespace: custom-metrics
  group: custom.metrics.k8s.io
  version: v1beta1
  insecureSkipTLSVerify: true
  groupPriorityMinimum: 100
  versionPriority: 100

      在这个APIService中设置的API组名为custom.metrics.k8s.io,版本号为v1beta1,这两个字段将作API路径的子目录注册到API路径“/apis/”下。注册成功后,就能通过Master API路径“/apis/custom.metrics.k8s.io/v1beta1”访问自定义的API Server了。

在service段中通过name和namespace设置了后端的自定义API Server,本例中的服务名为custom-metrics-server,命名空间为custom-metrics。
       通过kubectl create命令将这个APIService定义发送给Master,就完成了注册操作。
      之后,通过Master API Server对“/apis/custom.metrics.k8s.io/v1beta1”路径的访问都会被API聚合层代理转发到后端服务custom-metrics-server.custom-metrics.svc上了。

3.实现和部署自定义API Server

仅仅注册APIService资源还是不够的,用户对“/apis/custom.metrics.k8s.io/v1beta1”路径的访问实际上都被转发给了custom-metrics-server.custom-metrics.svc服务。这个服务通常能以普通Pod的形式在Kubernetes集群中运行。当然,这个服务需要由自定义API的开发者提供,并且需要遵循Kubernetes的开发规范,详细的开发示例可以参考官方给出的示例(https://github.com/kubernetes/sample-apiserver)。

下面是部署自定义APIServer的常规操作步骤

(1)确保APIService API已启用,这需要通过kube-apiserver的启动参数--runtime-config进行设置,默认是启用的。
(2)建议创建一个RBAC规则,允许添加APIService资源对象,因为API扩展对整个Kubernetes集群都生效,所以不推荐在生产环境中对API扩展进行开发或测试。

(3)创建一个新的Namespace用于运行扩展的API Server。
(4)创建一个CA证书用于对自定义API Server的HTTPS安全访问进行签名。
(5)创建服务端证书和秘钥用于自定义API Server的HTTPS安全访问。服务端证书应该由上面提及的CA证书进行签名,也应该包含含有DNS域名格式的CN名称。
(6)在新的Namespace中使用服务端证书和秘钥创建Kubernetes Secret对象。
(7)部署自定义API Server实例,通常可以以Deployment形式进行部署,并且将之前创建的Secret挂载到容器内部。该Deployment也应被部署在新的Namespace中。
(8)确保自定义的API Server通过Volume加载了Secret中的证书,这将用于后续的HTTPS握手校验。
(9)在新的Namespace中创建一个Service Account对象。
(10)创建一个ClusterRole用于对自定义API资源进行操作。
(11)使用之前创建的ServiceAccount为刚刚创建的ClusterRole创建一个ClusterRolebinding。
(12)使用之前创建的ServiceAccount为系统ClusterRole“system:auth-delegator”创建一个ClusterRolebinding,以使其可以将认证决策代理转发给Kubernetes核心API Server。
(13)使用之前创建的ServiceAccount为系统Role“extension-apiserver-authenticationreader”创建一个Rolebinding,以允许自定义API Server访问名为“extension-apiserverauthentication”的系统ConfigMap。

(14)创建APIService资源对象。
(15)访问APIService提供的API URL路径,验证对资源的访问能否成功。

下面以部署Metrics Server为例,说明一个聚合API的实现方式。

随着API聚合机制的出现,Heapster也进入弃用阶段,逐渐被Metrics Server替代。Metrics Server通过聚合API提供Pod和Node的资源使用数据,供HPA控制器、VPA控制器及kubectl top命令使用。Metrics Server的源码可以在GitHub代码库(https://github.com/kubernetes-incubator/metrics-server)找到,在部署完成后,Metrics Server将通过Kubernetes核心API Server的“/apis/metrics.k8s.io/v1beta1”路径提供Pod和Node的监控数据。

首先,部署Metrics Server实例,在下面的YAML配置中包含一个ServiceAccount、一个Deployment和一个Service的定义:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metrics-server
  namespace: kube-system
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  template:
    metadata:
      name: metrics-server
      labels:
        k8s-app: metrics-server
    spec:
      serviceAccountName: metrics-server
      containers:
      - name: metrics-server
        image: k8s.gcr.io/metrics-server-amd64:v0.3.1
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: tmp-dir
          mountPath: /tmp
      volumes:
      - name: tmp-dir
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    kubernetes.io/name: "Metrics-server"
spec:
  selector:
    k8s-app: metrics-server
  ports:
  - port: 443
    protocol: TCP
    targetPort: 443

然后,创建Metrics Server所需的RBAC权限配置:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: system:aggregated-metrics-reader
  labels:
    rbac.authorization.k8s.io/aggregate-to-view: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
rules:
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: system:metrics-server
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - nodes
  - nodes/stats
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:metrics-server
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:metrics-server
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: metrics-server:system:auth-delegator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: metrics-server-auth-reader
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system

最后,定义APIService资源,主要设置自定义API的组(group)、版本号(version)及对应的服务(metrics-server.kube-system):

apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  name: v1beta1.metrics.k8s.io
spec:
  service:
    name: metrics-server
    namespace: kube-system
  group: metrics.k8s.io
  version: v1beta1
  insecureSkipTLSVerify: true
  groupPriorityMinimum: 100
  versionPriority: 100

在所有资源都成功创建之后,在命名空间kube-system中会看到新建的metrics-server Pod。

通过Kubernetes Master API Server的URL“/apis/metrics.k8s.io/v1beta1”就能查询到Metrics Server提供的Pod和Node的性能数据了

# curl http://192.168.18.3:8080/apis/metrics.k8s.io/v1beta1/nodes

# curl http://192.168.18.3:8080/apis/metrics.k8s.io/v1beta1/pods

 

小结: 

          本节内容到此结束,大家可以尝试这来玩一下。

 

 

你可能感兴趣的:(kubernetes)