Kubernetes API服务器为API对象验证和配置数据,这些对象包含Pod、Service、ReplicationController等等。API Server提供REST操作以及前端到集群的共享状态,所有其他组件可以通过这些共享状态交互。
配置选项
- -admission-control:集群中资源的Admission Controller的插件的有序列表,分别使用逗号分隔;
- -advertise-address:广播API Server给所有集群成员的IP地址,其他集群可以访问该IP,如果为空,会使用
- -allow-privileged[=false]:true,表示允许特权容器;
- -authorization-mode=“AlwaysAllow”:安全端口授权插件的有序列表,分别以逗号分隔,AlwaysAllow,AlwaysDeny,ABAC-;
- authorization-policy-file=“”:授权策略的csv文件,使用于-authorization-mode=ABAC模式的配置;
- -basic-auth-file=“”:如果配置该选项,该文件会通过HTTP基本认证允许API Server安全端口的请求;
- -bind-address=0.0.0.0:服务-read-only-port和-secure-port端口的IP地址。相关端口必须是其他集群通过CLI/web客户端;
- -cert-dir=“/var/run/kubernetes/”:TLS证书目录(默认是/var/run/kubernetes)。
- -tls-cert-file和-tls-client-ca-file=“”:任何提交客户端证书的请求都会验证与相关客户端证书的CommonName的身份。(在1.5版本中--client_ca_file);
- -cloud-provide:“”:云提供商配置文件的路径,空表示没有该配置文件;
- -cloud-provider=””:云服务提供商,空表示没有该提供商;
- -cluster-name=“kubernetes”:集群实例的前缀;
- -cors-allowed-origins=[]:CORS的allowed origins的列表,用逗号分隔。一个allowed origins可以是-etcd-config=“”:ETCD客户端的配置文件,与-etcd-servers配置项互斥。
- -etcd-prefix=“/registry”:ETCD中所有资源路径的前缀;
- -etcd-servers=[]:ETCD服务器,与-etcd-config配置项互斥;
- -etcd-servers-overrides=[]:每个ETCD服务器覆盖文件,以逗号分隔;
- -expermental-keystone-url=“”:如果Passwd,激活keystone认证插件;
- -external-hostname=“”:为Master生成外部URLs使用的主机名;
- -google-json-key=“”:用户Google Cloud Platform Service Account JSON key认证;
- --insecure-bind-address=127.0.0.1:非安全端口(所有借口都设置为0.0.0.0)的服务IP地址,默认是本地地址。
- --insecure-port=8080:不安全且没有认证的进程访问端口,默认是8080;
- -kubelet-certificate-authority=“”:证书路径,证书授权文件;
- -kubelet-client-certificate=“”:TLS客户端证书文件路径;
- -kubelet-client-key=“”:TLS客户端秘钥文件路径;
- -kubelet--https[=true]:使用https建立Kubelet链接;
- -kubelet-port=10250:kubelet端口;
- -kubelet-timeout=5s:Kubelet操作Timeout值;
- -log-flush-frequency=5s:日志缓冲秒数的最大值;
- -long-running-request-regexp=“”:匹配长;
- -master-service-namespace=“default”:Namespace,该Namespace的Kubernetes主服务应该注入Pod;
- -max-connection-bytes-per-sec=0:如果非0,表示每个用户链接的最大值,字节数/秒,当前只适用于长时间运行的请求;
- -max-request-inflight=400:给定时间内运行请求的最大值。如果超过该最大值,该请求被拒绝。0表示没有限制;
- -min-request-timeout=1800:这是个可选字段,表示一个请求处理的最短时间,单位是秒,在超时之前,这个请求必须是激活的;
- -oidc-ca-file=“”:如果设置该选项,Oidc-ca-file中的相关机构会验证O喷ID服务的证书。否则会使用主机的根证书。
- -oidc-client-id=“”:如果设置了oidc-issue-url字那段,该字段,OpenID连接客户端的客户ID也必须设置;
- -oidc-issuer-url=“”:OpenID发行的URL,只接受HTTPS协议。如果设置该字段,将被用来验证OIDC JSON Web Token(JWT)
- -oidc-username-claim=“sub”:改进中;
- -runtime-config:key=value键值对集,描述运行时配置,也会回传到APIServer。apis/键值用于打开-secure-port=6443:用于HTTPS的认证和授权。0表示不支持HTTPS服务;
- -service-account-key-file=“”:该文件包含RPM-encoded x509 RSA的私钥和公钥,用于验证ServiceAccount的Token;
- -service-account-lookup[=false]:true,表示验证ServiceAccount的Token作为Authentication一部分在ETCD中的;
- -service-cluster-ip-range:
- -service-node-port-range:
- -ssh-user=“”:如果非空,使用安全SSH代理到该节点,用该用户名;
- -storage-versions:
- -tls-private-key-file:该文件包含x509私钥匹项-tls-cert-file;
- -token-auth-file=“”:该文件使用Token验证保护API Server的安全端口;
- -watch-cache[=true]:可以在API Server查看缓存;
Kubernetes API Server原理分析
总体来看,Kubernetes API Server的核心功能是提供了Kubernetes各类资源对象(如Pod、RC、Service等)的增、删、改、查及Watch等HTTP Rest接口,成为集群内各个功能模块之间数据交互和通信的中心枢纽,是整个系统的数据总线和数据中心。除此之外,他还有以下的特性:
- 是集群管理的API入口;
- 是资源配额控制的入口;
- 提供完备的集群安全机制;
Kubernetes API Server概述
Kubernetes API Server通过一个名为Kube-apiserver的进程提供服务,该进程运行在Master节点上。在默认情况下,kube-apiserver进程在本机的8080端口(对应参数--insecure-port)提供REST服务。我们可以同时启动HTTPS安全端口(--secure-port=6443)来启动安全机制,加强REST API访问的安全性。
通常我们可以通过命令行工具kubectl来与kubernetes API Server交互,他们之间的接口是REST调用。测试和学习的情况下也可以使用curl命令行工具进行快速验证。
比如,在Master节点上,运行下面的curl命令可以得到JSON方式返回的Kubernetes API的版本信息:
- curl localhost:8080/api
运行下面的命令查看Kubernetes API Server目前支持的资源对象的种类i:
- curl localhost:8080/api/v1
返回不同资源列表信息:
- curl localhost:8080/api/v1/pods
- curl localhost:8080/api/v1/services
- curl localhost:8080/api/v1/replicationcontrollers
如果我们只想对外暴露部分REST服务,则可以在Master或其他任何节点上通过运行kube-proxy进程启动一个内部代理来实现。
运行下面的命令,我们在8001端口启动代理,并且拒绝客户端访问RC的API:
- kubectl proxy --reject-paths=“^/api/v1/replicationcontrollers” --port=8001 --v=2
通过下面的命令进行验证:
- curl localhost:8001/api/v1/replicationcontrollers
kubectl proxy具有很多特性,最实用的一个特性是提供简单有效的安全机制,比如采用白名单来限制非法客户端访问时,只要采用下面的参数即可:
- --accept-host=“^localhost$,^127\.0\.0\.1$,^\[::1\]$”
最后一种方式是通过b编程的方式调用Kubernetes API Server。具体使用场景又细分为以下两种:
第一种使用场景:运行在Pod中的用户进程调用Kubernetes API,通常用来实现分布式集群搭建的目标。Pod中的进程如何知道API Server的访问地址呢,因为Kubernetes API Server本身也是一个Service,其名字就是Kubernetes,他的clusterIP地址是ClusterIP地址池中的第一个IP,他所服务的端口是HTTPS端口443,通过kubectl get svc可以确认这一点。
第二种使用场景:开发基于Kubernetes的管理平台。比如调用Kubernetes API 来完成Pod、Service、RC等资源对象的图形化创建和管理界面,此时可以使用kubernetes及各开源社区为开发人员提供的各种语言版本的Client Library。
独特的Kubernetes-Proxy API接口
这类接口的作用是代理REST请求,即kubernetes API Server把收到的REST请求转发到某个Node上的kubelet守护进程的REST端口上,由该kubelet进程负责响应。
Kubernetes Proxy API中管理Node的相关接口,该接口的REST路径为/api/v1/proxy/nodes/{name},其中name为节点名称或IP地址,包括以下几个具体的接口:
- /api/v1/proxy/nodes/{name}/pods #列出指定节点内的所有Pod的信息
- /api/v1/proxy/nodes/{name}/stats #列出指定节点内物理资源的统计信息
- /api/v1/proxy/nodes/{name}/spec #列出指定节点的概要信息
例:节点名为k8s-node-1,下面命令获取该节点上所有运行中的pod:
- curl localhost:8080/api/v1/proxy/nodes/k8s-node-1/pods
需要说明的是,此处获取pod信息数据来自Node而非etcd数据库,所以两者可能在某些时间点会有偏差。此外如果kubelet进程在启东时包含--enable-debugging-handles=true,namekubernetes Proxy API 还会增加下面的接口:
- /api/v1/proxy/nodes/{name}/run #在节点上运行某个容器
- /api/v1/proxy/nodes/{name}/exec #在节点的某个容器中运行某条命令
- /api/v1/proxy/nodes/{name}/attach #在节点上attach某个容器
- /api/v1/proxy/nodes/{name}/portForward #实现节点上的Pod端口转发
- /api/v1/proxy/nodes/{name}/logs #列出节点的各类日志信息,例如tallylog、lastlog、wtmp、ppp/、rhsm、audit、tuned、和anaconda等
- /api/v1/proxy/nodes/{name}/metrics #列出和该节点相关的Metrics信息
- /api/v1/proxy/nodes/{name}/runningpods #列出节点内运行中的Pod信息
- /api/v1/proxy/nodes/{name}/debug/pprof #列出节点内当前Web服务的状态,包括CPU和内存的使用情况
Kubernetes Proxy API里关于Pod的相关接口,通过这些接口,我们可以访问pod里某个容器提供的服务(如Tomcat在8080提供的服务)
- /api/v1/proxy/namespaces/{namespace}/pods/{name}/{patch:*} #访问pod的某个服务接口
- /api/v1/proxy/namespaces/{namespace}/pods/{name} #访问pod
- /api/v1/proxy/namespaces/{namespace}/pods/{name}/proxy/{patch:*} #访问pod的某个服务接口
- /api/v1/proxy/namespaces/{namespace}/pods/{name}/proxy #访问pod
在上面的4个接口中,后面两个接口的功能和前面两个完全一样,只是写法不同。
集群功能模块之间的通信
集群内各个功能模块通过API Server将信息存入etcd,当需要获取和操作这些数据时,则通过API Server提供的REST接口(用GET/LIST/WTCH方法)来实现,从而实现各模之间的信息交互;
例:kubelet进程与API Server的交互:每个node上的kubelet每隔一个时间周期,就会调用一次API Server的REST接口报告自身状态,API Server接收到这些信息后,将各节点信息更新到etcd中。此外kubelet也通过API Server的watch接口监听pod信息,如果监听到新的Pod副本被调度绑定到本节点,则执行Pod对应的容器的创建和启动逻辑;如果监听到Pod对象被删除,则删除本节点上的相应的Pod容器;如果监听到修改Pod信息,则kubelet监听到变化后,会相应的修改本节点的Pod容器。
例:另外一个交互场景:kube-controller-manager进程与API Server的交互。kube-controller-manager中的Node Controller模块通过API Server提供的Watch接口,实时监控Node的信息并做相应的处理;
例:kube-scheduler与API Server交互的场景,当scheduler通过API Server的Watch接口监听到新建Pod副本的信息后,他会检索所有符合该Pod要求的Node列表,开始执行Pod调度逻辑,调度成功后将Pod绑定到目标节点上。为了缓解集群各模块对API Server的压力,各功能模块都采用缓存的机制来缓存数据。各功能模块定时从API Server获取指定资源对象的信息(通过LIST或watch),然后将这些信息保存到本地缓存,功能模块在某些情况下不直接访问API Server,而是通过访问缓存数据来间接访问API Server