Kubernetes API Server 功能
Kubernete API Server 的核心功能主要是为 Kubernetes 的各类资源对象 (如 node,pod,service 等) 提供了增, 删, 改, 查以及 watch 的 HTTP Rest 接口.
API server 是集群中各个功能模块之间数据交互和通信的中心枢纽, 除此之外它还有以下特性:
集群管理的 API 入口
资源配额控制的入口
提供完备的集群安全机制
常规 API 接口
Kubernetes 的 API server 通过 kube-apiserver 进程提供服务, 一般会监听两个端口, http 的 8080(使用参数 --insecure-port)和 使用 https 的 6443 端口(--secure-port=6443), 两者功能相同, 只 https 安全性更高.
常用的 kubectl 命令, 也是通过与 API Server 的 REST 调用来实现交互.
通过使用 curl 命令能直接获取 REST api 的信息.
通过本地 8080 端口查看版本:
- [root@node-1 ~]# curl 127.0.0.1:8080/api
- {
- "kind": "APIVersions",
- "versions": [
- "v1"
- ],
- "serverAddressByClientCIDRs": [
- {
- "clientCIDR": "0.0.0.0/0",
- "serverAddress": "10.0.0.1:6443"
- }
- ]
- }
查看支持的资源对象:
curl 127.0.0.1:8080/api/v1
查看资源对象信息:
- curl 127.0.0.1:8080/api/v1/nodes
- curl 127.0.0.1:8080/api/v1/pods
- curl 127.0.0.1:8080/api/v1/services
- curl 127.0.0.1:8080/api/v1/replicationcontrollers
可以具体到某一个具体的对象:
curl 127.0.0.1:8080/api/v1/nodes/10.0.0.3
也可以指定不同 namespace 中的对象进行访问:
curl http://127.0.0.1:8080/api/v1/namespaces/default/services/php-apache
也可以直接访问后端服务内容:
- curl http://127.0.0.1:8080/api/v1/namespaces/default/services/http:tomcat-service:/proxy/
- curl http://127.0.0.1:8080/api/v1/namespaces/default/services/http:php-apache:/proxy/
除此之外还有其他的 API 信息:
curl 127.0.0.1:8080/apis/batch/v1
Kubernets Proxy API 接口
Kubernetes Proxy 主要用于代理 REST 请求. 可以通过这种代理方式将 API Server 收到的 REST 请求转发到某个 Node 上的 kubelet 上, 由 Kubelet 负责响应.
创建一个 Proxy 接口:
kubectl proxy --port=8001 --accept-hosts='.*' --address='10.0.0.1' &
此处创建一个监听本地 10.0.0.1 上的 8001 端口.
如果需要对访问的资源和源地址进行限制, 可以使用正则进行匹配, 限制对 services 进行访问:
kubectl proxy --port=8001 --accept-hosts='.*' --address=10.0.0.1 --reject-paths='^/api/v1/services'
通过此端口可以在外部直接访问此 api 代理, 在新的版本中, 访问方式和常规访问的 URL 一致:
- curl http://10.0.0.1:8001/api/v1/pods
- curl http://10.0.0.1:8001/api/v1/nodes
- curl http://10.0.0.1:8001/api/v1/services
- curl http://10.0.0.1:8001/api/v1/replicationcontrollers
- curl http://10.0.0.1:8001/api/v1/namespaces/default/pods/tomcat-deployment-65799d5fc4-5dx4h
- curl http://10.0.0.1:8001/api/v1/namespaces/default/services/http:php-apache:/proxy/
- curl 10.0.0.1:8001/apis/batch/v1
API server 和集群模块的交互
API Server 作为集群的核心, 负责集群各个功能模块之间的通信, 集群中的各个功能模块通过 API Server 将信息存入 etcd 数据库中, 获取这些数据就通过 API Server 提供的 REST 接口通过使用 GET,LIST, 或者 Watch 方法, 从而实现对各个模块之间的交互.
查看 ETCD 数据
ETCD V3 操作说明 https://github.com/doczhcn/etcd/blob/master/documentation/dev-guide/interacting_v3.md
参考链接 https://jimmysong.io/kubernetes-handbook/guide/using-etcdctl-to-access-kubernetes-data.html
在使用 ETCD V3 的版本时, 由于为了实现兼容性, etcd 默认使用的是 v2 的接口, Kubernetes 中需要使用 V3 的接口来查看数据, 所以查看前添加此参数:
- export ETCDCTL_API=3 # 修改默认接口版本为 V3
- export ETCDCTL_API=2 # 修改默认接口版本为 V2
在 V3 和 V2 中, 两者支持的命令是不一样的, 如在 V2 版本有 etcdctl ls 命令, 但是在 V3 版本中就没有, 指定接口版本后, 对应的 help 信息也会改变.
在使用默认的 V2 接口时, 使用 ls 命令只能看到一个目录:
- # 如果没有 TLS 进行 CA 设置直接执行:
- # etcdctl ls
- /kubernetes
- # 如果设置了 CA 认证, 使用如下参数, 指定证书和秘钥文件:
- # etcdctl --endpoints=https://10.0.0.1:2379 --ca-file=/opt/kubernetes/ssl/ca.pem --cert-file=/opt/kubernetes/ssl/etcd.pem --key-file=/opt/kubernetes/ssl/etcd-key.pem ls
- /kubernetes
这个 key 中只存储了少量的信息:
- [root@node-1 ~]# etcdctl --endpoints=https://10.0.0.2:2379 --ca-file=/opt/kubernetes/ssl/ca.pem --cert-file=/opt/kubernetes/ssl/etcd.pem --key-file=/opt/kubernetes/ssl/etcd-key.pem ls -r
- /kubernetes
- /kubernetes/network
- /kubernetes/network/config
- /kubernetes/network/subnets
- /kubernetes/network/subnets/10.2.70.0-24
- /kubernetes/network/subnets/10.2.67.0-24
- /kubernetes/network/subnets/10.2.49.0-24
- [root@node-1 ~]# etcdctl --endpoints=https://10.0.0.2:2379 --ca-file=/opt/kubernetes/ssl/ca.pem --cert-file=/opt/kubernetes/ssl/etcd.pem --key-file=/opt/kubernetes/ssl/etcd-key.pem get /kubernetes/network/subnets/10.2.49.0-24
- {"PublicIP":"10.0.0.2","BackendType":"vxlan","BackendData":{"VtepMAC":"a6:16:81:8a:af:71"}}
切换为 V3 接口, 获取 etcd 中的所有 key:
- export ETCDCTL_API=3
- # 无 ca 认证:
- [root@node-1 ~]# etcdctl get / --prefix --keys-only
- # CA 认证, 参数和 V2 版本不一样
- [root@node-1 ~]# etcdctl --endpoints=https://10.0.0.1:2379 --cacert=/opt/kubernetes/ssl/ca.pem --cert=/opt/kubernetes/ssl/etcd.pem --key=/opt/kubernetes/ssl/etcd-key.pem get / --prefix --keys-only
通过查询对应的 key, 可以获取 kubernete 对象的元数据:
[root@node-1 ~]# etcdctl --endpoints=https://10.0.0.1:2379 --cacert=/opt/kubernetes/ssl/ca.pem --cert=/opt/kubernetes/ssl/etcd.pem --key=/opt/kubernetes/ssl/etcd-key.pem get /registry/services/specs/default/php-apache -w=json|python -m json.tool
这里使用 json 格式化输出. 可以发现所有的数据都存放在 / registry / 开头的 key 中.
使用如下脚本, 对 key 值进行转换, 也能输出相同的 key 值列表:
- #!/bin/bash
- # Get kubernetes keys from etcd
- export ETCDCTL_API=3
- # not use ca TLS
- # keys=`etcdctl get /registry --prefix -w json|python -m json.tool|grep key|cut -d ":" -f2|tr -d '"'|tr -d","`
- # USE TLS ca
- keys=`etcdctl --cacert=/opt/kubernetes/ssl/ca.pem --cert=/opt/kubernetes/ssl/etcd.pem --key=/opt/kubernetes/ssl/etcd-key.pem get /registry --prefix -w json|python -m json.tool|grep key|cut -d ":" -f2|tr -d '"'|tr -d","`
- for x in $keys;do
- echo $x|base64 -d|sort
- done
key 的命名规则是按 / registry, 对象类型(复数),namespace, 具体对象名称命名.
API Server 与 kubelet 的交互
每个 Node 节点上的 kubelet 每隔一段时间就会向 API Server 的 REST 接口发送自身的状态信息.
API Server 收到这些信息后, 会更新到 etcd 中.
此外, kubelet 通过 API Server 的 watch 接口监听 Pod 的实时变化信息, 如果监听到新的 Pod 对象绑定到此节点, 则创建此 pod, 同理, 如果是 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.
来源: http://blog.51cto.com/tryingstuff/2138527